diff --git a/src/Mod/TechDraw/App/DrawUtil.cpp b/src/Mod/TechDraw/App/DrawUtil.cpp index f4cd1d0c6e..d65d2cce5b 100644 --- a/src/Mod/TechDraw/App/DrawUtil.cpp +++ b/src/Mod/TechDraw/App/DrawUtil.cpp @@ -113,29 +113,29 @@ std::string DrawUtil::makeGeomName(std::string geomType, int index) return newName.str(); } - -bool DrawUtil::isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2) +//! true if v1 and v2 are the same geometric point within tolerance +bool DrawUtil::isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2, double tolerance) { bool result = false; gp_Pnt p1 = BRep_Tool::Pnt(v1); gp_Pnt p2 = BRep_Tool::Pnt(v2); - if (p1.IsEqual(p2,Precision::Confusion())) { + if (p1.IsEqual(p2,tolerance)) { result = true; } return result; } -bool DrawUtil::isZeroEdge(TopoDS_Edge e) +bool DrawUtil::isZeroEdge(TopoDS_Edge e, double tolerance) { TopoDS_Vertex vStart = TopExp::FirstVertex(e); TopoDS_Vertex vEnd = TopExp::LastVertex(e); - bool result = isSamePoint(vStart,vEnd); + bool result = isSamePoint(vStart,vEnd, tolerance); if (result) { //closed edge will have same V's but non-zero length GProp_GProps props; BRepGProp::LinearProperties(e, props); double len = props.Mass(); - if (len > Precision::Confusion()) { + if (len > tolerance) { result = false; } } @@ -182,7 +182,8 @@ double DrawUtil::angleWithX(TopoDS_Edge e, bool reverse) return result; } -double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v) +//! find angle of edge with x-Axis at First/LastVertex +double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v, double tolerance) { double result = 0; double param = 0; @@ -190,9 +191,9 @@ double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v) //find tangent @ v double adjust = 1.0; //occ tangent points in direction of curve. at lastVert we need to reverse it. BRepAdaptor_Curve adapt(e); - if (isFirstVert(e,v)) { + if (isFirstVert(e,v,tolerance)) { param = adapt.FirstParameter(); - } else if (isLastVert(e,v)) { + } else if (isLastVert(e,v,tolerance)) { param = adapt.LastParameter(); adjust = -1; } else { @@ -203,7 +204,7 @@ double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v) Base::Vector3d uVec(0.0,0.0,0.0); gp_Dir uDir; - BRepLProp_CLProps prop(adapt,param,2,Precision::Confusion()); + BRepLProp_CLProps prop(adapt,param,2,tolerance); if (prop.IsTangentDefined()) { prop.Tangent(uDir); uVec = Base::Vector3d(uDir.X(),uDir.Y(),uDir.Z()) * adjust; @@ -213,9 +214,9 @@ double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v) Base::Vector3d start(gstart.X(),gstart.Y(),gstart.Z()); gp_Pnt gend = BRep_Tool::Pnt(TopExp::LastVertex(e)); Base::Vector3d end(gend.X(),gend.Y(),gend.Z()); - if (isFirstVert(e,v)) { + if (isFirstVert(e,v,tolerance)) { uVec = end - start; - } else if (isLastVert(e,v)) { + } else if (isLastVert(e,v,tolerance)) { uVec = end - start; } else { gp_Pnt errPnt = BRep_Tool::Pnt(v); @@ -230,30 +231,30 @@ double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v) return result; } -bool DrawUtil::isFirstVert(TopoDS_Edge e, TopoDS_Vertex v) +bool DrawUtil::isFirstVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance) { bool result = false; TopoDS_Vertex first = TopExp::FirstVertex(e); - if (isSamePoint(first,v)) { + if (isSamePoint(first,v, tolerance)) { result = true; } return result; } -bool DrawUtil::isLastVert(TopoDS_Edge e, TopoDS_Vertex v) +bool DrawUtil::isLastVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance) { bool result = false; TopoDS_Vertex last = TopExp::LastVertex(e); - if (isSamePoint(last,v)) { + if (isSamePoint(last,v, tolerance)) { result = true; } return result; } -bool DrawUtil::fpCompare(const double& d1, const double& d2) +bool DrawUtil::fpCompare(const double& d1, const double& d2, double tolerance) { bool result = false; - if (std::fabs(d1 - d2) < FLT_EPSILON) { + if (std::fabs(d1 - d2) < tolerance) { result = true; } return result; diff --git a/src/Mod/TechDraw/App/DrawUtil.h b/src/Mod/TechDraw/App/DrawUtil.h index 06ea4078ab..70e0844759 100644 --- a/src/Mod/TechDraw/App/DrawUtil.h +++ b/src/Mod/TechDraw/App/DrawUtil.h @@ -40,6 +40,8 @@ #include #include +#define VERTEXTOLERANCE (2.0 * Precision::Confusion()) + namespace TechDraw { @@ -49,15 +51,15 @@ class TechDrawExport DrawUtil { static int getIndexFromName(std::string geomName); static std::string getGeomTypeFromName(std::string geomName); static std::string makeGeomName(std::string geomType, int index); - static bool isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2); - static bool isZeroEdge(TopoDS_Edge e); + static bool isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2, double tolerance = VERTEXTOLERANCE); + static bool isZeroEdge(TopoDS_Edge e, double tolerance = VERTEXTOLERANCE); static double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2); static double sensibleScale(double working_scale); static double angleWithX(TopoDS_Edge e, bool reverse); - static double angleWithX(TopoDS_Edge e, TopoDS_Vertex v); - static bool isFirstVert(TopoDS_Edge e, TopoDS_Vertex v); - static bool isLastVert(TopoDS_Edge e, TopoDS_Vertex v); - static bool fpCompare(const double& d1, const double& d2); + static double angleWithX(TopoDS_Edge e, TopoDS_Vertex v, double tolerance = VERTEXTOLERANCE); + static bool isFirstVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance = VERTEXTOLERANCE); + static bool isLastVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance = VERTEXTOLERANCE); + static bool fpCompare(const double& d1, const double& d2, double tolerance = FLT_EPSILON); static Base::Vector3d vertex2Vector(const TopoDS_Vertex& v); static std::string formatVector(const Base::Vector3d& v); static std::string formatVector(const Base::Vector2d& v); diff --git a/src/Mod/TechDraw/App/EdgeWalker.cpp b/src/Mod/TechDraw/App/EdgeWalker.cpp index 30fa9a1b4e..f1c2af0999 100644 --- a/src/Mod/TechDraw/App/EdgeWalker.cpp +++ b/src/Mod/TechDraw/App/EdgeWalker.cpp @@ -98,6 +98,11 @@ void edgeVisitor::setGraph(TechDraw::graph& g) //* EdgeWalker methods //******************************************************* +//some shapes are being passed in where edges that should be connected are in fact +//separated by more than 2*Precision::Confusion (expected tolerance for 2 TopoDS_Vertex) +#define EWTOLERANCE 0.00001 //arbitrary number that seems to give good results for drawing + + EdgeWalker::EdgeWalker() { } @@ -308,9 +313,9 @@ std::vector EdgeWalker:: makeUniqueVList(std::vector bool addv1 = true; bool addv2 = true; for (auto v:uniqueVert) { - if (DrawUtil::isSamePoint(v,v1)) + if (DrawUtil::isSamePoint(v,v1,EWTOLERANCE)) addv1 = false; - if (DrawUtil::isSamePoint(v,v2)) + if (DrawUtil::isSamePoint(v,v2,EWTOLERANCE)) addv2 = false; } if (addv1) @@ -325,7 +330,7 @@ std::vector EdgeWalker:: makeUniqueVList(std::vector std::vector EdgeWalker::makeWalkerEdges(std::vector edges, std::vector verts) { - //Base::Console().Message("TRACE - EW::makeWalkerEdges()\n"); +// Base::Console().Message("TRACE - EW::makeWalkerEdges()\n"); m_saveInEdges = edges; std::vector walkerEdges; for (auto e:edges) { @@ -345,11 +350,11 @@ std::vector EdgeWalker::makeWalkerEdges(std::vector edg int EdgeWalker::findUniqueVert(TopoDS_Vertex vx, std::vector &uniqueVert) { - //Base::Console().Message("TRACE - EW::findUniqueVert()\n"); +// Base::Console().Message("TRACE - EW::findUniqueVert()\n"); int idx = 0; int result = 0; for(auto& v:uniqueVert) { //we're always going to find vx, right? - if (DrawUtil::isSamePoint(v,vx)) { + if (DrawUtil::isSamePoint(v,vx,EWTOLERANCE)) { result = idx; break; } @@ -412,12 +417,12 @@ std::vector EdgeWalker::makeEmbedding(const std::vector std::vector iiList; for (auto& e: edges) { double angle = 0; - if (DrawUtil::isFirstVert(e,v)) { - angle = DrawUtil::angleWithX(e,v); + if (DrawUtil::isFirstVert(e,v,EWTOLERANCE)) { + angle = DrawUtil::angleWithX(e,v,EWTOLERANCE); incidenceItem ii(ie, angle, m_saveWalkerEdges[ie].ed); iiList.push_back(ii); - } else if (DrawUtil::isLastVert(e,v)) { - angle = DrawUtil::angleWithX(e,v); + } else if (DrawUtil::isLastVert(e,v,EWTOLERANCE)) { + angle = DrawUtil::angleWithX(e,v,EWTOLERANCE); incidenceItem ii(ie, angle, m_saveWalkerEdges[ie].ed); iiList.push_back(ii); } else {