]> OCCT Git - occt-copy.git/commitdiff
0027490: BRepMesh: Reduce number of memory allocations
authormsv <msv@opencascade.com>
Wed, 4 May 2016 01:12:28 +0000 (04:12 +0300)
committermsv <msv@opencascade.com>
Fri, 13 May 2016 16:04:34 +0000 (19:04 +0300)
1) Reduce the number of calls to malloc by grouping requests to larger blocks. To achieve this goal, the following ways are used:

- Containers of types sequence, list and map are initialized with an instance of NCollection_IncAllocator, at this taking care of the time of life of allocated objects, so that not to occupy huge amount of memory.

- Allocation of several arrays having the same and short life time is changed so that to allocate a buffer array of necessary size and to place arrays in this buffer.

2) In BRepMesh_FastDiscretFace, optimize the function filterParameters so that to avoid excess memory allocations.

3) In NCollection_CellFilter, change declaration of the method Reset to accept array by reference rather than by value.

4) Add Allocator() method in map, sequence and vector collection classes by analogy with list collection.

5) Correct the size of block for IncAllocator for x64 platform. In order free-ed block to be returned to the system its size should be at least 1024K on x64 and 512K on x86. This allows to retain free virtual space almost to the state before algorithm run.

6) Decrease amount of memory zeroed by calloc. For that, reduce theIncrement parameter of the embedded vectors of the classes NCollection_UBTreeFiller and BRepMesh_VertexInspector to default value 256.

7) Avoid computing bounding box when not necessary (if no relative deflection is used)

8) Cycles by wires of face using TopExp_Explorer are converted to use TopoDS_Iterator instead.

9) BRepMesh_FastDiscret::Add optimized to avoid storing sequences of faces and edges

10) The tests "mesh standard_* W7" are corrected to accept the new behavior. Earlier the following error took place:
Not connected mesh inside face 9
{12 13}
Now this error was replaced with another one:
free nodes (in pairs: face / node):
{9 12}
Actually it is not a regression, rather improvement, if we look at the snapshot.

11) Change other test cases to their actual state.

26 files changed:
src/Adaptor3d/Adaptor3d_CurveOnSurface.cxx
src/BRepLib/BRepLib.cxx
src/BRepMesh/BRepMesh.hxx
src/BRepMesh/BRepMesh_DataStructureOfDelaun.cxx
src/BRepMesh/BRepMesh_Delaun.cxx
src/BRepMesh/BRepMesh_FaceAttribute.cxx
src/BRepMesh/BRepMesh_FastDiscret.cxx
src/BRepMesh/BRepMesh_FastDiscretFace.cxx
src/BRepMesh/BRepMesh_FastDiscretFace.hxx
src/BRepMesh/BRepMesh_IncrementalMesh.cxx
src/BRepMesh/BRepMesh_VertexInspector.hxx
src/BRepMesh/BRepMesh_VertexTool.cxx
src/BRepMesh/BRepMesh_VertexTool.hxx
src/BRepMesh/BRepMesh_WireChecker.cxx
src/GeomAdaptor/GeomAdaptor_Curve.cxx
src/NCollection/NCollection_BaseMap.hxx
src/NCollection/NCollection_BaseSequence.hxx
src/NCollection/NCollection_BaseVector.hxx
src/NCollection/NCollection_CellFilter.hxx
src/NCollection/NCollection_UBTreeFiller.hxx
tests/bugs/iges/buc60820_2
tests/bugs/iges/buc60823
tests/bugs/iges/bug306
tests/bugs/modalg_2/bug358
tests/bugs/vis/bug288_5
tests/mesh/data/standard/W7

index a6153e098c4baedbf7e3793a6fda6b8918a6ce93..14112d58e682d3b72b89ca385c74473fa7ddcfec 100644 (file)
@@ -846,16 +846,19 @@ Standard_Integer Adaptor3d_CurveOnSurface::NbIntervals (const GeomAbs_Shape S) c
   Standard_Integer nu,nv,nc;
   nu=mySurface->NbUIntervals(S);
   nv=mySurface->NbVIntervals(S);
+  nc=myCurve->NbIntervals(S);
+
+  // Allocate the memory for arrays TabU, TabV, TabC only once using the buffer TabBuf.
+  TColStd_Array1OfReal TabBuf(1, nu + nv + nc + 3);
+  TColStd_Array1OfReal TabU(TabBuf(1), 1, nu+1);
+  TColStd_Array1OfReal TabV(TabBuf(nu + 2), 1, nv+1);
+  TColStd_Array1OfReal TabC(TabBuf(nu + nv + 3), 1, nc+1);
 
-  TColStd_Array1OfReal TabU(1,nu+1);
-  TColStd_Array1OfReal TabV(1,nv+1);
   Standard_Integer NbSample = 20;
   Standard_Real U,V,Tdeb,Tfin;
   Tdeb=myCurve->FirstParameter();
   Tfin=myCurve->LastParameter();
 
-  nc=myCurve->NbIntervals(S);
-  TColStd_Array1OfReal TabC(1,nc+1);
   myCurve->Intervals(TabC,S);
 
   Standard_Real Tol= Precision::PConfusion()/10;
