View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0033385 | Community | OCCT:Modeling Algorithms | public | 2023-05-17 17:05 | 2023-08-07 16:02 |
Reporter | msoulignac | Assigned To | bugmaster | ||
Priority | normal | Severity | major | ||
Status | closed | Resolution | no change required | ||
Platform | Windows | OS | VC++ 2022 | ||
Product Version | 7.6.0 | ||||
Target Version | Unscheduled | ||||
Summary | 0033385: Modeling Algorithms - BRepPrimAPI_MakePrism stores duplicated curves in a transformed TopoDS_Shape | ||||
Description | Let us consider a TopoDS_Shape instance, called s, on with a transform as been made. Each time we call BRepPrimAPI_MakePrism(s, v), two instances of Brep_CurveOnSurface are added in s. In the example bellow, BRepPrimAPI_MakePrism(s, v) is called 100 times with the same shape s in parameter. This leads to 201 curves stored in s : 1 Brep_Curve3D instance and 200 (=2 x 100) Brep_CurveOnSurface instances. This this illustrated in the attached screenshot. These duplicates leads to 2 problems : 1. Memory Leak : memory usage grows at each call to BRepPrimAPI_MakePrism 2. Performance reduction : each call to BRepPrimAPI_MakePrism is a bit slower. I measured that the computation time needed to do exactly the same task was growing in a quadratic way with the number of calls. | ||||
Steps To Reproduce | #include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepPrimAPI_MakePrism.hxx> #include <BRepBuilderAPI_Transform.hxx> #include <GC_MakeCircle.hxx> #include <Geom_Curve.hxx> #include <TopoDS_Edge.hxx> #include <TopoDS_Shape.hxx> #include <gp_Pnt.hxx> #include <gp_Vec.hxx> #include <gp.hxx> #include <gp_Trsf.hxx> TopoDS_Shape BRepPrimAPI_MakePrism_duplicates() { gp_Pnt start(0, 0, 0); gp_Pnt end(0, 10, 0); gp_Ax1 profileAxis(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0)); Handle(Geom_Curve) circleCurve = GC_MakeCircle(gp::OZ(), 2).Value(); TopoDS_Edge circleEdge = BRepBuilderAPI_MakeEdge(circleCurve); gp_Vec extrusionVector(start, end); TopoDS_Shape cylinder; gp_Ax2 newAxes(profileAxis.Location(), profileAxis.Direction()); gp_Trsf transform; transform.SetTransformation(newAxes, gp_Ax2()); TopoDS_Shape transformedCircleEdge = BRepBuilderAPI_Transform(circleEdge, transform); for (int i = 0; i < 100; i++) { cylinder = BRepPrimAPI_MakePrism(transformedCircleEdge, extrusionVector); } return cylinder; } | ||||
Additional information and documentation updates | - This bug appears when the extruded shape is a circle, but we have no problem with a square or a rectangle. - This bug appears when the circle is transformed, but we have no problem if the use the original circle (use circleEdge instead of transformedCircleEdge in the above example and - duplicates will disappear) - This bug has not been observed on other sweeping algorithms, such as BRepOffsetAPI_MakePipe | ||||
Tags | No tags attached. | ||||
Test case number | |||||
|
bug_BRepPrimAPI_MakePrism_curves_duplicates.png (79,450 bytes) |
|
Dear @msoulignac Thank you for your research. The behaviour you have described is correct. Unfortunately, it is not possible to fix the memory leakage problem in this case. You are right, it can happen. This is due to the fact that a different PCurve is created for each Surface. I.e. If you used 3DCurve to generate different Surface, then your Curve will have multiple references to those Surface. They cannot be cleaned up in real time when the objects are destroyed because of the complex relationships. But if this is relevant to you, you can use the following code, passing in the root of your shape. If you have more than one root, please make a Compound of them. #include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepPrimAPI_MakePrism.hxx> #include <BRepBuilderAPI_Transform.hxx> #include <GC_MakeCircle.hxx> #include <TopExp.hxx> #include <Geom_Curve.hxx> #include <TopoDS_Edge.hxx> #include <TopoDS_Shape.hxx> #include <gp_Pnt.hxx> #include <gp_Ax2.hxx> #include <gp_Ax3.hxx> #include <gp_Vec.hxx> #include <gp.hxx> #include <BRep_CurveOnSurface.hxx> #include <BRep_CurveOn2Surfaces.hxx> #include <gp_Trsf.hxx> #include <BRep_TEdge.hxx> #include <BRepLib.hxx> TopoDS_Shape aRootShape; TopTools_IndexedMapOfShape aFaces, anEdges; TopExp::MapShapes(aRootShape, TopAbs_FACE, aFaces); TopExp::MapShapes(aRootShape, TopAbs_EDGE, anEdges); NCollection_Map<Handle(Geom_Surface)> aSurfaces; for (TopTools_IndexedMapOfShape::Iterator aFaceIter(aFaces); aFaceIter.More(); aFaceIter.Next()) { const TopoDS_Face& aCurFace = TopoDS::Face(aFaceIter.Value()); const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aCurFace); aSurfaces.Add(aSurf); } for (TopTools_IndexedMapOfShape::Iterator anEdgeIter(anEdges); anEdgeIter.More(); anEdgeIter.Next()) { BRep_TEdge* TE = static_cast<BRep_TEdge*>(anEdgeIter.Value().TShape().get()); BRep_ListOfCurveRepresentation& itcr = TE->ChangeCurves(); for (BRep_ListIteratorOfListOfCurveRepresentation aCurveIter(TE->Curves()); aCurveIter.More(); aCurveIter.Next()) { const Handle(BRep_CurveRepresentation)& aCurveRep = aCurveIter.Value(); if (aCurveRep->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) { if (aSurfaces.Contains(aCurveRep->Surface())) { continue; } itcr.Remove(aCurveIter); } else if (aCurveRep->IsKind(STANDARD_TYPE(BRep_CurveOn2Surfaces))) { if (aSurfaces.Contains(aCurveRep->Surface()) && aSurfaces.Contains(aCurveRep->Surface2())) { continue; } itcr.Remove(aCurveIter); } } } |
|
Dear @dpasukhi, Thanks for your answer, which is very clear and complete. I have a naive question : why is code is not directly included in BRepPrimAPI_MakePrism ? It could avoid the leakage, could'nt it ? |
|
It is not possible. In BRepPrimAPI_MakePrism we don't know about whish TopoDS_Face are used or not. The removing PCurve dependens on life-time of TopoDS_Face. But we can't connect PCurve and Face directly. Any new tool to control this will impact on performance. Only analyzing any shapes that you have can help you to avoid memory leak. To be honest it is not a leak. It is controlled process. As soon, as Edge will removed memory will free. |
|
If you would like to avoid to use one Edge for multiple faces please use true parameter in BRepPrimAPI_MakePrism. Parameter that means copy edge and use own copy of edge to generate Face. In this case your basis Edge will not updated. |
|
Thanks for your reactivity and your explanations. Your tips allows me getting around my issues, so I consider the subject as closed. Michaƫl |
|
closed. |
Date Modified | Username | Field | Change |
---|---|---|---|
2023-05-17 17:05 | msoulignac | New Issue | |
2023-05-17 17:05 | msoulignac | Assigned To | => oan |
2023-05-17 17:05 | msoulignac | File Added: bug_BRepPrimAPI_MakePrism_curves_duplicates.png | |
2023-05-22 15:43 | dpasukhi | Target Version | => Unscheduled |
2023-05-22 15:43 | dpasukhi | Summary | BRepPrimAPI_MakePrism stores duplicated curves in a transformed TopoDS_Shape => Modeling Algorithms - BRepPrimAPI_MakePrism stores duplicated curves in a transformed TopoDS_Shape |
2023-05-22 15:43 | dpasukhi | Steps to Reproduce Updated | |
2023-05-22 15:54 | dpasukhi | Steps to Reproduce Updated | |
2023-05-22 20:47 | dpasukhi | Assigned To | oan => dpasukhi |
2023-05-22 21:10 | dpasukhi | Assigned To | dpasukhi => msoulignac |
2023-05-22 21:10 | dpasukhi | Status | new => feedback |
2023-05-22 21:10 | dpasukhi | Note Added: 0113575 | |
2023-05-22 21:13 | dpasukhi | Note Edited: 0113575 | |
2023-05-30 10:13 | msoulignac | Note Added: 0113602 | |
2023-05-30 12:27 | dpasukhi | Note Added: 0113603 | |
2023-05-30 12:36 | dpasukhi | Note Added: 0113604 | |
2023-05-30 21:37 | msoulignac | Note Added: 0113605 | |
2023-05-31 12:41 | dpasukhi | Assigned To | msoulignac => bugmaster |
2023-08-07 16:02 | vglukhik | Status | feedback => closed |
2023-08-07 16:02 | vglukhik | Resolution | open => no change required |
2023-08-07 16:02 | vglukhik | Note Added: 0113910 |