void exportMeshToDassault(GModel *gm, const std::string &fn, int dim) { FILE *f = fopen(fn.c_str(),"w"); int numVertices = gm->indexMeshVertices(true); std::vector<GEntity*> entities; gm->getEntities(entities); fprintf(f,"%d %d\n", numVertices, dim); for(unsigned int i = 0; i < entities.size(); i++) for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){ MVertex *v = entities[i]->mesh_vertices[j]; if (dim == 2) fprintf(f,"%d %22.15E %22.15E\n", v->getIndex(), v->x(), v->y()); else if (dim == 3) fprintf(f,"%d %22.15E %22.15E %22.5E\n", v->getIndex(), v->x(), v->y(), v->z()); } if (dim == 2){ int nt = 0; int order = 0; for (GModel::fiter itf = gm->firstFace(); itf != gm->lastFace(); ++itf){ std::vector<MTriangle*> &tris = (*itf)->triangles; nt += tris.size(); if (tris.size())order = tris[0]->getPolynomialOrder(); } fprintf(f,"%d %d\n", nt,(order+1)*(order+2)/2); int count = 1; for (GModel::fiter itf = gm->firstFace(); itf != gm->lastFace(); ++itf){ std::vector<MTriangle*> &tris = (*itf)->triangles; for (size_t i=0;i<tris.size();i++){ MTriangle *t = tris[i]; fprintf(f,"%d ", count++); for (int j=0;j<t->getNumVertices();j++){ fprintf(f,"%d ", t->getVertex(j)->getIndex()); } fprintf(f,"\n"); } } int ne = 0; for (GModel::eiter ite = gm->firstEdge(); ite != gm->lastEdge(); ++ite){ std::vector<MLine*> &l = (*ite)->lines; ne += l.size(); } fprintf(f,"%d %d\n", ne,(order+1)); count = 1; for (GModel::eiter ite = gm->firstEdge(); ite != gm->lastEdge(); ++ite){ std::vector<MLine*> &l = (*ite)->lines; for (size_t i=0;i<l.size();i++){ MLine *t = l[i]; fprintf(f,"%d ", count++); for (int j=0;j<t->getNumVertices();j++){ fprintf(f,"%d ", t->getVertex(j)->getIndex()); } fprintf(f,"%d \n",(*ite)->tag()); } } } fclose(f); }
void Centerline::importFile(std::string fileName) { current = GModel::current(); std::vector<GFace*> currentFaces(current->firstFace(), current->lastFace()); for (unsigned int i = 0; i < currentFaces.size(); i++){ GFace *gf = currentFaces[i]; if (gf->geomType() == GEntity::DiscreteSurface){ for(unsigned int j = 0; j < gf->triangles.size(); j++) triangles.push_back(gf->triangles[j]); if (is_cut){ gf->triangles.clear(); gf->deleteVertexArrays(); current->remove(gf); } } } if(triangles.empty()){ Msg::Error("Current GModel has no triangles ..."); return; } mod = new GModel(); mod->load(fileName); mod->removeDuplicateMeshVertices(1.e-8); current->setAsCurrent(); current->setVisibility(1); int maxN = 0.0; std::vector<GEdge*> modEdges(mod->firstEdge(), mod->lastEdge()); MVertex *vin = modEdges[0]->lines[0]->getVertex(0); ptin = SPoint3(vin->x(), vin->y(), vin->z()); for (unsigned int i = 0; i < modEdges.size(); i++){ GEdge *ge = modEdges[i]; for(unsigned int j = 0; j < ge->lines.size(); j++){ MLine *l = ge->lines[j]; MVertex *v0 = l->getVertex(0); MVertex *v1 = l->getVertex(1); std::map<MVertex*, int>::iterator it0 = colorp.find(v0); std::map<MVertex*, int>::iterator it1 = colorp.find(v1); if (it0 == colorp.end() || it1 == colorp.end()){ lines.push_back(l); colorl.insert(std::make_pair(l, ge->tag())); maxN = std::max(maxN, ge->tag()); } if (it0 == colorp.end()) colorp.insert(std::make_pair(v0, ge->tag())); if (it1 == colorp.end()) colorp.insert(std::make_pair(v1, ge->tag())); } } createBranches(maxN); }
static void Subdivide(GEdge *ge) { std::vector<MLine*> lines2; for(unsigned int i = 0; i < ge->lines.size(); i++){ MLine *l = ge->lines[i]; if(l->getNumVertices() == 3){ lines2.push_back(new MLine(l->getVertex(0), l->getVertex(2))); lines2.push_back(new MLine(l->getVertex(2), l->getVertex(1))); } delete l; } ge->lines = lines2; // 2nd order meshing destroyed the ordering of the vertices on the edge std::sort(ge->mesh_vertices.begin(), ge->mesh_vertices.end(), MVertexLessThanParam()); for(unsigned int i = 0; i < ge->mesh_vertices.size(); i++) ge->mesh_vertices[i]->setPolynomialOrder(1); ge->deleteVertexArrays(); }
void Centerline::distanceToSurface() { Msg::Info("Centerline: computing distance to surface mesh "); //COMPUTE WITH REVERSE ANN TREE (SURFACE POINTS IN TREE) std::set<MVertex*> allVS; for(unsigned int j = 0; j < triangles.size(); j++) for(int k = 0; k<3; k++) allVS.insert(triangles[j]->getVertex(k)); int nbSNodes = allVS.size(); ANNpointArray nodesR = annAllocPts(nbSNodes, 3); vertices.resize(nbSNodes); int ind = 0; std::set<MVertex*>::iterator itp = allVS.begin(); while (itp != allVS.end()){ MVertex *v = *itp; nodesR[ind][0] = v->x(); nodesR[ind][1] = v->y(); nodesR[ind][2] = v->z(); vertices[ind] = v; itp++; ind++; } kdtreeR = new ANNkd_tree(nodesR, nbSNodes, 3); for(unsigned int i = 0; i < lines.size(); i++){ MLine *l = lines[i]; MVertex *v1 = l->getVertex(0); MVertex *v2 = l->getVertex(1); double midp[3] = {0.5*(v1->x()+v2->x()), 0.5*(v1->y()+v1->y()),0.5*(v1->z()+v2->z())}; ANNidx index[1]; ANNdist dist[1]; kdtreeR->annkSearch(midp, 1, index, dist); double minRad = sqrt(dist[0]); radiusl.insert(std::make_pair(lines[i], minRad)); } }
void Centerline::printSplit() const { FILE * f = Fopen("mySPLIT.pos","w"); fprintf(f, "View \"\"{\n"); for(unsigned int i = 0; i < edges.size(); ++i){ std::vector<MLine*> lines = edges[i].lines; for(unsigned int k = 0; k < lines.size(); ++k){ MLine *l = lines[k]; fprintf(f, "SL(%g,%g,%g,%g,%g,%g){%g,%g};\n", l->getVertex(0)->x(), l->getVertex(0)->y(), l->getVertex(0)->z(), l->getVertex(1)->x(), l->getVertex(1)->y(), l->getVertex(1)->z(), (double)edges[i].tag, (double)edges[i].tag); } } fprintf(f,"};\n"); fclose(f); // FILE * f3 = Fopen("myJUNCTIONS.pos","w"); // fprintf(f3, "View \"\"{\n"); // std::set<MVertex*>::const_iterator itj = junctions.begin(); // while (itj != junctions.end()){ // MVertex *v = *itj; // fprintf(f3, "SP(%g,%g,%g){%g};\n", // v->x(), v->y(), v->z(), // (double)v->getNum()); // itj++; // } // fprintf(f3,"};\n"); // fclose(f3); FILE * f4 = Fopen("myRADII.pos","w"); fprintf(f4, "View \"\"{\n"); for(unsigned int i = 0; i < lines.size(); ++i){ MLine *l = lines[i]; std::map<MLine*,double>::const_iterator itc = radiusl.find(l); fprintf(f4, "SL(%g,%g,%g,%g,%g,%g){%g,%g};\n", l->getVertex(0)->x(), l->getVertex(0)->y(), l->getVertex(0)->z(), l->getVertex(1)->x(), l->getVertex(1)->y(), l->getVertex(1)->z(), itc->second,itc->second); } fprintf(f4,"};\n"); fclose(f4); }
bool GEdge::computeDistanceFromMeshToGeometry (double &d2, double &dmax) { d2 = 0.0; dmax = 0.0; if (geomType() == Line) return true; if (!lines.size())return false; IntPt *pts; int npts; lines[0]->getIntegrationPoints(2*lines[0]->getPolynomialOrder(), &npts, &pts); for (unsigned int i = 0; i < lines.size(); i++){ MLine *l = lines[i]; double t[256]; for (int j=0; j< l->getNumVertices();j++){ MVertex *v = l->getVertex(j); if (v->onWhat() == getBeginVertex()){ t[j] = getLowerBound(); } else if (v->onWhat() == getEndVertex()){ t[j] = getUpperBound(); } else { v->getParameter(0,t[j]); } } for (int j=0;j<npts;j++){ SPoint3 p; l->pnt(pts[j].pt[0],0,0,p); double tinit = l->interpolate(t,pts[j].pt[0],0,0); GPoint pc = closestPoint(p, tinit); if (!pc.succeeded())continue; double dsq = (pc.x()-p.x())*(pc.x()-p.x()) + (pc.y()-p.y())*(pc.y()-p.y()) + (pc.z()-p.z())*(pc.z()-p.z()); d2 += pts[i].weight * fabs(l->getJacobianDeterminant(pts[j].pt[0],0,0)) * dsq; dmax = std::max(dmax,sqrt(dsq)); } } d2 = sqrt(d2); return true; }
static void orderMLines(std::vector<MLine*> &lines, MVertex *vB, MVertex *vE) { std::vector<MLine*> _m; std::list<MLine*> segments; std::map<MVertex*, MLine*> boundv; std::vector<int> _orientation; // store all lines in a list : segments for (unsigned int i = 0; i < lines.size(); i++){ segments.push_back(lines[i]); } // find a lonely MLine for (std::list<MLine*>::iterator it = segments.begin(); it != segments.end(); ++it){ MVertex *vL = (*it)->getVertex(0); MVertex *vR = (*it)->getVertex(1); std::map<MVertex*,MLine*>::iterator it1 = boundv.find(vL); if (it1 == boundv.end()) boundv.insert(std::make_pair(vL,*it)); else boundv.erase(it1); std::map<MVertex*,MLine*>::iterator it2 = boundv.find(vR); if (it2 == boundv.end()) boundv.insert(std::make_pair(vR,*it)); else boundv.erase(it2); } // find the first MLine and erase it from the list segments MLine *firstLine; if (boundv.size() == 2){ // non periodic MVertex *v = (boundv.begin())->first; if ( v == vB) firstLine = (boundv.begin())->second; else{ MVertex *v = (boundv.rbegin())->first; if (v == vB) firstLine = (boundv.rbegin())->second; else{ Msg::Error("begin vertex not found for branch"); return; } } for (std::list<MLine*>::iterator it = segments.begin(); it != segments.end(); ++it){ if (*it == firstLine){ segments.erase(it); break; } } } else{ Msg::Error("line is wrong (it has %d end points)", boundv.size()); } // loop over all segments to order segments and store it in the list _m _m.push_back(firstLine); _orientation.push_back(1); MVertex *first = _m[0]->getVertex(0); MVertex *last = _m[0]->getVertex(1); while (first != last){ if (segments.empty())break; bool found = false; for (std::list<MLine*>::iterator it = segments.begin(); it != segments.end(); ++it){ MLine *e = *it; if (e->getVertex(0) == last){ _m.push_back(e); segments.erase(it); _orientation.push_back(1); last = e->getVertex(1); found = true; break; } else if (e->getVertex(1) == last){ _m.push_back(e); segments.erase(it); _orientation.push_back(0); last = e->getVertex(0); found = true; break; } } if (!found && _orientation[0]==1){ //reverse orientation of first Line if (_m.size() == 1 ){ MVertex *temp = first; first = last; last = temp; _orientation[0] = 0; } else { Msg::Error("lines is wrong"); return; } } } //lines is now a list of ordered MLines lines = _m; //special case reverse orientation if (lines.size() < 2) return; if (_orientation[0] && lines[0]->getVertex(1) != lines[1]->getVertex(1) && lines[0]->getVertex(1) != lines[1]->getVertex(0)){ for (unsigned int i = 0; i < lines.size(); i++) _orientation[i] = !_orientation[i]; } }
void Centerline::createBranches(int maxN) { //sort colored lines and create edges std::vector<std::vector<MLine*> > color_edges; color_edges.resize(maxN); std::multiset<MVertex*> allV; std::map<MLine*, int>::iterator itl = colorl.begin(); while (itl != colorl.end()){ int color = itl->second; MLine* l = itl->first; allV.insert(l->getVertex(0)); allV.insert(l->getVertex(1)); color_edges[color-1].push_back(l); itl++; } //detect junctions std::multiset<MVertex*>::iterator it = allV.begin(); for ( ; it != allV.end(); ++it){ if (allV.count(*it) != 2) { junctions.insert(*it); } } //split edges int tag = 0; for(unsigned int i = 0; i < color_edges.size(); ++i){ std::vector<MLine*> lines = color_edges[i]; while (!lines.empty()) { std::vector<MLine*> myLines; std::vector<MLine*>::iterator itl = lines.begin(); MVertex *vB = (*itl)->getVertex(0); MVertex *vE = (*itl)->getVertex(1); myLines.push_back(*itl); erase(lines, *itl); itl = lines.begin(); while ( !( junctions.find(vE) != junctions.end() && junctions.find(vB) != junctions.end()) ) { MVertex *v1 = (*itl)->getVertex(0); MVertex *v2 = (*itl)->getVertex(1); bool goVE = (junctions.find(vE) == junctions.end()) ? true : false ; bool goVB = (junctions.find(vB) == junctions.end()) ? true : false; if (v1 == vE && goVE){ myLines.push_back(*itl); erase(lines, *itl); itl = lines.begin(); vE = v2; } else if ( v2 == vE && goVE){ myLines.push_back(*itl); erase(lines, *itl); itl = lines.begin(); vE = v1; } else if ( v1 == vB && goVB){ myLines.push_back(*itl); erase(lines, *itl); itl = lines.begin(); vB = v2; } else if ( v2 == vB && goVB){ myLines.push_back(*itl); erase(lines, *itl); itl = lines.begin(); vB = v1; } else itl++; } if (vB == vE) { Msg::Error("Begin and end points branch are the same \n"); break; } orderMLines(myLines, vB, vE); std::vector<Branch> children; Branch newBranch ={ tag++, myLines, computeLength(myLines), vB, vE, children, 1.e6, 0.0}; edges.push_back(newBranch) ; } } Msg::Info("Centerline: in/outlets =%d branches =%d ", (int)color_edges.size()+1, (int)edges.size()); //create children for(unsigned int i = 0; i < edges.size(); ++i) { MVertex *vE = edges[i].vE; std::vector<Branch> myChildren; for (std::vector<Branch>::iterator it = edges.begin(); it != edges.end(); ++it){ Branch myBranch = *it; if (myBranch.vB == vE) myChildren.push_back(myBranch); } edges[i].children = myChildren; } //compute radius distanceToSurface(); computeRadii(); //print for debug printSplit(); }
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()); }