index d6bac85e90800ef6b692dd8b2ab948adb01a7214..3e6a6c4931eec9f220c39229ac212840ff958b82 100644 (file)
@@ -2006,18 +2006,17 @@ void  BRepLib::ReverseSortFaces (const TopoDS_Shape& Sh,
   TopTools_ListOfShape& LF)
 {
   LF.Clear();
-  TopTools_ListOfShape LTri,LPlan,LCyl,LCon,LSphere,LTor,LOther;
+  // Use the allocator of the result LF for intermediate results
+  TopTools_ListOfShape LTri(LF.Allocator()), LPlan(LF.Allocator()),
+    LCyl(LF.Allocator()), LCon(LF.Allocator()), LSphere(LF.Allocator()),
+    LTor(LF.Allocator()), LOther(LF.Allocator());
   TopExp_Explorer exp(Sh,TopAbs_FACE);
   TopLoc_Location l;
-  Handle(Geom_Surface) S;
 
   for (; exp.More(); exp.Next()) {
     const TopoDS_Face&   F = TopoDS::Face(exp.Current());
-    S = BRep_Tool::Surface(F, l);
+    const Handle(Geom_Surface)& S = BRep_Tool::Surface(F, l);
     if (!S.IsNull()) {
-      if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-        S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
-      }
       GeomAdaptor_Surface AS(S);
       switch (AS.GetType()) {
       case GeomAbs_Plane: 
index 1bb38c8b934462d48b69510c59ffd67731a748c1..8d503f677021509dcaff1bca1363f7b414db1f81 100644 (file)
@@ -56,8 +56,16 @@ class BRepMesh_VertexTool;
 
 namespace BRepMesh
 {
-  //! Default size for memory block allocated by IncAllocator.
+  //! Default size for memory block allocated by IncAllocator. 
+  /**
+   * The idea here is that blocks of the given size are returned to the system
+   * rather than retained in the malloc heap, at least on WIN32 and WIN64 platforms.
+   */
+#ifdef _WIN64
+  const size_t MEMORY_BLOCK_SIZE_HUGE = 1024 * 1024;
+#else
   const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024;
+#endif
 
   //! Structure keeping parameters of segment.
   struct Segment
index 225103b5b11fcfad92295d0a6458d19332431fb7..9bcb9d12f8dc081092e41c91da9377c03bbcba29 100644 (file)
@@ -35,7 +35,8 @@ BRepMesh_DataStructureOfDelaun::BRepMesh_DataStructureOfDelaun(
   const Handle(NCollection_IncAllocator)& theAllocator,
   const Standard_Integer                  theReservedNodeSize)
   : myAllocator       (theAllocator),
-    myNodes           (new BRepMesh_VertexTool(theReservedNodeSize, myAllocator)),
+    myNodes           (new BRepMesh_VertexTool(myAllocator)),
+    myNodeLinks       (theReservedNodeSize * 3, myAllocator),
     myLinks           (theReservedNodeSize * 3, myAllocator),
     myDelLinks        (myAllocator),
     myElements        (theReservedNodeSize * 2, myAllocator),
index d635587c9ad38bdf72c953e4cd4a80a0741b7914..6d10ac50876b7d39f4f957f50ceb5b8ffaa92b3d 100644 (file)
@@ -429,8 +429,6 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
   Handle(NCollection_IncAllocator) aAllocator =
     new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
 
-  BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
-
   Standard_Real aTolU, aTolV;
   myMeshData->Data()->GetTolerance(aTolU, aTolV);
   const Standard_Real aSqTol = aTolU * aTolU + aTolV * aTolV;
@@ -442,8 +440,8 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
   Standard_Integer anUpper = theVertexIndexes.Upper();
   for( ; anIndex <= anUpper; ++anIndex ) 
   {
-    aLoopEdges.Clear();
     aAllocator->Reset(Standard_False);
+    BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
     
     Standard_Integer aVertexIdx = theVertexIndexes( anIndex );    
     const BRepMesh_Vertex& aVertex = GetVertex( aVertexIdx );
@@ -598,6 +596,7 @@ void BRepMesh_Delaun::cleanupMesh()
 
   for(;;)
   {
+    aAllocator->Reset(Standard_False);
     BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
     BRepMesh::MapOfInteger aDelTriangles(10, aAllocator);
 
@@ -679,7 +678,6 @@ void BRepMesh_Delaun::cleanupMesh()
         myMeshData->RemoveLink( aLoopEdgesIt.Key() );
     }
 
-    aAllocator->Reset(Standard_False);
     if ( aDeletedTrianglesNb == 0 )
       break;
   }
@@ -2173,7 +2171,8 @@ Standard_Boolean BRepMesh_Delaun::UseEdge( const Standard_Integer /*theIndex*/ )
 BRepMesh::HMapOfInteger BRepMesh_Delaun::getEdgesByType(
   const BRepMesh_DegreeOfFreedom theEdgeType ) const
 {
-  BRepMesh::HMapOfInteger aResult = new BRepMesh::MapOfInteger;
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  BRepMesh::HMapOfInteger aResult = new BRepMesh::MapOfInteger(1, anAlloc);
   BRepMesh::MapOfInteger::Iterator anEdgeIt( myMeshData->LinksOfDomain() );
 
   for ( ; anEdgeIt.More(); anEdgeIt.Next() )
index eba74c267c8e1cde565818a669ef04bb2db1f825..119a746785cd2e0bd7563aeb096e622b3be996bb 100644 (file)
@@ -25,7 +25,6 @@
 #include <TopoDS_Iterator.hxx>
 #include <BRep_Tool.hxx>
 
-
 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FaceAttribute,Standard_Transient)
 
 //=======================================================================
@@ -141,14 +140,12 @@ void BRepMesh_FaceAttribute::init()
     // between vertices
 
     myMinStep = RealLast();
-    for (TopExp_Explorer anExp(myFace, TopAbs_WIRE); anExp.More(); anExp.Next()) 
+    for (TopoDS_Iterator aFaceIt(myFace); aFaceIt.More(); aFaceIt.Next()) 
     {
-      TopoDS_Wire aWire = TopoDS::Wire(anExp.Current());
-
-      for (TopoDS_Iterator aWireExp(aWire); aWireExp.More(); aWireExp.Next()) 
+      for (TopoDS_Iterator aWireIt(aFaceIt.Value()); aWireIt.More(); aWireIt.Next()) 
       {
-        TopoDS_Edge anEdge = TopoDS::Edge(aWireExp.Value());
-        if (BRep_Tool::IsClosed(anEdge))
+        const TopoDS_Edge& anEdge = TopoDS::Edge(aWireIt.Value());
+        if (anEdge.IsNull() || BRep_Tool::IsClosed(anEdge))
           continue;
 
         // Get end points on 2d curve
index 7ed1129ae345851a97acb4865d37b5b1767581e2..1690227c5bb9cad98d2007f7f0d01f305c67c815 100644 (file)
@@ -47,6 +47,7 @@
 #include <Extrema_LocateExtPC.hxx>
 
 #include <TColStd_Array1OfInteger.hxx>
+#include <TColStd_Array1OfCharacter.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
 #include <TColGeom2d_SequenceOfCurve.hxx>
@@ -82,6 +83,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
 BRepMesh_FastDiscret::BRepMesh_FastDiscret( const Bnd_Box&         theBox,
                                             const BRepMesh_FastDiscret::Parameters& theParams)
    :
+  myMapdefle(1000, new NCollection_IncAllocator()),
   myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
   myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
   myParameters(theParams),
@@ -195,7 +197,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 
     resetDataStructure();
 
-    Standard_Real defedge;
+    Standard_Real defedge = myParameters.Deflection;
     Standard_Integer nbEdge = 0;
     Standard_Real savangle = myParameters.Angle;
     Standard_Real cdef;
@@ -205,18 +207,14 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
     if (!myParameters.Relative)
       defface = Max(myParameters.Deflection, maxdef);
 
-    NCollection_Sequence<EdgePCurve>  aPCurves;
-    NCollection_Sequence<TopoDS_Edge> aFaceEdges;
-
     const TopoDS_Face&                  aFace = myAttribute->Face();
-    const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-    TopExp_Explorer aWireIt(aFace, TopAbs_WIRE);
-    for (; aWireIt.More(); aWireIt.Next())
+    for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
     {
-      TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE);
-      for (; aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
+      for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
       {
-        const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+        const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Value());
+        if (aEdge.IsNull())
+          continue;
         if (!myMapdefle.IsBound(aEdge))
         {
           if (myParameters.Relative)
@@ -265,8 +263,6 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
           continue;
 
         EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
-        aPCurves.Append(aPCurve);
-        aFaceEdges.Append(aEdge);
 
         add(aEdge, aPCurve, defedge);
         myParameters.Angle = savangle;
@@ -293,6 +289,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 
     TopLoc_Location aLoc;
     Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
+    const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
 
     if ( aTriangulation.IsNull() )
     {
@@ -401,16 +398,29 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
             ++nbmaill;
 
             resetDataStructure();
-            for (Standard_Integer j = 1; j <= aFaceEdges.Length(); ++j)
-            {
-              const TopoDS_Edge& anEdge = aFaceEdges(j);
-              if (myEdges.IsBound(anEdge))
-                myEdges.UnBind(anEdge);
 
-              defedge = Max(myMapdefle(anEdge) / 3.0, eps);
-              myMapdefle.Bind(anEdge, defedge);
-
-              add(anEdge, aPCurves(j), defedge);
+            for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
+            {
+              for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
+              {
+                const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Value());
+                if (anEdge.IsNull())
+                  continue;
+                if (myEdges.IsBound(anEdge))
+                  myEdges.UnBind(anEdge);
+
+                defedge = Max(myMapdefle(anEdge) / 3.0, eps);
+                myMapdefle.Bind(anEdge, defedge);
+
+                Standard_Real aFirstParam, aLastParam;
+                Handle(Geom2d_Curve) aCurve2d =
+                  BRep_Tool::CurveOnSurface(anEdge, aFace, aFirstParam, aLastParam);
+                if (aCurve2d.IsNull())
+                  continue;
+
+                EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
+                add(anEdge, aPCurve, defedge);
+              }
             }
 
             aDFaceChecker.ReCompute(aClassifier);
@@ -806,18 +816,13 @@ void BRepMesh_FastDiscret::update(
   Handle(Poly_PolygonOnTriangulation) P1, P2;
   if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
   {
-    const Standard_Integer  aNodesNb = 2;
-    TColStd_Array1OfInteger aNewNodes      (1, aNodesNb);
-    TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
-    TColStd_Array1OfReal    aNewParams     (1, aNodesNb);
-
-    aNewNodInStruct(1) = ipf;
-    aNewNodes      (1) = isvf;
-    aNewParams     (1) = aEAttr.FirstParam;
-
-    aNewNodInStruct(aNodesNb) = ipl;
-    aNewNodes      (aNodesNb) = isvl;
-    aNewParams     (aNodesNb) = aEAttr.LastParam;
+    // two nodes
+    Standard_Integer aNewNodesArr[] = {isvf, isvl};
+    Standard_Integer aNewNodInStructArr[] = {ipf, ipl};
+    Standard_Real aNewParamsArr[] = {aEAttr.FirstParam, aEAttr.LastParam};
+    TColStd_Array1OfInteger aNewNodes      (aNewNodesArr[0], 1, 2);
+    TColStd_Array1OfInteger aNewNodInStruct(aNewNodInStructArr[0], 1, 2);
+    TColStd_Array1OfReal    aNewParams     (aNewParamsArr[0], 1, 2);
 
     P1 = new Poly_PolygonOnTriangulation(aNewNodes,       aNewParams);
     P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
@@ -825,9 +830,15 @@ void BRepMesh_FastDiscret::update(
   else
   {
     const Standard_Integer  aNodesNb = aEdgeTool->NbPoints();
-    TColStd_Array1OfInteger aNewNodesVec        (1, aNodesNb);
-    TColStd_Array1OfInteger aNewNodesInStructVec(1, aNodesNb);
-    TColStd_Array1OfReal    aNewParamsVec       (1, aNodesNb);
+    // Allocate the memory for arrays aNewNodesVec, aNewNodesInStructVec, aNewParamsVec
+    // only once using the buffer aBuf.
+    TColStd_Array1OfCharacter aBuf(1, aNodesNb * (2*sizeof(Standard_Integer) + sizeof(Standard_Real)));
+    TColStd_Array1OfInteger aNewNodesVec(*reinterpret_cast<const Standard_Integer*>
+      (&aBuf(1)), 1, aNodesNb);
+    TColStd_Array1OfInteger aNewNodesInStructVec(*reinterpret_cast<const Standard_Integer*>
+      (&aBuf(1 + aNodesNb*sizeof(Standard_Integer))), 1, aNodesNb);
+    TColStd_Array1OfReal    aNewParamsVec(*reinterpret_cast<const Standard_Real*>
+      (&aBuf(1 + aNodesNb*2*sizeof(Standard_Integer))), 1, aNodesNb);
 
     Standard_Integer aNodesCount = 1;
     aNewNodesInStructVec(aNodesCount) = ipf;
index 7d8882d1e474c6369c72e75dd032d935d64f0561..687387daf15288f36aa52ce2a06290b074e65615 100644 (file)
@@ -207,8 +207,8 @@ void BRepMesh_FastDiscretFace::initDataStructure()
   myStructure->Data()->SetTolerance( aTolU     / deltaX, aTolV     / deltaY);
 
   myAttribute->ChangeStructure() = myStructure;
-  myAttribute->ChangeSurfacePoints() = new BRepMesh::DMapOfIntegerPnt;
-  myAttribute->ChangeSurfaceVertices()= new BRepMesh::DMapOfVertexInteger;
+  myAttribute->ChangeSurfacePoints() = new BRepMesh::DMapOfIntegerPnt(1, aAllocator);
+  myAttribute->ChangeSurfaceVertices()= new BRepMesh::DMapOfVertexInteger(1, aAllocator);
 
   // Check the necessity to fill the map of parameters
   const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
@@ -217,8 +217,8 @@ void BRepMesh_FastDiscretFace::initDataStructure()
                                       thetype == GeomAbs_BSplineSurface);
   const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus || IsCompexSurface (thetype));
 
-  myUParam.Clear(); 
-  myVParam.Clear();
+  myUParam.Clear(aAllocator); 
+  myVParam.Clear(aAllocator);
 
   // essai de determination de la longueur vraie:
   // akm (bug OCC16) : We must calculate these measures in non-singular
@@ -393,7 +393,8 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
   Standard_Real aDef = -1;
   if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
   {
-    BRepMesh::ListOfVertex aNewVertices;
+    Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+    BRepMesh::ListOfVertex aNewVertices(anAlloc);
     if (!rajout)
     {
       aDef = control(aNewVertices, trigu, Standard_True);
@@ -463,8 +464,6 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams,
                              BRepMesh::SequenceOfReal&   theResult)
 {
   // Sort sequence of parameters
-  BRepMesh::SequenceOfReal aParamTmp;
-  Standard_Integer aParamLength = 1;
   const Standard_Integer anInitLen = theParams.Extent();
     
   TColStd_Array1OfReal aParamArray(1, anInitLen);
@@ -475,37 +474,26 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams,
   std::sort (aParamArray.begin(), aParamArray.end());
 
   // mandatory pre-filtering using the first (minimal) filter value
-  Standard_Real aP1, aP2;
-  aP1 = aParamArray(1);
-  aParamTmp.Append(aP1);
+  Standard_Integer aParamLength = 1;
   for (j = 2; j <= anInitLen; j++) 
   {
-    aP2 = aParamArray(j);
-    if ((aP2-aP1) > theMinDist)
+    if ((aParamArray(j)-aParamArray(aParamLength)) > theMinDist)
     {
-      aParamTmp.Append(aP2);
-      aP1 = aP2;
-      aParamLength++;
+      if (++aParamLength < j)
+        aParamArray(aParamLength) = aParamArray(j);
     }
   }
-
-  //add last point if required
-  if(aParamArray(anInitLen)-theParams(aParamLength) > theMinDist)
-  {
-    aParamTmp.Append(aParamArray(anInitLen));
-    aParamLength++;
-  }
   
   //perform filtering on series
   Standard_Real aLastAdded, aLastCandidate;
   Standard_Boolean isCandidateDefined = Standard_False;
-  aLastAdded = aParamTmp.First();
+  aLastAdded = aParamArray(1);
   aLastCandidate = aLastAdded;
-  theResult.Append(aParamTmp.First());
+  theResult.Append(aLastAdded);
   
-  for(j=2;j<aParamTmp.Length();j++) 
+  for(j=2; j < aParamLength; j++)
   {
-    Standard_Real aVal = aParamTmp.Value(j);
+    Standard_Real aVal = aParamArray(j);
     if(aVal-aLastAdded > theFilterDist) 
     {
       //adds the parameter
@@ -525,7 +513,7 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams,
     aLastCandidate = aVal;
     isCandidateDefined = Standard_True;
   }
-  theResult.Append(aParamTmp.Last());
+  theResult.Append(aParamArray(aParamLength));
 }
 
 void BRepMesh_FastDiscretFace::insertInternalVertices(
@@ -842,7 +830,9 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
   const Standard_Real                 aDefFace = myAttribute->GetDefFace();
   const Handle(BRepAdaptor_HSurface)& gFace    = myAttribute->Surface();
 
-  BRepMesh::SequenceOfReal aParams[2];
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  BRepMesh::SequenceOfReal aParams[2] = { BRepMesh::SequenceOfReal(anAlloc), 
+                                          BRepMesh::SequenceOfReal(anAlloc) };
   for (Standard_Integer i = 0; i < 2; ++i)
   {
     Standard_Boolean isU = (i == 0);
@@ -868,8 +858,10 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
   Handle (Geom_Surface) aSurface = gFace->ChangeSurface ().Surface ().Surface ();
   const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
 
-  BRepMesh::MapOfReal aParamsToRemove[2];
-  BRepMesh::MapOfReal aParamsForbiddenToRemove[2];
+  BRepMesh::MapOfReal aParamsToRemove[2] = { BRepMesh::MapOfReal(1, anAlloc),
+                                             BRepMesh::MapOfReal(1, anAlloc) };
+  BRepMesh::MapOfReal aParamsForbiddenToRemove[2] = { BRepMesh::MapOfReal(1, anAlloc),
+                                                      BRepMesh::MapOfReal(1, anAlloc) };
 
   // precision for compare square distances
   const Standard_Real aPrecision = Precision::Confusion();
@@ -1043,7 +1035,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
   const Standard_Real        theFaceDeflection,
   const BRepMesh_CircleTool& theCircleTool,
   BRepMesh::ListOfVertex&    theVertices,
-  Standard_Real&             theMaxTriangleDeflection)
+  Standard_Real&             theMaxTriangleDeflection,
+  const Handle(NCollection_IncAllocator)& theTempAlloc)
 {
   if (theTriangleDeflection > theMaxTriangleDeflection)
     theMaxTriangleDeflection = theTriangleDeflection;
@@ -1058,9 +1051,7 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
       const_cast<BRepMesh_CircleTool&>(theCircleTool).Select(
       myAttribute->Scale(theUV, Standard_True));
     
-    Handle(NCollection_IncAllocator) aAllocator =
-      new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
-    BRepMesh::MapOfInteger aUsedNodes(10, aAllocator);
+    BRepMesh::MapOfInteger aUsedNodes(10, theTempAlloc);
     BRepMesh::ListOfInteger::Iterator aCircleIt(aCirclesList);
     for (; aCircleIt.More(); aCircleIt.Next())
     {
@@ -1118,9 +1109,11 @@ Standard_Real BRepMesh_FastDiscretFace::control(
   if (IsCompexSurface (aSurfType) && aSurfType != GeomAbs_SurfaceOfExtrusion)
     aBSpline = gFace->ChangeSurface ().Surface().Surface();
 
-  NCollection_DataMap<Standard_Integer, gp_Dir> aNorMap;
-  BRepMesh::MapOfIntegerInteger                 aStatMap;
-  NCollection_Map<BRepMesh_OrientedEdge>        aCouples(3 * aTrianglesNb);
+  Handle(NCollection_IncAllocator) anAlloc =
+    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+  NCollection_DataMap<Standard_Integer, gp_Dir> aNorMap(1, anAlloc);
+  BRepMesh::MapOfIntegerInteger                 aStatMap(1, anAlloc);
+  NCollection_Map<BRepMesh_OrientedEdge>        aCouples(3 * aTrianglesNb, anAlloc);
   const BRepMesh_CircleTool& aCircles = theTrigu.Circles();
 
   // Perform refinement passes
@@ -1131,8 +1124,11 @@ Standard_Real BRepMesh_FastDiscretFace::control(
   Standard_Real aMaxSqDef = -1.;
   Standard_Integer aPass = 1, aInsertedNb = 1;
   Standard_Boolean isAllDegenerated = Standard_False;
+  Handle(NCollection_IncAllocator) aTempAlloc =
+    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
   for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass)
   {
+    aTempAlloc->Reset(Standard_False);
     theNewVertices.Clear();
 
     // Reset stop condition
@@ -1208,7 +1204,7 @@ Standard_Real BRepMesh_FastDiscretFace::control(
       aSqDef *= aSqDef;
 
       isSkipped = !checkDeflectionAndInsert(pDef, aCenter2d, theIsFirst, 
-        aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef);
+        aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef, aTempAlloc);
 
       if (isSkipped)
         break;
@@ -1242,7 +1238,7 @@ Standard_Real BRepMesh_FastDiscretFace::control(
           aSqDef = aLin.SquareDistance(pDef);
 
           isSkipped = !checkDeflectionAndInsert(pDef, mi2d, theIsFirst, 
-            aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef);
+            aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef, aTempAlloc);
         }
       }
 
@@ -1409,6 +1405,8 @@ void BRepMesh_FastDiscretFace::commitSurfaceTriangulation()
   BRepMesh_ShapeTool::AddInFace(aFace, aNewTriangulation);
 
   // Delete unused data
+  myUParam.Clear(0L);
+  myVParam.Clear(0L);
   myAttribute->ChangeStructure().Nullify();
   myAttribute->ChangeSurfacePoints().Nullify();
   myAttribute->ChangeSurfaceVertices().Nullify();
index cac3d2cac736f31910e37d97aa801bde61c77960..01a36a793836e7cefd289dab7feaeba4819e4a74 100644 (file)
@@ -174,7 +174,8 @@ private:
     const Standard_Real        theFaceDeflection,
     const BRepMesh_CircleTool& theCircleTool,
     BRepMesh::ListOfVertex&    theVertices,
-    Standard_Real&             theMaxTriangleDeflection);
+    Standard_Real&             theMaxTriangleDeflection,
+    const Handle(NCollection_IncAllocator)& theTempAlloc);
 
 private:
 
index c3f9d42f14682226a7547c8739610997f9aca2a0..8e7bace9e079503927a612d360e2c31f9694f7e7 100644 (file)
@@ -48,6 +48,7 @@
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
 #include <TColStd_Array1OfReal.hxx>
+#include <TColStd_MapOfTransient.hxx>
 #include <TopTools_HArray1OfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 
@@ -125,8 +126,11 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
 //=======================================================================
 void BRepMesh_IncrementalMesh::clear()
 {
-  myEdges.Clear();
-  myEdgeDeflection.Clear();
+  // the allocator will be alive while the structures are alive
+  Handle(NCollection_IncAllocator) anAlloc =
+    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+  myEdges.Clear(anAlloc);
+  myEdgeDeflection.Clear(anAlloc);
   myFaces.Clear();
   myMesh.Nullify();
 }
@@ -146,15 +150,18 @@ void BRepMesh_IncrementalMesh::init()
   collectFaces();
 
   Bnd_Box aBox;
-  BRepBndLib::Add(myShape, aBox, Standard_False);
-
-  if (aBox.IsVoid())
+  if ( myParameters.Relative ) 
   {
-    // Nothing to mesh.
-    return;
-  }
+    BRepBndLib::Add(myShape, aBox, Standard_False);
 
-  BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
+    if (aBox.IsVoid())
+    {
+      // Nothing to mesh.
+      return;
+    }
+
+    BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
+  }
 
   myMesh = new BRepMesh_FastDiscret (aBox, myParameters);
   
@@ -167,22 +174,21 @@ void BRepMesh_IncrementalMesh::init()
 //=======================================================================
 void BRepMesh_IncrementalMesh::collectFaces()
 {
-  TopTools_ListOfShape aFaceList;
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  TopTools_ListOfShape aFaceList(anAlloc);
   BRepLib::ReverseSortFaces(myShape, aFaceList);
-  TopTools_MapOfShape aFaceMap;
+  TColStd_MapOfTransient aTFaceMap(1, anAlloc);
 
   // make array of faces suitable for processing (excluding faces without surface)
   TopLoc_Location aDummyLoc;
-  const TopLoc_Location aEmptyLoc;
   TopTools_ListIteratorOfListOfShape aFaceIter(aFaceList);
   for (; aFaceIter.More(); aFaceIter.Next())
   {
-    TopoDS_Shape aFaceNoLoc = aFaceIter.Value();
-    aFaceNoLoc.Location(aEmptyLoc);
-    if (!aFaceMap.Add (aFaceNoLoc))
+    const TopoDS_Face& aFace = TopoDS::Face(aFaceIter.Value());
+    const Handle(TopoDS_TShape)& aTFace = aFace.TShape();
+    if (!aTFaceMap.Add (aTFace))
       continue; // already processed
 
-    TopoDS_Face aFace = TopoDS::Face(aFaceIter.Value());
     const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aDummyLoc);
     if (aSurf.IsNull())
       continue;
@@ -282,8 +288,9 @@ void BRepMesh_IncrementalMesh::discretizeFreeEdges()
 Standard_Real BRepMesh_IncrementalMesh::edgeDeflection(
   const TopoDS_Edge& theEdge)
 {
-  if (myEdgeDeflection.IsBound(theEdge))
-    return myEdgeDeflection(theEdge);
+  const Standard_Real* pDef = myEdgeDeflection.Seek(theEdge);
+  if (pDef)
+    return *pDef;
 
   Standard_Real aEdgeDeflection;
   if ( myParameters.Relative ) 
@@ -329,7 +336,7 @@ Standard_Real BRepMesh_IncrementalMesh::faceDeflection(
 void BRepMesh_IncrementalMesh::update(const TopoDS_Edge& theEdge)
 {
   if (!myEdges.IsBound(theEdge))
-    myEdges.Bind(theEdge, BRepMesh::DMapOfTriangulationBool());
+    myEdges.Bind(theEdge, BRepMesh::DMapOfTriangulationBool(3, myEdges.Allocator()));
 
   Standard_Real aEdgeDeflection = edgeDeflection(theEdge);
   // Check that triangulation relies to face of the given shape.
index 39d6e8f59c1299e220f826f955153c4dedd4b2f4..b3f6477877488daf9d6eda807e551e2dd7d5babf 100644 (file)
@@ -30,13 +30,11 @@ public:
   typedef Standard_Integer Target;
 
   //! Constructor.
-  //! @param theReservedSize size to be reserved for vector of vertices.
   //! @param theAllocator memory allocator to be used by internal collections.
   Standard_EXPORT BRepMesh_VertexInspector (
-    const Standard_Integer                  theReservedSize,
     const Handle(NCollection_IncAllocator)& theAllocator)
     : myResIndices(theAllocator),
-      myVertices  (new BRepMesh::VectorOfVertex(theReservedSize)),
+      myVertices  (new BRepMesh::VectorOfVertex),
       myDelNodes  (theAllocator)
   {
     SetTolerance( Precision::Confusion() );
index dfdff4bd095b96d0aee7ed87074c51945c79324a..ecad73c435328a66fd0229e13bd835ba6c4da192 100644 (file)
@@ -56,11 +56,10 @@ NCollection_CellFilter_Action BRepMesh_VertexInspector::Inspect(
 //purpose  : 
 //=======================================================================
 BRepMesh_VertexTool::BRepMesh_VertexTool(
-  const Standard_Integer                  theReservedSize,
   const Handle(NCollection_IncAllocator)& theAllocator)
   : myAllocator (theAllocator),
     myCellFilter(0., myAllocator),
-    mySelector  (Max(theReservedSize, 64),myAllocator)
+    mySelector  (myAllocator)
 {
   const Standard_Real aTol = Precision::Confusion();
   SetCellSize ( aTol + 0.05 * aTol );
index 4648331deb155b4e8484a19d630584a801a97071..a54be37d42b839ca340418f7f70e4b5e3d91030b 100644 (file)
@@ -36,10 +36,8 @@ public:
   DEFINE_STANDARD_ALLOC
   
   //! Constructor.
-  //! @param theReservedSize size to be reserved for vector of vertices.
   //! @param theAllocator memory allocator to be used by internal collections.
   Standard_EXPORT BRepMesh_VertexTool(
-    const Standard_Integer                  theReservedSize,
     const Handle(NCollection_IncAllocator)& theAllocator);
 
   //! Sets new size of cell for cellfilter equal in both directions.
index 007ecf35f506818542ac8042a29dc3eb6e671a6e..5def2f1be79ff1d0517ce2574f7903f94d4af47d 100644 (file)
@@ -22,7 +22,8 @@
 #include <BRepTools_WireExplorer.hxx>
 #include <TopAbs_Orientation.hxx>
 #include <TopoDS.hxx>
-#include <TopExp_Explorer.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
 #include <Poly_PolygonOnTriangulation.hxx>
 #include <BRepMesh_PairOfPolygon.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
@@ -147,10 +148,11 @@ BRepMesh_WireChecker::BRepMesh_WireChecker(
   TopoDS_Face aFace = theFace;
   aFace.Orientation(TopAbs_FORWARD);
 
-  TopExp_Explorer aFaceExplorer(aFace, TopAbs_WIRE);
-  for (; aFaceExplorer.More(); aFaceExplorer.Next())
+  for (TopoDS_Iterator aFaceIt(aFace); aFaceIt.More(); aFaceIt.Next())
   {
-    const TopoDS_Wire& aWire = TopoDS::Wire(aFaceExplorer.Current());
+    if (aFaceIt.Value().IsNull() || aFaceIt.Value().ShapeType() != TopAbs_WIRE) // may be inner vertex
+      continue;
+    const TopoDS_Wire& aWire = TopoDS::Wire(aFaceIt.Value());
 
     myWiresEdges.Append(ListOfEdges());
     ListOfEdges& aEdges = myWiresEdges.ChangeLast();
index ddd5996dfb3a4ba309ef72c310c789d5842a9780..6408cab9c4a11bf2e809c94f9935dfb677b6969e 100644 (file)
@@ -81,10 +81,8 @@ GeomAbs_Shape GeomAdaptor_Curve::LocalContinuity(const Standard_Real U1,
   Standard_Integer Index1 = 0;
   Standard_Integer Index2 = 0;
   Standard_Real newFirst, newLast;
-  TColStd_Array1OfReal    TK(1,Nb);
-  TColStd_Array1OfInteger TM(1,Nb);
-  myBSplineCurve->Knots(TK);
-  myBSplineCurve->Multiplicities(TM);
+  const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+  const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
   BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U1,myBSplineCurve->IsPeriodic(),
                            1,Nb,Index1,newFirst);
   BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,U2,myBSplineCurve->IsPeriodic(),
@@ -293,10 +291,8 @@ Standard_Integer GeomAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
           Standard_Integer Index1 = 0;
           Standard_Integer Index2 = 0;
           Standard_Real newFirst, newLast;
-          TColStd_Array1OfReal    TK(1,Nb);
-          TColStd_Array1OfInteger TM(1,Nb);
-          myBSplineCurve->Knots(TK);
-          myBSplineCurve->Multiplicities(TM);
+          const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+          const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
           BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
                                     myBSplineCurve->IsPeriodic(),
                                     1,Nb,Index1,newFirst);
@@ -418,10 +414,8 @@ void GeomAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
            Standard_Integer Index1 = 0;
            Standard_Integer Index2 = 0;
            Standard_Real newFirst, newLast;
-           TColStd_Array1OfReal    TK(1,Nb);
-           TColStd_Array1OfInteger TM(1,Nb);
-           myBSplineCurve->Knots(TK);
-           myBSplineCurve->Multiplicities(TM);
+            const TColStd_Array1OfReal& TK = myBSplineCurve->Knots();
+            const TColStd_Array1OfInteger& TM = myBSplineCurve->Multiplicities();
            BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
                                      myBSplineCurve->IsPeriodic(),
                                      1,Nb,Index1,newFirst);
index a84362bd743cf7d5316e9d6a9d7a9a44b8fcda3a..652cc0a823628208fee59f7e2d1d54476bf5903f 100644 (file)
@@ -149,6 +149,10 @@ public:
   //! Statistics
   Standard_EXPORT void Statistics(Standard_OStream& S) const;
 
+  //! Returns attached allocator
+  const Handle(NCollection_BaseAllocator)& Allocator() const
+  { return myAllocator; }
+
  protected:
   // -------- PROTECTED METHODS -----------
 
index c4a5bc794e0f5be41dddc46004387e318fda2417..42f4197b0ed11281f6d634db9c440041c387b877 100644 (file)
@@ -102,6 +102,10 @@ public:
       Standard_Boolean   IsEmpty     () const {return (mySize == 0);}
       Standard_Integer   Length      () const {return mySize;}
 
+      //! Returns attached allocator
+      const Handle(NCollection_BaseAllocator)& Allocator() const
+      { return myAllocator; }
+
  protected:
   // Methods PROTECTED
   // 
index 9b32c0c59b66139813123fa0a7c720d7717f0bc8..c0a93ec97cc6409fbe24424230b20b8f58d31f5d 100755 (executable)
@@ -212,6 +212,12 @@ public: //! @name public API
     }
   }
 
+  //! Returns attached allocator
+  const Handle(NCollection_BaseAllocator)& Allocator() const
+  {
+    return myAllocator;
+  }
+
 protected: //! @name Protected fields
 
   Handle(NCollection_BaseAllocator) myAllocator;
index fdc923cbcbf9dd03bc66cc4799c88b280d488423..a656df9788a69caedbfb1bd3e640736b63ecffe0 100644 (file)
@@ -158,7 +158,7 @@ public:
   }
 
   //! Clear the data structures and set new cell sizes and allocator
-  void Reset (NCollection_Array1<Standard_Real> theCellSize, 
+  void Reset (NCollection_Array1<Standard_Real>& theCellSize, 
               const Handle(NCollection_IncAllocator)& theAlloc=0)
   {
     myCellSize = theCellSize;
index 1c6d08059871bd8d1a963276e8096680277defab..a78e913598b112b670408334cd755e7c9c799fa0 100644 (file)
@@ -68,7 +68,7 @@ template <class TheObjType, class TheBndType> class NCollection_UBTreeFiller
   NCollection_UBTreeFiller (UBTree& theTree,
                             const Handle(NCollection_BaseAllocator)& theAlloc=0L,
                             const Standard_Boolean isFullRandom = Standard_True)
-    : myTree(theTree), mySeqPtr(1000, theAlloc),
+    : myTree(theTree), mySeqPtr(256, theAlloc),
       myRandGen (5489u /* == std::mt19937::default_seed, not defined in older environments, e.g, on Debian 6.0 with GCC 4.4.5 */),
       myIsFullRandom (isFullRandom) {}
 
index c03aebb93273d0c380eb039dbeabf8f2cfe4426f..9596850e466c07c964ae4aaeaad531b26817bbb4 100755 (executable)
@@ -13,6 +13,6 @@ vdisplay result
 vsetdispmode result 1
 vfit
 
-checktrinfo result -tri 444 -nod 435
+checktrinfo result -tri 430 -nod 428
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index a07f7d6be4b14c592a46dc5db96fe9e3b6c708d7..efabd93405bf4c3af57c9672b3503902b7837cfb 100755 (executable)
@@ -14,6 +14,6 @@ vdisplay result
 vsetdispmode result 1
 vfit
 
-checktrinfo result -tri 5497 -nod 3987
+checktrinfo result -tri 5457 -nod 3967
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index a9c10aa5e64ea6131e3a0c24189acbaec66b2fdb..1f484bcb88bb4f24f54d0b8b7bc0a44f5c150679 100755 (executable)
@@ -20,7 +20,7 @@ vsetdispmode result 1
 vdisplay result
 vfit
 
-checktrinfo result -tri 8142 -nod 7015
+checktrinfo result -tri 9198 -nod 7543
 
 checkmaxtol result -ref 0.92213088179312575
 checknbshapes result -shell 1
index caddcac70ebe27289db21eac892a16b5274ebb08..7356b5258184c9237fdda14ee2bd61edff542d3f 100755 (executable)
@@ -19,7 +19,7 @@ vdisplay result
 vfit
 vsetdispmode result 1
 
-checktrinfo result -tri 17548 -nod 9208
+checktrinfo result -tri 8970 -nod 4919
 checkprops result -s 24861.2 
 checkshape result
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index cb6ba51372f817bd38d24c3fac4cdfb3c63d889d..075eef4943bb3dba6936785aa8c1f90d78d5275d 100755 (executable)
@@ -13,5 +13,5 @@ isos result 0
 triangles result
 vfit
 
-checktrinfo result -tri 7988 -nod 8350
+checktrinfo result -tri 7980 -nod 8346
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
index a284efa38ae16dc19b4ec66ca9e605e94af62cc1..2f74cd183e1a1968905a7597686e9cbce6e3e942 100755 (executable)
@@ -1,10 +1,10 @@
 set TheFileName shading_wrongshape_027.brep
 set bug_freenodes "OCC22687"
-#set nbfreenodes(All) 2
+set nbfreenodes(All) 1
 set max_rel_tol_diff 1
 if { [string compare $command "shading"] != 0 } {
   #set bug_area "OCC22687"
-  set rel_tol 2.13
+  set rel_tol 1.2
 } else {
   set nbfreenodes(All) 2
   set rel_tol 0.48