1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
/*************************************************************************
* 2022 DLH van der Haven, dannyvdhaven@gmail.com *
* This program is free software, see file LICENSE for details. *
* Code here is based on the Gl1_PotentialParticle.*pp by CWBoon 2015 *
* for the implementation of potential particles in YADE. *
*************************************************************************/
#ifdef YADE_LS_DEM
#include "Gl1_LevelSet.hpp"
#ifdef YADE_OPENGL
#include <lib/opengl/OpenGLWrapper.hpp>
#endif
#include <core/Aabb.hpp>
#include <pkg/dem/ScGeom.hpp>
namespace yade { // Cannot have #include directive inside.
#ifdef YADE_OPENGL
bool Gl1_LevelSet::recompute;
bool Gl1_LevelSet::wire;
bool Gl1_LevelSet::surfNodes;
bool Gl1_LevelSet::surface;
void Gl1_LevelSet::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& /*state*/, bool wire2, const GLViewInfo&)
{
// Get the level set shape
LevelSet* LS = static_cast<LevelSet*>(cm.get());
// Render the surface nodes
glPointSize(15.f);
Vector3r pointColor = Vector3r(cm->color[0] > 0.5 ? 0 : 1, cm->color[1] > 0.5 ? 0 : 1, cm->color[2] > 0.5 ? 0 : 1);
glColor3v(pointColor);
if (surfNodes) {
glBegin(GL_POINTS)
;
for (unsigned int i1 = 0; i1 < LS->surfNodes.size(); i1++) {
glVertex3v(LS->surfNodes[i1]);
}
glEnd();
}
if (surface) {
if (recompute) { // Update the triangulation if we want that (necessary for fracturing or deforming particles)
LS->computeMarchingCubes();
}
// Retrieve the triangulation (initialisation is done automatically within the level set shape)
const vector<Vector3r>& triangles = LS->getMarchingCubeTriangles(); //mc.getTriangles();
const vector<Vector3r>& normals = LS->getMarchingCubeNormals(); //mc.getNormals();
int nbTriangles = LS->getMarchingCubeNbTriangles(); //mc.getNbTriangles();
glColor3v(cm->color); //glColor3v is used when lighting is not enabled
if (wire || wire2) {
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Turn on wireframe mode. Render front and back faces of the wireframe
} else {
// glEnable(GL_NORMALIZE); //Not needed for vertex-based shading. The normals have been normalised inside the Marching Cubes script
glMaterialv(
GL_FRONT_AND_BACK,
GL_AMBIENT_AND_DIFFUSE,
Vector3r(cm->color[0], cm->color[1], cm->color[2])); //glMaterialv is used when lighting is enabled
glDisable(GL_CULL_FACE);
// glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING); // 2D
glPolygonMode(GL_FRONT, GL_FILL); // Turn off wireframe mode
}
// // VERTEX-BASED SHADING: Use the normal vector of each vertex of each triangle (makes the shading of each face look smoother)
glBegin(GL_TRIANGLES)
;
for (int i = 0; i < 3 * nbTriangles; i += 3) {
glNormal3v(normals[i + 2]);
glVertex3v(
triangles[i + 2]); //vertex #2 The sequence of the vertices specifies which side of the faces is front and which is back
glNormal3v(normals[i + 1]);
glVertex3v(triangles[i + 1]); //vertex #1
glNormal3v(normals[i + 0]);
glVertex3v(triangles[i + 0]); //vertex #0
}
glEnd();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
return;
}
YADE_PLUGIN((Gl1_LevelSet));
#endif // YADE_OPENGL
} // namespace yade
#endif //YADE_LS_DEM
|