mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0025589: modify the wire interference checker to detect all types of intersections
This commit is contained in:
@@ -59,6 +59,47 @@ BRepMesh_WireInterferenceChecker::BRepMesh_WireInterferenceChecker(
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
//function : Checker's body
|
||||||
//purpose :
|
//purpose :
|
||||||
@@ -125,33 +166,15 @@ void BRepMesh_WireInterferenceChecker::operator ()(
|
|||||||
BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
|
BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
|
||||||
aSegment1.StartPnt, aSegment1.EndPnt,
|
aSegment1.StartPnt, aSegment1.EndPnt,
|
||||||
aSegment2.StartPnt, aSegment2.EndPnt,
|
aSegment2.StartPnt, aSegment2.EndPnt,
|
||||||
Standard_False, Standard_False,
|
Standard_True, Standard_True,
|
||||||
aIntPnt);
|
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.
|
// TODO: remove this block after implementation of LoopChecker2d.
|
||||||
if (isSelfIntCheck)
|
if (isSelfIntCheck && CheckSelftIntersectArea(aSegmentId1, aSegmentId2, aWireSegments1, aIntPnt))
|
||||||
{
|
{
|
||||||
gp_XY aPrevVec;
|
continue;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TBB
|
#ifdef HAVE_TBB
|
||||||
@@ -160,6 +183,45 @@ void BRepMesh_WireInterferenceChecker::operator ()(
|
|||||||
*myStatus = BRepMesh_SelfIntersectingWire;
|
*myStatus = BRepMesh_SelfIntersectingWire;
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user