mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-29 14:00:49 +03:00
0031586: BRepMesh hangs up
Use NCollection_UBTree to detect intersections between newly added links and contour of the polygon; Perform check of the solutions for link insertion after all possible solutions are found and sorted according to their priority.
This commit is contained in:
@@ -76,8 +76,137 @@ namespace {
|
|||||||
theBox.Add( thePnt2 );
|
theBox.Add( thePnt2 );
|
||||||
theBox.Enlarge(Precision);
|
theBox.Enlarge(Precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//function : IntSegSeg
|
||||||
|
//purpose : Checks intersection between the two segments.
|
||||||
|
//=============================================================================
|
||||||
|
BRepMesh_GeomTool::IntFlag IntSegSeg(
|
||||||
|
const Handle(BRepMesh_DataStructureOfDelaun)& theMeshData,
|
||||||
|
const BRepMesh_Edge& theEdg1,
|
||||||
|
const BRepMesh_Edge& theEdg2,
|
||||||
|
const Standard_Boolean isConsiderEndPointTouch,
|
||||||
|
const Standard_Boolean isConsiderPointOnEdge,
|
||||||
|
gp_Pnt2d& theIntPnt)
|
||||||
|
{
|
||||||
|
gp_XY p1, p2, p3, p4;
|
||||||
|
p1 = theMeshData->GetNode( theEdg1.FirstNode() ).Coord();
|
||||||
|
p2 = theMeshData->GetNode( theEdg1.LastNode () ).Coord();
|
||||||
|
p3 = theMeshData->GetNode( theEdg2.FirstNode() ).Coord();
|
||||||
|
p4 = theMeshData->GetNode( theEdg2.LastNode () ).Coord();
|
||||||
|
|
||||||
|
return BRepMesh_GeomTool::IntSegSeg( p1, p2, p3, p4,
|
||||||
|
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt );
|
||||||
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
//! Checks polygon links for intersection with current one of the same polygon.
|
||||||
|
class BRepMesh_Delaun::EBTreeOfB2d_Selector :
|
||||||
|
public NCollection_EBTree<Standard_Integer, Bnd_B2d>::Selector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor.
|
||||||
|
EBTreeOfB2d_Selector(
|
||||||
|
const Handle(BRepMesh_DataStructureOfDelaun)& theMeshData,
|
||||||
|
const DataMapOfPVoid& theSegmentsPolyMap,
|
||||||
|
const Standard_Boolean isConsiderEndPointTouch = Standard_False,
|
||||||
|
const Standard_Boolean isConsiderPointOnEdge = Standard_False)
|
||||||
|
: myMeshData ( theMeshData ),
|
||||||
|
mySegmentsPolyMap ( theSegmentsPolyMap ),
|
||||||
|
myConsiderEndPointTouch ( isConsiderEndPointTouch ),
|
||||||
|
myConsiderPointOnEdge ( isConsiderPointOnEdge ),
|
||||||
|
myPolygonPtr ( nullptr )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Implementation of rejection method
|
||||||
|
//! @return
|
||||||
|
//! True if the bounding box does not intersect with the current
|
||||||
|
virtual Standard_Boolean Reject (const Bnd_B2d& theBox) const
|
||||||
|
{
|
||||||
|
return (myBox.IsOut( theBox ));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Implementation of acceptance method
|
||||||
|
//! This method is called when the bounding box intersect with the current.
|
||||||
|
//! It stores the object - the index of box in the list of accepted objects.
|
||||||
|
//! @return
|
||||||
|
//! True, because the object is accepted
|
||||||
|
virtual Standard_Boolean Accept (const Standard_Integer& theObj)
|
||||||
|
{
|
||||||
|
if (mySkipLinks.Contains( theObj ))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto aPtr = mySegmentsPolyMap.Seek( theObj );
|
||||||
|
|
||||||
|
if (aPtr != nullptr && *aPtr == myPolygonPtr)
|
||||||
|
{
|
||||||
|
const BRepMesh_Edge& aPolyLink = myMeshData->GetLink( Abs( theObj ) );
|
||||||
|
|
||||||
|
if (!myLink.IsEqual( aPolyLink ))
|
||||||
|
{
|
||||||
|
// intersection is possible...
|
||||||
|
gp_Pnt2d anIntPnt;
|
||||||
|
BRepMesh_GeomTool::IntFlag aIntFlag = IntSegSeg(
|
||||||
|
myMeshData, myLink, aPolyLink,
|
||||||
|
myConsiderEndPointTouch, myConsiderPointOnEdge, anIntPnt );
|
||||||
|
|
||||||
|
myStop = (aIntFlag != BRepMesh_GeomTool::NoIntersection);
|
||||||
|
return myStop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Set current box to search for overlapping with him
|
||||||
|
void SetCurrent (const BRepMesh_Edge& theLink,
|
||||||
|
const Bnd_B2d& theBox,
|
||||||
|
const void* thePolygonPtr)
|
||||||
|
{
|
||||||
|
mySkipLinks.Clear();
|
||||||
|
|
||||||
|
myStop = Standard_False;
|
||||||
|
myLink = theLink;
|
||||||
|
myBox = theBox;
|
||||||
|
myPolygonPtr = thePolygonPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSkipLink(const int theLink)
|
||||||
|
{
|
||||||
|
mySkipLinks.Add( theLink );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... T>
|
||||||
|
void SetSkipLink( const int theLink, const T... theLinks )
|
||||||
|
{
|
||||||
|
SetSkipLink( theLink );
|
||||||
|
SetSkipLink( theLinks... );
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns true if the current segment intersects another one of the same polygon.
|
||||||
|
Standard_Boolean IsIntersected()
|
||||||
|
{
|
||||||
|
return myStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Handle(BRepMesh_DataStructureOfDelaun)& myMeshData;
|
||||||
|
const DataMapOfPVoid& mySegmentsPolyMap;
|
||||||
|
|
||||||
|
const Standard_Boolean myConsiderEndPointTouch;
|
||||||
|
const Standard_Boolean myConsiderPointOnEdge;
|
||||||
|
|
||||||
|
const void* myPolygonPtr;
|
||||||
|
|
||||||
|
BRepMesh_Edge myLink;
|
||||||
|
Bnd_B2d myBox;
|
||||||
|
|
||||||
|
NCollection_Map<Standard_Integer> mySkipLinks;
|
||||||
|
};
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : BRepMesh_Delaun
|
//function : BRepMesh_Delaun
|
||||||
//purpose :
|
//purpose :
|
||||||
@@ -1883,24 +2012,31 @@ void BRepMesh_Delaun::meshPolygon(IMeshData::SequenceOfInteger& thePolygon,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMeshData::SequenceOfInteger* aPolygon1 = &thePolygon;
|
SegmentsBoxes aSegmentsBoxes;
|
||||||
IMeshData::SequenceOfBndB2d* aPolyBoxes1 = &thePolyBoxes;
|
EBTreeOfB2dFiller aTreeFiller( aSegmentsBoxes.Boxes );
|
||||||
|
|
||||||
Handle(IMeshData::SequenceOfInteger) aPolygon2 = new IMeshData::SequenceOfInteger;
|
Standard_Integer aLinkIt = thePolygon.Lower();
|
||||||
Handle(IMeshData::SequenceOfBndB2d) aPolyBoxes2 = new IMeshData::SequenceOfBndB2d;
|
for (; aLinkIt <= thePolygon.Upper(); ++aLinkIt)
|
||||||
|
{
|
||||||
|
const Standard_Integer aLinkInfo = thePolygon( aLinkIt );
|
||||||
|
|
||||||
|
aTreeFiller .Add (aLinkInfo, thePolyBoxes( aLinkIt ));
|
||||||
|
aSegmentsBoxes.Rebind(aLinkInfo, &thePolygon);
|
||||||
|
}
|
||||||
|
aTreeFiller.Fill();
|
||||||
|
|
||||||
|
IMeshData::SequenceOfInteger* aPolygon1 = &thePolygon;
|
||||||
|
Handle(IMeshData::SequenceOfInteger) aPolygon2 = new IMeshData::SequenceOfInteger;
|
||||||
|
|
||||||
NCollection_Sequence<Handle(IMeshData::SequenceOfInteger)> aPolyStack;
|
NCollection_Sequence<Handle(IMeshData::SequenceOfInteger)> aPolyStack;
|
||||||
NCollection_Sequence<Handle(IMeshData::SequenceOfBndB2d)> aPolyBoxStack;
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
decomposeSimplePolygon(*aPolygon1, *aPolyBoxes1, *aPolygon2, *aPolyBoxes2);
|
decomposeSimplePolygon(*aPolygon1, *aPolygon2, aSegmentsBoxes);
|
||||||
if (!aPolygon2->IsEmpty())
|
if (!aPolygon2->IsEmpty())
|
||||||
{
|
{
|
||||||
aPolyStack.Append(aPolygon2);
|
aPolyStack.Append(aPolygon2);
|
||||||
aPolyBoxStack.Append(aPolyBoxes2);
|
|
||||||
|
|
||||||
aPolygon2 = new IMeshData::SequenceOfInteger;
|
aPolygon2 = new IMeshData::SequenceOfInteger;
|
||||||
aPolyBoxes2 = new IMeshData::SequenceOfBndB2d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aPolygon1->IsEmpty())
|
if (aPolygon1->IsEmpty())
|
||||||
@@ -1908,14 +2044,12 @@ void BRepMesh_Delaun::meshPolygon(IMeshData::SequenceOfInteger& thePolygon,
|
|||||||
if (!aPolyStack.IsEmpty() && aPolygon1 == &(*aPolyStack.First()))
|
if (!aPolyStack.IsEmpty() && aPolygon1 == &(*aPolyStack.First()))
|
||||||
{
|
{
|
||||||
aPolyStack.Remove(1);
|
aPolyStack.Remove(1);
|
||||||
aPolyBoxStack.Remove(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aPolyStack.IsEmpty())
|
if (aPolyStack.IsEmpty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
aPolygon1 = &(*aPolyStack.ChangeFirst());
|
aPolygon1 = &(*aPolyStack.ChangeFirst());
|
||||||
aPolyBoxes1 = &(*aPolyBoxStack.ChangeFirst());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1964,17 +2098,54 @@ Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
|
|||||||
//function : meshSimplePolygon
|
//function : meshSimplePolygon
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct Candidate
|
||||||
|
{
|
||||||
|
Standard_Integer PivotNode;
|
||||||
|
Standard_Integer LinkId;
|
||||||
|
Standard_Real Dist;
|
||||||
|
Standard_Real Angle;
|
||||||
|
|
||||||
|
Candidate()
|
||||||
|
: PivotNode (0),
|
||||||
|
LinkId (0),
|
||||||
|
Dist (RealLast()),
|
||||||
|
Angle (0.)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Candidate(const Standard_Integer thePivotNode,
|
||||||
|
const Standard_Integer theLinkId,
|
||||||
|
const Standard_Real theDist,
|
||||||
|
const Standard_Real theAngle)
|
||||||
|
: PivotNode (thePivotNode),
|
||||||
|
LinkId (theLinkId),
|
||||||
|
Dist (theDist),
|
||||||
|
Angle (theAngle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const Candidate& theOther) const
|
||||||
|
{
|
||||||
|
const bool isWorse = ((Dist >= theOther.Dist) &&
|
||||||
|
(Angle <= theOther.Angle || Angle > AngDeviation90Deg));
|
||||||
|
|
||||||
|
return !isWorse;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void BRepMesh_Delaun::decomposeSimplePolygon(
|
void BRepMesh_Delaun::decomposeSimplePolygon(
|
||||||
IMeshData::SequenceOfInteger& thePolygon,
|
IMeshData::SequenceOfInteger& thePolygon,
|
||||||
IMeshData::SequenceOfBndB2d& thePolyBoxes,
|
|
||||||
IMeshData::SequenceOfInteger& thePolygonCut,
|
IMeshData::SequenceOfInteger& thePolygonCut,
|
||||||
IMeshData::SequenceOfBndB2d& thePolyBoxesCut)
|
SegmentsBoxes& theSegmentsBoxes)
|
||||||
{
|
{
|
||||||
// Check is the given polygon elementary
|
// Check is the given polygon elementary
|
||||||
if ( meshElementaryPolygon( thePolygon ) )
|
if ( meshElementaryPolygon( thePolygon ) )
|
||||||
{
|
{
|
||||||
|
theSegmentsBoxes.Rebind( thePolygon, nullptr );
|
||||||
thePolygon.Clear();
|
thePolygon.Clear();
|
||||||
thePolyBoxes.Clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1994,8 +2165,8 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
|
|||||||
Standard_Real aRefEdgeLen = aRefEdgeDir.Magnitude();
|
Standard_Real aRefEdgeLen = aRefEdgeDir.Magnitude();
|
||||||
if ( aRefEdgeLen < Precision )
|
if ( aRefEdgeLen < Precision )
|
||||||
{
|
{
|
||||||
|
theSegmentsBoxes.Rebind( thePolygon, nullptr );
|
||||||
thePolygon.Clear();
|
thePolygon.Clear();
|
||||||
thePolyBoxes.Clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2003,19 +2174,16 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
|
|||||||
|
|
||||||
// Find a point with minimum distance respect
|
// Find a point with minimum distance respect
|
||||||
// the end of reference link
|
// the end of reference link
|
||||||
Standard_Integer aUsedLinkId = 0;
|
NCollection_Vector<Candidate> aCandidates( thePolygon.Length() );
|
||||||
Standard_Real aOptAngle = 0.0;
|
|
||||||
Standard_Real aMinDist = RealLast();
|
|
||||||
Standard_Integer aPivotNode = aNodes[1];
|
|
||||||
Standard_Integer aPolyLen = thePolygon.Length();
|
|
||||||
for ( Standard_Integer aLinkIt = 3; aLinkIt <= aPolyLen; ++aLinkIt )
|
|
||||||
{
|
|
||||||
Standard_Integer aLinkInfo = thePolygon( aLinkIt );
|
|
||||||
const BRepMesh_Edge& aNextEdge = GetEdge( Abs( aLinkInfo ) );
|
|
||||||
|
|
||||||
aPivotNode = aLinkInfo > 0 ?
|
for ( Standard_Integer aLinkIt = 3; aLinkIt <= thePolygon.Length(); ++aLinkIt )
|
||||||
|
{
|
||||||
|
const Standard_Integer aLinkInfo = thePolygon( aLinkIt );
|
||||||
|
const BRepMesh_Edge& aNextEdge = GetEdge( Abs( aLinkInfo ) );
|
||||||
|
|
||||||
|
const Standard_Integer aPivotNode = aLinkInfo > 0 ?
|
||||||
aNextEdge.FirstNode() :
|
aNextEdge.FirstNode() :
|
||||||
aNextEdge.LastNode();
|
aNextEdge.LastNode ();
|
||||||
|
|
||||||
// We have end points touch case in the polygon - ignore it
|
// We have end points touch case in the polygon - ignore it
|
||||||
if (aPivotNode == aNodes[1])
|
if (aPivotNode == aNodes[1])
|
||||||
@@ -2025,55 +2193,43 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
|
|||||||
gp_Vec2d aDistanceDir( aRefVertices[1], aPivotVertex );
|
gp_Vec2d aDistanceDir( aRefVertices[1], aPivotVertex );
|
||||||
|
|
||||||
Standard_Real aDist = aRefEdgeDir ^ aDistanceDir;
|
Standard_Real aDist = aRefEdgeDir ^ aDistanceDir;
|
||||||
Standard_Real aAngle = Abs( aRefEdgeDir.Angle(aDistanceDir) );
|
Standard_Real aAngle = Abs( aRefEdgeDir.Angle( aDistanceDir ) );
|
||||||
Standard_Real anAbsDist = Abs( aDist );
|
Standard_Real anAbsDist = Abs( aDist );
|
||||||
if (anAbsDist < Precision || aDist < 0.)
|
if (anAbsDist < Precision || aDist < 0.)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( ( anAbsDist >= aMinDist ) &&
|
aCandidates.Append( Candidate{ aPivotNode, aLinkIt, anAbsDist, aAngle });
|
||||||
( aAngle <= aOptAngle || aAngle > AngDeviation90Deg ) )
|
}
|
||||||
{
|
|
||||||
continue;
|
std::sort( aCandidates.begin(), aCandidates.end() );
|
||||||
}
|
|
||||||
|
Standard_Integer aUsedLinkId = 0;
|
||||||
|
EBTreeOfB2d_Selector aSelector( myMeshData, theSegmentsBoxes.PolyMap );
|
||||||
|
|
||||||
|
Standard_Integer aCandIt = aCandidates.Lower();
|
||||||
|
for (; aCandIt <= aCandidates.Upper(); ++aCandIt)
|
||||||
|
{
|
||||||
|
const Candidate& aCand = aCandidates.Value( aCandIt );
|
||||||
|
|
||||||
|
const gp_Pnt2d& aPivotVertex = GetVertex( aCand.PivotNode ).Coord();
|
||||||
|
|
||||||
// Check is the test link crosses the polygon boundaries
|
// Check is the test link crosses the polygon boundaries
|
||||||
Standard_Boolean isIntersect = Standard_False;
|
Standard_Boolean isIntersect = Standard_False;
|
||||||
for ( Standard_Integer aRefLinkNodeIt = 0; aRefLinkNodeIt < 2; ++aRefLinkNodeIt )
|
for ( Standard_Integer aRefLinkNodeIt = 0; aRefLinkNodeIt < 2; ++aRefLinkNodeIt )
|
||||||
{
|
{
|
||||||
const Standard_Integer& aLinkFirstNode = aNodes[aRefLinkNodeIt];
|
const Standard_Integer& aLinkFirstNode = aNodes [aRefLinkNodeIt];
|
||||||
const gp_Pnt2d& aLinkFirstVertex = aRefVertices[aRefLinkNodeIt];
|
const gp_Pnt2d& aLinkFirstVertex = aRefVertices[aRefLinkNodeIt];
|
||||||
|
|
||||||
Bnd_B2d aBox;
|
Bnd_B2d aBox;
|
||||||
UpdateBndBox(aLinkFirstVertex.Coord(), aPivotVertex.Coord(), aBox);
|
UpdateBndBox( aLinkFirstVertex.Coord(), aPivotVertex.Coord(), aBox );
|
||||||
|
|
||||||
BRepMesh_Edge aCheckLink( aLinkFirstNode, aPivotNode, BRepMesh_Free );
|
BRepMesh_Edge aCheckLink( aLinkFirstNode, aCand.PivotNode, BRepMesh_Free );
|
||||||
|
|
||||||
Standard_Integer aCheckLinkIt = 2;
|
aSelector.SetCurrent ( aCheckLink, aBox, &thePolygon );
|
||||||
for ( ; aCheckLinkIt <= aPolyLen; ++aCheckLinkIt )
|
aSelector.SetSkipLink( thePolygon.First(), thePolygon( aCand.LinkId ) );
|
||||||
{
|
|
||||||
if( aCheckLinkIt == aLinkIt )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( !aBox.IsOut( thePolyBoxes.Value( aCheckLinkIt ) ) )
|
theSegmentsBoxes.Boxes.Select( aSelector );
|
||||||
{
|
isIntersect = aSelector.IsIntersected();
|
||||||
const BRepMesh_Edge& aPolyLink =
|
|
||||||
GetEdge( Abs( thePolygon( aCheckLinkIt ) ) );
|
|
||||||
|
|
||||||
if ( aCheckLink.IsEqual( aPolyLink ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// intersection is possible...
|
|
||||||
gp_Pnt2d anIntPnt;
|
|
||||||
BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( aCheckLink, aPolyLink,
|
|
||||||
Standard_False, Standard_False, anIntPnt );
|
|
||||||
|
|
||||||
if( aIntFlag != BRepMesh_GeomTool::NoIntersection )
|
|
||||||
{
|
|
||||||
isIntersect = Standard_True;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isIntersect )
|
if ( isIntersect )
|
||||||
break;
|
break;
|
||||||
@@ -2083,17 +2239,16 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
aOptAngle = aAngle;
|
aNodes [2] = aCand.PivotNode;
|
||||||
aMinDist = anAbsDist;
|
|
||||||
aNodes[2] = aPivotNode;
|
|
||||||
aRefVertices[2] = aPivotVertex;
|
aRefVertices[2] = aPivotVertex;
|
||||||
aUsedLinkId = aLinkIt;
|
aUsedLinkId = aCand.LinkId;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( aUsedLinkId == 0 )
|
if ( aUsedLinkId == 0 )
|
||||||
{
|
{
|
||||||
|
theSegmentsBoxes.Rebind( thePolygon, nullptr );
|
||||||
thePolygon.Clear();
|
thePolygon.Clear();
|
||||||
thePolyBoxes.Clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2112,48 +2267,49 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
|
|||||||
for ( Standard_Integer aTriEdgeIt = 0; aTriEdgeIt < 3; ++aTriEdgeIt )
|
for ( Standard_Integer aTriEdgeIt = 0; aTriEdgeIt < 3; ++aTriEdgeIt )
|
||||||
{
|
{
|
||||||
const Standard_Integer& anEdgeInfo = aNewEdgesInfo[aTriEdgeIt];
|
const Standard_Integer& anEdgeInfo = aNewEdgesInfo[aTriEdgeIt];
|
||||||
anEdges[aTriEdgeIt] = Abs( anEdgeInfo );
|
anEdges [aTriEdgeIt] = Abs( anEdgeInfo );
|
||||||
anEdgesOri[aTriEdgeIt] = anEdgeInfo > 0;
|
anEdgesOri[aTriEdgeIt] = anEdgeInfo > 0;
|
||||||
}
|
}
|
||||||
addTriangle( anEdges, anEdgesOri, aNodes );
|
addTriangle( anEdges, anEdgesOri, aNodes );
|
||||||
|
|
||||||
if (aUsedLinkId == 3)
|
if (aUsedLinkId == 3)
|
||||||
{
|
{
|
||||||
thePolygon.Remove ( 1 );
|
theSegmentsBoxes.Rebind( thePolygon.First(), nullptr );
|
||||||
thePolyBoxes.Remove( 1 );
|
thePolygon .Remove( 1 );
|
||||||
|
|
||||||
thePolygon.SetValue( 1, -aNewEdgesInfo[2] );
|
thePolygon.SetValue( 1, -aNewEdgesInfo[2] );
|
||||||
|
|
||||||
Bnd_B2d aBox;
|
Bnd_B2d aBox;
|
||||||
UpdateBndBox(aRefVertices[0].Coord(), aRefVertices[2].Coord(), aBox);
|
UpdateBndBox( aRefVertices[0].Coord(), aRefVertices[2].Coord(), aBox );
|
||||||
thePolyBoxes.SetValue( 1, aBox );
|
theSegmentsBoxes.Add( thePolygon.First(), aBox, &thePolygon );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create triangle and split the source polygon on two
|
// Create triangle and split the source polygon on two
|
||||||
// parts (if possible) and mesh each part as independent
|
// parts (if possible) and mesh each part as independent
|
||||||
// polygon.
|
// polygon.
|
||||||
if ( aUsedLinkId < aPolyLen )
|
if ( aUsedLinkId < thePolygon.Length() )
|
||||||
{
|
{
|
||||||
thePolygon.Split(aUsedLinkId, thePolygonCut);
|
thePolygon.Split( aUsedLinkId, thePolygonCut );
|
||||||
thePolygonCut.Prepend( -aNewEdgesInfo[2] );
|
|
||||||
thePolyBoxes.Split(aUsedLinkId, thePolyBoxesCut);
|
theSegmentsBoxes.Rebind ( thePolygonCut, &thePolygonCut );
|
||||||
|
thePolygonCut .Prepend( -aNewEdgesInfo[2] );
|
||||||
|
|
||||||
Bnd_B2d aBox;
|
Bnd_B2d aBox;
|
||||||
UpdateBndBox(aRefVertices[0].Coord(), aRefVertices[2].Coord(), aBox);
|
UpdateBndBox( aRefVertices[0].Coord(), aRefVertices[2].Coord(), aBox );
|
||||||
thePolyBoxesCut.Prepend( aBox );
|
theSegmentsBoxes.Add( thePolygonCut.First(), aBox, &thePolygonCut );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thePolygon.Remove ( aPolyLen );
|
theSegmentsBoxes.Rebind( thePolygon.Last (), nullptr );
|
||||||
thePolyBoxes.Remove( aPolyLen );
|
thePolygon .Remove( thePolygon.Length() );
|
||||||
}
|
}
|
||||||
|
|
||||||
thePolygon.SetValue( 1, -aNewEdgesInfo[1] );
|
thePolygon.SetValue( 1, -aNewEdgesInfo[1] );
|
||||||
|
|
||||||
Bnd_B2d aBox;
|
Bnd_B2d aBox;
|
||||||
UpdateBndBox(aRefVertices[1].Coord(), aRefVertices[2].Coord(), aBox);
|
UpdateBndBox( aRefVertices[1].Coord(), aRefVertices[2].Coord(), aBox );
|
||||||
thePolyBoxes.SetValue( 1, aBox );
|
theSegmentsBoxes.Add( thePolygon.First(), aBox, &thePolygon );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2477,13 +2633,7 @@ BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
|
|||||||
const Standard_Boolean isConsiderPointOnEdge,
|
const Standard_Boolean isConsiderPointOnEdge,
|
||||||
gp_Pnt2d& theIntPnt) const
|
gp_Pnt2d& theIntPnt) const
|
||||||
{
|
{
|
||||||
gp_XY p1, p2, p3, p4;
|
return IntSegSeg (myMeshData, theEdg1, theEdg2,
|
||||||
p1 = GetVertex( theEdg1.FirstNode() ).Coord();
|
|
||||||
p2 = GetVertex( theEdg1.LastNode() ).Coord();
|
|
||||||
p3 = GetVertex( theEdg2.FirstNode() ).Coord();
|
|
||||||
p4 = GetVertex( theEdg2.LastNode() ).Coord();
|
|
||||||
|
|
||||||
return BRepMesh_GeomTool::IntSegSeg(p1, p2, p3, p4,
|
|
||||||
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt);
|
isConsiderEndPointTouch, isConsiderPointOnEdge, theIntPnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -165,6 +165,42 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
|
typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
|
||||||
|
typedef NCollection_DataMap<Standard_Integer, void*> DataMapOfPVoid;
|
||||||
|
typedef NCollection_EBTree <Standard_Integer, Bnd_B2d> EBTreeOfB2d;
|
||||||
|
typedef NCollection_UBTreeFiller <Standard_Integer, Bnd_B2d> EBTreeOfB2dFiller;
|
||||||
|
class EBTreeOfB2d_Selector;
|
||||||
|
|
||||||
|
struct SegmentsBoxes
|
||||||
|
{
|
||||||
|
EBTreeOfB2d Boxes;
|
||||||
|
DataMapOfPVoid PolyMap;
|
||||||
|
|
||||||
|
void Rebind (const Standard_Integer theLinkInfo,
|
||||||
|
void* const& thePolygonPtr)
|
||||||
|
{
|
||||||
|
PolyMap.Bind (theLinkInfo, thePolygonPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rebind (IMeshData::SequenceOfInteger& thePolygon,
|
||||||
|
void* const& thePolygonPtr)
|
||||||
|
{
|
||||||
|
Standard_Integer aLinkIt = thePolygon.Lower();
|
||||||
|
for (; aLinkIt <= thePolygon.Upper(); ++aLinkIt)
|
||||||
|
{
|
||||||
|
const Standard_Integer aLinkInfo = thePolygon (aLinkIt);
|
||||||
|
Rebind (aLinkInfo, thePolygonPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add (const Standard_Integer theLinkInfo,
|
||||||
|
const Bnd_B2d& theBox,
|
||||||
|
void* const& thePolygonPtr)
|
||||||
|
{
|
||||||
|
PolyMap.Bind (theLinkInfo, thePolygonPtr);
|
||||||
|
Boxes .Add (theLinkInfo, theBox);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//! Performs initialization of circles cell filter tool.
|
//! Performs initialization of circles cell filter tool.
|
||||||
void initCirclesTool (const Bnd_Box2d& theBox,
|
void initCirclesTool (const Bnd_Box2d& theBox,
|
||||||
@@ -245,14 +281,12 @@ private:
|
|||||||
//! In case if source polygon consists of three links, creates new triangle
|
//! In case if source polygon consists of three links, creates new triangle
|
||||||
//! and clears source container.
|
//! and clears source container.
|
||||||
//! @param thePolygon source polygon to be decomposed (first part of decomposition).
|
//! @param thePolygon source polygon to be decomposed (first part of decomposition).
|
||||||
//! @param thePolyBoxes bounding boxes corresponded to source polygon's links.
|
|
||||||
//! @param thePolygonCut product of decomposition of source polygon (second part of decomposition).
|
//! @param thePolygonCut product of decomposition of source polygon (second part of decomposition).
|
||||||
//! @param thePolyBoxesCut bounding boxes corresponded to resulting polygon's links.
|
//! @param theSegmentsBoxes map of relations between semgents and their polygons.
|
||||||
void decomposeSimplePolygon (
|
void decomposeSimplePolygon (
|
||||||
IMeshData::SequenceOfInteger& thePolygon,
|
IMeshData::SequenceOfInteger& thePolygon,
|
||||||
IMeshData::SequenceOfBndB2d& thePolyBoxes,
|
|
||||||
IMeshData::SequenceOfInteger& thePolygonCut,
|
IMeshData::SequenceOfInteger& thePolygonCut,
|
||||||
IMeshData::SequenceOfBndB2d& thePolyBoxesCut);
|
SegmentsBoxes& theSegmentsBoxes);
|
||||||
|
|
||||||
//! Triangulation of closed polygon containing only three edges.
|
//! Triangulation of closed polygon containing only three edges.
|
||||||
Standard_Boolean meshElementaryPolygon (const IMeshData::SequenceOfInteger& thePolygon);
|
Standard_Boolean meshElementaryPolygon (const IMeshData::SequenceOfInteger& thePolygon);
|
||||||
|
14
tests/bugs/mesh/bug31586
Normal file
14
tests/bugs/mesh/bug31586
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "0031586: BRepMesh hangs up"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
puts "TODO OCC31586 All: Not connected mesh inside face"
|
||||||
|
|
||||||
|
restore [locate_data_file bug31586.brep] result
|
||||||
|
|
||||||
|
incmesh result 0.022627417117969499
|
||||||
|
|
||||||
|
checkview -display result -3d -path ${imagedir}/${test_image}.png
|
||||||
|
|
||||||
|
tricheck result
|
Reference in New Issue
Block a user