mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-18 14:27:39 +03:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
40c01dedcf | ||
|
d644a7b47f |
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
const Standard_Real AngDeviation1Deg = M_PI / 180.;
|
const Standard_Real AngDeviation1Deg = M_PI / 180.;
|
||||||
const Standard_Real AngDeviation90Deg = 90 * AngDeviation1Deg;
|
const Standard_Real AngDeviation90Deg = 90 * AngDeviation1Deg;
|
||||||
@@ -79,6 +80,66 @@ void UpdateBndBox(const gp_XY& thePnt1, const gp_XY& thePnt2, Bnd_B2d& theBox)
|
|||||||
theBox.Add(thePnt2);
|
theBox.Add(thePnt2);
|
||||||
theBox.Enlarge(Precision);
|
theBox.Enlarge(Precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Class representing a stack of frames. Each frame is a range of elements to be processed.
|
||||||
|
// The stack allows to process elements in depth-first order meaning that when new elements
|
||||||
|
// are added to the stack, they will be processed before the remaining elements of the
|
||||||
|
// current frame.
|
||||||
|
// Frames are processed in LIFO order while elements inside a frame are processed in FIFO order.
|
||||||
|
class StackOfFrames
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// A frame is a range of elements to be processed.
|
||||||
|
class Frame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Construct a frame for the given range of elements.
|
||||||
|
// Note that the range is [theFrameStart, theFrameEnd).
|
||||||
|
Frame(const int theFrameStart, const int theFrameEnd)
|
||||||
|
: CurrentElement(theFrameStart),
|
||||||
|
FrameEnd(theFrameEnd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the index of the current element and advance to the next one.
|
||||||
|
inline int Advance() { return CurrentElement++; }
|
||||||
|
|
||||||
|
// Check if all elements in the frame have been processed.
|
||||||
|
inline bool IsEmpty() const { return CurrentElement == FrameEnd; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int CurrentElement; // Index of the current element of the frame.
|
||||||
|
int FrameEnd; // Index of the last element + 1 of the frame.
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Adds a new frame for the given range of elements.
|
||||||
|
// Note that the range is [theFrameStart, theFrameEnd).
|
||||||
|
inline void PushFrame(const int theFrameStart, const int theFrameEnd)
|
||||||
|
{
|
||||||
|
myFrames.emplace_back(theFrameStart, theFrameEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the index of the current element of the top frame
|
||||||
|
// and advances to the next element. If all elements of the top
|
||||||
|
// frame have been processed, the frame is removed from the stack.
|
||||||
|
// Precondition: the stack is not empty.
|
||||||
|
inline int PopElement()
|
||||||
|
{
|
||||||
|
Frame& aFrame = myFrames.back();
|
||||||
|
const int anElem = aFrame.Advance();
|
||||||
|
if (aFrame.IsEmpty())
|
||||||
|
myFrames.pop_back();
|
||||||
|
|
||||||
|
return anElem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the stack is empty.
|
||||||
|
inline bool IsEmpty() const { return myFrames.empty(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Frame, NCollection_Allocator<Frame>> myFrames; // Container of frames.
|
||||||
|
};
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
//=================================================================================================
|
//=================================================================================================
|
||||||
@@ -1339,17 +1400,28 @@ void BRepMesh_Delaun::cleanupPolygon(const IMeshData::SequenceOfInteger& thePoly
|
|||||||
|
|
||||||
IMeshData::MapOfInteger aSurvivedLinks(anIgnoredEdges);
|
IMeshData::MapOfInteger aSurvivedLinks(anIgnoredEdges);
|
||||||
|
|
||||||
Standard_Integer aPolyVertIt = 0;
|
for (Standard_Integer aPolyVertIt = 0; aPolyVertIt < aPolyVertices.Length() - 1; ++aPolyVertIt)
|
||||||
Standard_Integer anUniqueVerticesNum = aPolyVertices.Length() - 1;
|
|
||||||
for (; aPolyVertIt < anUniqueVerticesNum; ++aPolyVertIt)
|
|
||||||
{
|
{
|
||||||
killTrianglesAroundVertex(aPolyVertices(aPolyVertIt),
|
StackOfFrames aStackFames;
|
||||||
aPolyVertices,
|
IMeshData::VectorOfInteger aStackData;
|
||||||
aPolyVerticesFindMap,
|
for (int aCurrentVictim = aPolyVertices(aPolyVertIt); aCurrentVictim != -1;
|
||||||
thePolygon,
|
aCurrentVictim = aStackFames.IsEmpty() ? -1 : aStackData(aStackFames.PopElement()))
|
||||||
thePolyBoxes,
|
{
|
||||||
aSurvivedLinks,
|
const int aPrevStackDataSize = aStackData.Length();
|
||||||
aLoopEdges);
|
killTrianglesAroundVertex(aCurrentVictim,
|
||||||
|
aPolyVertices,
|
||||||
|
aPolyVerticesFindMap,
|
||||||
|
thePolygon,
|
||||||
|
thePolyBoxes,
|
||||||
|
aSurvivedLinks,
|
||||||
|
aLoopEdges,
|
||||||
|
aStackData);
|
||||||
|
const int aNewStackDataSize = aStackData.Length();
|
||||||
|
if (aNewStackDataSize > aPrevStackDataSize)
|
||||||
|
{
|
||||||
|
aStackFames.PushFrame(aPrevStackDataSize, aNewStackDataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt(aLoopEdges);
|
IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt(aLoopEdges);
|
||||||
@@ -1376,12 +1448,12 @@ void BRepMesh_Delaun::killTrianglesAroundVertex(
|
|||||||
const IMeshData::SequenceOfInteger& thePolygon,
|
const IMeshData::SequenceOfInteger& thePolygon,
|
||||||
const IMeshData::SequenceOfBndB2d& thePolyBoxes,
|
const IMeshData::SequenceOfBndB2d& thePolyBoxes,
|
||||||
IMeshData::MapOfInteger& theSurvivedLinks,
|
IMeshData::MapOfInteger& theSurvivedLinks,
|
||||||
IMeshData::MapOfIntegerInteger& theLoopEdges)
|
IMeshData::MapOfIntegerInteger& theLoopEdges,
|
||||||
|
IMeshData::VectorOfInteger& theVictimNodes)
|
||||||
{
|
{
|
||||||
IMeshData::ListOfInteger::Iterator aNeighborsIt = myMeshData->LinksConnectedTo(theZombieNodeId);
|
IMeshData::ListOfInteger::Iterator aNeighborsIt = myMeshData->LinksConnectedTo(theZombieNodeId);
|
||||||
|
|
||||||
// Try to infect neighbor nodes
|
// Try to infect neighbor nodes
|
||||||
IMeshData::VectorOfInteger aVictimNodes;
|
|
||||||
for (; aNeighborsIt.More(); aNeighborsIt.Next())
|
for (; aNeighborsIt.More(); aNeighborsIt.Next())
|
||||||
{
|
{
|
||||||
const Standard_Integer& aNeighborLinkId = aNeighborsIt.Value();
|
const Standard_Integer& aNeighborLinkId = aNeighborsIt.Value();
|
||||||
@@ -1421,7 +1493,7 @@ void BRepMesh_Delaun::killTrianglesAroundVertex(
|
|||||||
if (isVertexInsidePolygon(anOtherNode, thePolyVertices))
|
if (isVertexInsidePolygon(anOtherNode, thePolyVertices))
|
||||||
{
|
{
|
||||||
// Got you!
|
// Got you!
|
||||||
aVictimNodes.Append(anOtherNode);
|
theVictimNodes.Append(anOtherNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1444,19 +1516,6 @@ void BRepMesh_Delaun::killTrianglesAroundVertex(
|
|||||||
theSurvivedLinks.Add(aNeighborLinkId);
|
theSurvivedLinks.Add(aNeighborLinkId);
|
||||||
killLinkTriangles(aNeighborLinkId, theLoopEdges);
|
killLinkTriangles(aNeighborLinkId, theLoopEdges);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go and do your job!
|
|
||||||
IMeshData::VectorOfInteger::Iterator aVictimIt(aVictimNodes);
|
|
||||||
for (; aVictimIt.More(); aVictimIt.Next())
|
|
||||||
{
|
|
||||||
killTrianglesAroundVertex(aVictimIt.Value(),
|
|
||||||
thePolyVertices,
|
|
||||||
thePolyVerticesFindMap,
|
|
||||||
thePolygon,
|
|
||||||
thePolyBoxes,
|
|
||||||
theSurvivedLinks,
|
|
||||||
theLoopEdges);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@@ -302,7 +302,8 @@ private:
|
|||||||
const IMeshData::SequenceOfInteger& thePolygon,
|
const IMeshData::SequenceOfInteger& thePolygon,
|
||||||
const IMeshData::SequenceOfBndB2d& thePolyBoxes,
|
const IMeshData::SequenceOfBndB2d& thePolyBoxes,
|
||||||
IMeshData::MapOfInteger& theSurvivedLinks,
|
IMeshData::MapOfInteger& theSurvivedLinks,
|
||||||
IMeshData::MapOfIntegerInteger& theLoopEdges);
|
IMeshData::MapOfIntegerInteger& theLoopEdges,
|
||||||
|
IMeshData::VectorOfInteger& theVictimNodes);
|
||||||
|
|
||||||
//! Checks is the given link crosses the polygon boundary.
|
//! Checks is the given link crosses the polygon boundary.
|
||||||
//! If yes, kills its triangles and checks neighbor links on boundary intersection. Does nothing
|
//! If yes, kills its triangles and checks neighbor links on boundary intersection. Does nothing
|
||||||
|
Reference in New Issue
Block a user