1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0031586: BRepMesh hangs up

Cosmetic corrections.
This commit is contained in:
oan
2022-11-09 18:27:41 +03:00
parent be163914f8
commit d18dc282e7
2 changed files with 123 additions and 53 deletions

View File

@@ -101,23 +101,27 @@ namespace {
} // anonymous namespace } // anonymous namespace
//! Checks polygon links for intersection with current one of the same polygon. //! Checks polygon links for intersection with current one of the same polygon.
class BRepMesh_Delaun::UBTreeOfB2d_Selector : public NCollection_UBTree<Standard_Integer, Bnd_B2d>::Selector class BRepMesh_Delaun::EBTreeOfB2d_Selector : public NCollection_EBTree<Standard_Integer, Bnd_B2d>::Selector
{ {
public: public:
//! Constructor. //! Constructor.
UBTreeOfB2d_Selector( EBTreeOfB2d_Selector(
const Handle(BRepMesh_DataStructureOfDelaun)& theMeshData, const Handle(BRepMesh_DataStructureOfDelaun)& theMeshData,
const DataMapOfPVoid& theSegmentsPolyMap) const DataMapOfPVoid& theSegmentsPolyMap,
: myMeshData (theMeshData), const Standard_Boolean isConsiderEndPointTouch = Standard_False,
mySegmentsPolyMap (theSegmentsPolyMap), const Standard_Boolean isConsiderPointOnEdge = Standard_False)
myPolygonPtr (nullptr) : myMeshData (theMeshData),
mySegmentsPolyMap (theSegmentsPolyMap),
myConsiderEndPointTouch (isConsiderEndPointTouch),
myConsiderPointOnEdge (isConsiderPointOnEdge),
myPolygonPtr (nullptr)
{ {
} }
//! Implementation of rejection method //! Implementation of rejection method
//! @return //! @return
//! True if the bounding box does not intersect with the current //! True if the bounding box does not intersect with the current
Standard_Boolean Reject (const Bnd_B2d& theBox) const virtual Standard_Boolean Reject (const Bnd_B2d& theBox) const
{ {
return (myBox.IsOut (theBox)); return (myBox.IsOut (theBox));
} }
@@ -127,7 +131,7 @@ public:
//! It stores the object - the index of box in the list of accepted objects. //! It stores the object - the index of box in the list of accepted objects.
//! @return //! @return
//! True, because the object is accepted //! True, because the object is accepted
Standard_Boolean Accept (const Standard_Integer& theObj) virtual Standard_Boolean Accept (const Standard_Integer& theObj)
{ {
if (mySkipLinks.Contains (theObj)) if (mySkipLinks.Contains (theObj))
{ {
@@ -146,7 +150,7 @@ public:
gp_Pnt2d anIntPnt; gp_Pnt2d anIntPnt;
BRepMesh_GeomTool::IntFlag aIntFlag = IntSegSeg ( BRepMesh_GeomTool::IntFlag aIntFlag = IntSegSeg (
myMeshData, myLink, aPolyLink, myMeshData, myLink, aPolyLink,
Standard_False, Standard_False, anIntPnt); myConsiderEndPointTouch, myConsiderPointOnEdge, anIntPnt);
myStop = (aIntFlag != BRepMesh_GeomTool::NoIntersection); myStop = (aIntFlag != BRepMesh_GeomTool::NoIntersection);
return myStop; return myStop;
@@ -187,17 +191,57 @@ public:
return myStop; return myStop;
} }
private: protected:
const Handle(BRepMesh_DataStructureOfDelaun)& myMeshData; const Handle(BRepMesh_DataStructureOfDelaun)& myMeshData;
const DataMapOfPVoid& mySegmentsPolyMap; const DataMapOfPVoid& mySegmentsPolyMap;
BRepMesh_Edge myLink; const Standard_Boolean myConsiderEndPointTouch;
Bnd_B2d myBox; const Standard_Boolean myConsiderPointOnEdge;
const void* myPolygonPtr; const void* myPolygonPtr;
BRepMesh_Edge myLink;
Bnd_B2d myBox;
NCollection_Map<Standard_Integer> mySkipLinks; NCollection_Map<Standard_Integer> mySkipLinks;
}; };
//! Checks polygon links for intersection with current one of the same polygon.
class BRepMesh_Delaun::EBTreeOfB2d_SelectorMovability : public EBTreeOfB2d_Selector
{
public:
//! Constructor.
EBTreeOfB2d_SelectorMovability(
const Handle(BRepMesh_DataStructureOfDelaun)& theMeshData,
const DataMapOfPVoid& theSegmentsPolyMap,
const Standard_Boolean isConsiderEndPointTouch = Standard_False,
const Standard_Boolean isConsiderPointOnEdge = Standard_False)
: EBTreeOfB2d_Selector(theMeshData, theSegmentsPolyMap,
isConsiderEndPointTouch, isConsiderPointOnEdge)
{
}
//! 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) Standard_OVERRIDE
{
// intersection is possible...
const BRepMesh_Edge& aPolyLink = myMeshData->GetLink(Abs(theObj));
// skip intersections between frontier edges
if (aPolyLink.Movability() == BRepMesh_Frontier &&
myLink .Movability() == BRepMesh_Frontier)
{
return Standard_False;
}
return EBTreeOfB2d_Selector::Accept(theObj);
}
};
//======================================================================= //=======================================================================
//function : BRepMesh_Delaun //function : BRepMesh_Delaun
//purpose : //purpose :
@@ -2004,7 +2048,7 @@ void BRepMesh_Delaun::meshPolygon(IMeshData::SequenceOfInteger& thePolygon,
} }
SegmentsBoxes aSegmentsBoxes; SegmentsBoxes aSegmentsBoxes;
UBTreeOfB2dFiller aTreeFiller (aSegmentsBoxes.Boxes); EBTreeOfB2dFiller aTreeFiller (aSegmentsBoxes.Boxes);
Standard_Integer aLinkIt = thePolygon.Lower(); Standard_Integer aLinkIt = thePolygon.Lower();
for (; aLinkIt <= thePolygon.Upper(); ++aLinkIt) for (; aLinkIt <= thePolygon.Upper(); ++aLinkIt)
@@ -2089,15 +2133,59 @@ Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
//function : meshSimplePolygon //function : meshSimplePolygon
//purpose : //purpose :
//======================================================================= //=======================================================================
namespace
{
struct Candidate
{
Standard_Integer Node;
gp_Pnt2d RefVertex;
Standard_Integer UsedLinkId;
Standard_Real AbsDist;
Standard_Real Angle;
Candidate()
: Node (0),
RefVertex (gp::Origin2d()),
UsedLinkId (0),
AbsDist (RealLast()),
Angle (RealLast())
{
}
Candidate(const Standard_Integer theNode,
const gp_Pnt2d theRefVertex,
const Standard_Integer theUsedLinkId,
const Standard_Real theAbsDist,
const Standard_Real theAngle)
: Node (theNode),
RefVertex (theRefVertex),
UsedLinkId (theUsedLinkId),
AbsDist (theAbsDist),
Angle (theAngle)
{
}
bool operator< (const Candidate& theOther) const
{
if (AbsDist < theOther.AbsDist)
{
return (Angle > theOther.Angle && Angle <= AngDeviation90Deg);
}
return false;
}
};
}
void BRepMesh_Delaun::decomposeSimplePolygon( void BRepMesh_Delaun::decomposeSimplePolygon(
IMeshData::SequenceOfInteger& thePolygon, IMeshData::SequenceOfInteger& thePolygon,
IMeshData::SequenceOfInteger& thePolygonCut, IMeshData::SequenceOfInteger& thePolygonCut,
SegmentsBoxes& theSegmentsPolyMap) SegmentsBoxes& theSegmentsBoxes)
{ {
// Check is the given polygon elementary // Check is the given polygon elementary
if ( meshElementaryPolygon( thePolygon ) ) if ( meshElementaryPolygon( thePolygon ) )
{ {
theSegmentsPolyMap.Rebind (thePolygon, nullptr); theSegmentsBoxes.Rebind (thePolygon, nullptr);
thePolygon.Clear(); thePolygon.Clear();
return; return;
} }
@@ -2118,7 +2206,7 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
Standard_Real aRefEdgeLen = aRefEdgeDir.Magnitude(); Standard_Real aRefEdgeLen = aRefEdgeDir.Magnitude();
if ( aRefEdgeLen < Precision ) if ( aRefEdgeLen < Precision )
{ {
theSegmentsPolyMap.Rebind (thePolygon, nullptr); theSegmentsBoxes.Rebind (thePolygon, nullptr);
thePolygon.Clear(); thePolygon.Clear();
return; return;
} }
@@ -2130,26 +2218,7 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
Standard_Integer aPivotNode = aNodes[1]; Standard_Integer aPivotNode = aNodes[1];
Standard_Integer aPolyLen = thePolygon.Length(); Standard_Integer aPolyLen = thePolygon.Length();
struct Cand NCollection_Vector<Candidate> aCandList(thePolygon.Length());
{
Standard_Integer Node = 0;
gp_Pnt2d RefVertex;
Standard_Integer UsedLinkId = 0;
Standard_Real AbsDist = RealLast();
Standard_Real Angle = RealLast();
bool operator< (const Cand& theOther) const
{
if (AbsDist < theOther.AbsDist)
{
return (Angle > theOther.Angle && Angle <= AngDeviation90Deg);
}
return false;
}
};
NCollection_Vector<Cand> aCandList(thePolygon.Length());
for ( Standard_Integer aLinkIt = 3; aLinkIt <= aPolyLen; ++aLinkIt ) for ( Standard_Integer aLinkIt = 3; aLinkIt <= aPolyLen; ++aLinkIt )
{ {
@@ -2173,19 +2242,19 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
if (anAbsDist < Precision || aDist < 0.) if (anAbsDist < Precision || aDist < 0.)
continue; continue;
aCandList.Append (Cand { aPivotNode, aPivotVertex, aLinkIt, anAbsDist, aAngle }); aCandList.Append (Candidate{ aPivotNode, aPivotVertex, aLinkIt, anAbsDist, aAngle });
} }
std::sort (aCandList.begin(), aCandList.end()); std::sort (aCandList.begin(), aCandList.end());
UBTreeOfB2d_Selector aSelector (myMeshData, theSegmentsPolyMap.PolyMap); EBTreeOfB2d_Selector aSelector (myMeshData, theSegmentsBoxes.PolyMap);
Standard_Integer aUsedLinkId = 0; Standard_Integer aUsedLinkId = 0;
Standard_Integer aCandIt = aCandList.Lower(); Standard_Integer aCandIt = aCandList.Lower();
for (; aCandIt <= aCandList.Upper(); ++aCandIt) for (; aCandIt <= aCandList.Upper(); ++aCandIt)
{ {
const Cand& aCand = aCandList.Value (aCandIt); const Candidate& aCand = aCandList.Value (aCandIt);
// 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;
@@ -2202,7 +2271,7 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
aSelector.SetCurrent (aCheckLink, aBox, &thePolygon); aSelector.SetCurrent (aCheckLink, aBox, &thePolygon);
aSelector.SetSkipLink (thePolygon.First(), thePolygon (aCand.UsedLinkId)); aSelector.SetSkipLink (thePolygon.First(), thePolygon (aCand.UsedLinkId));
theSegmentsPolyMap.Boxes.Select (aSelector); theSegmentsBoxes.Boxes.Select (aSelector);
isIntersect = aSelector.IsIntersected(); isIntersect = aSelector.IsIntersected();
if ( isIntersect ) if ( isIntersect )
@@ -2221,7 +2290,7 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
if ( aUsedLinkId == 0 ) if ( aUsedLinkId == 0 )
{ {
theSegmentsPolyMap.Rebind (thePolygon, nullptr); theSegmentsBoxes.Rebind (thePolygon, nullptr);
thePolygon.Clear(); thePolygon.Clear();
return; return;
} }
@@ -2248,14 +2317,14 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
if (aUsedLinkId == 3) if (aUsedLinkId == 3)
{ {
theSegmentsPolyMap.Rebind (thePolygon.First(), nullptr); theSegmentsBoxes.Rebind (thePolygon.First(), nullptr);
thePolygon.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);
theSegmentsPolyMap.Add (thePolygon.First(), aBox, &thePolygon); theSegmentsBoxes.Add (thePolygon.First(), aBox, &thePolygon);
} }
else else
{ {
@@ -2266,17 +2335,17 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
{ {
thePolygon.Split(aUsedLinkId, thePolygonCut); thePolygon.Split(aUsedLinkId, thePolygonCut);
theSegmentsPolyMap.Rebind (thePolygonCut, &thePolygonCut); theSegmentsBoxes.Rebind (thePolygonCut, &thePolygonCut);
thePolygonCut.Prepend( -aNewEdgesInfo[2] ); 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);
theSegmentsPolyMap.Add (thePolygonCut.First(), aBox, &thePolygonCut); theSegmentsBoxes.Add (thePolygonCut.First(), aBox, &thePolygonCut);
} }
else else
{ {
theSegmentsPolyMap.Rebind(thePolygon.Last(), nullptr); theSegmentsBoxes.Rebind(thePolygon.Last(), nullptr);
thePolygon.Remove ( aPolyLen ); thePolygon.Remove ( aPolyLen );
} }
@@ -2284,7 +2353,7 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
Bnd_B2d aBox; Bnd_B2d aBox;
UpdateBndBox(aRefVertices[1].Coord(), aRefVertices[2].Coord(), aBox); UpdateBndBox(aRefVertices[1].Coord(), aRefVertices[2].Coord(), aBox);
theSegmentsPolyMap.Add (thePolygon.First(), aBox, &thePolygon); theSegmentsBoxes.Add (thePolygon.First(), aBox, &thePolygon);
} }
} }

View File

@@ -166,13 +166,14 @@ 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_DataMap<Standard_Integer, void*> DataMapOfPVoid;
typedef NCollection_UBTree <Standard_Integer, Bnd_B2d> UBTreeOfB2d; typedef NCollection_EBTree <Standard_Integer, Bnd_B2d> EBTreeOfB2d;
typedef NCollection_UBTreeFiller <Standard_Integer, Bnd_B2d> UBTreeOfB2dFiller; typedef NCollection_UBTreeFiller <Standard_Integer, Bnd_B2d> EBTreeOfB2dFiller;
class UBTreeOfB2d_Selector; class EBTreeOfB2d_Selector;
class EBTreeOfB2d_SelectorMovability;
struct SegmentsBoxes struct SegmentsBoxes
{ {
UBTreeOfB2d Boxes; EBTreeOfB2d Boxes;
DataMapOfPVoid PolyMap; DataMapOfPVoid PolyMap;
void Rebind (const Standard_Integer theLinkInfo, void Rebind (const Standard_Integer theLinkInfo,
@@ -282,11 +283,11 @@ private:
//! 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 thePolygonCut product of decomposition of source polygon (second part of decomposition). //! @param thePolygonCut product of decomposition of source polygon (second part of decomposition).
//! @param theSegmentsPolyMap map of relations between semgents and their polygons. //! @param theSegmentsBoxes map of relations between semgents and their polygons.
void decomposeSimplePolygon ( void decomposeSimplePolygon (
IMeshData::SequenceOfInteger& thePolygon, IMeshData::SequenceOfInteger& thePolygon,
IMeshData::SequenceOfInteger& thePolygonCut, IMeshData::SequenceOfInteger& thePolygonCut,
SegmentsBoxes& theSegmentsPolyMap); 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);