diff --git a/Common/gmsh.cpp b/Common/gmsh.cpp index 75a324b3a14b50d6b5dff071481246b48af4ff17..814c20676ad6c51cedbd879f9ed8678912624c69 100644 --- a/Common/gmsh.cpp +++ b/Common/gmsh.cpp @@ -943,7 +943,7 @@ gmsh::model::getParametrization(const int dim, const int tag, GFace *gf = static_cast<GFace *>(entity); for(std::size_t i = 0; i < coord.size(); i += 3) { SPoint3 p(coord[i], coord[i + 1], coord[i + 2]); - SPoint2 uv = gf->parFromPoint(p); + SPoint2 uv = gf->parFromPoint(p, true, true); parametricCoord.push_back(uv.x()); parametricCoord.push_back(uv.y()); } @@ -6476,6 +6476,7 @@ _addModelData(const int tag, const int step, const std::string &modelName, d->initAdaptiveData(view->getOptions()->timeStep, view->getOptions()->maxRecursionLevel, view->getOptions()->targetError); + view->setChanged(true); #else Msg::Error("Views require the post-processing module"); #endif @@ -6722,6 +6723,7 @@ GMSH_API void gmsh::view::addListData(const int tag, for(int idxtype = 0; idxtype < 24; idxtype++) { if(dataType == types[idxtype]) { d->importList(idxtype, numElements, data, true); + view->setChanged(true); return; } } @@ -6838,6 +6840,7 @@ gmsh::view::addListDataString(const int tag, const std::vector<double> &coord, } } d->finalize(); + view->setChanged(true); #else Msg::Error("Views require the post-processing module"); #endif @@ -6965,6 +6968,7 @@ GMSH_API void gmsh::view::setInterpolationMatrices( if(dGeo <= 0) { data->setInterpolationMatrices(itype, F, P); + view->setChanged(true); return; } @@ -6985,6 +6989,7 @@ GMSH_API void gmsh::view::setInterpolationMatrices( for(int j = 0; j < 3; j++) { Pg(i, j) = expGeo[3 * i + j]; } } data->setInterpolationMatrices(itype, F, P, Fg, Pg); + view->setChanged(true); #else Msg::Error("Views require the post-processing module"); #endif @@ -7026,6 +7031,7 @@ GMSH_API void gmsh::view::copyOptions(const int refTag, const int tag) return; } view->setOptions(ref->getOptions()); + view->setChanged(true); #if defined(HAVE_FLTK) if(FlGui::available()) FlGui::instance()->updateViews(true, true); #endif diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp index 82ca8bfc08a3639823b514f894eae94189cf1571..c78cb27e98e7755686fc8019862f830d9974e706 100644 --- a/Geo/GFace.cpp +++ b/Geo/GFace.cpp @@ -468,7 +468,7 @@ void GFace::writeGEO(FILE *fp) num.push_back((*it)->tag()); for(auto it = dir.begin(); it != dir.end(); it++) ori.push_back((*it) > 0 ? 1 : -1); - fprintf(fp, "Line Loop(%d) = ", tag()); + fprintf(fp, "Curve Loop(%d) = ", tag()); for(std::size_t i = 0; i < num.size(); i++) { if(i) fprintf(fp, ", %d", num[i] * ori[i]); @@ -988,11 +988,12 @@ void GFace::getMetricEigenVectors(const SPoint2 ¶m, double eigVal[2], } void GFace::XYZtoUV(double X, double Y, double Z, double &U, double &V, - double relax, bool onSurface) const + double relax, bool onSurface, bool convTestXYZ) const { const double Precision = onSurface ? 1.e-8 : 1.e-3; const int MaxIter = onSurface ? 25 : 10; const int NumInitGuess = 9; + bool testXYZ = (convTestXYZ || CTX::instance()->mesh.NewtonConvergenceTestXYZ); double Unew = 0., Vnew = 0., err, err2; int iter; @@ -1063,17 +1064,15 @@ void GFace::XYZtoUV(double X, double Y, double Z, double &U, double &V, if(iter < MaxIter && err <= tol && Unew <= umax && Vnew <= vmax && Unew >= umin && Vnew >= vmin) { - if(onSurface && err2 > 1.e-4 * CTX::instance()->lc && - !CTX::instance()->mesh.NewtonConvergenceTestXYZ) { + if(onSurface && err2 > 1.e-4 * CTX::instance()->lc && !testXYZ) { Msg::Warning("Converged at iter. %d for initial guess (%d,%d) " "with uv error = %g, but xyz error = %g in point " - "(%e,%e,%e) on surface %d", + "(%e, %e, %e) on surface %d", iter, i, j, err, err2, X, Y, Z, tag()); } - if(onSurface && err2 > 1.e-4 * CTX::instance()->lc && - CTX::instance()->mesh.NewtonConvergenceTestXYZ) { - // not converged in XYZ coordinates + if(onSurface && err2 > 1.e-4 * CTX::instance()->lc && testXYZ) { + // not converged in XYZ coordinates: try again } else { return; @@ -1084,18 +1083,19 @@ void GFace::XYZtoUV(double X, double Y, double Z, double &U, double &V, if(!onSurface) return; - if(relax < 1.e-6) - Msg::Error("Could not converge: surface mesh will be wrong"); + if(relax < 1.e-3) + Msg::Error("Inverse surface mapping could not converge"); else { Msg::Info("point %g %g %g : Relaxation factor = %g", X, Y, Z, 0.75 * relax); - XYZtoUV(X, Y, Z, U, V, 0.75 * relax); + XYZtoUV(X, Y, Z, U, V, 0.75 * relax, onSurface, convTestXYZ); } } -SPoint2 GFace::parFromPoint(const SPoint3 &p, bool onSurface) const +SPoint2 GFace::parFromPoint(const SPoint3 &p, bool onSurface, + bool convTestXYZ) const { double U = 0., V = 0.; - XYZtoUV(p.x(), p.y(), p.z(), U, V, 1.0, onSurface); + XYZtoUV(p.x(), p.y(), p.z(), U, V, 1.0, onSurface, convTestXYZ); return SPoint2(U, V); } diff --git a/Geo/GFace.h b/Geo/GFace.h index dab4b377575a1cf8e2ae73a6e33e559fd4489fdd..a0b222e52c0948f5261bff925f49f157d79803fb 100644 --- a/Geo/GFace.h +++ b/Geo/GFace.h @@ -148,7 +148,7 @@ public: // compute the parameters UV from a point XYZ void XYZtoUV(double X, double Y, double Z, double &U, double &V, double relax, - bool onSurface = true) const; + bool onSurface = true, bool convTestXYZ = false) const; // get the bounding box virtual SBoundingBox3d bounds(bool fast = false); @@ -181,7 +181,8 @@ public: // return the parameter location on the face given a point in space // that is on the face - virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface = true) const; + virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface = true, + bool convTestXYZ = false) const; // true if the parameter value is interior to the face virtual bool containsParam(const SPoint2 &pt); diff --git a/Geo/OCCFace.cpp b/Geo/OCCFace.cpp index cdc4b132511f47536f69c125ce21a64e7cfeef05..ab4f0a3c20c178851607a9c9876f8ac46c6d3e08 100644 --- a/Geo/OCCFace.cpp +++ b/Geo/OCCFace.cpp @@ -285,16 +285,17 @@ GPoint OCCFace::closestPoint(const SPoint3 &qp, return GFace::closestPoint(qp, initialGuess); } -SPoint2 OCCFace::parFromPoint(const SPoint3 &qp, bool onSurface) const +SPoint2 OCCFace::parFromPoint(const SPoint3 &qp, bool onSurface, + bool convTestXYZ) const { // less robust but can be much faster if(CTX::instance()->geom.occUseGenericClosestPoint) - return GFace::parFromPoint(qp); + return GFace::parFromPoint(qp, onSurface, convTestXYZ); double uv[2]; if(_project(qp.data(), uv, nullptr)) return SPoint2(uv[0], uv[1]); - else - return GFace::parFromPoint(qp); + else // fallback: force convergence test in XYZ coordinates + return GFace::parFromPoint(qp, true, true); } GEntity::GeomType OCCFace::geomType() const diff --git a/Geo/OCCFace.h b/Geo/OCCFace.h index 2f870bbd5f8c572c6bfe1b1f72db9511768ce904..611994b68bb4ae10ea1385543f223363224164d3 100644 --- a/Geo/OCCFace.h +++ b/Geo/OCCFace.h @@ -45,7 +45,8 @@ public: virtual GEntity::GeomType geomType() const; virtual ModelType getNativeType() const { return OpenCascadeModel; } virtual void *getNativePtr() const { return (void *)&_s; } - virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface = true) const; + virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface = true, + bool convTestXYZ = false) const; virtual double curvatureMax(const SPoint2 ¶m) const; virtual double curvatures(const SPoint2 ¶m, SVector3 &dirMax, SVector3 &dirMin, double &curvMax, diff --git a/Geo/discreteFace.cpp b/Geo/discreteFace.cpp index 58e724951a149696ad6b70e9fd9986be794eb293..fe0ad5ed0a9a5a9f2245e09a334db4ed76a07d88 100644 --- a/Geo/discreteFace.cpp +++ b/Geo/discreteFace.cpp @@ -254,7 +254,8 @@ GPoint discreteFace::closestPoint(const SPoint3 &queryPoint, return closestPoint(queryPoint, 1e-1); } -SPoint2 discreteFace::parFromPoint(const SPoint3 &p, bool onSurface) const +SPoint2 discreteFace::parFromPoint(const SPoint3 &p, bool onSurface, + bool convTestXYZ) const { GPoint gp = closestPoint(p, 1e-6); return SPoint2(gp.u(), gp.v()); diff --git a/Geo/discreteFace.h b/Geo/discreteFace.h index 26853964630287ed76b980cecf8a7ad7cba23671..6d12db6525982751b1860eb6b1dd78d3be58a445 100644 --- a/Geo/discreteFace.h +++ b/Geo/discreteFace.h @@ -43,7 +43,8 @@ public: virtual ~discreteFace() {} using GFace::point; GPoint point(double par1, double par2) const; - SPoint2 parFromPoint(const SPoint3 &p, bool onSurface = true) const; + SPoint2 parFromPoint(const SPoint3 &p, bool onSurface = true, + bool convTestXYZ = false) const; Range<double> parBounds(int i) const; bool containsParam(const SPoint2 &pt); GPoint closestPoint(const SPoint3 &queryPoint, double maxDistance, diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp index c4d0dd483bf670a0082729dfa14b888baaa98550..633bb8ac14158d824b66324c144d053dcf559559 100644 --- a/Geo/gmshFace.cpp +++ b/Geo/gmshFace.cpp @@ -287,7 +287,8 @@ GPoint gmshFace::closestPoint(const SPoint3 &qp, return GPoint(v.Pos.X, v.Pos.Y, v.Pos.Z, this, u); } -SPoint2 gmshFace::parFromPoint(const SPoint3 &qp, bool onSurface) const +SPoint2 gmshFace::parFromPoint(const SPoint3 &qp, bool onSurface, + bool convTestXYZ) const { if(_s->Typ == MSH_SURF_PLAN) { double x, y, z, VX[3], VY[3]; @@ -298,7 +299,7 @@ SPoint2 gmshFace::parFromPoint(const SPoint3 &qp, bool onSurface) const return SPoint2(u, v); } else { - return GFace::parFromPoint(qp, onSurface); + return GFace::parFromPoint(qp, onSurface, convTestXYZ); } } diff --git a/Geo/gmshFace.h b/Geo/gmshFace.h index e616af4c88ce0a7d5129e370632f7afde97edba0..01ba5ab2917c8263ed124ddd34beda7712276ce6 100644 --- a/Geo/gmshFace.h +++ b/Geo/gmshFace.h @@ -32,7 +32,8 @@ public: virtual bool haveParametrization(); virtual ModelType getNativeType() const { return GmshModel; } virtual void *getNativePtr() const { return _s; } - virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface = true) const; + virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface = true, + bool convTestXYZ = false) const; virtual void resetMeshAttributes(); void resetNativePtr(Surface *s); bool degenerate(int dim) const;