Increase tolerance for overlapping Vertexes
Some "valid" shapes are being passed to findShapeOutline where edges that should be connected are in fact separated 10x the expected tolerance (2*Precision::Confusion) for 2 overlapping TopoDS_Vertex. IntTools_Tools:ComputeVV also reports these Vertices as further apart than their combined tolerances should allow. This change introduces a tolerance into DrawUtil and EdgeWalker vertex comparisions that is quite "sloppy" (0.00001) but which handles the sample objects correctly. This tolerance is adequate for drawings. Other uses should be considered on case by case basis.
This commit is contained in:
committed by
Yorik van Havre
parent
21f683e86a
commit
97ca11f9f2
@@ -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;
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/Matrix.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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<TopoDS_Vertex> EdgeWalker:: makeUniqueVList(std::vector<TopoDS_Edge>
|
||||
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<TopoDS_Vertex> EdgeWalker:: makeUniqueVList(std::vector<TopoDS_Edge>
|
||||
std::vector<WalkerEdge> EdgeWalker::makeWalkerEdges(std::vector<TopoDS_Edge> edges,
|
||||
std::vector<TopoDS_Vertex> verts)
|
||||
{
|
||||
//Base::Console().Message("TRACE - EW::makeWalkerEdges()\n");
|
||||
// Base::Console().Message("TRACE - EW::makeWalkerEdges()\n");
|
||||
m_saveInEdges = edges;
|
||||
std::vector<WalkerEdge> walkerEdges;
|
||||
for (auto e:edges) {
|
||||
@@ -345,11 +350,11 @@ std::vector<WalkerEdge> EdgeWalker::makeWalkerEdges(std::vector<TopoDS_Edge> edg
|
||||
|
||||
int EdgeWalker::findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &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<embedItem> EdgeWalker::makeEmbedding(const std::vector<TopoDS_Edge>
|
||||
std::vector<incidenceItem> 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 {
|
||||
|
||||
Reference in New Issue
Block a user