From de1fcc2018d18b4c56d459a4b8b9e0682aaf109d Mon Sep 17 00:00:00 2001 From: Dmitrii Kulikov <164657232+AtheneNoctuaPt@users.noreply.github.com> Date: Thu, 16 Oct 2025 18:46:10 +0100 Subject: [PATCH] Mesh - Import of STEP file crashes at the very end when visualizing the boundary curves (#745) When an edge (BRepMeshData_Edge) has multiple PCurve curves (IMeshData_PCurve) with different orientations, the index array is filled for only one PCurve curve. This would cause problems later, so a fix was made to fill index arrays for curves with another orientation. --- .../TKMesh/BRepMesh/BRepMesh_BaseMeshAlgo.cxx | 55 ++++++++++--------- .../TKMesh/BRepMeshData/BRepMeshData_Edge.cxx | 8 +++ .../TKMesh/BRepMeshData/BRepMeshData_Edge.hxx | 4 ++ .../TKMesh/IMeshData/IMeshData_Edge.hxx | 4 ++ tests/hlr/poly_hlr/bug25813_2 | 4 +- tests/hlr/poly_hlr/bug25813_3 | 4 +- tests/hlr/poly_hlr/bug25813_4 | 2 +- 7 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_BaseMeshAlgo.cxx b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_BaseMeshAlgo.cxx index acc102de0f..930a6239ff 100644 --- a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_BaseMeshAlgo.cxx +++ b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_BaseMeshAlgo.cxx @@ -86,39 +86,42 @@ Standard_Boolean BRepMesh_BaseMeshAlgo::initDataStructure() for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt) { - const IMeshData::IEdgeHandle aDEdge = aDWire->GetEdge(aEdgeIt); - const IMeshData::ICurveHandle& aCurve = aDEdge->GetCurve(); - const IMeshData::IPCurveHandle& aPCurve = - aDEdge->GetPCurve(myDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt)); + const IMeshData::IEdgeHandle aDEdge = aDWire->GetEdge(aEdgeIt); + const IMeshData::ICurveHandle& aCurve = aDEdge->GetCurve(); + const IMeshData::ListOfInteger& aListOfPCurves = aDEdge->GetPCurves(myDFace.get()); - const TopAbs_Orientation aOri = fixSeamEdgeOrientation(aDEdge, aPCurve); - - Standard_Integer aPrevNodeIndex = -1; - const Standard_Integer aLastPoint = aPCurve->ParametersNb() - 1; - for (Standard_Integer aPointIt = 0; aPointIt <= aLastPoint; ++aPointIt) + for (IMeshData::ListOfInteger::Iterator aPCurveIt(aListOfPCurves); aPCurveIt.More(); + aPCurveIt.Next()) { - const Standard_Integer aNodeIndex = - registerNode(aCurve->GetPoint(aPointIt), - aPCurve->GetPoint(aPointIt), - BRepMesh_Frontier, - Standard_False /*aPointIt > 0 && aPointIt < aLastPoint*/); - - aPCurve->GetIndex(aPointIt) = aNodeIndex; - myUsedNodes->Bind(aNodeIndex, aNodeIndex); + const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(aPCurveIt.Value()); + const TopAbs_Orientation aOri = fixSeamEdgeOrientation(aDEdge, aPCurve); - if (aPrevNodeIndex != -1 && aPrevNodeIndex != aNodeIndex) + Standard_Integer aPrevNodeIndex = -1; + const Standard_Integer aLastPoint = aPCurve->ParametersNb() - 1; + for (Standard_Integer aPointIndex = 0; aPointIndex <= aLastPoint; ++aPointIndex) { - const Standard_Integer aLinksNb = myStructure->NbLinks(); - const Standard_Integer aLinkIndex = addLinkToMesh(aPrevNodeIndex, aNodeIndex, aOri); - if (aWireIt != 0 && aLinkIndex <= aLinksNb) + const Standard_Integer aNodeIndex = registerNode(aCurve->GetPoint(aPointIndex), + aPCurve->GetPoint(aPointIndex), + BRepMesh_Frontier, + Standard_False); + + aPCurve->GetIndex(aPointIndex) = aNodeIndex; + myUsedNodes->Bind(aNodeIndex, aNodeIndex); + + if (aPrevNodeIndex != -1 && aPrevNodeIndex != aNodeIndex) { - // Prevent holes around wire of zero area. - BRepMesh_Edge& aLink = const_cast(myStructure->GetLink(aLinkIndex)); - aLink.SetMovability(BRepMesh_Fixed); + const Standard_Integer aLinksNb = myStructure->NbLinks(); + const Standard_Integer aLinkIndex = addLinkToMesh(aPrevNodeIndex, aNodeIndex, aOri); + if (aWireIt != 0 && aLinkIndex <= aLinksNb) + { + // Prevent holes around wire of zero area. + BRepMesh_Edge& aLink = const_cast(myStructure->GetLink(aLinkIndex)); + aLink.SetMovability(BRepMesh_Fixed); + } } - } - aPrevNodeIndex = aNodeIndex; + aPrevNodeIndex = aNodeIndex; + } } } } diff --git a/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.cxx b/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.cxx index 2096f4b328..90e8ab23dc 100644 --- a/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.cxx +++ b/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.cxx @@ -84,3 +84,11 @@ const IMeshData::IPCurveHandle& BRepMeshData_Edge::GetPCurve(const Standard_Inte { return myPCurves(theIndex); } + +//================================================================================================== + +const IMeshData::ListOfInteger& BRepMeshData_Edge::GetPCurves( + const IMeshData::IFacePtr& theDFace) const +{ + return myPCurvesMap.Find(theDFace); +} diff --git a/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.hxx b/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.hxx index 82c1ebb71d..00528ab74e 100644 --- a/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.hxx +++ b/src/ModelingAlgorithms/TKMesh/BRepMeshData/BRepMeshData_Edge.hxx @@ -50,6 +50,10 @@ public: Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve( const Standard_Integer theIndex) const Standard_OVERRIDE; + //! Returns an array of pcurves indices for the specified discrete face. + Standard_EXPORT virtual const IMeshData::ListOfInteger& GetPCurves( + const IMeshData::IFacePtr& theDFace) const Standard_OVERRIDE; + DEFINE_STANDARD_RTTIEXT(BRepMeshData_Edge, IMeshData_Edge) private: diff --git a/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Edge.hxx b/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Edge.hxx index d349a29ecf..876602c848 100644 --- a/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Edge.hxx +++ b/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Edge.hxx @@ -49,6 +49,10 @@ public: Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve( const Standard_Integer theIndex) const = 0; + //! Returns an array of pcurves indices for the specified discrete face. + Standard_EXPORT virtual const IMeshData::ListOfInteger& GetPCurves( + const IMeshData::IFacePtr& theDFace) const = 0; + //! Clears curve and all pcurves assigned to the edge from discretization. void Clear(const Standard_Boolean isKeepEndPoints) { diff --git a/tests/hlr/poly_hlr/bug25813_2 b/tests/hlr/poly_hlr/bug25813_2 index 38478c883b..0c6d438e3e 100644 --- a/tests/hlr/poly_hlr/bug25813_2 +++ b/tests/hlr/poly_hlr/bug25813_2 @@ -1,4 +1,4 @@ -puts "TODO OCC30286 Linux: Error : The length of result shape is 3025.48, expected 3025.49" +puts "TODO OCC30286 Linux: Error : The length of result shape is 3025.32, expected 3025.36" puts "===========================================" puts "OCC25813: regression in Hidden Line Removal" @@ -6,7 +6,7 @@ puts "===========================================" puts "" set viewname "" -set length 3025.49 +set length 3025.36 restore [locate_data_file bug25813_hlr-bus1-draw-Fusion001.brep] a COMPUTE_HLR $viewname $algotype diff --git a/tests/hlr/poly_hlr/bug25813_3 b/tests/hlr/poly_hlr/bug25813_3 index 9cddd23203..ef2a510b8c 100644 --- a/tests/hlr/poly_hlr/bug25813_3 +++ b/tests/hlr/poly_hlr/bug25813_3 @@ -1,4 +1,4 @@ -puts "TODO OCC30286 Linux: Error : The length of result shape is 302.443, expected 301.999" +puts "TODO OCC30286 Linux: Error : The length of result shape is 302.183, expected 302.238" puts "===========================================" puts "OCC25813: regression in Hidden Line Removal" @@ -6,7 +6,7 @@ puts "===========================================" puts "" set viewname "" -set length 301.999 +set length 302.238 ptorus a 30 10 diff --git a/tests/hlr/poly_hlr/bug25813_4 b/tests/hlr/poly_hlr/bug25813_4 index 4dcd33347f..dbfca2240d 100644 --- a/tests/hlr/poly_hlr/bug25813_4 +++ b/tests/hlr/poly_hlr/bug25813_4 @@ -4,7 +4,7 @@ puts "===========================================" puts "" set viewname "" -set length 1196.29 +set length 1196.25 restore [locate_data_file bug25813_hlr-test_normandc1m1-draw-Cut001.brep] a COMPUTE_HLR $viewname $algotype -- 2.39.5