From 2caff0b32fdddc27244e226977c5c3b7a1fac57f Mon Sep 17 00:00:00 2001 From: oan Date: Wed, 5 Nov 2014 17:57:41 +0300 Subject: [PATCH] 0025364: BRepMesh is not able to triangulate the shape with fine deflection Don't create data structures for whole set of faces. Necessary structures are created directly in BRepMesh_FastDiscret. Don't copy nodes data during scaling, single structure is used. Remove lines used for debug Fix sphere: resolve problem came from merging. Keep code clean - remove unnecessary logic, expected to be used for complicated restoration process. Test cases for issue CR25364 --- src/BRepMesh/BRepMesh.hxx | 7 + .../BRepMesh_DataStructureOfDelaun.cxx | 101 +++++--- .../BRepMesh_DataStructureOfDelaun.hxx | 60 ++--- src/BRepMesh/BRepMesh_Delaun.cxx | 53 +++-- src/BRepMesh/BRepMesh_Delaun.hxx | 7 +- src/BRepMesh/BRepMesh_FaceAttribute.cxx | 80 ++----- src/BRepMesh/BRepMesh_FaceAttribute.hxx | 46 ++-- src/BRepMesh/BRepMesh_FastDiscret.cxx | 106 ++++----- src/BRepMesh/BRepMesh_FastDiscret.hxx | 11 +- src/BRepMesh/BRepMesh_FastDiscretFace.cxx | 216 ++++++++++++------ src/BRepMesh/BRepMesh_FastDiscretFace.hxx | 19 +- src/BRepMesh/BRepMesh_IncrementalMesh.cxx | 48 ++-- src/BRepMesh/BRepMesh_IncrementalMesh.hxx | 11 +- ...epMesh_SelectorOfDataStructureOfDelaun.cxx | 20 +- ...epMesh_SelectorOfDataStructureOfDelaun.hxx | 1 + src/BRepMesh/BRepMesh_ShapeTool.cxx | 8 +- src/BRepMesh/BRepMesh_Vertex.hxx | 6 + src/BRepMesh/BRepMesh_VertexInspector.hxx | 38 +-- src/BRepMesh/BRepMesh_VertexTool.cxx | 39 +--- src/BRepMesh/BRepMesh_VertexTool.hxx | 35 ++- src/MeshTest/MeshTest_DrawableMesh.cxx | 5 +- tests/bugs/mesh/bug25364 | 97 ++++++++ tests/mesh/data/standard/E9 | 7 - 23 files changed, 601 insertions(+), 420 deletions(-) create mode 100755 tests/bugs/mesh/bug25364 diff --git a/src/BRepMesh/BRepMesh.hxx b/src/BRepMesh/BRepMesh.hxx index 4c24eb7900..121abdd1c6 100644 --- a/src/BRepMesh/BRepMesh.hxx +++ b/src/BRepMesh/BRepMesh.hxx @@ -53,9 +53,13 @@ class BRepMesh_VertexInspector; class BRepMesh_CircleInspector; class BRepMesh_Classifier; class Poly_Triangulation; +class BRepMesh_VertexTool; namespace BRepMesh { + //! Default size for memory block allocated by IncAllocator. + const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024; + //! Structure keeping parameters of segment. struct Segment { @@ -112,6 +116,7 @@ namespace BRepMesh typedef NCollection_CellFilter VertexCellFilter; //! Handles + typedef NCollection_Handle HVectorOfVertex; typedef NCollection_Handle HMapOfInteger; typedef NCollection_Handle HIMapOfInteger; typedef NCollection_Handle HDMapOfShapePairOfPolygon; @@ -120,6 +125,8 @@ namespace BRepMesh typedef NCollection_Handle HBndBox2dTree; typedef NCollection_Handle HArray1OfSegments; typedef NCollection_Handle HDMapOfVertexInteger; + typedef NCollection_Handle HDMapOfIntegerListOfXY; + typedef NCollection_Handle HVertexTool; //! Other data structures typedef std::pair SegmentsTree; diff --git a/src/BRepMesh/BRepMesh_DataStructureOfDelaun.cxx b/src/BRepMesh/BRepMesh_DataStructureOfDelaun.cxx index c84de01be6..149df8210a 100644 --- a/src/BRepMesh/BRepMesh_DataStructureOfDelaun.cxx +++ b/src/BRepMesh/BRepMesh_DataStructureOfDelaun.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -33,16 +34,31 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_DataStructureOfDelaun, Standard_Transient) BRepMesh_DataStructureOfDelaun::BRepMesh_DataStructureOfDelaun( const Handle(NCollection_IncAllocator)& theAllocator, const Standard_Integer theReservedNodeSize) - : myNodes (theReservedNodeSize, theAllocator), - myLinks (theReservedNodeSize * 3), - myDelLinks (theAllocator), - myElements (theReservedNodeSize * 2), - myElementsOfDomain(theReservedNodeSize * 2, theAllocator), - myLinksOfDomain (theReservedNodeSize * 2, theAllocator), - myAllocator (theAllocator) + : myAllocator (theAllocator), + myNodes (new BRepMesh_VertexTool(theReservedNodeSize, myAllocator)), + myLinks (theReservedNodeSize * 3, myAllocator), + myDelLinks (myAllocator), + myElements (theReservedNodeSize * 2, myAllocator), + myElementsOfDomain(theReservedNodeSize * 2, myAllocator), + myLinksOfDomain (theReservedNodeSize * 2, myAllocator) { } +//======================================================================= +//function : SubstituteNode +//purpose : +//======================================================================= +Standard_Integer BRepMesh_DataStructureOfDelaun::AddNode( + const BRepMesh_Vertex& theNode, + const Standard_Boolean isForceAdd) +{ + const Standard_Integer aNodeId = myNodes->Add(theNode, isForceAdd); + if (!myNodeLinks.IsBound(aNodeId)) + myNodeLinks.Bind(aNodeId, BRepMesh::ListOfInteger(myAllocator)); + + return aNodeId; +} + //======================================================================= //function : SubstituteNode //purpose : @@ -51,11 +67,10 @@ Standard_Boolean BRepMesh_DataStructureOfDelaun::SubstituteNode( const Standard_Integer theIndex, const BRepMesh_Vertex& theNewNode) { - if (myNodes.FindIndex(theNewNode) != 0) + if (myNodes->FindIndex(theNewNode) != 0) return Standard_False; - const BRepMesh::ListOfInteger& aLinks = myNodes(theIndex); - myNodes.Substitute(theIndex, theNewNode, aLinks); + myNodes->Substitute(theIndex, theNewNode); return Standard_True; } @@ -84,8 +99,8 @@ Standard_Integer BRepMesh_DataStructureOfDelaun::AddLink( aLinkIndex = myLinks.Add(theLink, aPair); const Standard_Integer aLinkId = Abs(aLinkIndex); - myNodes(theLink.FirstNode()).Append(aLinkId); - myNodes(theLink.LastNode() ).Append(aLinkId); + linksConnectedTo(theLink.FirstNode()).Append(aLinkId); + linksConnectedTo(theLink.LastNode() ).Append(aLinkId); myLinksOfDomain.Add(aLinkIndex); return aLinkIndex; @@ -115,8 +130,8 @@ Standard_Boolean BRepMesh_DataStructureOfDelaun::SubstituteLink( cleanLink(theIndex, aLink); const Standard_Integer aLinkId = Abs(theIndex); - myNodes(theNewLink.FirstNode()).Append(aLinkId); - myNodes(theNewLink.LastNode() ).Append(aLinkId); + linksConnectedTo(theNewLink.FirstNode()).Append(aLinkId); + linksConnectedTo(theNewLink.LastNode() ).Append(aLinkId); myLinks.Substitute(theIndex, theNewLink, aPair); return Standard_True; @@ -158,7 +173,7 @@ void BRepMesh_DataStructureOfDelaun::cleanLink( const Standard_Integer aNodeId = (i == 0) ? theLink.FirstNode() : theLink.LastNode(); - BRepMesh::ListOfInteger& aLinkList = myNodes(aNodeId); + BRepMesh::ListOfInteger& aLinkList = linksConnectedTo(aNodeId); BRepMesh::ListOfInteger::Iterator aLinkIt(aLinkList); for(; aLinkIt.More(); aLinkIt.Next()) { @@ -381,7 +396,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedLinks() const Standard_Integer aCurNodeId = (i == 0) ? aLink.FirstNode() : aLink.LastNode(); - for (aLinkIt.Init(myNodes(aCurNodeId)); aLinkIt.More(); aLinkIt.Next()) + for (aLinkIt.Init(linksConnectedTo(aCurNodeId)); aLinkIt.More(); aLinkIt.Next()) { Standard_Integer& aLinkId = aLinkIt.ChangeValue(); if (aLinkId == aLastLiveItemId) @@ -422,7 +437,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedLinks() void BRepMesh_DataStructureOfDelaun::clearDeletedNodes() { BRepMesh::ListOfInteger& aDelNodes = - (BRepMesh::ListOfInteger&)myNodes.GetListOfDelNodes(); + (BRepMesh::ListOfInteger&)myNodes->GetListOfDelNodes(); Standard_Integer aLastLiveItem = NbNodes(); while (!aDelNodes.IsEmpty()) @@ -432,7 +447,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedNodes() if (GetNode(aLastLiveItem).Movability() != BRepMesh_Deleted) break; - myNodes.RemoveLast(); + myNodes->RemoveLast(); --aLastLiveItem; } @@ -443,12 +458,13 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedNodes() continue; BRepMesh_Vertex aNode = GetNode(aLastLiveItem); - BRepMesh::ListOfInteger& aLinkList = myNodes(aLastLiveItem); + BRepMesh::ListOfInteger& aLinkList = linksConnectedTo(aLastLiveItem); - myNodes.RemoveLast(); + myNodes->RemoveLast(); --aLastLiveItem; - myNodes.Substitute(aDelItem, aNode, aLinkList); + myNodes->Substitute(aDelItem, aNode); + myNodeLinks.ChangeFind(aDelItem) = aLinkList; const Standard_Integer aLastLiveItemId = aLastLiveItem + 1; BRepMesh::ListOfInteger::Iterator aLinkIt(aLinkList); @@ -477,8 +493,8 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedNodes() void BRepMesh_DataStructureOfDelaun::Statistics(Standard_OStream& theStream) const { theStream << " Map of nodes : \n"; - myNodes.Statistics(theStream); - theStream << "\n Deleted nodes : " << myNodes.GetListOfDelNodes().Extent() << endl; + myNodes->Statistics(theStream); + theStream << "\n Deleted nodes : " << myNodes->GetListOfDelNodes().Extent() << endl; theStream << "\n\n Map of Links : \n"; myLinks.Statistics(theStream); @@ -518,24 +534,37 @@ Standard_CString BRepMesh_Dump(void* theMeshHandlePtr, { OCC_CATCH_SIGNALS - BRepMesh::MapOfInteger::Iterator aLinksIt(aMeshData->LinksOfDomain()); - for (; aLinksIt.More(); aLinksIt.Next()) + if (aMeshData->LinksOfDomain().IsEmpty()) { - const BRepMesh_Edge& aLink = aMeshData->GetLink(aLinksIt.Value()); - gp_Pnt aPnt[2]; - for (Standard_Integer i = 0; i < 2; ++i) + const Standard_Integer aNodesNb = aMeshData->NbNodes(); + for (Standard_Integer i = 1; i <= aNodesNb; ++i) { - const Standard_Integer aNodeId = - (i == 0) ? aLink.FirstNode() : aLink.LastNode(); - - const gp_XY& aNode = aMeshData->GetNode(aNodeId).Coord(); - aPnt[i] = gp_Pnt(aNode.X(), aNode.Y(), 0.); + const gp_XY& aNode = aMeshData->GetNode(i).Coord(); + gp_Pnt aPnt(aNode.X(), aNode.Y(), 0.); + aBuilder.Add(aMesh, BRepBuilderAPI_MakeVertex(aPnt)); } + } + else + { + BRepMesh::MapOfInteger::Iterator aLinksIt(aMeshData->LinksOfDomain()); + for (; aLinksIt.More(); aLinksIt.Next()) + { + const BRepMesh_Edge& aLink = aMeshData->GetLink(aLinksIt.Value()); + gp_Pnt aPnt[2]; + for (Standard_Integer i = 0; i < 2; ++i) + { + const Standard_Integer aNodeId = + (i == 0) ? aLink.FirstNode() : aLink.LastNode(); + + const gp_XY& aNode = aMeshData->GetNode(aNodeId).Coord(); + aPnt[i] = gp_Pnt(aNode.X(), aNode.Y(), 0.); + } - if (aPnt[0].SquareDistance(aPnt[1]) < Precision::SquareConfusion()) - continue; + if (aPnt[0].SquareDistance(aPnt[1]) < Precision::SquareConfusion()) + continue; - aBuilder.Add(aMesh, BRepBuilderAPI_MakeEdge(aPnt[0], aPnt[1])); + aBuilder.Add(aMesh, BRepBuilderAPI_MakeEdge(aPnt[0], aPnt[1])); + } } if (!BRepTools::Write(aMesh, theFileNameStr)) diff --git a/src/BRepMesh/BRepMesh_DataStructureOfDelaun.hxx b/src/BRepMesh/BRepMesh_DataStructureOfDelaun.hxx index 3177224fca..e09cc42275 100644 --- a/src/BRepMesh/BRepMesh_DataStructureOfDelaun.hxx +++ b/src/BRepMesh/BRepMesh_DataStructureOfDelaun.hxx @@ -47,24 +47,25 @@ public: //! @name API for accessing mesh nodes. //! Returns number of nodes. inline Standard_Integer NbNodes() const { - return myNodes.Extent(); + return myNodes->Extent(); } //! Adds node to the mesh if it is not already in the mesh. //! @param theNode node to be added to the mesh. + //! @param isForceAdd adds the given node to structure without + //! checking on coincidence with other nodes. //! @return index of the node in the structure. - inline Standard_Integer AddNode(const BRepMesh_Vertex& theNode) - { - return myNodes.Add(theNode); - } + Standard_EXPORT Standard_Integer AddNode( + const BRepMesh_Vertex& theNode, + const Standard_Boolean isForceAdd = Standard_False); //! Finds the index of the given node. //! @param theNode node to find. //! @return index of the given element of zero if node is not in the mesh. Standard_EXPORT Standard_Integer IndexOf(const BRepMesh_Vertex& theNode) { - return myNodes.FindIndex(theNode); + return myNodes->FindIndex(theNode); } //! Get node by the index. @@ -72,7 +73,7 @@ public: //! @name API for accessing mesh nodes. //! @return node with the given index. inline const BRepMesh_Vertex& GetNode(const Standard_Integer theIndex) { - return myNodes.FindKey(theIndex); + return myNodes->FindKey(theIndex); } //! Alias for GetNode. @@ -81,16 +82,6 @@ public: //! @name API for accessing mesh nodes. return GetNode(theIndex); } - //! Replaces nodes of mesh by the given ones. - //! @param theNewNodes nodes to be set instead of existing ones. - Standard_EXPORT void ReplaceNodes(const BRepMesh_VertexTool& theNewNodes) - { - if (theNewNodes.IsEmpty()) - return; - - myNodes = theNewNodes; - } - //! Substitutes the node with the given index by new one. //! @param theIndex index of node to be substituted. //! @param theNewNode substituting node. @@ -107,10 +98,10 @@ public: //! @name API for accessing mesh nodes. Standard_EXPORT void RemoveNode(const Standard_Integer theIndex, const Standard_Boolean isForce = Standard_False) { - if (isForce || myNodes.FindKey(theIndex).Movability() == BRepMesh_Free) + if (isForce || myNodes->FindKey(theIndex).Movability() == BRepMesh_Free) { - if (myNodes.FindFromIndex(theIndex).Extent()==0) - myNodes.Delete(theIndex); + if (LinksConnectedTo(theIndex).Extent()==0) + myNodes->Delete(theIndex); } } @@ -120,11 +111,10 @@ public: //! @name API for accessing mesh nodes. inline const BRepMesh::ListOfInteger& LinksConnectedTo( const Standard_Integer theIndex) const { - return myNodes.FindFromIndex(theIndex); + return linksConnectedTo(theIndex); } - public: //! @name API for accessing mesh links. //! Returns number of links. @@ -254,7 +244,7 @@ public: //! @name Auxilary API } //! Gives the data structure for initialization of cell size and tolerance. - inline BRepMesh_VertexTool& Data() + inline BRepMesh::HVertexTool& Data() { return myNodes; } @@ -274,6 +264,15 @@ public: //! @name Auxilary API private: + //! Get list of links attached to the node with the given index. + //! @param theIndex index of node whose links should be retrieved. + //! @return list of links attached to the node. + inline BRepMesh::ListOfInteger& linksConnectedTo( + const Standard_Integer theIndex) const + { + return (BRepMesh::ListOfInteger&)myNodeLinks.Find(theIndex); + } + //! Substitutes deleted links by the last one from corresponding map //! to have only non-deleted links in the structure. Standard_EXPORT void clearDeletedLinks(); @@ -305,13 +304,14 @@ private: private: - BRepMesh_VertexTool myNodes; - BRepMesh::IDMapOfLink myLinks; - BRepMesh::ListOfInteger myDelLinks; - BRepMesh::IMapOfElement myElements; - BRepMesh::MapOfInteger myElementsOfDomain; - BRepMesh::MapOfInteger myLinksOfDomain; - Handle(NCollection_IncAllocator) myAllocator; + Handle(NCollection_IncAllocator) myAllocator; + BRepMesh::HVertexTool myNodes; + BRepMesh::DMapOfIntegerListOfInteger myNodeLinks; + BRepMesh::IDMapOfLink myLinks; + BRepMesh::ListOfInteger myDelLinks; + BRepMesh::IMapOfElement myElements; + BRepMesh::MapOfInteger myElementsOfDomain; + BRepMesh::MapOfInteger myLinksOfDomain; }; DEFINE_STANDARD_HANDLE(BRepMesh_DataStructureOfDelaun,Standard_Transient) diff --git a/src/BRepMesh/BRepMesh_Delaun.cxx b/src/BRepMesh/BRepMesh_Delaun.cxx index b300b13927..cf3778ebb1 100644 --- a/src/BRepMesh/BRepMesh_Delaun.cxx +++ b/src/BRepMesh/BRepMesh_Delaun.cxx @@ -77,12 +77,14 @@ namespace { //======================================================================= BRepMesh_Delaun::BRepMesh_Delaun( BRepMesh::Array1OfVertexOfDelaun& theVertices) -: myCircles( theVertices.Length(), new NCollection_IncAllocator() ) + : myCircles(theVertices.Length(), new NCollection_IncAllocator( + BRepMesh::MEMORY_BLOCK_SIZE_HUGE)) { if ( theVertices.Length() > 2 ) { - myMeshData = new BRepMesh_DataStructureOfDelaun( new NCollection_IncAllocator(), - theVertices.Length() ); + myMeshData = new BRepMesh_DataStructureOfDelaun( + new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE), + theVertices.Length() ); Init( theVertices ); } } @@ -247,7 +249,7 @@ void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex, void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes) { // Insertion of edges of super triangles in the list of free edges: - BRepMesh::MapOfIntegerInteger aLoopEdges( 10, myMeshData->Allocator() ); + BRepMesh::MapOfIntegerInteger aLoopEdges(10, myMeshData->Allocator()); Standard_Integer e[3]; Standard_Boolean o[3]; mySupTrian.Edges( e, o ); @@ -418,7 +420,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn void BRepMesh_Delaun::createTrianglesOnNewVertices( BRepMesh::Array1OfInteger& theVertexIndexes) { - BRepMesh::MapOfIntegerInteger aLoopEdges( 10, myMeshData->Allocator() ); + Handle(NCollection_IncAllocator) aAllocator = + new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); + + BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator); // Insertion of nodes : Standard_Boolean isModify = Standard_True; @@ -428,6 +433,7 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices( for( ; anIndex <= anUpper; ++anIndex ) { aLoopEdges.Clear(); + aAllocator->Reset(Standard_False); Standard_Integer aVertexIdx = theVertexIndexes( anIndex ); const BRepMesh_Vertex& aVertex = GetVertex( aVertexIdx ); @@ -574,10 +580,13 @@ Standard_Boolean BRepMesh_Delaun::isBoundToFrontier( //======================================================================= void BRepMesh_Delaun::cleanupMesh() { + Handle(NCollection_IncAllocator) aAllocator = + new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); + for(;;) { - BRepMesh::MapOfIntegerInteger aLoopEdges( 10, myMeshData->Allocator() ); - BRepMesh::MapOfInteger aDelTriangles; + BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator); + BRepMesh::MapOfInteger aDelTriangles(10, aAllocator); BRepMesh::HMapOfInteger aFreeEdges = FreeEdges(); BRepMesh::MapOfInteger::Iterator aFreeEdgesIt( *aFreeEdges ); @@ -657,6 +666,7 @@ void BRepMesh_Delaun::cleanupMesh() myMeshData->RemoveLink( aLoopEdgesIt.Key() ); } + aAllocator->Reset(Standard_False); if ( aDeletedTrianglesNb == 0 ) break; } @@ -669,9 +679,15 @@ void BRepMesh_Delaun::cleanupMesh() void BRepMesh_Delaun::frontierAdjust() { BRepMesh::HMapOfInteger aFrontier = Frontier(); - BRepMesh::VectorOfInteger aFailedFrontiers; - BRepMesh::MapOfIntegerInteger aLoopEdges( 10, myMeshData->Allocator() ); - BRepMesh::HMapOfInteger aIntFrontierEdges = new BRepMesh::MapOfInteger; + + Handle(NCollection_IncAllocator) aAllocator = + new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); + + BRepMesh::VectorOfInteger aFailedFrontiers(256, aAllocator); + BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator); + BRepMesh::HMapOfInteger aIntFrontierEdges = + new BRepMesh::MapOfInteger(10, aAllocator); + for ( Standard_Integer aPass = 1; aPass <= 2; ++aPass ) { // 1 pass): find external triangles on boundary edges; @@ -1089,10 +1105,13 @@ void BRepMesh_Delaun::cleanupPolygon(const BRepMesh::SequenceOfInteger& thePolyg if ( aPolyLen < 3 ) return; - BRepMesh::MapOfIntegerInteger aLoopEdges( 10, myMeshData->Allocator() ); - BRepMesh::MapOfInteger anIgnoredEdges; - BRepMesh::MapOfInteger aPolyVerticesFindMap; - BRepMesh::VectorOfInteger aPolyVertices; + Handle(NCollection_IncAllocator) aAllocator = + new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); + + BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator); + BRepMesh::MapOfInteger anIgnoredEdges(10, aAllocator); + BRepMesh::MapOfInteger aPolyVerticesFindMap(10, aAllocator); + BRepMesh::VectorOfInteger aPolyVertices(256, aAllocator); // Collect boundary vertices of the polygon for ( Standard_Integer aPolyIt = 1; aPolyIt <= aPolyLen; ++aPolyIt ) { @@ -1336,8 +1355,8 @@ void BRepMesh_Delaun::killTrianglesOnIntersectingLinks( killLinkTriangles( theLinkToCheckId, theLoopEdges ); - BRepMesh::ListOfInteger::Iterator aNeighborsIt = - myMeshData->LinksConnectedTo( theEndPoint ); + BRepMesh::ListOfInteger::Iterator aNeighborsIt( + myMeshData->LinksConnectedTo(theEndPoint)); for ( ; aNeighborsIt.More(); aNeighborsIt.Next() ) { @@ -1918,7 +1937,7 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex ) BRepMesh_SelectorOfDataStructureOfDelaun aSelector( myMeshData ); aSelector.NeighboursOf( theVertex ); - BRepMesh::MapOfIntegerInteger aLoopEdges( 10, myMeshData->Allocator() ); + BRepMesh::MapOfIntegerInteger aLoopEdges;//( 10, myMeshData->Allocator() ); // Loop on triangles to be destroyed : BRepMesh::MapOfInteger::Iterator aTriangleIt( aSelector.Elements() ); diff --git a/src/BRepMesh/BRepMesh_Delaun.hxx b/src/BRepMesh/BRepMesh_Delaun.hxx index fd289e18cf..0899898327 100755 --- a/src/BRepMesh/BRepMesh_Delaun.hxx +++ b/src/BRepMesh/BRepMesh_Delaun.hxx @@ -149,9 +149,10 @@ private: void frontierAdjust(); //! Find left polygon of the given edge and call meshPolygon. - Standard_Boolean meshLeftPolygonOf (const Standard_Integer theEdgeIndex, - const Standard_Boolean isForward, - BRepMesh::HMapOfInteger theSkipped = NULL); + Standard_Boolean meshLeftPolygonOf( + const Standard_Integer theEdgeIndex, + const Standard_Boolean isForward, + BRepMesh::HMapOfInteger theSkipped = NULL); //! Find next link starting from the given node and has maximum //! angle respect the given reference link. diff --git a/src/BRepMesh/BRepMesh_FaceAttribute.cxx b/src/BRepMesh/BRepMesh_FaceAttribute.cxx index 6788fbfed9..43e5dceb1d 100644 --- a/src/BRepMesh/BRepMesh_FaceAttribute.cxx +++ b/src/BRepMesh/BRepMesh_FaceAttribute.cxx @@ -34,8 +34,7 @@ BRepMesh_FaceAttribute::BRepMesh_FaceAttribute() myVMax (0.), myDeltaX (1.), myDeltaY (1.), - myStatus (BRepMesh_NoError), - myAllocator (new NCollection_IncAllocator(64000)) + myStatus (BRepMesh_NoError) { init(); } @@ -58,8 +57,7 @@ BRepMesh_FaceAttribute::BRepMesh_FaceAttribute( myStatus (BRepMesh_NoError), myBoundaryVertices(theBoundaryVertices), myBoundaryPoints (theBoundaryPoints), - myFace (theFace), - myAllocator (new NCollection_IncAllocator(64000)) + myFace (theFace) { init(); } @@ -70,8 +68,6 @@ BRepMesh_FaceAttribute::BRepMesh_FaceAttribute( //======================================================================= BRepMesh_FaceAttribute::~BRepMesh_FaceAttribute() { - Clear(); - myAllocator.Nullify(); } //======================================================================= @@ -82,74 +78,30 @@ void BRepMesh_FaceAttribute::init() { myVertexEdgeMap = new BRepMesh::IMapOfInteger; myInternalEdges = new BRepMesh::DMapOfShapePairOfPolygon; - mySurfacePoints = new BRepMesh::DMapOfIntegerPnt; + myLocation2D = new BRepMesh::DMapOfIntegerListOfXY; myClassifier = new BRepMesh_Classifier; - if (!myFace.IsNull()) - { - BRepTools::Update(myFace); - myFace.Orientation(TopAbs_FORWARD); + if (myFace.IsNull()) + return; - BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False); - mySurface = new BRepAdaptor_HSurface(aSurfAdaptor); - } + BRepTools::Update(myFace); + myFace.Orientation(TopAbs_FORWARD); + BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax); - ResetStructure(); + BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False); + mySurface = new BRepAdaptor_HSurface(aSurfAdaptor); } //======================================================================= //function : Clear //purpose : //======================================================================= -void BRepMesh_FaceAttribute::Clear( - const Standard_Boolean isClearSurfaceDataOnly) +void BRepMesh_FaceAttribute::Clear() { - clearLocal(isClearSurfaceDataOnly); - - mySurfaceVertices.Clear(); - mySurfacePoints->Clear(); - - mySurface.Nullify(); - myClassifier.Nullify(); -} - -//======================================================================= -//function : clearLocal -//purpose : -//======================================================================= -void BRepMesh_FaceAttribute::clearLocal( - const Standard_Boolean isClearSurfaceDataOnly) -{ - myLocation2D.Clear(); - myVertexEdgeMap->Clear(); - - if (!isClearSurfaceDataOnly) - { - myInternalEdges->Clear(); - } - myStructure.Nullify(); - myAllocator->Reset(isClearSurfaceDataOnly); -} - -//======================================================================= -//function : ResetStructure -//purpose : -//======================================================================= -Handle(BRepMesh_DataStructureOfDelaun)& BRepMesh_FaceAttribute::ResetStructure() -{ - clearLocal(); - myStructure = new BRepMesh_DataStructureOfDelaun(myAllocator); - - if (!myFace.IsNull()) - BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax); - - Standard_Real aTolU = ToleranceU(); - Standard_Real aTolV = ToleranceV(); - - myStructure->Data().SetCellSize(14.0 * aTolU, 14.0 * aTolV); - myStructure->Data().SetTolerance(aTolU, aTolV); - return myStructure; + myLocation2D->Clear(); + myInternalEdges->Clear(); + myVertexEdgeMap->Clear(); } //======================================================================= @@ -174,8 +126,8 @@ Standard_Boolean BRepMesh_FaceAttribute::getVertexIndex( { if (!myBoundaryVertices.IsNull() && myBoundaryVertices->IsBound(theVertex)) theVertexIndex = myBoundaryVertices->Find(theVertex); - else if (mySurfaceVertices.IsBound(theVertex)) - theVertexIndex = mySurfaceVertices.Find(theVertex); + else if (!mySurfaceVertices.IsNull() && mySurfaceVertices->IsBound(theVertex)) + theVertexIndex = mySurfaceVertices->Find(theVertex); else return Standard_False; diff --git a/src/BRepMesh/BRepMesh_FaceAttribute.hxx b/src/BRepMesh/BRepMesh_FaceAttribute.hxx index d602dbf93e..6f3efe904f 100644 --- a/src/BRepMesh/BRepMesh_FaceAttribute.hxx +++ b/src/BRepMesh/BRepMesh_FaceAttribute.hxx @@ -190,13 +190,7 @@ public: //! @name main geometrical properties. public: //! @name auxiliary structures //! Clear face attribute. - //! @param isClearSurfaceDataOnly clears only surface attributes if true value is set. - Standard_EXPORT void Clear( - const Standard_Boolean isClearSurfaceDataOnly = Standard_False); - - //! Resets mesh data structure. - //! @returns reset data structure. - Standard_EXPORT Handle(BRepMesh_DataStructureOfDelaun)& ResetStructure(); + Standard_EXPORT void Clear(); //! Gives reference to map of internal edges of face. inline BRepMesh::HDMapOfShapePairOfPolygon& ChangeInternalEdges() @@ -205,7 +199,7 @@ public: //! @name auxiliary structures } //! Gives reference to map of 2D points of discretization. - inline BRepMesh::DMapOfIntegerListOfXY& ChangeLocation2D() + inline BRepMesh::HDMapOfIntegerListOfXY& ChangeLocation2D() { return myLocation2D; } @@ -216,6 +210,12 @@ public: //! @name auxiliary structures return mySurfacePoints; } + //! Gives reference to map of vertices of discretization. + inline BRepMesh::HDMapOfVertexInteger& ChangeSurfaceVertices() + { + return mySurfaceVertices; + } + //! Gives reference on map of (vertex, edge) pairs of face. inline BRepMesh::HIMapOfInteger& ChangeVertexEdgeMap() { @@ -234,13 +234,19 @@ public: //! @name auxiliary structures return myClassifier; } + //! Returns mesh nodes calculated for boundaries. + inline BRepMesh::HVectorOfVertex& ChangeMeshNodes() + { + return myMeshNodes; + } + public: //! @name Point/Vertex/Node manipulators //! Gives the number of different locations in 3D space. inline Standard_Integer LastPointId() const { - return (myBoundaryPoints.IsNull() ? 0 : myBoundaryPoints->Extent()) - + mySurfacePoints->Extent(); + return (myBoundaryPoints.IsNull() ? 0 : myBoundaryPoints->Extent()) + + (mySurfacePoints.IsNull() ? 0 : mySurfacePoints->Extent()); } //! Gives the 3D location of the vertex. @@ -252,7 +258,7 @@ public: //! @name Point/Vertex/Node manipulators //! Gives the 3D location of the vertex. inline const gp_Pnt& GetPoint(const Standard_Integer theIndex) const { - if (myBoundaryPoints.IsNull() || theIndex > myBoundaryPoints->Extent()) + if (!mySurfacePoints.IsNull() && theIndex > myBoundaryPoints->Extent()) return mySurfacePoints->Find(theIndex); return myBoundaryPoints->Find(theIndex); @@ -287,7 +293,7 @@ public: //! @name Point/Vertex/Node manipulators } BRepMesh::DMapOfVertexInteger& aVertexMap = isFillEdgeVertices ? - *myBoundaryVertices : mySurfaceVertices; + *myBoundaryVertices : *mySurfaceVertices; aVertexMap.Bind(aVertex, aNewVertexIndex); @@ -362,16 +368,20 @@ private: TopoDS_Face myFace; Handle(BRepAdaptor_HSurface) mySurface; - BRepMesh::DMapOfVertexInteger mySurfaceVertices; - BRepMesh::HDMapOfIntegerPnt mySurfacePoints; + BRepMesh::HClassifier myClassifier; - BRepMesh::DMapOfIntegerListOfXY myLocation2D; - BRepMesh::HIMapOfInteger myVertexEdgeMap; BRepMesh::HDMapOfShapePairOfPolygon myInternalEdges; + BRepMesh::HDMapOfIntegerListOfXY myLocation2D; + BRepMesh::HIMapOfInteger myVertexEdgeMap; + + // This field is intended to keep calculated mesh nodes to prevent + // extremely high memory consumption in case if the whole structure is kept. + BRepMesh::HVectorOfVertex myMeshNodes; + + BRepMesh::HDMapOfVertexInteger mySurfaceVertices; + BRepMesh::HDMapOfIntegerPnt mySurfacePoints; Handle(BRepMesh_DataStructureOfDelaun) myStructure; - BRepMesh::HClassifier myClassifier; - Handle(NCollection_IncAllocator) myAllocator; }; DEFINE_STANDARD_HANDLE(BRepMesh_FaceAttribute, Standard_Transient) diff --git a/src/BRepMesh/BRepMesh_FastDiscret.cxx b/src/BRepMesh/BRepMesh_FastDiscret.cxx index 3cea490ec4..273b152697 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.cxx @@ -203,6 +203,34 @@ void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const } } +//======================================================================= +//function : resetDataStructure +//purpose : +//======================================================================= +void BRepMesh_FastDiscret::resetDataStructure() +{ + Handle(NCollection_IncAllocator) aAllocator; + if (myAttribute->ChangeStructure().IsNull()) + aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); + else + aAllocator = myAttribute->ChangeStructure()->Allocator(); + + myAttribute->Clear(); + aAllocator->Reset(Standard_False); + Handle(BRepMesh_DataStructureOfDelaun) aStructure = + new BRepMesh_DataStructureOfDelaun(aAllocator); + + const Standard_Real aTolU = myAttribute->ToleranceU(); + const Standard_Real aTolV = myAttribute->ToleranceV(); + const Standard_Real uCellSize = 14.0 * aTolU; + const Standard_Real vCellSize = 14.0 * aTolV; + + aStructure->Data()->SetCellSize ( uCellSize, vCellSize); + aStructure->Data()->SetTolerance( aTolU , aTolV ); + + myAttribute->ChangeStructure() = aStructure; +} + //======================================================================= //function : Add(face) //purpose : @@ -224,10 +252,10 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) myAttributes.Bind(theFace, myAttribute); } - myVertexEdgeMap = myAttribute->ChangeVertexEdgeMap(); - myInternalEdges = myAttribute->ChangeInternalEdges(); - Handle(BRepMesh_DataStructureOfDelaun)& aStructure = - myAttribute->ResetStructure(); + BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap(); + BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges(); + + resetDataStructure(); if (!myWithShare) { @@ -314,8 +342,9 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) } } - if ( nbEdge == 0 || myVertexEdgeMap->Extent() < 3 ) + if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 ) { + myAttribute->ChangeStructure().Nullify(); myAttribute->SetStatus(BRepMesh_Failure); return myAttribute->GetStatus(); } @@ -345,9 +374,10 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) Standard_Integer ipn = 0; Standard_Integer i1 = 1; - for ( i1 = 1; i1 <= myVertexEdgeMap->Extent(); ++i1 ) + for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 ) { - const BRepMesh_Vertex& aVertex = aStructure->GetNode(myVertexEdgeMap->FindKey(i1)); + const BRepMesh_Vertex& aVertex = + myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1)); ++ipn; @@ -410,6 +440,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) if (aSurfType == GeomAbs_BezierSurface && (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) ) { + myAttribute->ChangeStructure().Nullify(); myAttribute->SetStatus(BRepMesh_Failure); return myAttribute->GetStatus(); } @@ -421,7 +452,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) { BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier(); BRepMesh_WireChecker aDFaceChecker(aFace, Precision::PConfusion(), - myInternalEdges, myVertexEdgeMap, aStructure, + aInternalEdges, aVertexEdgeMap, myAttribute->ChangeStructure(), myumin, myumax, myvmin, myvmax, myInParallel ); aDFaceChecker.ReCompute(aClassifier); @@ -435,10 +466,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) { ++nbmaill; - // Clear the structure of links - aStructure = myAttribute->ResetStructure(); - - + resetDataStructure(); for (Standard_Integer j = 1; j <= aFaceEdges.Length(); ++j) { const TopoDS_Edge& anEdge = aFaceEdges(j); @@ -459,8 +487,10 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) myAttribute->SetStatus(aCheckStatus); if (!myAttribute->IsValid()) - //RemoveFaceAttribute(theFace); + { + myAttribute->ChangeStructure().Nullify(); return myAttribute->GetStatus(); + } } // try to find the real length: @@ -514,6 +544,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) if (longu <= 1.e-16 || longv <= 1.e-16) { //yes, it is seen!! + myAttribute->ChangeStructure().Nullify(); myAttribute->SetStatus(BRepMesh_Failure); return myAttribute->GetStatus(); } @@ -543,7 +574,10 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) Standard_Real aa = sqrt(Du*Du + oldDv*oldDv); if (aa < gp::Resolution()) + { + myAttribute->ChangeStructure().Nullify(); return myAttribute->GetStatus(); + } Du = Du * Min(oldDv, Du) / aa; } @@ -599,27 +633,11 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) myAttribute->SetStatus(BRepMesh_Failure); } - return myAttribute->GetStatus(); -} + myAttribute->ChangeMeshNodes() = + myAttribute->ChangeStructure()->Data()->Vertices(); -//======================================================================= -//function : addLinkToMesh -//purpose : -//======================================================================= -void BRepMesh_FastDiscret::addLinkToMesh( - const Standard_Integer theFirstNodeId, - const Standard_Integer theLastNodeId, - const TopAbs_Orientation theOrientation) -{ - Handle(BRepMesh_DataStructureOfDelaun)& aStructure = - myAttribute->ChangeStructure(); - - if (theOrientation == TopAbs_FORWARD) - aStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier)); - else if (theOrientation == TopAbs_REVERSED) - aStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier)); - else if (theOrientation == TopAbs_INTERNAL) - aStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed)); + myAttribute->ChangeStructure().Nullify(); + return myAttribute->GetStatus(); } //======================================================================= @@ -788,14 +806,7 @@ void BRepMesh_FastDiscret::add( aNewNodes (i) = isv; aNewParams(i) = aParam; - - addLinkToMesh(ivf, iv2, orEdge); - ivf = iv2; } - - // last point - if (ivf != ivl) - addLinkToMesh(ivf, ivl, orEdge); } Handle(Poly_PolygonOnTriangulation) P1 = @@ -858,7 +869,6 @@ void BRepMesh_FastDiscret::update( Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl; registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl); - TopAbs_Orientation orEdge = theEdge.Orientation(); Handle(Poly_PolygonOnTriangulation) P1, P2; if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace)) { @@ -908,19 +918,12 @@ void BRepMesh_FastDiscret::update( aNewNodInStruct(i) = aLastPointId; aNewNodes (i) = isv; aNewParams (i) = aParam; - - addLinkToMesh(ivf, iv2, orEdge); - ivf = iv2; } P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams); P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams); } - // last point - if (ivf != ivl) - addLinkToMesh(ivf, ivl, orEdge); - storePolygon(theEdge, P1, theDefEdge); storePolygonSharedData(theEdge, P2, theDefEdge); } @@ -935,9 +938,10 @@ void BRepMesh_FastDiscret::storePolygon( const Standard_Real theDeflection) { thePolygon->Deflection(theDeflection); - if (myInternalEdges->IsBound(theEdge)) + BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges(); + if (aInternalEdges->IsBound(theEdge)) { - BRepMesh_PairOfPolygon& aPair = myInternalEdges->ChangeFind(theEdge); + BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge); if (theEdge.Orientation() == TopAbs_REVERSED) aPair.Append(thePolygon); else @@ -948,7 +952,7 @@ void BRepMesh_FastDiscret::storePolygon( BRepMesh_PairOfPolygon aPair; aPair.Append(thePolygon); - myInternalEdges->Bind(theEdge, aPair); + aInternalEdges->Bind(theEdge, aPair); } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_FastDiscret.hxx b/src/BRepMesh/BRepMesh_FastDiscret.hxx index 66382cec8a..b1fe24d407 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.hxx @@ -317,12 +317,6 @@ private: const Standard_Real theEdgeDeflection, EdgeAttributes& theAttributes); - //! Adds new link to the mesh data structure. - //! Movability of the link and order of nodes depend on orientation parameter. - void addLinkToMesh(const Standard_Integer theFirstNodeId, - const Standard_Integer theLastNodeId, - const TopAbs_Orientation theOrientation); - //! Stores polygonal model of the given edge. //! @param theEdge edge which polygonal model is stored. //! @param thePolygon polygonal model of the edge. @@ -343,6 +337,9 @@ private: Handle(Poly_PolygonOnTriangulation)& thePolygon, const Standard_Real theDeflection); + //! Resets temporary data structure used to collect unique nodes. + void resetDataStructure(); + private: TopoDS_Face myFace; @@ -364,8 +361,6 @@ private: // Fast access to attributes of current face Handle(BRepMesh_FaceAttribute) myAttribute; - BRepMesh::HIMapOfInteger myVertexEdgeMap; - BRepMesh::HDMapOfShapePairOfPolygon myInternalEdges; TopTools_IndexedDataMapOfShapeListOfShape mySharedFaces; }; diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx index 9639740d23..5ec84b646b 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx @@ -146,7 +146,8 @@ BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace : myAngle(theAngle), myInternalVerticesMode(Standard_True) { - myAllocator = new NCollection_IncAllocator(64000); + myAllocator = new NCollection_IncAllocator( + BRepMesh::MEMORY_BLOCK_SIZE_HUGE); } //======================================================================= @@ -155,98 +156,145 @@ BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace //======================================================================= void BRepMesh_FastDiscretFace::Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute) { - Add(theAttribute); + add(theAttribute); commitSurfaceTriangulation(); } //======================================================================= -//function : Add +//function : initDataStructure //purpose : //======================================================================= -void BRepMesh_FastDiscretFace::Add(const Handle(BRepMesh_FaceAttribute)& theAttribute) +void BRepMesh_FastDiscretFace::initDataStructure() { - if (!theAttribute->IsValid()) - return; + const Standard_Real aTolU = myAttribute->ToleranceU(); + const Standard_Real aTolV = myAttribute->ToleranceV(); + const Standard_Real uCellSize = 14.0 * aTolU; + const Standard_Real vCellSize = 14.0 * aTolV; + + const Standard_Real deltaX = myAttribute->GetDeltaX(); + const Standard_Real deltaY = myAttribute->GetDeltaY(); - myAttribute = theAttribute; - myStructure = myAttribute->ChangeStructure(); - myVertexEdgeMap = myAttribute->ChangeVertexEdgeMap(); - myClassifier = myAttribute->ChangeClassifier(); - mySurfacePoints = myAttribute->ChangeSurfacePoints(); + myStructure = new BRepMesh_DataStructureOfDelaun(myAllocator); + myStructure->Data()->SetCellSize ( uCellSize / deltaX, vCellSize / deltaY); + myStructure->Data()->SetTolerance( aTolU / deltaX, aTolV / deltaY); - Standard_Real aTolU = myAttribute->ToleranceU(); - Standard_Real aTolV = myAttribute->ToleranceV(); - Standard_Real uCellSize = 14.0 * aTolU; - Standard_Real vCellSize = 14.0 * aTolV; + myAttribute->ChangeStructure() = myStructure; + myAttribute->ChangeSurfacePoints() = new BRepMesh::DMapOfIntegerPnt; + myAttribute->ChangeSurfaceVertices()= new BRepMesh::DMapOfVertexInteger; + // Check the necessity to fill the map of parameters const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); GeomAbs_SurfaceType thetype = gFace->GetType(); + const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus || + thetype == GeomAbs_BezierSurface || + thetype == GeomAbs_BSplineSurface); + myUParam.Clear(); + myVParam.Clear(); - Standard_Integer i = 1; + // essai de determination de la longueur vraie: + // akm (bug OCC16) : We must calculate these measures in non-singular + // parts of face. Let`s try to compute average value of three + // (umin, (umin+umax)/2, umax), and respectively for v. + // vvvvv + //Standard_Real longu = 0.0, longv = 0.0; //, last , first; + //gp_Pnt P11, P12, P21, P22, P31, P32; + BRepMesh::HVectorOfVertex& aBoundaryNodes = myAttribute->ChangeMeshNodes(); + BRepMesh::VectorOfVertex::Iterator aNodesIt(*aBoundaryNodes); + for (; aNodesIt.More(); aNodesIt.Next()) + { + BRepMesh_Vertex& aNode = aNodesIt.ChangeValue(); + gp_XY aPnt2d = aNode.Coord(); + + if (useUVParam) + { + myUParam.Add(aPnt2d.X()); + myVParam.Add(aPnt2d.Y()); + } + + aNode.ChangeCoord() = myAttribute->Scale(aPnt2d, Standard_True); + myStructure->AddNode(aNode, Standard_True); + } + aBoundaryNodes.Nullify(); //////////////////////////////////////////////////////////// //add internal vertices after self-intersection check - Standard_Integer nbVertices = 0; if ( myInternalVerticesMode ) { TopExp_Explorer anExplorer(myAttribute->Face(), TopAbs_VERTEX, TopAbs_EDGE); for ( ; anExplorer.More(); anExplorer.Next() ) add(TopoDS::Vertex(anExplorer.Current())); - nbVertices = myVertexEdgeMap->Extent(); } - // essai de determination de la longueur vraie: - // akm (bug OCC16) : We must calculate these measures in non-singular - // parts of face. Let`s try to compute average value of three - // (umin, (umin+umax)/2, umax), and respectively for v. - // vvvvv - //Standard_Real longu = 0.0, longv = 0.0; //, last , first; - //gp_Pnt P11, P12, P21, P22, P31, P32; - - const Standard_Real deltaX = myAttribute->GetDeltaX(); - const Standard_Real deltaY = myAttribute->GetDeltaY(); + const BRepMesh::HDMapOfShapePairOfPolygon& aEdges = myAttribute->ChangeInternalEdges(); + TopExp_Explorer aWireIt(myAttribute->Face(), TopAbs_WIRE); + for (; aWireIt.More(); aWireIt.Next()) + { + TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE); + for (; aEdgeIt.More(); aEdgeIt.Next()) + { + const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current()); + BRepMesh_PairOfPolygon aPair; + if (!aEdges->Find(aEdge, aPair)) + continue; - BRepMesh::Array1OfInteger tabvert_corr(1, nbVertices); + TopAbs_Orientation aOri = aEdge.Orientation(); + const Handle(Poly_PolygonOnTriangulation)& aPolygon = + aOri == TopAbs_REVERSED ? aPair.Last() : aPair.First(); - // Check the necessity to fill the map of parameters - const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus || - thetype == GeomAbs_BezierSurface || - thetype == GeomAbs_BSplineSurface); - myUParam.Clear(); - myVParam.Clear(); + const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes(); + const Standard_Integer aNodesNb = aPolygon->NbNodes(); - BRepMesh_VertexTool aMoveNodes(nbVertices, myAllocator); + Standard_Integer aPrevId = aIndices(1); + for (Standard_Integer i = 2; i <= aNodesNb; ++i) + { + const Standard_Integer aCurId = aIndices(i); + addLinkToMesh(aPrevId, aCurId, aOri); + aPrevId = aCurId; + } + } + } +} - aMoveNodes.SetCellSize ( uCellSize / deltaX, vCellSize / deltaY); - aMoveNodes.SetTolerance( aTolU / deltaX, aTolV / deltaY); +//======================================================================= +//function : addLinkToMesh +//purpose : +//======================================================================= +void BRepMesh_FastDiscretFace::addLinkToMesh( + const Standard_Integer theFirstNodeId, + const Standard_Integer theLastNodeId, + const TopAbs_Orientation theOrientation) +{ + if (theOrientation == TopAbs_FORWARD) + myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier)); + else if (theOrientation == TopAbs_REVERSED) + myStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier)); + else if (theOrientation == TopAbs_INTERNAL) + myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed)); +} - for ( i = 1; i <= myStructure->NbNodes(); ++i ) - { - const BRepMesh_Vertex& v = myStructure->GetNode(i); - gp_XY aPnt2d = v.Coord(); +//======================================================================= +//function : Add +//purpose : +//======================================================================= +void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttribute) +{ + if (!theAttribute->IsValid() || theAttribute->ChangeMeshNodes()->IsEmpty()) + return; - if (useUVParam) - { - myUParam.Add(aPnt2d.X()); - myVParam.Add(aPnt2d.Y()); - } + myAttribute = theAttribute; + initDataStructure(); - aPnt2d = myAttribute->Scale(aPnt2d, Standard_True); - BRepMesh_Vertex v_new(aPnt2d, v.Location3d(), v.Movability()); - const BRepMesh::ListOfInteger& alist = myStructure->LinksConnectedTo(i); - aMoveNodes.Add(v_new, alist); + BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap(); + Standard_Integer nbVertices = aVertexEdgeMap->Extent(); + BRepMesh::Array1OfInteger tabvert_corr(1, nbVertices); + for ( Standard_Integer i = 1; i <= nbVertices; ++i ) tabvert_corr(i) = i; - } - myStructure->ReplaceNodes(aMoveNodes); - - Standard_Boolean rajout = - (thetype == GeomAbs_Sphere || thetype == GeomAbs_Torus); BRepMesh_Delaun trigu(myStructure, tabvert_corr); //removed all free edges from triangulation const Standard_Integer nbLinks = myStructure->NbLinks(); - for( i = 1; i <= nbLinks; i++ ) + for( Standard_Integer i = 1; i <= nbLinks; i++ ) { if( myStructure->ElementsConnectedTo(i).Extent() < 1 ) { @@ -259,6 +307,17 @@ void BRepMesh_FastDiscretFace::Add(const Handle(BRepMesh_FaceAttribute)& theAttr } } + const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); + GeomAbs_SurfaceType thetype = gFace->GetType(); + + Standard_Boolean rajout = + (thetype == GeomAbs_Sphere || thetype == GeomAbs_Torus); + + // Check the necessity to fill the map of parameters + const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus || + thetype == GeomAbs_BezierSurface || + thetype == GeomAbs_BSplineSurface); + const Standard_Real umax = myAttribute->GetUMax(); const Standard_Real umin = myAttribute->GetUMin(); const Standard_Real vmax = myAttribute->GetVMax(); @@ -300,22 +359,17 @@ void BRepMesh_FastDiscretFace::Add(const Handle(BRepMesh_FaceAttribute)& theAttr } //modify myStructure back - aMoveNodes.SetCellSize ( uCellSize, vCellSize ); - aMoveNodes.SetTolerance( aTolU , aTolV ); - - for ( i = 1; i <= myStructure->NbNodes(); ++i ) + BRepMesh::HVectorOfVertex& aMeshNodes = myStructure->Data()->ChangeVertices(); + for ( Standard_Integer i = 1; i <= myStructure->NbNodes(); ++i ) { - const BRepMesh_Vertex& v = myStructure->GetNode(i); - gp_XY aPnt2d = myAttribute->Scale(v.Coord(), Standard_False); - BRepMesh_Vertex v_new(aPnt2d, v.Location3d(), v.Movability()); - const BRepMesh::ListOfInteger& alist = myStructure->LinksConnectedTo(i); - aMoveNodes.Add(v_new, alist); + BRepMesh_Vertex& aNode = aMeshNodes->ChangeValue(i - 1); + aNode.ChangeCoord() = myAttribute->Scale(aNode.Coord(), Standard_False); + const BRepMesh::ListOfInteger& alist = myStructure->LinksConnectedTo(i); // Register internal nodes used in triangulation - if (!alist.IsEmpty() && myVertexEdgeMap->FindIndex(i) == 0) - myVertexEdgeMap->Add(i); + if (!alist.IsEmpty() && aVertexEdgeMap->FindIndex(i) == 0) + aVertexEdgeMap->Add(i); } - myStructure->ReplaceNodes(aMoveNodes); if (!(aDef < 0.)) myAttribute->SetDefFace(aDef); @@ -778,6 +832,8 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline( else if (aSurfType == GeomAbs_BSplineSurface) aBSpline = gFace->BSpline(); + const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier(); + // precision for compare square distances const Standard_Real aPrecision = Precision::Confusion(); const Standard_Real aSqPrecision = aPrecision * aPrecision; @@ -864,7 +920,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline( aStPnt1.SetX(aPrevParam2); // Classify intersection point - if (myClassifier->Perform(aStPnt1) == TopAbs_IN) + if (aClassifier->Perform(aStPnt1) == TopAbs_IN) { insertVertex(aPrevPnt2, aStPnt1.Coord(), theNewVertices); } @@ -940,6 +996,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther( Adaptor3d_IsoCurve aIsoV; aIsoV.Load(gFace); + const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier(); const Standard_Integer aUPointsNb = aParams[0].Length(); const Standard_Integer aVPointsNb = aParams[1].Length(); for (Standard_Integer i = 2; i < aVPointsNb; ++i) @@ -952,7 +1009,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther( const Standard_Real aU = aParams[0].Value(j); const gp_Pnt2d aNewPoint(aU, aV); - if (myClassifier->Perform(aNewPoint) == TopAbs_IN) + if (aClassifier->Perform(aNewPoint) == TopAbs_IN) insertVertex(aIsoV.Value(aU), aNewPoint.Coord(), theNewVertices); } } @@ -1197,6 +1254,7 @@ void BRepMesh_FastDiscretFace::add(const TopoDS_Vertex& theVertex) theVertex, BRep_Tool::Tolerance(theVertex), myAttribute); Standard_Integer aTmpId1, aTmpId2; + anUV = myAttribute->Scale(anUV, Standard_True); myAttribute->AddNode(aIndex, anUV, BRepMesh_Fixed, aTmpId1, aTmpId2); } catch (Standard_Failure) @@ -1214,7 +1272,7 @@ void BRepMesh_FastDiscretFace::insertVertex( BRepMesh::ListOfVertex& theVertices) { Standard_Integer aNbLocat = myAttribute->LastPointId(); - mySurfacePoints->Bind(++aNbLocat, thePnt3d); + myAttribute->ChangeSurfacePoints()->Bind(++aNbLocat, thePnt3d); gp_XY aPnt2d = myAttribute->Scale(theUV, Standard_True); BRepMesh_Vertex aVertex(aPnt2d, aNbLocat, BRepMesh_Free); @@ -1230,14 +1288,17 @@ void BRepMesh_FastDiscretFace::commitSurfaceTriangulation() if (myAttribute.IsNull() || !myAttribute->IsValid()) return; - TopoDS_Face aFace = myAttribute->Face(); + const TopoDS_Face& aFace = myAttribute->Face(); BRepMesh_ShapeTool::NullifyFace(aFace); Handle(BRepMesh_DataStructureOfDelaun)& aStructure = myAttribute->ChangeStructure(); const BRepMesh::MapOfInteger& aTriangles = aStructure->ElementsOfDomain(); if (aTriangles.IsEmpty()) + { + myAttribute->SetStatus(BRepMesh_Failure); return; + } BRepMesh::HIMapOfInteger& aVetrexEdgeMap = myAttribute->ChangeVertexEdgeMap(); @@ -1283,6 +1344,11 @@ void BRepMesh_FastDiscretFace::commitSurfaceTriangulation() BRepMesh_ShapeTool::AddInFace(aFace, aNewTriangulation); // Delete unused data - myStructure.Nullify(); - myAttribute->Clear(Standard_True); + myAttribute->ChangeStructure().Nullify(); + myAttribute->ChangeSurfacePoints().Nullify(); + myAttribute->ChangeSurfaceVertices().Nullify(); + + myAttribute->ChangeClassifier().Nullify(); + myAttribute->ChangeLocation2D().Nullify(); + myAttribute->ChangeVertexEdgeMap().Nullify(); } diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx index 37dee2a02f..6f469b83b1 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx @@ -53,13 +53,13 @@ public: Standard_EXPORT BRepMesh_FastDiscretFace( const Standard_Real theAngle); - Standard_EXPORT void Add(const Handle(BRepMesh_FaceAttribute)& theAttribute); Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute); DEFINE_STANDARD_RTTI(BRepMesh_FastDiscretFace) private: + void add(const Handle(BRepMesh_FaceAttribute)& theAttribute); void add(const TopoDS_Vertex& theVertex); Standard_Real control(BRepMesh::ListOfVertex& theNewVertices, @@ -118,7 +118,8 @@ private: const AnalyticSurface& theAnalyticSurface, BRepMesh::ListOfVertex& theVertices) { - if (myClassifier->Perform(thePnt2d) != TopAbs_IN) + const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier(); + if (aClassifier->Perform(thePnt2d) != TopAbs_IN) return; gp_Pnt aPnt; @@ -137,20 +138,26 @@ private: //! Stores mesh into the face (without internal edges). void commitSurfaceTriangulation(); + //! Performs initialization of data structure using existing data. + void initDataStructure(); + + //! Adds new link to the mesh data structure. + //! Movability of the link and order of nodes depend on orientation parameter. + void addLinkToMesh(const Standard_Integer theFirstNodeId, + const Standard_Integer theLastNodeId, + const TopAbs_Orientation theOrientation); + private: Standard_Real myAngle; Standard_Boolean myInternalVerticesMode; BRepMesh::IMapOfReal myUParam; BRepMesh::IMapOfReal myVParam; - Handle(NCollection_IncAllocator) myAllocator; // Fast access to attributes of current face + Handle(NCollection_IncAllocator) myAllocator; Handle(BRepMesh_FaceAttribute) myAttribute; Handle(BRepMesh_DataStructureOfDelaun) myStructure; - BRepMesh::HIMapOfInteger myVertexEdgeMap; - BRepMesh::HClassifier myClassifier; - BRepMesh::HDMapOfIntegerPnt mySurfacePoints; }; DEFINE_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient) diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx index f7473da41a..7460b1cf95 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx @@ -106,6 +106,18 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh() { } +//======================================================================= +//function : clear +//purpose : +//======================================================================= +void BRepMesh_IncrementalMesh::clear() +{ + myEmptyEdges.Clear(); + myEdgeDeflection.Clear(); + myFaces.Clear(); + myMesh.Nullify(); +} + //======================================================================= //function : init //purpose : @@ -115,10 +127,8 @@ void BRepMesh_IncrementalMesh::init() myStatus = 0; myModified = Standard_False; - myEdgeDeflection.Clear(); - myFaces.clear(); - setDone(); + clear(); if (!isCorrectPolyData()) BRepTools::Clean(myShape); @@ -129,7 +139,6 @@ void BRepMesh_IncrementalMesh::init() if (aBox.IsVoid()) { // Nothing to mesh. - myMesh.Nullify(); return; } @@ -160,9 +169,9 @@ Standard_Boolean BRepMesh_IncrementalMesh::isCorrectPolyData() else { #endif - std::vector::iterator aFaceIt = myFaces.begin(); - for (; aFaceIt != myFaces.end(); aFaceIt++) - aFaceChecker(*aFaceIt); + NCollection_Vector::Iterator aFaceIt(myFaces); + for (; aFaceIt.More(); aFaceIt.Next()) + aFaceChecker(aFaceIt.Value()); #ifdef HAVE_TBB } #endif @@ -179,7 +188,6 @@ void BRepMesh_IncrementalMesh::collectFaces() TopTools_ListOfShape aFaceList; BRepLib::ReverseSortFaces(myShape, aFaceList); TopTools_MapOfShape aFaceMap; - myFaces.reserve(aFaceList.Extent()); // make array of faces suitable for processing (excluding faces without surface) TopLoc_Location aDummyLoc; @@ -197,7 +205,7 @@ void BRepMesh_IncrementalMesh::collectFaces() if (aSurf.IsNull()) continue; - myFaces.push_back(aFace); + myFaces.Append(aFace); } } @@ -233,9 +241,9 @@ void BRepMesh_IncrementalMesh::update() } // Update faces data - std::vector::iterator aFaceIt(myFaces.begin()); - for (; aFaceIt != myFaces.end(); aFaceIt++) - update(*aFaceIt); + NCollection_Vector::Iterator aFaceIt(myFaces); + for (; aFaceIt.More(); aFaceIt.Next()) + update(aFaceIt.Value()); // Mesh faces #ifdef HAVE_TBB @@ -246,13 +254,14 @@ void BRepMesh_IncrementalMesh::update() else { #endif - for (aFaceIt = myFaces.begin(); aFaceIt != myFaces.end(); aFaceIt++) - myMesh->Process(*aFaceIt); + for (aFaceIt.Init(myFaces); aFaceIt.More(); aFaceIt.Next()) + myMesh->Process(aFaceIt.Value()); #ifdef HAVE_TBB } #endif commit(); + clear(); } //======================================================================= @@ -479,9 +488,9 @@ void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace) //======================================================================= void BRepMesh_IncrementalMesh::commit() { - std::vector::iterator aFaceIt(myFaces.begin()); - for (; aFaceIt != myFaces.end(); aFaceIt++) - commitEdges(*aFaceIt); + NCollection_Vector::Iterator aFaceIt(myFaces); + for (; aFaceIt.More(); aFaceIt.Next()) + commitEdges(aFaceIt.Value()); discretizeFreeEdges(); } @@ -509,10 +518,7 @@ void BRepMesh_IncrementalMesh::commitEdges(const TopoDS_Face& theFace) Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc); if (aTriangulation.IsNull()) - { - aFaceAttribute->Clear(); return; - } try { @@ -533,8 +539,6 @@ void BRepMesh_IncrementalMesh::commitEdges(const TopoDS_Face& theFace) else BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aPolygon2, aTriangulation, aLoc); } - - aFaceAttribute->Clear(); } catch (Standard_Failure) { diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.hxx b/src/BRepMesh/BRepMesh_IncrementalMesh.hxx index bc1bed4492..dc0f3c1e26 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.hxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.hxx @@ -124,12 +124,6 @@ public: //! @name plugin API //! Discret() static method (thus applied only to Mesh Factories). Standard_EXPORT static void SetParallelDefault(const Standard_Boolean isInParallel); - //! Returns mesh tool storing mesh data. - inline const Handle(BRepMesh_FastDiscret)& Mesh() const - { - return myMesh; - } - DEFINE_STANDARD_RTTI(BRepMesh_IncrementalMesh) protected: @@ -191,6 +185,9 @@ private: //! Stores mesh of internal edges to the face. void commitEdges(const TopoDS_Face& theFace); + + //! Clears internal data structures. + void clear(); protected: @@ -202,7 +199,7 @@ protected: TopTools_DataMapOfShapeReal myEdgeDeflection; Standard_Real myMaxShapeSize; Standard_Integer myStatus; - std::vector myFaces; + NCollection_Vector myFaces; }; DEFINE_STANDARD_HANDLE(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot) diff --git a/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.cxx b/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.cxx index c434e6c799..03217709ea 100644 --- a/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.cxx +++ b/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.cxx @@ -22,10 +22,11 @@ //purpose : //======================================================================= BRepMesh_SelectorOfDataStructureOfDelaun::BRepMesh_SelectorOfDataStructureOfDelaun() -: myNodes (10, new NCollection_IncAllocator), - myLinks (10, new NCollection_IncAllocator), - myElements(10, new NCollection_IncAllocator), - myFrontier(10, new NCollection_IncAllocator) +: myAllocator(new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE)), + myNodes (10, myAllocator), + myLinks (10, myAllocator), + myElements(10, myAllocator), + myFrontier(10, myAllocator) { } @@ -35,11 +36,12 @@ BRepMesh_SelectorOfDataStructureOfDelaun::BRepMesh_SelectorOfDataStructureOfDela //======================================================================= BRepMesh_SelectorOfDataStructureOfDelaun::BRepMesh_SelectorOfDataStructureOfDelaun( const Handle(BRepMesh_DataStructureOfDelaun)& theMesh) -: myMesh (theMesh), - myNodes (10, myMesh->Allocator()), - myLinks (10, myMesh->Allocator()), - myElements(10, myMesh->Allocator()), - myFrontier(10, myMesh->Allocator()) +: myAllocator(new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE)), + myMesh (theMesh), + myNodes (10, myAllocator), + myLinks (10, myAllocator), + myElements(10, myAllocator), + myFrontier(10, myAllocator) { } diff --git a/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.hxx b/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.hxx index 718869293a..65847ad557 100644 --- a/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.hxx +++ b/src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.hxx @@ -104,6 +104,7 @@ private: void elementsOfLink(const Standard_Integer theIndex); private: + Handle(NCollection_IncAllocator) myAllocator; Handle(BRepMesh_DataStructureOfDelaun) myMesh; BRepMesh::MapOfInteger myNodes; BRepMesh::MapOfInteger myLinks; diff --git a/src/BRepMesh/BRepMesh_ShapeTool.cxx b/src/BRepMesh/BRepMesh_ShapeTool.cxx index d5573aa083..9ac6957464 100644 --- a/src/BRepMesh/BRepMesh_ShapeTool.cxx +++ b/src/BRepMesh/BRepMesh_ShapeTool.cxx @@ -135,18 +135,18 @@ gp_XY BRepMesh_ShapeTool::FindUV( const Handle(BRepMesh_FaceAttribute)& theFaceAttribute) { const gp_XY& aPnt2d = thePnt2d.Coord(); - BRepMesh::DMapOfIntegerListOfXY& aLocation2D = + BRepMesh::HDMapOfIntegerListOfXY& aLocation2D = theFaceAttribute->ChangeLocation2D(); - if (!aLocation2D.IsBound(theIndexOfPnt3d)) + if (!aLocation2D->IsBound(theIndexOfPnt3d)) { BRepMesh::ListOfXY aPoints2d; aPoints2d.Append(aPnt2d); - aLocation2D.Bind(theIndexOfPnt3d, aPoints2d); + aLocation2D->Bind(theIndexOfPnt3d, aPoints2d); return aPnt2d; } - BRepMesh::ListOfXY& aPoints2d = aLocation2D.ChangeFind(theIndexOfPnt3d); + BRepMesh::ListOfXY& aPoints2d = aLocation2D->ChangeFind(theIndexOfPnt3d); // Find the most closest 2d point to the given one. gp_XY aUV; diff --git a/src/BRepMesh/BRepMesh_Vertex.hxx b/src/BRepMesh/BRepMesh_Vertex.hxx index afb2aa48a8..a04b779042 100644 --- a/src/BRepMesh/BRepMesh_Vertex.hxx +++ b/src/BRepMesh/BRepMesh_Vertex.hxx @@ -78,6 +78,12 @@ public: { return myUV; } + + //! Returns position of the vertex in parametric space for modification. + inline gp_XY& ChangeCoord() + { + return myUV; + } //! Returns index of 3d point associated with the vertex. inline Standard_Integer Location3d() const diff --git a/src/BRepMesh/BRepMesh_VertexInspector.hxx b/src/BRepMesh/BRepMesh_VertexInspector.hxx index 899458d3b0..0d92db1107 100644 --- a/src/BRepMesh/BRepMesh_VertexInspector.hxx +++ b/src/BRepMesh/BRepMesh_VertexInspector.hxx @@ -36,7 +36,7 @@ public: const Standard_Integer theReservedSize, const Handle(NCollection_IncAllocator)& theAllocator) : myResIndices(theAllocator), - myVertices (theReservedSize), + myVertices (new BRepMesh::VectorOfVertex(theReservedSize)), myDelNodes (theAllocator) { SetTolerance( Precision::Confusion() ); @@ -48,12 +48,12 @@ public: { if( myDelNodes.IsEmpty() ) { - myVertices.Append(theVertex); - return myVertices.Length(); + myVertices->Append(theVertex); + return myVertices->Length(); } Standard_Integer aNodeIndex = myDelNodes.First(); - myVertices(aNodeIndex - 1) = theVertex; + myVertices->ChangeValue(aNodeIndex - 1) = theVertex; myDelNodes.RemoveFirst(); return aNodeIndex; } @@ -81,7 +81,7 @@ public: //! Clear inspector's internal data structures. inline void Clear() { - myVertices.Clear(); + myVertices->Clear(); myDelNodes.Clear(); } @@ -89,20 +89,20 @@ public: //! @param theIndex index of vertex to be removed. inline void Delete(const Standard_Integer theIndex) { - myVertices(theIndex - 1).SetMovability(BRepMesh_Deleted); + myVertices->ChangeValue(theIndex - 1).SetMovability(BRepMesh_Deleted); myDelNodes.Append(theIndex); } //! Returns number of registered vertices. inline Standard_Integer NbVertices() const { - return myVertices.Length(); + return myVertices->Length(); } //! Returns vertex with the given index. inline BRepMesh_Vertex& GetVertex(Standard_Integer theIndex) { - return myVertices(theIndex - 1); + return myVertices->ChangeValue(theIndex - 1); } //! Set reference point to be checked. @@ -129,6 +129,18 @@ public: return myDelNodes; } + //! Returns set of mesh vertices. + inline const BRepMesh::HVectorOfVertex& Vertices() const + { + return myVertices; + } + + //! Returns set of mesh vertices for modification. + inline BRepMesh::HVectorOfVertex& ChangeVertices() + { + return myVertices; + } + //! Performs inspection of a point with the given index. //! @param theTargetIndex index of a circle to be checked. //! @return status of the check. @@ -143,11 +155,11 @@ public: private: - Standard_Real myTolerance[2]; - BRepMesh::ListOfInteger myResIndices; - BRepMesh::VectorOfVertex myVertices; - BRepMesh::ListOfInteger myDelNodes; - gp_XY myPoint; + Standard_Real myTolerance[2]; + BRepMesh::ListOfInteger myResIndices; + BRepMesh::HVectorOfVertex myVertices; + BRepMesh::ListOfInteger myDelNodes; + gp_XY myPoint; }; #endif diff --git a/src/BRepMesh/BRepMesh_VertexTool.cxx b/src/BRepMesh/BRepMesh_VertexTool.cxx index c5238f7f82..dfdff4bd09 100644 --- a/src/BRepMesh/BRepMesh_VertexTool.cxx +++ b/src/BRepMesh/BRepMesh_VertexTool.cxx @@ -27,7 +27,7 @@ NCollection_CellFilter_Action BRepMesh_VertexInspector::Inspect( const Standard_Integer theTarget) { - const BRepMesh_Vertex& aVertex = myVertices(theTarget - 1); + const BRepMesh_Vertex& aVertex = myVertices->Value(theTarget - 1); if(aVertex.Movability() == BRepMesh_Deleted) { myDelNodes.Append(theTarget); @@ -71,32 +71,19 @@ BRepMesh_VertexTool::BRepMesh_VertexTool( //function : Add //purpose : //======================================================================= -Standard_Integer BRepMesh_VertexTool::Add(const BRepMesh_Vertex& theVertex) +Standard_Integer BRepMesh_VertexTool::Add( + const BRepMesh_Vertex& theVertex, + const Standard_Boolean isForceAdd) { - Standard_Integer aIndex = FindIndex(theVertex); + Standard_Integer aIndex = isForceAdd ? 0 : FindIndex(theVertex); if (aIndex == 0) { - BRepMesh::ListOfInteger aParams(myAllocator); - aIndex = Add(theVertex, aParams); - } - return aIndex; -} - -//======================================================================= -//function : Add -//purpose : -//======================================================================= -Standard_Integer BRepMesh_VertexTool::Add( - const BRepMesh_Vertex& theVertex, - const BRepMesh::ListOfInteger& theParams) -{ - Standard_Integer aIndex = mySelector.Add(theVertex); - myLinksMap.Bind(aIndex, theParams); - - gp_XY aMinPnt, aMaxPnt; - expandPoint(theVertex.Coord(), aMinPnt, aMaxPnt); - myCellFilter.Add(aIndex, aMinPnt, aMaxPnt); + aIndex = mySelector.Add(theVertex); + gp_XY aMinPnt, aMaxPnt; + expandPoint(theVertex.Coord(), aMinPnt, aMaxPnt); + myCellFilter.Add(aIndex, aMinPnt, aMaxPnt); + } return aIndex; } @@ -120,9 +107,8 @@ void BRepMesh_VertexTool::Delete(const Standard_Integer theIndex) //purpose : //======================================================================= void BRepMesh_VertexTool::Substitute( - const Standard_Integer theIndex, - const BRepMesh_Vertex& theVertex, - const BRepMesh::ListOfInteger& theData) + const Standard_Integer theIndex, + const BRepMesh_Vertex& theVertex) { BRepMesh_Vertex& aV = mySelector.GetVertex(theIndex); @@ -134,7 +120,6 @@ void BRepMesh_VertexTool::Substitute( aV = theVertex; expandPoint(aV.Coord(), aMinPnt, aMaxPnt); myCellFilter.Add(theIndex, aMinPnt, aMaxPnt); - FindFromIndex(theIndex) = theData; } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_VertexTool.hxx b/src/BRepMesh/BRepMesh_VertexTool.hxx index b49a36dadb..3fe895b3c8 100644 --- a/src/BRepMesh/BRepMesh_VertexTool.hxx +++ b/src/BRepMesh/BRepMesh_VertexTool.hxx @@ -81,29 +81,27 @@ public: } //! Adds vertex with empty data to the tool. - Standard_EXPORT Standard_Integer Add(const BRepMesh_Vertex& theVertex); - - //! Adds vertex with associated data to the tool. - //! @param theVertex vertex to be added. - //! @param theParams data associated with the vertex. - Standard_EXPORT Standard_Integer Add(const BRepMesh_Vertex& theVertex, - const BRepMesh::ListOfInteger& theParams); + //! @param theVertex node to be added to the mesh. + //! @param isForceAdd adds the given node to structure without + //! checking on coincidence with other nodes. + //! @return index of the node in the structure. + Standard_EXPORT Standard_Integer Add( + const BRepMesh_Vertex& theVertex, + const Standard_Boolean isForceAdd); //! Deletes vertex with the given index from the tool. Standard_EXPORT void Delete(const Standard_Integer theIndex); - //! Returns data assigned to link with the given index. - //! @param theIndex index of link which data should be returned. - //! @return attached data. - inline BRepMesh::ListOfInteger& FindFromIndex(const Standard_Integer theIndex) const + //! Returns set of mesh vertices. + inline const BRepMesh::HVectorOfVertex& Vertices() const { - return (BRepMesh::ListOfInteger&)myLinksMap.Find(theIndex); + return mySelector.Vertices(); } - //! Alias for FindFromIndex. - BRepMesh::ListOfInteger& operator()(const Standard_Integer theIndex) const + //! Returns set of mesh vertices. + inline BRepMesh::HVectorOfVertex& ChangeVertices() { - return FindFromIndex(theIndex); + return mySelector.ChangeVertices(); } //! Returns vertex by the given index. @@ -135,10 +133,8 @@ public: //! Substitutes vertex with the given by the given vertex with attributes. //! @param theIndex index of vertex to be substituted. //! @param theVertex replacement vertex. - //! @param theData data associated to the vertex. - Standard_EXPORT void Substitute(const Standard_Integer theIndex, - const BRepMesh_Vertex& theVertex, - const BRepMesh::ListOfInteger& theData); + Standard_EXPORT void Substitute(const Standard_Integer theIndex, + const BRepMesh_Vertex& theVertex); //! Remove last node from the structure. inline void RemoveLast() @@ -177,7 +173,6 @@ private: Handle(NCollection_IncAllocator) myAllocator; BRepMesh::VertexCellFilter myCellFilter; BRepMesh_VertexInspector mySelector; - BRepMesh::DMapOfIntegerListOfInteger myLinksMap; Standard_Real myTolerance[2]; }; diff --git a/src/MeshTest/MeshTest_DrawableMesh.cxx b/src/MeshTest/MeshTest_DrawableMesh.cxx index c238141d3b..f97e3ab790 100644 --- a/src/MeshTest/MeshTest_DrawableMesh.cxx +++ b/src/MeshTest/MeshTest_DrawableMesh.cxx @@ -233,10 +233,9 @@ void MeshTest_DrawableMesh::Dump(Standard_OStream&) const //======================================================================= void MeshTest_DrawableMesh::Whatis(Draw_Interpretor& theStream) const { - const TopoDS_Shape& aShape = myMesher->Shape(); - const Handle(BRepMesh_FastDiscret)& aMesh = myMesher->Mesh(); + const TopoDS_Shape& aShape = myMesher->Shape(); - Standard_Integer aPointsNb = aMesh->NbBoundaryPoints(); + Standard_Integer aPointsNb = 0; Standard_Integer aTrianglesNb = 0; Standard_Integer aEdgesNb = 0; diff --git a/tests/bugs/mesh/bug25364 b/tests/bugs/mesh/bug25364 new file mode 100755 index 0000000000..0092759d82 --- /dev/null +++ b/tests/bugs/mesh/bug25364 @@ -0,0 +1,97 @@ +puts "============" +puts "CR25364" +puts "============" +puts "" +################################################################################### +# BRepMesh is not able to triangulate the shape with fine deflection +################################################################################### + +restore [locate_data_file bug25364_WT_Grundplatte.brep] result + +set mem_private_1 [meminfo private] +set mem_swap_1 [meminfo swap] +set mem_swappeak_1 [meminfo swappeak] +set mem_wset_1 [meminfo wset] +set mem_wsetpeak_1 [meminfo wsetpeak] +set mem_virt_1 [meminfo virt] +set mem_heap_1 [meminfo heap] + +incmesh result 0.002 + +set mem_private_2 [meminfo private] +set mem_swap_2 [meminfo swap] +set mem_swappeak_2 [meminfo swappeak] +set mem_wset_2 [meminfo wset] +set mem_wsetpeak_2 [meminfo wsetpeak] +set mem_virt_2 [meminfo virt] +set mem_heap_2 [meminfo heap] + +if [catch { tricheck result } ] { + puts "Error : Problem of triangulation" +} else { + puts "OK : Triangulation is good" +} + +set mem_private_1 [expr ${mem_private_1}/(1024 * 1024)] +set mem_swap_1 [expr ${mem_swap_1}/(1024 * 1024)] +set mem_swappeak_1 [expr ${mem_swappeak_1}/(1024 * 1024)] +set mem_wset_1 [expr ${mem_wset_1}/(1024 * 1024)] +set mem_wsetpeak_1 [expr ${mem_wsetpeak_1}/(1024 * 1024)] +set mem_virt_1 [expr ${mem_virt_1}/(1024 * 1024)] +set mem_heap_1 [expr ${mem_heap_1}/(1024 * 1024)] + +puts "mem_private_1=${mem_private_1}" +puts "mem_swap_1=${mem_swap_1}" +puts "mem_swappeak_1=${mem_swappeak_1}" +puts "mem_wset_1=${mem_wset_1}" +puts "mem_wsetpeak_1=${mem_wsetpeak_1}" +puts "mem_virt_1=${mem_virt_1}" +puts "mem_heap_1=${mem_heap_1}" + +set mem_private_2 [expr ${mem_private_2}/(1024 * 1024)] +set mem_swap_2 [expr ${mem_swap_2}/(1024 * 1024)] +set mem_swappeak_2 [expr ${mem_swappeak_2}/(1024 * 1024)] +set mem_wset_2 [expr ${mem_wset_2}/(1024 * 1024)] +set mem_wsetpeak_2 [expr ${mem_wsetpeak_2}/(1024 * 1024)] +set mem_virt_2 [expr ${mem_virt_2}/(1024 * 1024)] +set mem_heap_2 [expr ${mem_heap_2}/(1024 * 1024)] + +puts "mem_private_2=${mem_private_2}" +puts "mem_swap_2=${mem_swap_2}" +puts "mem_swappeak_2=${mem_swappeak_2}" +puts "mem_wset_2=${mem_wset_2}" +puts "mem_wsetpeak_2=${mem_wsetpeak_2}" +puts "mem_virt_2=${mem_virt_2}" +puts "mem_heap_2=${mem_heap_2}" + +set mem_delta_private 180 +set mem_delta_swap 100 +set mem_delta_swappeak 150 +set mem_delta_wset 180 +set mem_delta_wsetpeak 180 +set mem_delta_virt 180 +set mem_delta_heap 80 + +if { [expr ${mem_private_2} - ${mem_private_1}] > ${mem_delta_private}} { + puts "Error : there is memory problem (private)" +} +if { [expr ${mem_swap_2} - ${mem_swap_1}] > ${mem_delta_swap}} { + puts "Error : there is memory problem (swap)" +} +if { [expr ${mem_swappeak_2} - ${mem_swappeak_1}] > ${mem_delta_swappeak}} { + puts "Error : there is memory problem (swappeak)" +} +if { [expr ${mem_wset_2} - ${mem_wset_1}] > ${mem_delta_wset}} { + puts "Error : there is memory problem (wset)" +} +if { [expr ${mem_wsetpeak_2} - ${mem_wsetpeak_1}] > ${mem_delta_wsetpeak}} { + puts "Error : there is memory problem (wsetpeak)" +} +if { [expr ${mem_virt_2} - ${mem_virt_1}] > ${mem_delta_virt}} { + puts "Error : there is memory problem (virt)" +} +if { [expr ${mem_heap_2} - ${mem_heap_1}] > ${mem_delta_heap}} { + puts "Error : there is memory problem (heap)" +} + +set 3dviewer 1 diff --git a/tests/mesh/data/standard/E9 b/tests/mesh/data/standard/E9 index 2fb6436508..dc7eeaa6b0 100755 --- a/tests/mesh/data/standard/E9 +++ b/tests/mesh/data/standard/E9 @@ -1,8 +1 @@ set TheFileName shading_045.brep -set bug_freenodes "OCC23106" -set nbfreenodes(All) 3 -if { [string compare $command "shading"] == 0 && [string compare $group "standard"] == 0} { - set nbfreenodes(All) 7 - set bug_freelinks "OCC23106" - set nbfree(All) 2 -} -- 2.20.1