diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp index c55eacd260275a58e16de5969204c3dc9ebaa3f7..d616de0380df27c46f9d5d998e74cfbf2cd004fa 100644 --- a/Common/CommandLine.cpp +++ b/Common/CommandLine.cpp @@ -365,6 +365,16 @@ void Get_Options(int argc, char *argv[]) else Msg::Fatal("Missing number"); } + else if(!strcmp(argv[i] + 1, "edgelmin")) { + i++; + if(argv[i] != NULL) { + CTX.mesh.tolerance_edge_length = atof(argv[i++]); + if( CTX.mesh.tolerance_edge_length <= 0.0) + Msg::Fatal("Tolerance for model edge length must be > 0 (here %g)", CTX.mesh.tolerance_edge_length); + } + else + Msg::Fatal("Missing number"); + } else if(!strcmp(argv[i] + 1, "epslc1d")) { i++; if(argv[i] != NULL) { diff --git a/Common/Context.h b/Common/Context.h index 3e4161a615c5dfdec903055efee20f8743d32a8d..76fe3a90d58e099f899299d869fe75df0cbcd049 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -158,7 +158,7 @@ class Context_T { int optimize, optimize_netgen, refine_steps; int quality_type, label_type; double quality_inf, quality_sup, radius_inf, radius_sup; - double scaling_factor, lc_factor, rand_factor, lc_integration_precision, lc_min, lc_max; + double scaling_factor, lc_factor, rand_factor, lc_integration_precision, lc_min, lc_max, tolerance_edge_length; int lc_from_points, lc_from_curvature, lc_extend_from_boundary; int dual, voronoi, draw_skin_only; int light, light_two_side, light_lines; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 9f854006e7203b3ea4757f6365be6a818cdd7b62..db33263c66e1a6445c4fe8ae9cb1538780ef04d9 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -938,7 +938,7 @@ StringXNumber MeshOptions_Number[] = { "Factor applied to all characteristic lengths" }, { F|O, "CharacteristicLengthMin" , opt_mesh_lc_min, 0.0 , "Minimum characteristic length" }, - { F|O, "CharacteristicLengthMax" , opt_mesh_lc_max, 1.e22 , + { F|O, "CharacteristicLengthMax" , opt_mesh_lc_max, 1.e22, "Maximum characteristic length" }, { F|O, "CharacteristicLengthFromCurvature" , opt_mesh_lc_from_curvature , 0. , "Compute characteristic lengths from curvature" }, @@ -1093,6 +1093,8 @@ StringXNumber MeshOptions_Number[] = { "Display size of tangent vectors (in pixels)" }, { F|O, "Tetrahedra" , opt_mesh_tetrahedra , 1. , "Display mesh tetrahedra?" }, + { F|O, "ToleranceEdgeLength" , opt_mesh_tolerance_edge_length, 0.0, + "Skip a model edge in mesh generation if its length is less than user's defined tolerance" }, { F|O, "Triangles" , opt_mesh_triangles , 1. , "Display mesh triangles?" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index e251ff772726ee55cf8be0230f3c59a345bc4deb..b6423408ed7ef0167a3974394a15cdaa06dc323c 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -4497,6 +4497,14 @@ double opt_mesh_lc_max(OPT_ARGS_NUM) return CTX.mesh.lc_max; } +double opt_mesh_tolerance_edge_length(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.mesh.tolerance_edge_length = val; + return CTX.mesh.tolerance_edge_length; +} + + double opt_mesh_lc_from_curvature(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index d46301269a01616dfe2702230bf402b02d319643..e2b4408be53144862f2d57f357648416a9e69e5b 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -429,6 +429,7 @@ double opt_mesh_explode(OPT_ARGS_NUM); double opt_mesh_scaling_factor(OPT_ARGS_NUM); double opt_mesh_lc_min(OPT_ARGS_NUM); double opt_mesh_lc_max(OPT_ARGS_NUM); +double opt_mesh_tolerance_edge_length(OPT_ARGS_NUM); double opt_mesh_lc_factor(OPT_ARGS_NUM); double opt_mesh_lc_from_curvature(OPT_ARGS_NUM); double opt_mesh_lc_from_points(OPT_ARGS_NUM); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index a6f2aef38072865375f45e607a64572ab39c78bf..20a5accb0ae39325b976b89ca360d54c0c71a5f4 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1109,7 +1109,6 @@ void mesh_options_ok_cb(CALLBACK_ARGS) opt_mesh_light_two_side(0, GMSH_SET, WID->mesh_butt[18]->value()); opt_mesh_smooth_normals(0, GMSH_SET, WID->mesh_butt[19]->value()); opt_mesh_light_lines(0, GMSH_SET, WID->mesh_butt[20]->value()); - opt_mesh_nb_smoothing(0, GMSH_SET, WID->mesh_value[0]->value()); opt_mesh_lc_factor(0, GMSH_SET, WID->mesh_value[2]->value()); opt_mesh_lc_min(0, GMSH_SET, WID->mesh_value[25]->value()); diff --git a/Geo/GEdge.cpp b/Geo/GEdge.cpp index 1d3bcc087f501a54a250001bc38ae191b82b4be5..78ba2ade13c6b3415a0a36e4674f867e8fc1b8a9 100644 --- a/Geo/GEdge.cpp +++ b/Geo/GEdge.cpp @@ -19,7 +19,7 @@ #endif GEdge::GEdge(GModel *model, int tag, GVertex *_v0, GVertex *_v1) - : GEntity(model, tag), v0(_v0), v1(_v1) + : GEntity(model, tag), _tooSmall(false), v0(_v0), v1(_v1) { if(v0) v0->addEdge(this); if(v1 && v1 != v0) v1->addEdge(this); diff --git a/Geo/GEdge.h b/Geo/GEdge.h index d9a01a4577a3d667db86a4ac833902f6fe10edab..5eff3e278394cfebc0d7ad9a08a8c7941567bb71 100644 --- a/Geo/GEdge.h +++ b/Geo/GEdge.h @@ -20,6 +20,7 @@ class ExtrudeParams; class GEdge : public GEntity { private: double _length; + bool _tooSmall; protected: GVertex *v0, *v1; @@ -99,7 +100,8 @@ class GEdge : public GEntity { virtual double prescribedMeshSizeAtVertex() const { return meshAttributes.meshSize; } // true if start == end and no more than 2 segments - bool isMeshDegenerated() const{ return (v0 == v1 && mesh_vertices.size() < 2); } + void setTooSmall ( bool b) {_tooSmall = b;} + bool isMeshDegenerated() const{ return _tooSmall || (v0 == v1 && mesh_vertices.size() < 2); } // number of types of elements int getNumElementTypes() const { return 1; } diff --git a/Geo/gmshEdge.cpp b/Geo/gmshEdge.cpp index eacdb7a9602c3c61b3fa76f5d499062b27ded796..ec185692cc0d197de5d4048119ae2fd89d718301 100644 --- a/Geo/gmshEdge.cpp +++ b/Geo/gmshEdge.cpp @@ -201,6 +201,7 @@ SPoint2 gmshEdge::reparamOnFace(GFace *face, double epar,int dir) const } } + if(s->Typ == MSH_SURF_REGL){ Curve *C[4]; for(int i = 0; i < 4; i++) diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp index 08e101ea84f69139e2ae88c6f9798ec5e236a21a..95802691d3549d1da14cc9f0fd4378240cb06169 100644 --- a/Geo/gmshFace.cpp +++ b/Geo/gmshFace.cpp @@ -186,6 +186,53 @@ GPoint gmshFace::point(double par1, double par2) const GPoint gmshFace::closestPoint(const SPoint3 & qp, const double initialGuess[2]) const { + + if (s->Typ == MSH_SURF_PLAN && !s->geometry){ + double XP = qp.x(); + double YP = qp.y(); + double ZP = qp.z(); + double a = meanPlane.a; + double b = meanPlane.b; + double c = meanPlane.c; + double d = meanPlane.d; + // X = P + H N, find y such that + // a X_1 + b X_2 + c X_3 + d = 0 + // a ( XP + y XN) + b ( YP + y YN) + c ( ZP + y ZN) + d = 0 + // H ( a XN + b YN + c ZN ) = - (a XP + b YP + c ZP + d) + const double H = -(a*XP + b*YP + c *ZP + d)/(a*a + b*b + c*c); + const double X = XP + H * a; + const double Y = YP + H * b; + const double Z = ZP + H * c; + // now compute parametric coordinates + double x,y,z,VX[3], VY[3]; + getMeanPlaneData(VX, VY, x, y, z); + // XP = X + u VX + v VY + // We are sure to be on the plane + double M[3][2] = {{VX[0],VY[0]},{VX[1],VY[1]},{VX[2],VY[2]}}; + double MN[2][2]; + double B[3] = {XP-x,YP-y,ZP-z}; + double BN[2],UV[2]; + for (int i=0;i<2;i++){ + BN[i] = 0; + for (int k=0;k<3;k++){ + BN[i] += B[k] * M[k][i]; + } + } + for (int i=0;i<2;i++){ + for (int j=0;j<2;j++){ + MN[i][j] = 0; + for (int k=0;k<3;k++){ + MN[i][j] += M[k][i] * M[k][j]; + } + } + } + sys2x2(MN,BN,UV); + + // GPoint test = point (UV[0],UV[1]); + // printf("%g %g %g vs %g %g %g\n",XP,YP,ZP,test.x(),test.y(),test.z()); + return GPoint(XP, YP, ZP, this, UV); + } + Vertex v; double u[2] = {initialGuess[0],initialGuess[1]}; v.Pos.X = qp.x(); @@ -193,7 +240,7 @@ GPoint gmshFace::closestPoint(const SPoint3 & qp, const double initialGuess[2]) v.Pos.Z = qp.z(); bool result = ProjectPointOnSurface(s, v, u); if (!result) - printf("Project Point on surface %d \n",result); + printf("Project Point on surface %d\n",result); return GPoint(v.Pos.X, v.Pos.Y, v.Pos.Z, this, u); } diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp index b7e2f3ea4b197733ef369a4573e50953f0c38a25..ee68065662d849b8f05b7f43c557d0a822d84ded 100644 --- a/Mesh/BackgroundMesh.cpp +++ b/Mesh/BackgroundMesh.cpp @@ -163,7 +163,9 @@ double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double if(lc <= 0.){ Msg::Error("Wrong characteristic length lc = %g", lc); - lc = l1; + printf("%g %g \n", CTX.mesh.lc_min, CTX.mesh.lc_max); + + lc = l1; } return lc * CTX.mesh.lc_factor; diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index 4e382bc428819a197928f442183a3773f3e6e2e2..3cfcb07d1d89ff2e8a69c3d20e9030e8970d0495 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -25,6 +25,107 @@ extern Context_T CTX; + +static MVertex* isEquivalentTo ( std::multimap<MVertex *, MVertex *> & m, MVertex *v ) +{ + std::multimap<MVertex *, MVertex *>::iterator it = m.lower_bound(v); + std::multimap<MVertex *, MVertex *>::iterator ite = m.upper_bound(v); + if (it == ite) return v; + MVertex *res = it->second; ++it; + while (it !=ite){ + res = std::min(res,it->second);++it; + } + if (res < v) return isEquivalentTo ( m, res) ; + return res; +} + +static void buildASetOfEquivalentMeshVertices ( GFace *gf , std::multimap<MVertex *, MVertex *> & equivalent , std::map<GVertex*,MVertex*> &bm) +{ + // an edge is degenerated when is length is considered to be + // zero. In some cases, a model edge can be considered as too + // small an is ignored. + + // for taking that into account, we loop over the edges + // and create pairs of MVertices that are considered as + // equal. + + std::list<GEdge*> edges = gf->edges(); + std::list<GEdge*> emb_edges = gf->embeddedEdges(); + std::list<GEdge*>::iterator it = edges.begin(); + + while(it != edges.end()){ + if((*it)->isMeshDegenerated()){ + MVertex *va = *((*it)->getBeginVertex()->mesh_vertices.begin()); + MVertex *vb = *((*it)->getEndVertex()->mesh_vertices.begin()); + if (va != vb){ + equivalent.insert(std::make_pair (va,vb)); + equivalent.insert(std::make_pair (vb,va)); + bm[(*it)->getBeginVertex()] = va; + bm[(*it)->getEndVertex()] = vb; + printf("%d equivalent to %d\n",va->getNum(),vb->getNum()); + + } + } + ++it; + } + + it = emb_edges.begin(); + while(it != emb_edges.end()){ + if((*it)->isMeshDegenerated()){ + MVertex *va = *((*it)->getBeginVertex()->mesh_vertices.begin()); + MVertex *vb = *((*it)->getEndVertex()->mesh_vertices.begin()); + if (va != vb){ + equivalent.insert(std::make_pair (va,vb)); + equivalent.insert(std::make_pair (vb,va)); + bm[(*it)->getBeginVertex()] = va; + bm[(*it)->getEndVertex()] = vb; + } + } + ++it; + } +} + +struct geomTresholdVertexEquivalence +{ + // Initial MVertex associated to one given MVertex + std::map<GVertex *, MVertex *> backward_map; + // initiate the forward and backward maps + geomTresholdVertexEquivalence (GModel *g); + // restores the initial state + ~geomTresholdVertexEquivalence (); +}; + + +geomTresholdVertexEquivalence :: geomTresholdVertexEquivalence (GModel *g) +{ + std::multimap<MVertex *, MVertex *> equivalenceMap; + for (GModel::fiter it = g->firstFace(); it != g->lastFace(); ++it) + buildASetOfEquivalentMeshVertices ( *it, equivalenceMap, backward_map ); + // build the structure that identifiate geometrically equivalent + // mesh vertices. + for (std::map<GVertex*,MVertex *>::iterator it = backward_map.begin() ; it != backward_map.end() ; ++it){ + GVertex *g = it->first; + MVertex *v = it->second; + MVertex *other = isEquivalentTo (equivalenceMap,v); + if (v != other){ + printf("Finally : %d equivalent to %d\n",v->getNum(),other->getNum()); + g->mesh_vertices.clear(); + g->mesh_vertices.push_back(other); + } + } +} + +geomTresholdVertexEquivalence :: ~geomTresholdVertexEquivalence () +{ + // restore the initial data + for (std::map<GVertex*,MVertex *>::iterator it = backward_map.begin() ; it != backward_map.end() ; ++it){ + GVertex *g = it->first; + MVertex *v = it->second; + g->mesh_vertices.clear(); + g->mesh_vertices.push_back(v); + } +} + template<class T> static void GetQualityMeasure(std::vector<T*> &ele, double &gamma, double &gammaMin, double &gammaMax, @@ -282,6 +383,9 @@ static void Mesh2D(GModel *m) Msg::StatusBar(1, true, "Meshing 2D..."); double t1 = Cpu(); + // skip short mesh edges + geomTresholdVertexEquivalence inst (m); + // boundary layers are special: their generation (including vertices // and curve meshes) is global as it depends on a smooth normal // field generated from the surface mesh of the source surfaces diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index 4e5a3c78da071685e959fa65e06c150cb279cf9f..638601d5242bd007c403e28780ba801239288705 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -436,24 +436,31 @@ void getFaceVertices(GFace *gf, MVertex *v; const double t1 = points(k, 0); const double t2 = points(k, 1); - if(!reparamOK || linear || gf->geomType() == GEntity::DiscreteSurface){ + if(linear || gf->geomType() == GEntity::DiscreteSurface){ SPoint3 pc = face.interpolate(t1, t2); v = new MVertex(pc.x(), pc.y(), pc.z(), gf); } else{ double X(0),Y(0),Z(0),GUESS[2]={0,0}; + for (int j=0; j<incomplete->getNumVertices(); j++){ double sf ; incomplete->getShapeFunction(j,t1,t2,0,sf); MVertex *vt = incomplete->getVertex(j); X += sf * vt->x(); Y += sf * vt->y(); Z += sf * vt->z(); - GUESS[0] += sf * pts[j][0]; - GUESS[1] += sf * pts[j][1]; + if (reparamOK){ + GUESS[0] += sf * pts[j][0]; + GUESS[1] += sf * pts[j][1]; + } + } + if (reparamOK){ + GPoint gp = gf->closestPoint(SPoint3(X,Y,Z),GUESS); + v = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, gp.u(), gp.v()); + } + else{ + v = new MVertex(X,Y,Z, gf); } - GPoint gp = gf->closestPoint(SPoint3(X,Y,Z),GUESS); - // printf("%g %g %g -- %g %g %g\n",X,Y,Z,gp.x(),gp.y(),gp.z()); - v = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, gp.u(), gp.v()); } faceVertices[p].push_back(v); gf->mesh_vertices.push_back(v); @@ -718,13 +725,13 @@ void setHighOrder(GFace *gf, edgeContainer &edgeVertices, ve, nPts + 1)); } else{ - if (gf->geomType() == GEntity::Plane){ + if (0 && gf->geomType() == GEntity::Plane){ getFaceVertices(gf, t, vf, faceVertices, linear, nPts); } else{ - MTriangleN incpl (t->getVertex(0), t->getVertex(1), t->getVertex(2), - ve, nPts + 1); - getFaceVertices(gf, &incpl, t, vf, faceVertices, linear, nPts); + MTriangleN incpl (t->getVertex(0), t->getVertex(1), t->getVertex(2), + ve, nPts + 1); + getFaceVertices(gf, &incpl, t, vf, faceVertices, linear, nPts); } ve.insert(ve.end(), vf.begin(), vf.end()); triangles2.push_back diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp index 67f7ca73b23ef96fd2cd7d9b9f375797966b117c..6302508a5aabf07f72f15f9738662200b79a7e90 100644 --- a/Mesh/meshGEdge.cpp +++ b/Mesh/meshGEdge.cpp @@ -292,6 +292,10 @@ void meshGEdge::operator() (GEdge *ge) if(length == 0.0) Msg::Debug("Curve %d has a zero length", ge->tag()); + // TEST + if (length < CTX.mesh.tolerance_edge_length)ge->setTooSmall(true); + + // Integrate detJ/lc du double a; int N; diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 985c21489a52f60a080439b595b5667499b507cf..c50a9662369ea965c905630a82c261abc29f7bed 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -316,6 +316,7 @@ static bool recover_medge(BDS_Mesh *m, GEdge *ge, std::set<EdgeToRecover> *e2r, return true; } + // Builds An initial triangular mesh that respects the boundaries of // the domain, including embedded points and surfaces @@ -346,18 +347,21 @@ static bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) it = emb_edges.begin(); while(it != emb_edges.end()){ - all_vertices.insert((*it)->mesh_vertices.begin(), - (*it)->mesh_vertices.end() ); - all_vertices.insert((*it)->getBeginVertex()->mesh_vertices.begin(), - (*it)->getBeginVertex()->mesh_vertices.end()); - all_vertices.insert((*it)->getEndVertex()->mesh_vertices.begin(), - (*it)->getEndVertex()->mesh_vertices.end()); + if(!(*it)->isMeshDegenerated()){ + all_vertices.insert((*it)->mesh_vertices.begin(), + (*it)->mesh_vertices.end() ); + all_vertices.insert((*it)->getBeginVertex()->mesh_vertices.begin(), + (*it)->getBeginVertex()->mesh_vertices.end()); + all_vertices.insert((*it)->getEndVertex()->mesh_vertices.begin(), + (*it)->getEndVertex()->mesh_vertices.end()); + } ++it; } if (all_vertices.size() < 3){ - Msg::Warning("Cannot triangulate less than 3 vertices"); - return false; + Msg::Warning("Mesh Generation of Model Face %d Skipped : Only %d Mesh Vertices on The Contours",gf->tag(),all_vertices.size()); + gf->meshStatistics.status = GFace::DONE; + return true; } double *U_ = new double[all_vertices.size()]; @@ -506,7 +510,8 @@ static bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) } it = emb_edges.begin(); while(it != emb_edges.end()){ - recover_medge(m, *it, &edgesToRecover, &edgesNotRecovered, 1); + if(!(*it)->isMeshDegenerated()) + recover_medge(m, *it, &edgesToRecover, &edgesNotRecovered, 1); ++it; } @@ -581,7 +586,8 @@ static bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) it = emb_edges.begin(); while(it != emb_edges.end()){ - recover_medge(m, *it, &edgesToRecover, &edgesNotRecovered, 2); + if(!(*it)->isMeshDegenerated()) + recover_medge(m, *it, &edgesToRecover, &edgesNotRecovered, 2); ++it; } // compute characteristic lengths at vertices @@ -1286,6 +1292,7 @@ const int debugSurface = -1; void meshGFace::operator() (GFace *gf) { + gf->model()->setCurrentMeshEntity(gf); if (debugSurface >= 0 && gf->tag() != debugSurface){ diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp index e88a2140bc17cefffb5d5be8b50ba96772e2f9fc..68f649ed82124068b0d3fc5b78c3a038f9550a1b 100644 --- a/Mesh/meshGRegion.cpp +++ b/Mesh/meshGRegion.cpp @@ -153,8 +153,29 @@ void TransferTetgenMesh(GRegion *gr, tetgenio &in, tetgenio &out, int Count = 0; for(int j = 0; j < 3; j++){ if(v[j]->onWhat()->dim() == 2){ - v[j]->getParameter(0,guess[0]); - v[j]->getParameter(1,guess[1]); + double uu,vv; + v[j]->getParameter(0,uu); + v[j]->getParameter(1,vv); + guess[0] += uu; + guess[1] += vv; + Count++; + } + else if (v[j]->onWhat()->dim() == 1){ + GEdge *ge = (GEdge*)v[j]->onWhat(); + double UU; + v[j]->getParameter(0, UU); + SPoint2 param; + param = ge->reparamOnFace(gf, UU, 1); + guess[0]+=param.x(); + guess[1]+=param.y(); + Count++; + } + else if (v[j]->onWhat()->dim() == 0){ + SPoint2 param; + GVertex *gv = (GVertex*)v[j]->onWhat(); + param = gv->reparamOnFace(gf,1); + guess[0]+=param.x(); + guess[1]+=param.y(); Count++; } } @@ -171,14 +192,16 @@ void TransferTetgenMesh(GRegion *gr, tetgenio &in, tetgenio &out, // PARAMETRIC COORDINATES SHOULD BE SET for the vertex !!!!!!!!!!!!! // This is not 100 % safe yet, so we reserve that operation for high order // meshes. + Msg::Debug("A new point has been inserted in mesh face %d by the 3D mesher, guess %g %g",gf->tag(),guess[0],guess[1]); GPoint gp = gf->closestPoint (SPoint3(v[j]->x(), v[j]->y(), v[j]->z()),guess); - - Msg::Debug("A new point has been inserted in mesh face %d by the 3D mesher",gf->tag()); - Msg::Debug("The point has been projected back to the surface (%g %g %g) -> (%g %g %g)", - v[j]->x(), v[j]->y(), v[j]->z(),gp.x(),gp.y(),gp.z()); + Msg::Debug("The point has been projected back to the surface (%g %g %g) -> (%g %g %g), (%g,%g)", + v[j]->x(), v[j]->y(), v[j]->z(),gp.x(),gp.y(),gp.z(),gp.u(),gp.v()); // To be safe, we should ensure that this mesh motion does not lead to an invalid mesh !!!! + //v1b = new MVertex(gp.x(),gp.y(),gp.z(),gf); v1b = new MFaceVertex(gp.x(),gp.y(),gp.z(),gf,gp.u(),gp.v()); + //v1b = new MVertex(v[j]->x(), v[j]->y(), v[j]->z(),gf); + } else{ v1b = new MVertex(v[j]->x(), v[j]->y(), v[j]->z(),gf);