1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

1 Commits

Author SHA1 Message Date
razmyslovich
30d665dfb0 0025589: modify the wire interference checker to detect all types of intersections 2014-12-10 14:43:53 +01:00

View File

@@ -59,6 +59,47 @@ BRepMesh_WireInterferenceChecker::BRepMesh_WireInterferenceChecker(
}
#endif
bool ArePointsOnDifferentSides(const gp_Pnt2d & point1, const gp_Pnt2d & point2, const BRepMesh::Segment & segment1, const BRepMesh::Segment & segment2)
{
return 0 > (((segment1.EndPnt.X()-segment1.StartPnt.X())*(point1.Y()-segment1.StartPnt.Y())-(point1.X()-segment1.StartPnt.X())*(segment1.EndPnt.Y()-segment1.StartPnt.Y())) *
((segment2.EndPnt.X()-segment2.StartPnt.X())*(point2.Y()-segment2.StartPnt.Y())-(point2.X()-segment2.StartPnt.X())*(segment2.EndPnt.Y()-segment2.StartPnt.Y())));
}
const BRepMesh::Segment& GetSegmentFromArray(Standard_Integer idx, const BRepMesh::HArray1OfSegments& segsarray)
{
if (idx < segsarray->Lower())
{
idx = segsarray->Upper();
}
if (idx > segsarray->Upper())
{
idx = segsarray->Lower();
}
return segsarray->Value(idx);
}
bool CheckSelftIntersectArea(Standard_Integer idx1, Standard_Integer idx2, const BRepMesh::HArray1OfSegments& segsarray, const gp_Pnt2d & intPnt)
{
gp_XY aPrevVec;
Standard_Real aSumS = 0.;
const gp_XY& aRefPnt = intPnt.Coord();
for (Standard_Integer i = idx1; i < idx2; ++i)
{
const BRepMesh::Segment& aSeg = segsarray->Value(i);
gp_XY aCurVec = aSeg.EndPnt - aRefPnt;
if (aCurVec.SquareModulus() < gp::Resolution())
continue;
if (aPrevVec.SquareModulus() > gp::Resolution())
aSumS += aPrevVec ^ aCurVec;
aPrevVec = aCurVec;
}
return (Abs(aSumS / 2.) < MIN_LOOP_S);
}
//=======================================================================
//function : Checker's body
//purpose :
@@ -125,33 +166,15 @@ void BRepMesh_WireInterferenceChecker::operator ()(
BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
aSegment1.StartPnt, aSegment1.EndPnt,
aSegment2.StartPnt, aSegment2.EndPnt,
Standard_False, Standard_False,
Standard_True, Standard_True,
aIntPnt);
if (aIntStatus == BRepMesh_GeomTool::Cross)
if (aIntStatus == BRepMesh_GeomTool::Cross || aIntStatus == BRepMesh_GeomTool::Glued || aIntStatus == BRepMesh_GeomTool::PointOnSegment)
{
// TODO: remove this block after implementation of LoopChecker2d.
if (isSelfIntCheck)
if (isSelfIntCheck && CheckSelftIntersectArea(aSegmentId1, aSegmentId2, aWireSegments1, aIntPnt))
{
gp_XY aPrevVec;
Standard_Real aSumS = 0.;
const gp_XY& aRefPnt = aIntPnt.Coord();
for (Standard_Integer i = aSegmentId1; i < aSegmentId2; ++i)
{
const BRepMesh::Segment& aSeg = aWireSegments1->Value(i);
gp_XY aCurVec = aSeg.EndPnt - aRefPnt;
if (aCurVec.SquareModulus() < gp::Resolution())
continue;
if (aPrevVec.SquareModulus() > gp::Resolution())
aSumS += aPrevVec ^ aCurVec;
aPrevVec = aCurVec;
}
if (Abs(aSumS / 2.) < MIN_LOOP_S)
continue;
continue;
}
#ifdef HAVE_TBB
@@ -160,6 +183,45 @@ void BRepMesh_WireInterferenceChecker::operator ()(
*myStatus = BRepMesh_SelfIntersectingWire;
return;
}
if (aIntStatus == BRepMesh_GeomTool::EndPointTouch && (!isSelfIntCheck || abs(aSegmentId1 - aSegmentId2) > 2))
{
bool segmentsAreEqual = false;
gp_Pnt2d otherPnt1;
gp_Pnt2d otherPnt2;
const BRepMesh::Segment * refSegment1 = &aSegment2;
const BRepMesh::Segment * refSegment2 = NULL;
Standard_Boolean s1s2 = aSegment1.StartPnt.IsEqual(aSegment2.StartPnt, Precision::PConfusion());
Standard_Boolean s1e2 = aSegment1.StartPnt.IsEqual(aSegment2.EndPnt, Precision::PConfusion());
Standard_Boolean e1e2 = aSegment1.EndPnt.IsEqual(aSegment2.EndPnt, Precision::PConfusion());
Standard_Boolean e1s2 = aSegment1.EndPnt.IsEqual(aSegment2.StartPnt, Precision::PConfusion());
if ((s1s2 && e1e2) || (s1e2 && e1s2))
{
segmentsAreEqual = true;
}
else
{
otherPnt1 = (s1s2 || s1e2)? aSegment1.EndPnt : aSegment1.StartPnt;
otherPnt2 = GetSegmentFromArray(aSegmentId1 + ((s1s2 || s1e2)? -1 : 1), aWireSegments1).StartPnt;
refSegment2 = &(GetSegmentFromArray(aSegmentId2 + ((s1s2 || e1s2)? -1 : 1), aWireSegments2));
}
if (!segmentsAreEqual && NULL != refSegment1 && NULL != refSegment2 && ArePointsOnDifferentSides(otherPnt1, otherPnt2, *refSegment1, *refSegment2))
{
if (isSelfIntCheck && CheckSelftIntersectArea(aSegmentId1, aSegmentId2, aWireSegments1, aIntPnt))
{
continue;
}
#ifdef HAVE_TBB
Standard_Mutex::Sentry aSentry(myMutex);
#endif
*myStatus = BRepMesh_SelfIntersectingWire;
return;
}
}
}
}
}