static void _relocateVertexOfPyramid(MVertex *ver, const std::vector<MElement *> <, double relax) { if(ver->onWhat()->dim() != 3) return; double x = 0.0, y = 0.0, z = 0.0; int N = 0; MElement *pyramid = NULL; for(std::size_t i = 0; i < lt.size(); i++) { double XCG = 0.0, YCG = 0.0, ZCG = 0.0; if(lt[i]->getNumVertices() == 5) pyramid = lt[i]; else { for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) { XCG += lt[i]->getVertex(j)->x(); YCG += lt[i]->getVertex(j)->y(); ZCG += lt[i]->getVertex(j)->z(); } x += XCG; y += YCG; z += ZCG; N += lt[i]->getNumVertices(); } } x /= N; y /= N; z /= N; if(pyramid) { MFace q = pyramid->getFace(4); double A = q.approximateArea(); SVector3 n = q.normal(); n.normalize(); SPoint3 c = q.barycenter(); SVector3 d(x - c.x(), y - c.y(), z - c.z()); if(dot(n, d) < 0) n = n * (-1.0); double H = .5 * sqrt(fabs(A)); double XOPT = c.x() + relax * H * n.x(); double YOPT = c.y() + relax * H * n.y(); double ZOPT = c.z() + relax * H * n.z(); double FULL_MOVE_OBJ = objective_function(1.0, ver, XOPT, YOPT, ZOPT, lt, true); // printf("relax %g obj %g\n",relax,FULL_MOVE_OBJ); if(FULL_MOVE_OBJ > 0.1) { ver->x() = XOPT; ver->y() = YOPT; ver->z() = ZOPT; return; } } }
/* 1.31 CreateMFaces creates a static MFaces-object from a list of faces. */ MFaces Face::CreateMFaces(vector<Face> *faces) { MFaces ret; for (unsigned int i = 0; i < faces->size(); i++) { MFace mf = (*faces)[i].GetMSegs(false); for (unsigned int j = 0; j < (*faces)[i].holes.size(); j++) { mf.AddConcavity((*faces)[i].holes[j].GetMSegs(false)); } mf.MergeConcavities(); ret.AddMFace(mf); } return ret; }
void MeshPainter::drawMarkedFacesPass(MMesh *mesh) { Array<MFace*> &faces = mesh->getFaces(); int first = 0; int last = faces.size() - 1; glDepthMask( GL_FALSE ); glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); glBegin( GL_TRIANGLES ); glColor4( getMarkedFaceColour(), getMarkedFaceAlpha() ); for (int i = first; i <= last; i++) { MFace *fc = faces[i]; if ( fc->isFaceMarked() ) { const Tesselation *t = fc->getTesselation(); if ( t != NULL ) { for (int i = 0; i < t->size(); i++) { drawFaceMark( fc, t->at( i ).a, t->at( i ).b, t->at( i ).c ); } } else { int a = 0, b = 1; for (int c = 2; c < fc->getSize(); c++) { drawFaceMark( fc, a, b, c ); b = c; } } } } glEnd(); glDepthMask( GL_TRUE ); }
bool MFace::computeCorrespondence(const MFace &other, int &rotation, bool &swap) const { rotation = 0; swap = false; if (*this == other) { for (int i = 0; i < getNumVertices(); i++) { if (_v[0] == other.getVertex(i)) { rotation = i; break; } } if (_v[1] == other.getVertex((rotation + 1) % getNumVertices())) swap = false; else swap = true; return true; } return false; }
void MeshPainter::drawSolidTransparent(MMesh *mesh, bool smooth) { Array<MFace*> &faces = mesh->getFaces(); int first = 0; int last = faces.size() - 1; setupTransparentMaterial(); glBegin( GL_TRIANGLES ); for (int i = first; i <= last; i++) { MFace *fc = faces[i]; const Tesselation *t = fc->getTesselation(); if ( t != NULL ) { for (int i = 0; i < t->size(); i++) { drawUntexturedFace( fc, t->at( i ).a, t->at( i ).b, t->at( i ).c, smooth ); } } else { int a = 0, b = 1; for (int c = 2; c < fc->getSize(); c++) { drawUntexturedFace( fc, a, b, c, smooth ); b = c; } } } glEnd(); }
void MeshPainter::drawMeshUV(ViewportUVSettings *viewportSettings, GSProductMesh *meshProduct) { MMesh *mesh = &( meshProduct->getMMeshForDisplay() ); if ( mesh->getVertices().size() == 0 ) { return; } Array<MFace*> &faces = mesh->getFaces(); glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); glBegin( GL_LINES ); glColor4( getUVEdgeColour(), getUVEdgeAlpha() ); for (int i = 0; i < faces.size(); i++) { MFace *fc = faces[i]; int a = fc->getSize() - 1; for (int b = 0; b < fc->getSize(); b++) { glVertex3( fc->getVertexAttrib( a )->getPoint() ); glVertex3( fc->getVertexAttrib( b )->getPoint() ); a = b; } } glEnd(); }
static void drawVoronoiDual(std::vector<T*> &elements) { glColor4ubv((GLubyte *) & CTX::instance()->color.fg); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x0F0F); gl2psEnable(GL2PS_LINE_STIPPLE); glBegin(GL_LINES); for(unsigned int i = 0; i < elements.size(); i++){ T *ele = elements[i]; if(!isElementVisible(ele)) continue; SPoint3 pc = ele->circumcenter(); if(ele->getDim() == 2){ for(int j = 0; j < ele->getNumEdges(); j++){ MEdge e = ele->getEdge(j); SVector3 p2p1(e.getVertex(1)->x() - e.getVertex(0)->x(), e.getVertex(1)->y() - e.getVertex(0)->y(), e.getVertex(1)->z() - e.getVertex(0)->z()); SVector3 pcp1(pc.x() - e.getVertex(0)->x(), pc.y() - e.getVertex(0)->y(), pc.z() - e.getVertex(0)->z()); double alpha = dot(pcp1,p2p1) / dot(p2p1,p2p1); SPoint3 p((1 - alpha)*e.getVertex(0)->x() + alpha * e.getVertex(1)->x(), (1 - alpha)*e.getVertex(0)->y() + alpha * e.getVertex(1)->y(), (1 - alpha)*e.getVertex(0)->z() + alpha * e.getVertex(1)->z()); glVertex3d(pc.x(), pc.y(), pc.z()); glVertex3d(p.x(), p.y(), p.z()); } } else if(ele->getDim() == 3){ for(int j = 0; j < ele->getNumFaces(); j++){ MFace f = ele->getFace(j); SPoint3 p = f.barycenter(); glVertex3d(pc.x(), pc.y(), pc.z()); glVertex3d(p.x(), p.y(), p.z()); for(int k = 0; k < f.getNumVertices(); k++){ MEdge e(f.getVertex(k), (k == f.getNumVertices() - 1) ? f.getVertex(0) : f.getVertex(k + 1)); SPoint3 pe = e.barycenter(); glVertex3d(p.x(), p.y(), p.z()); glVertex3d(pe.x(), pe.y(), pe.z()); } } } } glEnd(); glDisable(GL_LINE_STIPPLE); gl2psDisable(GL2PS_LINE_STIPPLE); }
void updateBoVec<3, MFace>( const int normalSource, const MVertex *const vertex, const int zoneIndex, const int vertIndex, const CCon::FaceVector<MZoneBoundary<3>::GlobalVertexData<MFace>::FaceDataB> &faces, ZoneBoVec &zoneBoVec, BCPatchIndex &patch, bool &warnNormFromElem) { GEntity *ent; if(normalSource == NormalSourceElement) goto getNormalFromElements; ent = vertex->onWhat(); if(ent == 0) { goto getNormalFromElements; // No entity: try to find a normal from the faces } else { switch(ent->dim()) { case 0: case 1: /*--------------------------------------------------------------------* * In this case, there are possibly multiple GFaces from this zone * connected to the vertex. One patch for each GFace will be written. *--------------------------------------------------------------------*/ { //--Get a list of face entities connected to 'ent' std::list<GFace *> gFaceList; switch(ent->dim()) { case 0: { std::vector<GEdge *> gEdgeList = ent->edges(); std::list<GFace *> gFaceList; for(std::vector<GEdge *>::const_iterator gEIt = gEdgeList.begin(); gEIt != gEdgeList.end(); ++gEIt) { std::vector<GFace *> alist = (*gEIt)->faces(); gFaceList.insert(gFaceList.end(), alist.begin(), alist.end()); } // Remove duplicates gFaceList.sort(); gFaceList.unique(); } break; case 1: { std::vector<GFace *> fac = ent->faces(); gFaceList.insert(gFaceList.end(), fac.begin(), fac.end()); } break; } //--Get a list of face entities connected to the 'vertex' that are also // in the //--zone std::list<const GFace *> useGFace; std::vector<GEdge *> gEdgeList; const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(zoneIndex == faces[iFace].zoneIndex) { bool matchedFace = false; MFace mFace = faces[iFace].parentElement->getFace(faces[iFace].parentFace); const int nVOnF = mFace.getNumVertices(); int vertexOnF = 0; // The index of 'vertex' in the face for(int iVOnF = 0; iVOnF != nVOnF; ++iVOnF) { const MVertex *const vertex2 = mFace.getVertex(iVOnF); if(vertex == vertex2) vertexOnF = iVOnF; else { const GEntity *const ent2 = vertex2->onWhat(); if(ent2->dim() == 2) { matchedFace = true; useGFace.push_back(static_cast<const GFace *>(ent2)); break; } } } // Triangle MElements are a total P.I.T.A.: // - If the original 'ent' is a vertex, one MVertex can be on the // GVertex, and the other two on GEdges, and then the MElement is // still on the GFace. // - If the original 'ent' is an edge, one MVertex can be on the // original GEdge, another on a GVertex, and the final on another // GEdge, and then the MElement is still on the GFace. There is // also the unlikely case where the two other MVertex are both on // edges ... and the MElement is still on the GFace. if(!matchedFace && (3 == nVOnF)) { const MVertex *vertex2 = 0; const MVertex *vertex3 = 0; switch(vertexOnF) { case 0: vertex2 = mFace.getVertex(1); vertex3 = mFace.getVertex(2); break; case 1: vertex2 = mFace.getVertex(0); vertex3 = mFace.getVertex(2); break; case 2: vertex2 = mFace.getVertex(0); vertex3 = mFace.getVertex(1); break; } if(vertex2 && vertex3) { const GEntity *const ent2 = vertex2->onWhat(); const GEntity *const ent3 = vertex3->onWhat(); if(ent2 && ent3) { if(ent2->dim() == 1 && ent3->dim() == 1) { // Which GFace is bounded by edges ent2 and ent3? for(std::list<GFace *>::const_iterator gFIt = gFaceList.begin(); gFIt != gFaceList.end(); ++gFIt) { gEdgeList = (*gFIt)->edges(); if((std::find(gEdgeList.begin(), gEdgeList.end(), ent2) != gEdgeList.end()) && (std::find(gEdgeList.begin(), gEdgeList.end(), ent3) != gEdgeList.end())) { // Edges ent2 and ent3 bound this face useGFace.push_back(*gFIt); break; } } } else if(ent->dim() == 1 && (ent2->dim() + ent3->dim() == 1)) { const GEntity *entCmp; if(ent2->dim() == 1) entCmp = ent2; else entCmp = ent3; // Which GFace is bounded by entCmp for(std::list<GFace *>::const_iterator gFIt = gFaceList.begin(); gFIt != gFaceList.end(); ++gFIt) { gEdgeList = (*gFIt)->edges(); if(std::find(gEdgeList.begin(), gEdgeList.end(), entCmp) != gEdgeList.end()) { // Edge entCmp and the original edge bound this face useGFace.push_back(*gFIt); break; } } } } } } // Stupid triangles } // End if face in zone } // End loop over faces // Duplicates are a possibility, remove useGFace.sort(); useGFace.unique(); //--'useGFace' now contains the face entities that connect to vertex. A // BC //--patch will be written for each of them. for(std::list<const GFace *>::const_iterator gFIt = useGFace.begin(); gFIt != useGFace.end(); ++gFIt) { SPoint2 par; if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), *gFIt, par)) goto getNormalFromElements; // :P After all that! SVector3 boNormal = (*gFIt)->normal(par); SPoint3 interior(0., 0., 0.); int cFace = 0; const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { ++cFace; interior += faces[iFace].parentElement->barycenter(); } } interior /= cFace; if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.) boNormal.negate(); zoneBoVec.push_back( VertexBoundary(zoneIndex, (*gFIt)->tag(), boNormal, const_cast<MVertex *>(vertex), vertIndex)); patch.add((*gFIt)->tag()); } } break; case 2: /*--------------------------------------------------------------------* * The vertex exists on a face and belongs to only 1 BC patch. *--------------------------------------------------------------------*/ { const GFace *const gFace = static_cast<const GFace *>(ent); SPoint2 par; if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), gFace, par)) goto getNormalFromElements; SVector3 boNormal = static_cast<const GFace *>(ent)->normal(par); SPoint3 interior(0., 0., 0.); int cFace = 0; const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { ++cFace; interior += faces[iFace].parentElement->barycenter(); } } interior /= cFace; if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.) boNormal.negate(); zoneBoVec.push_back(VertexBoundary(zoneIndex, gFace->tag(), boNormal, const_cast<MVertex *>(vertex), vertIndex)); patch.add(gFace->tag()); } break; default: goto getNormalFromElements; } } return; getNormalFromElements:; /*--------------------------------------------------------------------* * Geometry information cannot be used - generate normals from the * elements *--------------------------------------------------------------------*/ { if(warnNormFromElem && normalSource == 1) { Msg::Warning("Some or all boundary normals were determined from mesh " "elements instead of from the geometry"); warnNormFromElem = false; } // Sum the normals from each element connected to the vertex and in the // zone. Each normal has to be converted independently into an inwards- // pointing normal. //**Weight each normal by the area of the boundary element? SVector3 boNormal(0.); const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { // Normal to the boundary (unknown direction) SVector3 bnt = faces[iFace].parentElement->getFace(faces[iFace].parentFace).normal(); // Inwards normal const SVector3 inwards(vertex->point(), faces[iFace].parentElement->barycenter()); if(dot(bnt, inwards) < 0.) bnt.negate(); boNormal += bnt; } } boNormal.normalize(); zoneBoVec.push_back(VertexBoundary( zoneIndex, 0, boNormal, const_cast<MVertex *>(vertex), vertIndex)); patch.add(0); } }
/* 1.2 ~AddFace~ adds an additional MFace to this MFaces-object */ void MFaces::AddMFace(MFace face) { if (!face.isEmpty()) faces.push_back(face); }
float sdf( const Point& q, const Mesh &mesh, const vector<double>& weights, KdTree& kd_tree, const Triangulation& triang ) { VECTOR3 query (CGAL::to_double(q.x()), CGAL::to_double(q.y()), CGAL::to_double(q.z())); kd_tree.queryPosition(query); // Initialize the search structure, and search all N points int n_vid = kd_tree.getNeighbourPositionIndex(0); if(n_vid == -1) throw std::runtime_error("No nearest neighbor. MDS empty?"); CGAL_assertion( ! mesh.vert_list[n_vid].iso()); MVertex nv = mesh.vert_list[n_vid]; double min_sq_d = HUGE; int n_fid = -1; for(int i = 0; i < nv.num_inc_face; i ++) { MFace f = mesh.face_list[nv.inc_face(i)]; Point p[3] = {mesh.vert_list[f.get_corner(0)].point(), mesh.vert_list[f.get_corner(1)].point(), mesh.vert_list[f.get_corner(2)].point()}; Triangle_3 t (p[0], p[1], p[2]); Plane_3 H (p[0], p[1], p[2]); Point _q = H.projection(q); // check if _q is inside t. if( t.has_on(_q) ) { double sq_d = CGAL::to_double((q-_q)*(q-_q)); if( sq_d < min_sq_d ) { min_sq_d = sq_d; n_fid = nv.inc_face(i); } } else { for(int j = 0; j < 3; j ++) { double _d = CGAL::to_double(CGAL::squared_distance(_q,Segment(p[j], p[(j+1)%3]))); double sq_d = CGAL::to_double((q-_q)*(q-_q)) + _d; if( sq_d < min_sq_d ) { min_sq_d = sq_d; n_fid = nv.inc_face(i); } } } } // locate the query point in the triang which is already tagged // with in-out flag by the reconstruction. bool is_q_outside = false; Triangulation::Locate_type lt; int u = -1, v = -1; Cell_handle c = triang.locate(q, lt, u, v); if( lt == Triangulation::OUTSIDE_AFFINE_HULL ) { is_q_outside = true; cerr << "Point " << q << " is outside the affine hull." << endl; } else if( lt == Triangulation::OUTSIDE_CONVEX_HULL ) is_q_outside = true; else { if( lt == Triangulation::CELL ) { if( c->outside ) is_q_outside = true; else is_q_outside = false; } else if( lt == Triangulation::FACET ) { Cell_handle _c = c->neighbor(u); if( c->outside && _c->outside ) is_q_outside = true; else is_q_outside = false; } else if( lt == Triangulation::EDGE ) { if( is_outside_VF(triang, Edge(c, u, v)) ) is_q_outside = true; else is_q_outside = false; } else { CGAL_assertion( lt == Triangulation::VERTEX ); is_q_outside = false; } } double w; if(weights.size() && mesh.face_list[n_fid].label != -1) w = weights[mesh.face_list[n_fid].label]; else w = 1.0; // double w = mesh.face_list[n_fid].w; double gen_sdf = 0; if( is_q_outside ) gen_sdf = w*sqrt(min_sq_d); else gen_sdf = -w*min_sq_d; #if 0 double MAX = 10, MIN = -10; if( gen_sdf > MAX ) gen_sdf = MAX; if( gen_sdf < MIN ) gen_sdf = MIN; #endif return gen_sdf; }
void highOrderTools::computeStraightSidedPositions() { _clean(); // compute straigh sided positions that are actually X,Y,Z positions // that are NOT always on curves and surfaces // points classified on model vertices shall not move ! for(GModel::viter it = _gm->firstVertex(); it != _gm->lastVertex(); ++it){ if ((*it)->points.size()){ MPoint *p = (*it)->points[0]; MVertex *v = p->getVertex(0); _straightSidedLocation [v] = SVector3((*it)->x(),(*it)->y(),(*it)->z()); _targetLocation [v] = SVector3((*it)->x(),(*it)->y(),(*it)->z()); } } // printf("coucou2\n"); // compute stright sided positions of vertices that are classified on model edges for(GModel::eiter it = _gm->firstEdge(); it != _gm->lastEdge(); ++it){ for (unsigned int i=0;i<(*it)->lines.size();i++){ MLine *l = (*it)->lines[i]; int N = l->getNumVertices()-2; SVector3 p0((*it)->lines[i]->getVertex(0)->x(), (*it)->lines[i]->getVertex(0)->y(), (*it)->lines[i]->getVertex(0)->z()); SVector3 p1((*it)->lines[i]->getVertex(1)->x(), (*it)->lines[i]->getVertex(1)->y(), (*it)->lines[i]->getVertex(1)->z()); for (int j=1;j<=N;j++){ const double xi = (double)(j)/(N+1); // printf("xi = %g\n",xi); const SVector3 straightSidedPoint = p0 *(1.-xi) + p1*xi; MVertex *v = (*it)->lines[i]->getVertex(j+1); if (_straightSidedLocation.find(v) == _straightSidedLocation.end()){ _straightSidedLocation [v] = straightSidedPoint; _targetLocation[v] = SVector3(v->x(),v->y(),v->z()); } } } } // printf("coucou3\n"); // compute stright sided positions of vertices that are classified on model faces for(GModel::fiter it = _gm->firstFace(); it != _gm->lastFace(); ++it){ for (unsigned int i=0;i<(*it)->mesh_vertices.size();i++){ MVertex *v = (*it)->mesh_vertices[i]; _targetLocation[v] = SVector3(v->x(),v->y(),v->z()); } for (unsigned int i=0;i<(*it)->triangles.size();i++){ MTriangle *t = (*it)->triangles[i]; MFace face = t->getFace(0); const nodalBasis* fs = t->getFunctionSpace(); for (int j=0;j<t->getNumVertices();j++){ if (t->getVertex(j)->onWhat() == *it){ const double t1 = fs->points(j, 0); const double t2 = fs->points(j, 1); SPoint3 pc = face.interpolate(t1, t2); _straightSidedLocation [t->getVertex(j)] = SVector3(pc.x(),pc.y(),pc.z()); } } } for (unsigned int i=0;i<(*it)->quadrangles.size();i++){ // printf("coucou quad %d\n",i); MQuadrangle *q = (*it)->quadrangles[i]; MFace face = q->getFace(0); const nodalBasis* fs = q->getFunctionSpace(); for (int j=0;j<q->getNumVertices();j++){ if (q->getVertex(j)->onWhat() == *it){ const double t1 = fs->points(j, 0); const double t2 = fs->points(j, 1); SPoint3 pc = face.interpolate(t1, t2); _straightSidedLocation [q->getVertex(j)] = SVector3(pc.x(),pc.y(),pc.z()); } } } } for(GModel::riter it = _gm->firstRegion(); it != _gm->lastRegion(); ++it){ for (unsigned int i=0;i<(*it)->mesh_vertices.size();i++){ MVertex *v = (*it)->mesh_vertices[i]; _targetLocation[v] = SVector3(v->x(),v->y(),v->z()); } for (unsigned int i=0;i<(*it)->tetrahedra.size();i++){ _dim = 3; MTetrahedron *t = (*it)->tetrahedra[i]; MTetrahedron t_1 ((*it)->tetrahedra[i]->getVertex(0), (*it)->tetrahedra[i]->getVertex(1), (*it)->tetrahedra[i]->getVertex(2), (*it)->tetrahedra[i]->getVertex(3)); const nodalBasis* fs = t->getFunctionSpace(); for (int j=0;j<t->getNumVertices();j++){ if (t->getVertex(j)->onWhat() == *it){ double t1 = fs->points(j, 0); double t2 = fs->points(j, 1); double t3 = fs->points(j, 2); SPoint3 pc; t_1.pnt(t1, t2, t3,pc); _straightSidedLocation [t->getVertex(j)] = SVector3(pc.x(),pc.y(),pc.z()); } } } for (unsigned int i=0;i<(*it)->hexahedra.size();i++){ _dim = 3; MHexahedron *h = (*it)->hexahedra[i]; MHexahedron h_1 ((*it)->hexahedra[i]->getVertex(0), (*it)->hexahedra[i]->getVertex(1), (*it)->hexahedra[i]->getVertex(2), (*it)->hexahedra[i]->getVertex(3), (*it)->hexahedra[i]->getVertex(4), (*it)->hexahedra[i]->getVertex(5), (*it)->hexahedra[i]->getVertex(6), (*it)->hexahedra[i]->getVertex(7)); const nodalBasis* fs = h->getFunctionSpace(); for (int j=0;j<h->getNumVertices();j++){ if (h->getVertex(j)->onWhat() == *it){ double t1 = fs->points(j, 0); double t2 = fs->points(j, 1); double t3 = fs->points(j, 2); SPoint3 pc; h_1.pnt(t1, t2, t3,pc); _straightSidedLocation [h->getVertex(j)] = SVector3(pc.x(),pc.y(),pc.z()); } } } } Msg::Info("highOrderTools has been set up : %d nodes are considered", _straightSidedLocation.size()); }
static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVertices) { if(!splitIntoHexas){ std::vector<MTetrahedron*> tetrahedra2; for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){ MTetrahedron *t = gr->tetrahedra[i]; if(t->getNumVertices() == 10){ tetrahedra2.push_back (new MTetrahedron(t->getVertex(0), t->getVertex(4), t->getVertex(7), t->getVertex(6))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(1), t->getVertex(4), t->getVertex(5), t->getVertex(9))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(2), t->getVertex(5), t->getVertex(6), t->getVertex(8))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(3), t->getVertex(7), t->getVertex(9), t->getVertex(8))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(5), t->getVertex(8), t->getVertex(7), t->getVertex(9))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(5), t->getVertex(7), t->getVertex(4), t->getVertex(9))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(7), t->getVertex(8), t->getVertex(5), t->getVertex(6))); tetrahedra2.push_back (new MTetrahedron(t->getVertex(4), t->getVertex(7), t->getVertex(5), t->getVertex(6))); } delete t; } gr->tetrahedra = tetrahedra2; } std::vector<MHexahedron*> hexahedra2; for(unsigned int i = 0; i < gr->hexahedra.size(); i++){ MHexahedron *h = gr->hexahedra[i]; if(h->getNumVertices() == 27){ hexahedra2.push_back (new MHexahedron(h->getVertex(0), h->getVertex(8), h->getVertex(20), h->getVertex(9), h->getVertex(10), h->getVertex(21), h->getVertex(26), h->getVertex(22))); hexahedra2.push_back (new MHexahedron(h->getVertex(10), h->getVertex(21), h->getVertex(26), h->getVertex(22), h->getVertex(4), h->getVertex(16), h->getVertex(25), h->getVertex(17))); hexahedra2.push_back (new MHexahedron(h->getVertex(8), h->getVertex(1), h->getVertex(11), h->getVertex(20), h->getVertex(21), h->getVertex(12), h->getVertex(23), h->getVertex(26))); hexahedra2.push_back (new MHexahedron(h->getVertex(21), h->getVertex(12), h->getVertex(23), h->getVertex(26), h->getVertex(16), h->getVertex(5), h->getVertex(18), h->getVertex(25))); hexahedra2.push_back (new MHexahedron(h->getVertex(9), h->getVertex(20), h->getVertex(13), h->getVertex(3), h->getVertex(22), h->getVertex(26), h->getVertex(24), h->getVertex(15))); hexahedra2.push_back (new MHexahedron(h->getVertex(22), h->getVertex(26), h->getVertex(24), h->getVertex(15), h->getVertex(17), h->getVertex(25), h->getVertex(19), h->getVertex(7))); hexahedra2.push_back (new MHexahedron(h->getVertex(20), h->getVertex(11), h->getVertex(2), h->getVertex(13), h->getVertex(26), h->getVertex(23), h->getVertex(14), h->getVertex(24))); hexahedra2.push_back (new MHexahedron(h->getVertex(26), h->getVertex(23), h->getVertex(14), h->getVertex(24), h->getVertex(25), h->getVertex(18), h->getVertex(6), h->getVertex(19))); } delete h; } if(splitIntoHexas){ for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){ MTetrahedron *t = gr->tetrahedra[i]; if(t->getNumVertices() == 10){ std::vector<MVertex*> newv; for(int j = 0; j < t->getNumFaces(); j++){ MFace face = t->getFace(j); faceContainer::iterator fIter = faceVertices.find(face); if (fIter != faceVertices.end()){ newv.push_back(fIter->second[0]); } else{ SPoint3 pc = face.barycenter(); newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr)); faceVertices[face].push_back(newv.back()); gr->mesh_vertices.push_back(newv.back()); } } SPoint3 pc = t->barycenter(); newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr)); gr->mesh_vertices.push_back(newv.back()); hexahedra2.push_back (new MHexahedron(t->getVertex(0), t->getVertex(4), newv[0], t->getVertex(6), t->getVertex(7), newv[1], newv[4], newv[2])); hexahedra2.push_back (new MHexahedron(t->getVertex(4), t->getVertex(1), t->getVertex(5), newv[0], newv[1], t->getVertex(9), newv[3], newv[4])); hexahedra2.push_back (new MHexahedron(t->getVertex(6), newv[0], t->getVertex(5), t->getVertex(2), newv[2], newv[4], newv[3], t->getVertex(8))); hexahedra2.push_back (new MHexahedron(t->getVertex(3), t->getVertex(9), newv[1], t->getVertex(7), t->getVertex(8), newv[3], newv[4], newv[2])); delete t; } } gr->tetrahedra.clear(); for(unsigned int i = 0; i < gr->prisms.size(); i++){ MPrism *p = gr->prisms[i]; if(p->getNumVertices() == 18){ std::vector<MVertex*> newv; for(int j = 0; j < 2; j++){ MFace face = p->getFace(j); faceContainer::iterator fIter = faceVertices.find(face); if (fIter != faceVertices.end()){ newv.push_back(fIter->second[0]); } else{ SPoint3 pc = face.barycenter(); newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr)); faceVertices[face].push_back(newv.back()); gr->mesh_vertices.push_back(newv.back()); } } SPoint3 pc = p->barycenter(); newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr)); gr->mesh_vertices.push_back(newv.back()); hexahedra2.push_back (new MHexahedron(p->getVertex(0), p->getVertex(6), newv[0], p->getVertex(7), p->getVertex(8), p->getVertex(15), newv[2], p->getVertex(16))); hexahedra2.push_back (new MHexahedron(p->getVertex(1), p->getVertex(9), newv[0], p->getVertex(6), p->getVertex(10), p->getVertex(17), newv[2], p->getVertex(15))); hexahedra2.push_back (new MHexahedron(p->getVertex(2), p->getVertex(7), newv[0], p->getVertex(9), p->getVertex(11), p->getVertex(16), newv[2], p->getVertex(17))); hexahedra2.push_back (new MHexahedron(p->getVertex(8), p->getVertex(15), newv[2], p->getVertex(16), p->getVertex(3), p->getVertex(12), newv[1], p->getVertex(13))); hexahedra2.push_back (new MHexahedron(p->getVertex(10), p->getVertex(17), newv[2], p->getVertex(15), p->getVertex(4), p->getVertex(14), newv[1], p->getVertex(12))); hexahedra2.push_back (new MHexahedron(p->getVertex(11), p->getVertex(16), newv[2], p->getVertex(17), p->getVertex(5), p->getVertex(13), newv[1], p->getVertex(14))); } } gr->prisms.clear(); } gr->hexahedra = hexahedra2; std::vector<MPrism*> prisms2; for(unsigned int i = 0; i < gr->prisms.size(); i++){ MPrism *p = gr->prisms[i]; if(p->getNumVertices() == 18){ prisms2.push_back (new MPrism(p->getVertex(0), p->getVertex(6), p->getVertex(7), p->getVertex(8), p->getVertex(15), p->getVertex(16))); prisms2.push_back (new MPrism(p->getVertex(8), p->getVertex(15), p->getVertex(16), p->getVertex(3), p->getVertex(12), p->getVertex(13))); prisms2.push_back (new MPrism(p->getVertex(6), p->getVertex(1), p->getVertex(9), p->getVertex(15), p->getVertex(10), p->getVertex(17))); prisms2.push_back (new MPrism(p->getVertex(15), p->getVertex(10), p->getVertex(17), p->getVertex(12), p->getVertex(4), p->getVertex(14))); prisms2.push_back (new MPrism(p->getVertex(7), p->getVertex(9), p->getVertex(2), p->getVertex(16), p->getVertex(17), p->getVertex(11))); prisms2.push_back (new MPrism(p->getVertex(16), p->getVertex(17), p->getVertex(11), p->getVertex(13), p->getVertex(14), p->getVertex(5))); prisms2.push_back (new MPrism(p->getVertex(9), p->getVertex(7), p->getVertex(6), p->getVertex(17), p->getVertex(16), p->getVertex(15))); prisms2.push_back (new MPrism(p->getVertex(17), p->getVertex(16), p->getVertex(15), p->getVertex(14), p->getVertex(13), p->getVertex(12))); } delete p; } gr->prisms = prisms2; std::vector<MPyramid*> pyramids2; for(unsigned int i = 0; i < gr->pyramids.size(); i++){ if(splitIntoHexas){ Msg::Error("Full hexahedron subdivision is not implemented for pyramids"); return; } MPyramid *p = gr->pyramids[i]; if(p->getNumVertices() == 14){ // Base pyramids2.push_back (new MPyramid(p->getVertex(0), p->getVertex(5), p->getVertex(13), p->getVertex(6), p->getVertex(7))); pyramids2.push_back (new MPyramid(p->getVertex(5), p->getVertex(1), p->getVertex(8), p->getVertex(13), p->getVertex(9))); pyramids2.push_back (new MPyramid(p->getVertex(13), p->getVertex(8), p->getVertex(2), p->getVertex(10), p->getVertex(11))); pyramids2.push_back (new MPyramid(p->getVertex(6), p->getVertex(13), p->getVertex(10), p->getVertex(3), p->getVertex(12))); // Split remaining into tets // Top gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(9), p->getVertex(12), p->getVertex(4)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(9), p->getVertex(11), p->getVertex(12), p->getVertex(4)))); // Upside down one gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(9), p->getVertex(12), p->getVertex(11), p->getVertex(13)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(12), p->getVertex(9), p->getVertex(13)))); // Four tets around bottom perimeter gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(9), p->getVertex(5), p->getVertex(13)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(9), p->getVertex(11), p->getVertex(8), p->getVertex(13)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(12), p->getVertex(10), p->getVertex(11), p->getVertex(13)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(6), p->getVertex(12), p->getVertex(13)))); } delete p; } gr->pyramids = pyramids2; for(unsigned int i = 0; i < gr->mesh_vertices.size(); i++) gr->mesh_vertices[i]->setPolynomialOrder(1); gr->deleteVertexArrays(); }
void MeshPainter::drawSolidUntextured(MMesh *mesh, bool background, bool reflection, bool subdivided, bool smooth) { Array<MFace*> &faces = mesh->getFaces(); int first = 0; int last = faces.size() - 1; if ( subdivided ) { setupSubdividedMaterial(); } else { setupUntexturedMaterial( reflection && !background ); } glBegin( GL_TRIANGLES ); for (int i = first; i <= last; i++) { MFace *fc = faces[i]; const Tesselation *t = fc->getTesselation(); if ( t != NULL ) { for (int i = 0; i < t->size(); i++) { drawUntexturedFace( fc, t->at( i ).a, t->at( i ).b, t->at( i ).c, smooth ); } } else { int a = 0, b = 1; for (int c = 2; c < fc->getSize(); c++) { drawUntexturedFace( fc, a, b, c, smooth ); b = c; } } } glEnd(); #ifdef DEBUG_PRINT_MESH_POINTERS if ( !reflection && !subdivided ) { glDisable( GL_LIGHTING ); glColor3d( 0.0, 0.5, 0.0 ); for (int i = first; i <= last; i++) { Point3 pos = faces[i]->computeCentroid(); std::ostringstream stream; stream << faces[i] << (char)0x00; glDrawString3( pos, stream.str().c_str() ); } glEnable( GL_LIGHTING ); } #endif }
void MHexahedron::getFaceInfo(const MFace &face, int &ithFace, int &sign, int &rot) const { for (ithFace = 0; ithFace < 6; ithFace++){ MVertex *v0 = _v[faces_hexa(ithFace, 0)]; MVertex *v1 = _v[faces_hexa(ithFace, 1)]; MVertex *v2 = _v[faces_hexa(ithFace, 2)]; MVertex *v3 = _v[faces_hexa(ithFace, 3)]; if (v0 == face.getVertex(0) && v1 == face.getVertex(1) && v2 == face.getVertex(2) && v3 == face.getVertex(3)){ sign = 1; rot = 0; return; } if (v0 == face.getVertex(1) && v1 == face.getVertex(2) && v2 == face.getVertex(3) && v3 == face.getVertex(0)){ sign = 1; rot = 1; return; } if (v0 == face.getVertex(2) && v1 == face.getVertex(3) && v2 == face.getVertex(0) && v3 == face.getVertex(1)){ sign = 1; rot = 2; return; } if (v0 == face.getVertex(3) && v1 == face.getVertex(0) && v2 == face.getVertex(1) && v3 == face.getVertex(2)){ sign = 1; rot = 3; return; } // reverse if (v0 == face.getVertex(0) && v1 == face.getVertex(3) && v2 == face.getVertex(2) && v3 == face.getVertex(1)){ sign = -1; rot = 0; return; } if (v0 == face.getVertex(3) && v1 == face.getVertex(2) && v2 == face.getVertex(1) && v3 == face.getVertex(0)){ sign = -1; rot = 1; return; } if (v0 == face.getVertex(2) && v1 == face.getVertex(1) && v2 == face.getVertex(0) && v3 == face.getVertex(3)){ sign = -1; rot = 2; return; } if (v0 == face.getVertex(1) && v1 == face.getVertex(0) && v2 == face.getVertex(3) && v3 == face.getVertex(2)){ sign = -1; rot = 3; return; } } Msg::Error("Could not get face information for hexahedron %d", getNum()); }