View Issue Details

IDProjectCategoryView StatusLast Update
0033385CommunityOCCT:Modeling Algorithmspublic2023-08-07 16:02
Reportermsoulignac Assigned Tobugmaster  
PrioritynormalSeveritymajor 
Status closedResolutionno change required 
PlatformWindowsOSVC++ 2022 
Product Version7.6.0 
Target VersionUnscheduled 
Summary0033385: Modeling Algorithms - BRepPrimAPI_MakePrism stores duplicated curves in a transformed TopoDS_Shape
DescriptionLet 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
TagsNo tags attached.
Test case number

Attached Files

  • bug_BRepPrimAPI_MakePrism_curves_duplicates.png (79,450 bytes)

Activities

msoulignac

2023-05-17 17:05

reporter  

bug_BRepPrimAPI_MakePrism_curves_duplicates.png (79,450 bytes)

dpasukhi

2023-05-22 21:10

administrator   ~0113575

Last edited: 2023-05-22 21:13

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);
      }
    }
  }

msoulignac

2023-05-30 10:13

reporter   ~0113602

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 ?

dpasukhi

2023-05-30 12:27

administrator   ~0113603

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.

dpasukhi

2023-05-30 12:36

administrator   ~0113604

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.

msoulignac

2023-05-30 21:37

reporter   ~0113605

Thanks for your reactivity and your explanations.
Your tips allows me getting around my issues, so I consider the subject as closed.

Michaƫl

vglukhik

2023-08-07 16:02

administrator   ~0113910

closed.

Issue History

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