#include "MESH_Drawer.h" #include "MESH_DrawerCoreVisitor.h" #include using namespace std; namespace X3DTK { namespace MESH { Drawer::Drawer() : X3DOnePassProcessor(), drawPoints(false), drawEdges(true), drawFaces(true), selectedType(NOTHING) { setGraphTraversal(new DFSGraphTraversal()); setComponentVisitor(new DrawerCoreVisitor()); } Drawer::~Drawer() { Singleton::removeInstance(); } void Drawer::changeDrawPoints() { drawPoints = !drawPoints; } void Drawer::changeDrawEdges() { drawEdges = !drawEdges; } void Drawer::changeDrawFaces() { drawFaces = !drawFaces; } void Drawer::changeOneColorPerMesh() { Singleton::getInstance()->changeOneColorPerMesh(); } void Drawer::setSelectedType(SelectedType selectedType) { this->selectedType = selectedType; } void Drawer::setSelectedMesh(int selectedMesh) { this->selectedMesh = selectedMesh; } void Drawer::setSelectedId(int selectedId) { this->selectedId = selectedId; } void Drawer::drawMesh(X3DNode *N, bool selection) { Singleton::getInstance()->setSelectionMode(selection); if (selection || drawPoints) { Singleton::getInstance()->setPrimitiveType(VERTICES); Singleton::getInstance()->initTraversal(); traverse(N); Singleton::getInstance()->finishTraversal(); } if (selection || drawEdges) { Singleton::getInstance()->setPrimitiveType(EDGES); Singleton::getInstance()->initTraversal(); traverse(N); Singleton::getInstance()->finishTraversal(); } if (selection || drawFaces) { Singleton::getInstance()->setPrimitiveType(FACES); Singleton::getInstance()->initTraversal(); traverse(N); Singleton::getInstance()->finishTraversal(); } } void Drawer::drawSelected() { if (selectedType == NOTHING) return; glPushMatrix(); glMultMatrixf(Singleton::getInstance()->getMatrix(selectedMesh).toFloat16()); const Mesh *mesh = Singleton::getInstance()->getMesh(selectedMesh); bool normalPerVertex = mesh->data().getNormalPerVertex(); glEnable(GL_POLYGON_OFFSET_FILL); #ifdef GL_POLYGON_OFFSET_LINES glEnable(GL_POLYGON_OFFSET_LINES); #endif glPointSize(15.0); glLineWidth(8.0); switch (selectedType) { case NOTHING : break; case VERTICES : { glPointSize(25.0); SFVertex *vertex = (mesh->getVertices())[selectedId]; const SFVertex::MFFace &faces = vertex->getFaces(); // Normal SFFace *firstFace = (*(faces.begin())); SFVec3f normal; if (normalPerVertex) normal = vertex->data().getNormalOfFace(firstFace); else normal = firstFace->data().getNormal(); glNormal3fv(normal.f_data()); glColor3f(1.0, 1.0, 0.0); drawVertex(vertex); glColor3f(0.0, 0.8, 0.0); const SFVertex::MFEdge &edges = vertex->getEdges(); for (SFVertex::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e) drawEdge(*e); glColor3f(0.7, 0.9, 0.7); for (SFVertex::MFFace::const_iterator f = faces.begin(); f != faces.end(); ++f) drawFace(*f); break; } case EDGES : { glLineWidth(15.0); SFEdge *edge = (mesh->getEdges())[selectedId]; // Normal SFFace *firstFace = (*(edge->getLeftFaces().begin())); if (!firstFace) firstFace = (*(edge->getRightFaces().begin())); SFVec3f normal; if (normalPerVertex) normal = edge->getFromVertex()->data().getNormalOfFace(firstFace); else normal = firstFace->data().getNormal(); glNormal3fv(normal.f_data()); glColor3f(1.0, 1.0, 0.0); drawEdge(edge); glColor3f(0.0, 0.8, 0.0); drawVertex(edge->getFromVertex()); drawVertex(edge->getToVertex()); glColor3f(0.9, 0.7, 0.7); const SFEdge::MFFace &lfaces = edge->getLeftFaces(); for (SFEdge::MFFace::const_iterator lf = lfaces.begin(); lf != lfaces.end(); ++lf) drawFace(*lf); glColor3f(0.7, 0.9, 0.7); const SFEdge::MFFace &rfaces = edge->getRightFaces(); for (SFEdge::MFFace::const_iterator rf = rfaces.begin(); rf != rfaces.end(); ++rf) drawFace(*rf); break; } case FACES : { SFFace *face = (mesh->getFaces())[selectedId]; const SFFace::MFEdge &edges = face->getEdges(); SFFace::MFVertex vertices = face->getVertices(); // Normal SFEdge *firstEdge = (*(edges.begin())); SFVec3f normal; if (normalPerVertex) normal = firstEdge->getFromVertex()->data().getNormalOfFace(face); else normal = face->data().getNormal(); glNormal3fv(normal.f_data()); glColor3f(1.0, 1.0, 0.0); drawFace(face); for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e) { glColor3f(0.0, 0.8, 0.0); drawEdge(*e); } for (SFFace::MFVertex::const_iterator v = vertices.begin(); v != vertices.end(); ++v) { glColor3f(0.7, 0.7, 0.7); drawVertex(*v); } break; } } glDisable(GL_POLYGON_OFFSET_FILL); #ifdef GL_POLYGON_OFFSET_LINES glDisable(GL_POLYGON_OFFSET_LINES); #endif glPopMatrix(); } void Drawer::drawVertex(const SFVertex *vertex) { glBegin(GL_POINTS); SFPoint3f point = vertex->data().getPoint(); glVertex3fv(point.f_data()); glEnd(); } void Drawer::drawEdge(SFEdge *edge) { glPolygonOffset(-100, -100); glDisable(GL_LIGHTING); glBegin(GL_LINES); SFPoint3f point = edge->getFromVertex()->data().getPoint(); glVertex3fv(point.f_data()); point = edge->getToVertex()->data().getPoint(); glVertex3fv(point.f_data()); glEnd(); glEnable(GL_LIGHTING); glPolygonOffset(-2, -2); } void Drawer::drawFace(const SFFace *face) { const SFFace::MFEdge &edges = face->getEdges(); glBegin(GL_POLYGON); for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e) { SFPoint3f point = (*e)->getFromVertex()->data().getPoint(); glVertex3fv(point.f_data()); } glEnd(); } } }