diff --git a/Common/OS.cpp b/Common/OS.cpp index fda2a9afcdb1428e49d4dbbc9b3ca1868e76643e..4b21dff83990927ddb9bde8e88575f4ed2bf1cda 100644 --- a/Common/OS.cpp +++ b/Common/OS.cpp @@ -348,12 +348,12 @@ void CheckResources() // Try to get at least 16 MB of stack. Running with too small a stack // can cause crashes in the recursive calls (e.g. for tet // classification in 3D Delaunay) - if(r.rlim_cur < 16 * 1024 * 1024) { - Msg::Info("Increasing process stack size (%d kB < 16 MB)", - r.rlim_cur / 1024); - r.rlim_cur = r.rlim_max; - setrlimit(RLIMIT_STACK, &r); - } + if(r.rlim_cur < 16 * 1024 * 1024) { + Msg::Info("Increasing process stack size (%d kB < 16 MB)", + r.rlim_cur / 1024); + r.rlim_cur = r.rlim_max; + setrlimit(RLIMIT_STACK, &r); + } #endif } diff --git a/Fltk/classificationEditor.cpp b/Fltk/classificationEditor.cpp index 63931d77b45a9a27aa4dd3466e417d46cd6c2074..6088536cc51537b1cc06f034a1f38be35c980c75 100644 --- a/Fltk/classificationEditor.cpp +++ b/Fltk/classificationEditor.cpp @@ -262,6 +262,7 @@ static void reset_selection_cb(Fl_Widget *w, void *data) static void classify_cb(Fl_Widget *w, void *data) { + // printf("cpoc<<<\n"); classificationEditor *e = (classificationEditor *)data; if(!e->selected) { @@ -270,9 +271,14 @@ static void classify_cb(Fl_Widget *w, void *data) GModel::current()->getMaxElementaryNumber(1) + 1, 0, 0); GModel::current()->add(e->selected); } + // printf("cpoc<<<\n"); - if(e->toggles[CLASS_TOGGLE_ENSURE_PARAMETRIZABLE_SURFACES]->value()) + std::map<MVertex* , std::pair<SVector3, SVector3> > CURVATURES; + if(e->toggles[CLASS_TOGGLE_ENSURE_PARAMETRIZABLE_SURFACES]->value()){ + computeDiscreteCurvatures(GModel::current(), CURVATURES ); computeEdgeCut(GModel::current(), e->selected->lines, 100000); + } + // printf("cpoc<<<\n"); computeNonManifoldEdges(GModel::current(), e->selected->lines, true); @@ -285,16 +291,21 @@ static void classify_cb(Fl_Widget *w, void *data) delete e->selected; e->selected = 0; } + // printf("cpoc<<<\n"); e->elements.clear(); e->edges_detected.clear(); GModel::current()->pruneMeshVertexAssociations(); NoElementsSelectedMode(e); + // printf("cpoc<<< PARAMETRIZE\n"); if(e->toggles[CLASS_TOGGLE_ENSURE_PARAMETRIZABLE_SURFACES]->value()){ + // printf("ZAZOU\n"); parametrizeAllGEdge(GModel::current()); - parametrizeAllGFace(GModel::current()); + // printf("ZAZOU\n"); + parametrizeAllGFace(GModel::current(), &CURVATURES); } + // printf("cpoc<<<\n"); } diff --git a/Geo/GFace.h b/Geo/GFace.h index 11c14d2ed0963fd1b673c2b8d9ce86f495a8c186..f1ca7c23220da3a6ceb2d1266d82b1f7a514947e 100644 --- a/Geo/GFace.h +++ b/Geo/GFace.h @@ -327,6 +327,7 @@ public: std::vector<SPoint2> stl_vertices_uv; std::vector<SPoint3> stl_vertices_xyz; std::vector<SVector3> stl_normals; + std::vector<SVector3> stl_curvatures; std::vector<int> stl_triangles; // a vertex array containing a geometrical representation of the diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index e1eff1dc1a4aab8e082991cb828cea470f383964..eba8bb620e78bc59488d80d83be99b0bc8fa6aad 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -2938,53 +2938,71 @@ void GModel::classifyAllFaces(double angleThreshold, bool includeBoundary) } #if defined(HAVE_MESH) -void recurClassifyEdges(MTri3 *t, std::map<MTriangle *, GFace *> &reverse, +static void recurClassifyEdges(MTri3 *t, std::map<MTriangle *, GFace *> &reverse, std::map<MLine *, GEdge *, compareMLinePtr> &lines, std::set<MLine *> &touched, std::set<MTri3 *> &trisTouched, std::map<std::pair<int, int>, GEdge *> &newEdges) { - if(!t->isDeleted()) { - trisTouched.erase(t); - t->setDeleted(true); - GFace *gf1 = reverse[t->tri()]; - for(int i = 0; i < 3; i++) { - GFace *gf2 = 0; - MTri3 *tn = t->getNeigh(i); - if(tn) gf2 = reverse[tn->tri()]; - edgeXface exf(t, i); - MLine ml(exf._v(0), exf._v(1)); - std::map<MLine *, GEdge *, compareMLinePtr>::iterator it = - lines.find(&ml); - if(it != lines.end()) { - if(touched.find(it->first) == touched.end()) { - GEdge *ge = getNewModelEdge(gf1, gf2, newEdges); - if(ge) ge->lines.push_back(it->first); - touched.insert(it->first); - } - } - if(tn) - recurClassifyEdges(tn, reverse, lines, touched, trisTouched, newEdges); - } - } -} -void recurClassify(MTri3 *t, GFace *gf, + std::stack<MTri3 *> _stack; + _stack.push(t); + + while (!_stack.empty()){ + t = _stack.top(); + _stack.pop(); + // printf("%d\n",rec); + if(!t->isDeleted()) { + trisTouched.erase(t); + t->setDeleted(true); + GFace *gf1 = reverse[t->tri()]; + for(int i = 0; i < 3; i++) { + GFace *gf2 = 0; + MTri3 *tn = t->getNeigh(i); + if(tn) gf2 = reverse[tn->tri()]; + edgeXface exf(t, i); + MLine ml(exf._v(0), exf._v(1)); + std::map<MLine *, GEdge *, compareMLinePtr>::iterator it = + lines.find(&ml); + if(it != lines.end()) { + if(touched.find(it->first) == touched.end()) { + GEdge *ge = getNewModelEdge(gf1, gf2, newEdges); + if(ge) ge->lines.push_back(it->first); + touched.insert(it->first); + } + } + if(tn){ + _stack.push(tn); + // recurClassifyEdges(tn, reverse, lines, touched, trisTouched, newEdges,rec+1); + } + } + } + } +} + +static void recurClassify(MTri3 *t, GFace *gf, std::map<MLine *, GEdge *, compareMLinePtr> &lines, std::map<MTriangle *, GFace *> &reverse) { - if(!t->isDeleted()) { - gf->triangles.push_back(t->tri()); - reverse[t->tri()] = gf; - t->setDeleted(true); - for(int i = 0; i < 3; i++) { - MTri3 *tn = t->getNeigh(i); - if(tn) { - edgeXface exf(t, i); - MLine ml(exf._v(0), exf._v(1)); - std::map<MLine *, GEdge *, compareMLinePtr>::iterator it = - lines.find(&ml); - if(it == lines.end()) recurClassify(tn, gf, lines, reverse); + std::stack<MTri3 *> _stack; + _stack.push(t); + + while (!_stack.empty()){ + t = _stack.top(); + _stack.pop(); + if(!t->isDeleted()) { + gf->triangles.push_back(t->tri()); + reverse[t->tri()] = gf; + t->setDeleted(true); + for(int i = 0; i < 3; i++) { + MTri3 *tn = t->getNeigh(i); + if(tn) { + edgeXface exf(t, i); + MLine ml(exf._v(0), exf._v(1)); + std::map<MLine *, GEdge *, compareMLinePtr>::iterator it = + lines.find(&ml); + if(it == lines.end()) _stack.push(tn);//recurClassify(tn, gf, lines, reverse); + } } } } @@ -3013,6 +3031,7 @@ void GModel::classifyFaces() for(size_t i = 0; i < edgesToRemove.size(); ++i) { remove(edgesToRemove[i]); } + // printf("cpoc<<<s\n"); // create triangle 2 triangle connections std::map<MTriangle *, GFace *> reverse_old; @@ -3031,7 +3050,9 @@ void GModel::classifyFaces() } } if(tris.empty()) return; + // printf("cpoc<<<ss\n"); connectTriangles(tris); + // printf("cpoc<<<sq\n"); // classify std::map<MTriangle *, GFace *> reverse; @@ -3053,6 +3074,7 @@ void GModel::classifyFaces() } ++it; } + // printf("cpoc<<<s\n"); // now we have all faces coloured. If some regions were existing, replace // their faces by the new ones @@ -3071,6 +3093,7 @@ void GModel::classifyFaces() } (*rit)->set(std::vector<GFace *>(_newFaces.begin(), _newFaces.end())); } + // printf("cpoc<<<s\n"); // color some lines it = tris.begin(); @@ -3090,6 +3113,7 @@ void GModel::classifyFaces() recurClassifyEdges(*trisTouched.begin(), reverse, lines, touched, trisTouched, newEdges); + // printf("cpoc<<<s\n"); std::map<discreteFace *, std::vector<int> > newFaceTopology; // check if new edges should not be splitted @@ -3186,12 +3210,14 @@ void GModel::classifyFaces() if(gf2) newFaceTopology[gf2].push_back(newGe->tag()); } } + // printf("edededededecpocss<<<s\n"); std::map<discreteFace *, std::vector<int> >::iterator itFT = newFaceTopology.begin(); for(; itFT != newFaceTopology.end(); ++itFT) { itFT->first->setBoundEdges(itFT->second); } + // printf("edededededecpocss<<<s\n"); for(std::map<std::pair<int, int>, GEdge *>::iterator it = newEdges.begin(); it != newEdges.end(); ++it) { @@ -3206,6 +3232,7 @@ void GModel::classifyFaces() ++it; } + // printf("cpoc<<<s\n"); // delete empty mesh faces and reclasssify std::set<GFace *, GEntityLessThan> fac = faces; for(fiter fit = fac.begin(); fit != fac.end(); ++fit) { diff --git a/Geo/GModelIO_MSH4.cpp b/Geo/GModelIO_MSH4.cpp index fb08c8b9b617b66d4f6b5458c8f33ec242895039..599731f35123412b85a074067cad2112ab140c6f 100644 --- a/Geo/GModelIO_MSH4.cpp +++ b/Geo/GModelIO_MSH4.cpp @@ -1297,11 +1297,13 @@ static bool readMSH4Parametrizations(GModel *const model, FILE *fp, bool binary gf->stl_vertices_uv.clear(); gf->stl_normals.clear(); for (int i=0;i<n;i++){ - double u,v,x,y,z; - fscanf (fp,"%lf %lf %lf %lf %lf",&u,&v,&x,&y,&z); + double u,v,x,y,z,cxM,cyM,czM,cxm,cym,czm; + fscanf (fp,"%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",&u,&v,&x,&y,&z,&cxM,&cyM,&czM,&cxm,&cym,&czm); gf->stl_vertices_uv.push_back(SPoint2(u,v)); gf->stl_vertices_xyz.push_back(SPoint3(x,y,z)); gf->stl_normals.push_back(SVector3(0,0,0)); + gf->stl_curvatures.push_back(SVector3(cxM,cyM,czM)); + gf->stl_curvatures.push_back(SVector3(cxm,cym,czm)); } gf->stl_triangles.clear(); for (int i=0;i<t;i++){ @@ -2821,8 +2823,15 @@ static void writeMSH4Parametrizations(GModel *const model, FILE *fp, bool binar if (gf->stl_vertices_uv.size()){ fprintf(fp,"%d %lu %lu\n",gf->tag(),gf->stl_vertices_uv.size(),gf->stl_triangles.size()/3); for (size_t i=0;i<gf->stl_vertices_uv.size();i++){ - fprintf(fp,"%g %g %g %g %g\n",gf->stl_vertices_uv[i].x(),gf->stl_vertices_uv[i].y(), - gf->stl_vertices_xyz[i].x(),gf->stl_vertices_xyz[i].y(),gf->stl_vertices_xyz[i].z()); + if (gf->stl_curvatures.empty()) + fprintf(fp,"%22.15e %22.15e %22.15e %22.15e %22.15e 0 0 0 0 0 0\n",gf->stl_vertices_uv[i].x(),gf->stl_vertices_uv[i].y(), + gf->stl_vertices_xyz[i].x(),gf->stl_vertices_xyz[i].y(),gf->stl_vertices_xyz[i].z()); + else + fprintf(fp,"%22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e\n",gf->stl_vertices_uv[i].x(),gf->stl_vertices_uv[i].y(), + gf->stl_vertices_xyz[i].x(),gf->stl_vertices_xyz[i].y(),gf->stl_vertices_xyz[i].z(), + gf->stl_curvatures[2*i].x(),gf->stl_curvatures[2*i].y(),gf->stl_curvatures[2*i].z(), + gf->stl_curvatures[2*i+1].x(),gf->stl_curvatures[2*i+1].y(),gf->stl_curvatures[2*i+1].z()); + } for (size_t i=0;i<gf->stl_triangles.size()/3;i++){ fprintf(fp,"%d %d %d\n",gf->stl_triangles[3 * i + 0],gf->stl_triangles[3 * i + 1],gf->stl_triangles[3 * i + 2]); diff --git a/Geo/GModelParametrize.cpp b/Geo/GModelParametrize.cpp index 489941ebf44a87d64e0203aba1b2d4b62db0eca6..bbd18693916c155c76da270586591391f18b8123 100644 --- a/Geo/GModelParametrize.cpp +++ b/Geo/GModelParametrize.cpp @@ -79,6 +79,36 @@ static HXTStatus gmsh2hxt(GFace *gf, HXTMesh **pm, return HXT_STATUS_OK; } +HXTStatus computeDiscreteCurvatures(GModel *gm, std::map<MVertex* , std::pair<SVector3, SVector3> > &C ){ + C.clear(); + + for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) { + HXTMesh *m; + HXTEdges *edges; + double *nodalCurvatures; + double *crossField; + std::map<MVertex *, int> v2c; + std::vector<MVertex *> c2v; + gmsh2hxt(*it, &m, v2c, c2v); + HXT_CHECK(hxtEdgesCreate(m, &edges)); + HXT_CHECK(hxtCurvatureRusinkiewicz(m, &nodalCurvatures, &crossField, edges, false)); + for (size_t i=0;i<m->vertices.num;i++){ + MVertex *v = c2v[i]; + double *c = &nodalCurvatures[6*i]; + SVector3 cMax (c[0],c[1],c[2]); + SVector3 cMin (c[3],c[4],c[5]); + std::pair<SVector3, SVector3> out = std::make_pair(cMax,cMin); + C.insert(std::make_pair(v,out)); + } + HXT_CHECK(hxtEdgesDelete(&edges)); + HXT_CHECK(hxtFree(&nodalCurvatures)); + HXT_CHECK(hxtFree(&crossField)); + HXT_CHECK(hxtMeshDelete(&m)); + } + return HXT_STATUS_OK; +} + + void parametrizeAllGEdge(GModel *gm) { for(GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it) { @@ -87,17 +117,17 @@ void parametrizeAllGEdge(GModel *gm) } } -int parametrizeAllGFace(GModel *gm) +int parametrizeAllGFace(GModel *gm, std::map<MVertex* , std::pair<SVector3, SVector3> > *C) { int result = 0; for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) { discreteFace *df = dynamic_cast<discreteFace *>(*it); - if(df) result += parametrizeGFace(df); + if(df) result += parametrizeGFace(df,C); } return result; } -int parametrizeGFace(discreteFace *gf) +int parametrizeGFace(discreteFace *gf, std::map<MVertex* , std::pair<SVector3, SVector3> > *C) { int n = 1; if(gf->triangles.empty()) return 0; @@ -110,6 +140,7 @@ int parametrizeGFace(discreteFace *gf) gmsh2hxt(gf, &m, v2c, c2v); // double *nodalCurvatures; // double *crossField; + // printf("A %d triangles\n",m->triangles.num); HXT_CHECK(hxtEdgesCreate(m, &edges)); HXT_CHECK(hxtMeanValuesCreate(edges, ¶m)); HXT_CHECK(hxtMeanValuesCompute(param)); @@ -120,10 +151,20 @@ int parametrizeGFace(discreteFace *gf) gf->stl_vertices_uv.resize(nv); gf->stl_vertices_xyz.clear(); gf->stl_vertices_xyz.resize(nv); + gf->stl_curvatures.clear(); + if (C) gf->stl_curvatures.resize(2*nv); gf->stl_normals.clear(); gf->stl_normals.resize(nv); - + for(int iv = 0; iv < nv; iv++) { + if (C){ + MVertex *v = c2v[iv]; + std::map<MVertex* , std::pair<SVector3, SVector3> >::iterator it = C->find(v); + if (it == C->end())Msg::Error("POINT %d NOT FOUND FOR COMPUTING CURVATURES",v->getNum()); + // printf("%g %g %g\n",it->second.first.x(),it->second.first.y(),it->second.first.z()); + gf->stl_curvatures[2*iv] = it->second.first; + gf->stl_curvatures[2*iv+1] = it->second.second; + } gf->stl_vertices_uv[iv] = SPoint2(uvc[2*iv],uvc[2*iv+1]); gf->stl_vertices_xyz[iv] = @@ -138,14 +179,16 @@ int parametrizeGFace(discreteFace *gf) gf->stl_triangles[3 * ie + 1] = m->triangles.node[3 * ie + 1]; gf->stl_triangles[3 * ie + 2] = m->triangles.node[3 * ie + 2]; } + // printf("A\n"); gf->fillVertexArray(false); HXT_CHECK(hxtMeshDelete(&m)); HXT_CHECK(hxtEdgesDelete(&edges)); HXT_CHECK(hxtFree(&uvc)); + // printf("B\n"); return 0; } #else -int parametrizeGFace(GFace *gf) +int parametrizeGFace(GFace *gf, std::map<std::pair<MVertex*,GFace*> , std::pair<SVector3, SVector3> > *C) { Msg::Error("Gmsh should be compiled against HXT for being able to compute " "discrete parametrizations"); @@ -174,12 +217,27 @@ int isTriangulationParametrizable(const std::vector<MTriangle *> &t, int Nmax, } std::map<MEdge, int, Less_Edge>::iterator it = e.begin(); std::vector<MEdge> _bnd; - for(; it != e.end(); ++it) + for(; it != e.end(); ++it){ if(it->second == 1) _bnd.push_back(it->first); + } + std::vector<std::vector<MVertex *> > vs; - // printf("%d triangles %d edges %d vertices %d edges on - // boundaries\n",t.size(),v.size(),e.size(),_bnd.size()); - if(!SortEdgeConsecutive(_bnd, vs)) return 2; + if(!SortEdgeConsecutive(_bnd, vs)) { + // we have vertices adjacent to more than 2 model edges + // FILE *f = fopen("bug.pos","w"); + // fprintf(f,"View\"\"{\n"); + // for (size_t i=0;i<t.size();i++){ + // fprintf(f,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d};\n", + // t[i]->getVertex(0)->x(),t[i]->getVertex(0)->y(),t[i]->getVertex(0)->z(), + // t[i]->getVertex(1)->x(),t[i]->getVertex(1)->y(),t[i]->getVertex(1)->z(), + // t[i]->getVertex(2)->x(),t[i]->getVertex(2)->y(),t[i]->getVertex(2)->z(), + // t[i]->getVertex(0)->getNum(),t[i]->getVertex(1)->getNum(),t[i]->getVertex(2)->getNum()); + // } + // fprintf(f,"};\n"); + // fclose(f); + // getchar(); + return 2; + } double lmax = 0; for(size_t i = 0; i < vs.size(); i++) { double li = 0; @@ -189,7 +247,7 @@ int isTriangulationParametrizable(const std::vector<MTriangle *> &t, int Nmax, lmax = std::max(li, lmax); } - if(ar * lmax * lmax < 2 * M_PI * surf) { return 2; } + if(ar * lmax * lmax < 2 * M_PI * surf) { return 4; } int poincare = t.size() - (2 * (v.size() - 1) - _bnd.size() + 2 * (vs.size() - 1)); @@ -206,6 +264,26 @@ void computeEdgeCut(GModel *gm, std::vector<MLine *> &cut, int max_elems_per_cut) { GModel m; + + // ---------------------------------------------------------------------------------- + // STUPID FIX !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) { + std::vector<MTriangle*> aa; + for(size_t i = 0; i < (*it)->triangles.size(); i++){ + if ((*it)->triangles[i]->getVertex(0) == (*it)->triangles[i]->getVertex(1) || + (*it)->triangles[i]->getVertex(0) == (*it)->triangles[i]->getVertex(2) || + (*it)->triangles[i]->getVertex(1) == (*it)->triangles[i]->getVertex(2)){ + // printf("TRIANGLE BAD %d %d %d\n",(*it)->triangles[i]->getVertex(0)->getNum() + // ,(*it)->triangles[i]->getVertex(1)->getNum() + // ,(*it)->triangles[i]->getVertex(2)->getNum()); + } + else aa.push_back((*it)->triangles[i]); + } + (*it)->triangles = aa; + } + // END STUPID FIX !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // ---------------------------------------------------------------------------------- + for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) { int part = 0; if((*it)->triangles.empty()) continue; diff --git a/Geo/GModelParametrize.h b/Geo/GModelParametrize.h index 8cf198bd4ee7dc0a0c15bf64b463c5c1a5d2ee1b..22b93922d80fb8043222ff7b60f7046cf226a7c2 100644 --- a/Geo/GModelParametrize.h +++ b/Geo/GModelParametrize.h @@ -13,8 +13,9 @@ void computeEdgeCut(GModel *gm, std::vector<MLine *> &cut, int max_elems_per_cut); void computeNonManifoldEdges(GModel *gm, std::vector<MLine *> &cut, bool addBoundary); -int parametrizeAllGFace(GModel *gm); +int parametrizeAllGFace(GModel *gm, std::map<MVertex* , std::pair<SVector3, SVector3> > *C=NULL); void parametrizeAllGEdge(GModel *gm); -int parametrizeGFace(discreteFace *gf); +int parametrizeGFace(discreteFace *gf, std::map<MVertex* , std::pair<SVector3, SVector3> > *C=NULL); +HXTStatus computeDiscreteCurvatures(GModel *gm, std::map<MVertex* , std::pair<SVector3, SVector3> > &C ); #endif diff --git a/Geo/MEdge.cpp b/Geo/MEdge.cpp index cbde5cfc662f7ad6c8c4a8cb24cb3e992f0d0d07..ff2f9b6a5ae640abb9727ef8903fb411e07ac46a 100644 --- a/Geo/MEdge.cpp +++ b/Geo/MEdge.cpp @@ -83,7 +83,7 @@ bool SortEdgeConsecutive(const std::vector<MEdge> &e, else { if(it0->second.second == NULL) { it0->second.second = v1; } else { - Msg::Error( + Msg::Debug( "A list of edges is has points that are adjacet to 3 edges ! "); return false; } @@ -93,7 +93,14 @@ bool SortEdgeConsecutive(const std::vector<MEdge> &e, else { if(it1->second.second == NULL) { it1->second.second = v0; } else { - Msg::Error("Wrong topology for a list of edges "); + Msg::Debug("Wrong topology for a list of edges "); + Msg::Debug("Vertex %d is adjacent to more than 2 vertices %d %d",v1->getNum(),it1->second.first->getNum(),it1->second.second->getNum()); + // printf("Vertex %d is adjacent to more than 2 vertices %d %d\n",v1->getNum(),it1->second.first->getNum(),it1->second.second->getNum()); + // for (size_t j=0;j<e.size();j++){ + // printf("(%d %d)",e[j].getVertex(0)->getNum(), + // e[j].getVertex(1)->getNum()); + // } + // printf("\n"); return false; } } diff --git a/Geo/discreteEdge.cpp b/Geo/discreteEdge.cpp index 982870c19f3c7bfceb53c6fffc53c873356c70b1..0c12436aad53f9ef943a181a353ce9dc1d3c9b7c 100644 --- a/Geo/discreteEdge.cpp +++ b/Geo/discreteEdge.cpp @@ -152,8 +152,18 @@ SVector3 discreteEdge::firstDer(double par) const return der; } +SPoint2 discreteEdge::reparamOnFace(const GFace *face, double epar, int dir) const { + GPoint p = point(epar); + double guess[2]; + GPoint ps = face->closestPoint(SPoint3(p.x(),p.y(),p.z()),guess); + // printf("garouclaboucazou %g %g %g %g %g %g\n",p.x(),p.y(),p.z(),ps.x(),ps.y(),ps.z()); + return SPoint2(ps.u(),ps.v()); +} + + double discreteEdge::curvature(double par) const { + return 1.e-12; double tLoc; int iEdge; if(_discretization.size() <= 3) @@ -238,8 +248,14 @@ void discreteEdge::createGeometry() if(lines.empty()) return; if(!_discretization.empty()) return; - + + // printf("line %d\n",tag()); + // for(std::size_t i = 0; i < lines.size(); i++) { + // printf("(%d %d)",lines[i]->getVertex(0)->getNum(),lines[i]->getVertex(1)->getNum()); + // } + // printf("\n"); orderMLines(); + // printf("done \n"); bool reverse = false; if(getEndVertex()) diff --git a/Geo/discreteEdge.h b/Geo/discreteEdge.h index 0365d161de04e2857e4bc0bb0c2dbaddc20df446..aa4d4c603284b3d6e281c1ad0fce5a9062fe0330 100644 --- a/Geo/discreteEdge.h +++ b/Geo/discreteEdge.h @@ -32,6 +32,7 @@ public: virtual void mesh(bool verbose); int minimumDrawSegments() const { return 2 * _pars.size(); } virtual int minimumMeshSegments() const { return periodic(0) ? 3 : 2; } + virtual SPoint2 reparamOnFace(const GFace *face, double epar, int dir) const; void setSplit(discreteEdge *e0, discreteEdge *e1, GVertex *vs) { _split[0] = e0; diff --git a/Mesh/BackgroundMeshTools.cpp b/Mesh/BackgroundMeshTools.cpp index 0a234f89671d85a7ddf4b0293b6077202c0e18b1..db69a2de1405a59114146f6e35fa8c4a32350d3a 100644 --- a/Mesh/BackgroundMeshTools.cpp +++ b/Mesh/BackgroundMeshTools.cpp @@ -14,12 +14,12 @@ static double max_surf_curvature(const GEdge *ge, double u) { - double val = 0; + double val = 0; std::vector<GFace *> faces = ge->faces(); std::vector<GFace *>::iterator it = faces.begin(); while(it != faces.end()) { SPoint2 par = ge->reparamOnFace((*it), u, 1); - double cc = (*it)->curvature(par); + double cc = (*it)->curvatureMax(par); val = std::max(cc, val); ++it; } diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index 2292bbefdaf0a9455937c69ea238158cd529447d..c03e5d68d31fe84fe808aa7191899b03193dee88 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -482,10 +482,10 @@ static void Mesh2D(GModel *m) for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) { // STL remeshing is not yet thread-safe - if((*it)->geomType() == GEntity::DiscreteSurface){ - if(static_cast<discreteFace *>(*it)->haveParametrization()) - Msg::SetNumThreads(1); - } + // if((*it)->geomType() == GEntity::DiscreteSurface){ + // if(static_cast<discreteFace *>(*it)->haveParametrization()) + // Msg::SetNumThreads(1); + // } // Frontal-Delaunay for quads and co are not yet thread-safe if((*it)->getMeshingAlgo() == ALGO_2D_FRONTAL_QUAD || (*it)->getMeshingAlgo() == ALGO_2D_PACK_PRLGRMS || diff --git a/contrib/hxt/hxt_mean_values.c b/contrib/hxt/hxt_mean_values.c index 1983923af9b9c713d0d5768ec3e2e758c900754a..adb2c4761018432884624790c8a097c581380c7b 100644 --- a/contrib/hxt/hxt_mean_values.c +++ b/contrib/hxt/hxt_mean_values.c @@ -34,7 +34,10 @@ HXTStatus hxtMeanValuesCreate(HXTEdges *edges, HXTMeanValues **meanValues) // be moved into parametrization? HXTBoundaries *boundaries; + printf("1 %d %d %d\n",mesh->triangles.node[0],mesh->triangles.node[1],mesh->triangles.node[2]); + printf("1 %d %d %d\n",mesh->triangles.node[3],mesh->triangles.node[4],mesh->triangles.node[5]); HXT_CHECK(hxtEdgesSetBoundaries(edges, &boundaries)); + printf("2\n"); map->boundaries = boundaries; @@ -82,11 +85,12 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ HXT_CHECK(hxtBoundariesGetNumberOfEdgesOfLineLoop(meanValues->boundaries,meanValues->hole[i],&c)); nby += c; } - + +#ifdef __FILLERGAP_ uint32_t *fillergap; HXT_CHECK(hxtMalloc(&fillergap, 3*(nTriangles+nby)*sizeof(uint32_t))); memcpy(fillergap, mesh->triangles.node, 3*nTriangles*sizeof(uint32_t)); - + int s=0; for(int i=0; i<meanValues->nHoles; i++){ uint32_t *cedgs; @@ -100,20 +104,27 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ } s += n_; } +#endif // __FILLERGAP_ + /* for(int i=0; i<nTriangles+nby; i++) printf("tri %d (nby=%d) \t %u %u %u\n",i,nby,fillergap[3*i+0],fillergap[3*i+1],fillergap[3*i+2]); */ - + HXTLinearSystem *sys; - + +#ifdef __FILLERGAP_ HXT_CHECK(hxtLinearSystemCreateLU(&sys,nTriangles+nby,3,1,fillergap)); - +#else + HXT_CHECK(hxtLinearSystemCreateLU(&sys,nTriangles,3,1,mesh->triangles.node)); +#endif + + uint32_t *flag; HXT_CHECK(hxtMalloc(&flag,nNodes*sizeof(uint32_t))); for(uint32_t ii=0; ii<nNodes; ii++) flag[ii] = 0; - + /* boundary conditions */ double *uv = meanValues->uv; int n; @@ -130,28 +141,28 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ uv[2*edges->node[2*edges_ll[i]+0]+1] = sin(angle); currentLength += hxtEdgesLength(meanValues->initialEdges, edges_ll[i]); } - + double *U, *V, *Urhs, *Vrhs; //printf("allocation: %d\n",nNodes+meanValues->nHoles); HXT_CHECK( hxtMalloc(&U,(nNodes+meanValues->nHoles)*sizeof(double)) ); HXT_CHECK( hxtMalloc(&V,(nNodes+meanValues->nHoles)*sizeof(double)) ); HXT_CHECK( hxtMalloc(&Urhs,(nNodes+meanValues->nHoles)*sizeof(double)) ); HXT_CHECK( hxtMalloc(&Vrhs,(nNodes+meanValues->nHoles)*sizeof(double)) ); - - + + // init linear system HXT_CHECK(hxtLinearSystemZeroMatrix(sys)); for(uint32_t i=0; i<(nNodes+meanValues->nHoles); i++){ Urhs[i] = 0.; Vrhs[i] = 0.; } - + // setting linear system for(uint32_t ie=0; ie<edges->numEdges; ie++){ int ik[2] = {-1,-1}; uint64_t *tri = edges->edg2tri + 2*ie; - + // gather local edge index for(int it=0; it<2; it++){ if(tri[it]==(uint64_t)-1) @@ -163,21 +174,21 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ } } } - + for(int ij=0; ij<2; ij++){ - + uint32_t v0 = edges->node[2*ie+ij]; uint32_t v1 = edges->node[2*ie+(1-ij)]; - + if (flag[v0]==1){//boundary nodes/conditons - HXT_CHECK(hxtLinearSystemSetMatrixRowIdentity(sys,v0,0)); + HXT_CHECK(hxtLinearSystemSetMatrixRowIdentity(sys,v0,0)); HXT_CHECK(hxtLinearSystemSetRhsEntry(sys,Urhs, v0,0, uv[2*v0+0])); HXT_CHECK(hxtLinearSystemSetRhsEntry(sys,Vrhs, v0,0, uv[2*v0+1])); } else {// inner node - double e[3] = {mesh->vertices.coord[4*v1+0]-mesh->vertices.coord[4*v0+0],mesh->vertices.coord[4*v1+1]-mesh->vertices.coord[4*v0+1],mesh->vertices.coord[4*v1+2]-mesh->vertices.coord[4*v0+2]}; - double ne = sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]); - + double e[3] = {mesh->vertices.coord[4*v1+0]-mesh->vertices.coord[4*v0+0],mesh->vertices.coord[4*v1+1]-mesh->vertices.coord[4*v0+1],mesh->vertices.coord[4*v1+2]-mesh->vertices.coord[4*v0+2]}; + double ne = sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]); + uint32_t vLeft = mesh->triangles.node[3*tri[0] + (ik[0]+2)%3]; double a[3] = {mesh->vertices.coord[4*vLeft+0]-mesh->vertices.coord[4*v0+0],mesh->vertices.coord[4*vLeft+1]-mesh->vertices.coord[4*v0+1],mesh->vertices.coord[4*vLeft+2]-mesh->vertices.coord[4*v0+2]}; double na = sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); @@ -199,9 +210,9 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ } } }// end for int ie + - - +#ifdef __FILLERGAP_ // holes are filled somehow for(int i=0; i<meanValues->nHoles; i++){ @@ -258,6 +269,8 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ HXT_CHECK(hxtFree(&c)); HXT_CHECK(hxtFree(&d)); } +#endif + HXT_CHECK(hxtLinearSystemSolve(sys,Urhs,U)); HXT_CHECK(hxtLinearSystemSolve(sys,Vrhs,V)); for(uint32_t i=0; i<nNodes; i++){ @@ -265,7 +278,9 @@ HXTStatus hxtMeanValuesCompute(HXTMeanValues *meanValues){ uv[2*i+1] = V[i] ; } +#ifdef __FILLERGAP_ HXT_CHECK(hxtFree(&fillergap)); +#endif HXT_CHECK(hxtFree(&flag)); HXT_CHECK(hxtFree(&U)); HXT_CHECK(hxtFree(&V));