0025378: Building of triangulation for distored surfaces can take very long using...
authoroan <oan@opencascade.com>
Thu, 11 Dec 2014 14:15:42 +0000 (17:15 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Dec 2014 14:17:06 +0000 (17:17 +0300)
New parameter MinSize has been introduced to BRepMesh and GCPnts_TangentialDeflection;

Check length of remaining part of curve for min size parameter instead of distance between two points to avoid large gaps in case highly distorted BSpline surfaces;

Produce fine mesh for sphere and fix other surface;

Test cases for issue CR25378

Correction of test cases for issue CR25378

31 files changed:
src/BRepMesh/BRepMesh_Delaun.hxx
src/BRepMesh/BRepMesh_EdgeTessellator.cxx
src/BRepMesh/BRepMesh_EdgeTessellator.hxx
src/BRepMesh/BRepMesh_FastDiscret.cxx
src/BRepMesh/BRepMesh_FastDiscret.hxx
src/BRepMesh/BRepMesh_FastDiscretFace.cxx
src/BRepMesh/BRepMesh_FastDiscretFace.hxx
src/BRepMesh/BRepMesh_GeomTool.cxx
src/BRepMesh/BRepMesh_GeomTool.hxx
src/BRepMesh/BRepMesh_IncrementalMesh.cxx
src/BRepMesh/BRepMesh_IncrementalMesh.hxx
src/GCPnts/GCPnts_TangentialDeflection.cdl
src/GCPnts/GCPnts_TangentialDeflection.cxx
src/GCPnts/GCPnts_TangentialDeflection.gxx
src/MeshTest/MeshTest.cxx
tests/bugs/begin
tests/bugs/demo/bug25445
tests/bugs/mesh/bug25378_1_1 [new file with mode: 0755]
tests/bugs/mesh/bug25378_1_2 [new file with mode: 0755]
tests/bugs/mesh/bug25378_1_3 [new file with mode: 0755]
tests/bugs/mesh/bug25378_2_1 [new file with mode: 0644]
tests/bugs/mesh/bug25378_2_2 [new file with mode: 0644]
tests/bugs/mesh/bug25378_2_3 [new file with mode: 0644]
tests/bugs/mesh/bug25378_3_1 [new file with mode: 0644]
tests/bugs/mesh/bug25378_3_2 [new file with mode: 0644]
tests/bugs/mesh/bug25378_3_3 [new file with mode: 0644]
tests/bugs/mesh/bug25378_4_1 [new file with mode: 0644]
tests/bugs/mesh/bug25378_4_2 [new file with mode: 0644]
tests/bugs/mesh/bug25378_4_3 [new file with mode: 0644]
tests/bugs/vis/buc60587
tests/mesh/data/standard/B3

index 0899898..527f2ea 100755 (executable)
@@ -105,6 +105,12 @@ public:
     return myMeshData->GetElement (theIndex);
   }
 
+  //! Returns tool used to build mesh consistent to Delaunay criteria.
+  inline const BRepMesh_CircleTool& Circles() const
+  {
+    return myCircles;
+  }
+
   //! Test is the given triangle contains the given vertex.
   //! If theEdgeOn != 0 the vertex lies onto the edge index
   //! returned through this parameter.
index 1a4f4d4..d0c636d 100644 (file)
@@ -43,7 +43,8 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
   const Handle(BRepMesh_FaceAttribute)&            theFaceAttribute,
   const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
   const Standard_Real                              theLinDeflection,
-  const Standard_Real                              theAngDeflection)
+  const Standard_Real                              theAngDeflection,
+  const Standard_Real                              theMinSize)
   : mySurface(theFaceAttribute->Surface())
 {
   Standard_Real aPreciseAngDef = 0.5 * theAngDeflection;
@@ -52,6 +53,7 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
     aPreciseLinDef *= 0.5;
 
   mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
+  mySquareMinSize = Max(mySquareEdgeDef, theMinSize * theMinSize);
 
   Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
   if (isSameParam)
@@ -67,7 +69,7 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
   Standard_Real aFirstParam, aLastParam;
   BRep_Tool::Range(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
   myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam, 
-    aPreciseLinDef, aPreciseAngDef, aMinPntNb);
+    aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
 
   if (aCurveType == GeomAbs_BSplineCurve)
   {
@@ -83,7 +85,7 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
         const Standard_Real& anEndInt  = anIntervals.Value( aIntIt + 1 );
 
         BRepMesh_GeomTool aDetalizator(myCOnS, aStartInt, anEndInt,
-          aPreciseLinDef, aPreciseAngDef, aMinPntNb);
+          aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
 
         Standard_Integer aNbAddNodes = aDetalizator.NbPoints();
         for ( Standard_Integer aNodeIt = 1; aNodeIt <= aNbAddNodes; ++aNodeIt )
@@ -191,16 +193,19 @@ void BRepMesh_EdgeTessellator::splitSegment(
   P3dF = theSurf->Value(uvf.X(), uvf.Y());
   P3dL = theSurf->Value(uvl.X(), uvl.Y());
   
-  if(P3dF.SquareDistance(P3dL) < mySquareEdgeDef)
+  if(P3dF.SquareDistance(P3dL) < mySquareMinSize)
     return;
 
   uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
   midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
 
+  gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
+  if(Vec1.SquareModulus() < mySquareMinSize)
+    return;
+
   gp_XYZ aVec = P3dL.XYZ() - P3dF.XYZ();
   aVec.Normalize();
 
-  gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
   Standard_Real aModulus = Vec1.Dot(aVec);
   gp_XYZ aProj = aVec * aModulus;
   gp_XYZ aDist = Vec1 - aProj;
index 5eb9f0d..6e5f0a0 100644 (file)
@@ -47,7 +47,8 @@ public:
     const Handle(BRepMesh_FaceAttribute)&            theFaceAttribute,
     const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
     const Standard_Real                              theLinDeflection,
-    const Standard_Real                              theAngDeflection);
+    const Standard_Real                              theAngDeflection,
+    const Standard_Real                              theMinSize);
 
   //! Returns number of dicretization points.
   virtual Standard_Integer NbPoints() const
@@ -81,6 +82,7 @@ private:
   Handle(BRepAdaptor_HSurface)          mySurface;
   BRepAdaptor_Curve                     myCOnS;
   Standard_Real                         mySquareEdgeDef;
+  Standard_Real                         mySquareMinSize;
 };
 
 DEFINE_STANDARD_HANDLE(BRepMesh_EdgeTessellator, BRepMesh_IEdgeTool)
index 72e4ac8..2ce0d39 100644 (file)
@@ -86,15 +86,16 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret, Standard_Transient)
 //purpose  : 
 //=======================================================================
 BRepMesh_FastDiscret::BRepMesh_FastDiscret(
-  const Standard_Real    theDefle,
-  const Standard_Real    theAngl,
-  const Bnd_Box&         theBox,
-  const Standard_Boolean theWithShare,
-  const Standard_Boolean theInshape,
-  const Standard_Boolean theRelative,
-  const Standard_Boolean theShapetrigu,
-  const Standard_Boolean isInParallel,
-  const Standard_Boolean isInternalVerticesMode)
+  const Standard_Real                              theDefle,
+  const Standard_Real                              theAngl,
+  const Bnd_Box&                                   theBox,
+  const Standard_Boolean                           theWithShare,
+  const Standard_Boolean                           theInshape,
+  const Standard_Boolean                           theRelative,
+  const Standard_Boolean                           theShapetrigu,
+  const Standard_Boolean                           isInParallel,
+  const Standard_Real                              theMinSize,
+  const Standard_Boolean                           isInternalVerticesMode)
 : myAngle (theAngl),
   myDeflection (theDefle),
   myWithShare (theWithShare),
@@ -104,6 +105,7 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(
   myInshape (theInshape),
   myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
   myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
+  myMinSize(theMinSize),
   myInternalVerticesMode(isInternalVerticesMode)
 {
   if ( myRelative )
@@ -124,6 +126,7 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(
   const Standard_Boolean theRelative,
   const Standard_Boolean theShapetrigu,
   const Standard_Boolean isInParallel,
+  const Standard_Real    theMinSize,
   const Standard_Boolean isInternalVerticesMode)
 : myAngle (theAngl),
   myDeflection (theDefle),
@@ -134,6 +137,7 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(
   myInshape (theInshape),
   myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
   myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
+  myMinSize(theMinSize),
   myInternalVerticesMode(isInternalVerticesMode)
 {
   if ( myRelative )
@@ -198,7 +202,7 @@ void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
     {
       OCC_CATCH_SIGNALS
 
-      BRepMesh_FastDiscretFace aTool(GetAngle(), myInternalVerticesMode);
+      BRepMesh_FastDiscretFace aTool(GetAngle(), myMinSize, myInternalVerticesMode);
       aTool.Perform(anAttribute);
     }
     catch (Standard_Failure)
@@ -868,7 +872,7 @@ void BRepMesh_FastDiscret::update(
   if (aEdgeTool.IsNull())
   {
     aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute, 
-      mySharedFaces, theDefEdge, myAngle);
+      mySharedFaces, theDefEdge, myAngle, myMinSize);
   }
 
   Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
index e0c6db9..37599a1 100644 (file)
@@ -58,16 +58,16 @@ class BRepMesh_FastDiscret : public Standard_Transient
 {
 public:
   
-  Standard_EXPORT BRepMesh_FastDiscret(
-    const Standard_Real defle,
-    const Standard_Real angle,
-    const Bnd_Box& B,
-    const Standard_Boolean withShare = Standard_True,
-    const Standard_Boolean inshape = Standard_False,
-    const Standard_Boolean relative = Standard_False,
-    const Standard_Boolean shapetrigu = Standard_False,
-    const Standard_Boolean isInParallel = Standard_False,
-    const Standard_Boolean isInternalVerticesMode = Standard_True);
+  Standard_EXPORT BRepMesh_FastDiscret(const Standard_Real defle,
+                                       const Standard_Real angle,
+                                       const Bnd_Box& B,
+                                       const Standard_Boolean withShare = Standard_True,
+                                       const Standard_Boolean inshape = Standard_False,
+                                       const Standard_Boolean relative = Standard_False,
+                                       const Standard_Boolean shapetrigu = Standard_False,
+                                       const Standard_Boolean isInParallel = Standard_False,
+                                       const Standard_Real    theMinSize   = Precision::Confusion(),
+                                       const Standard_Boolean isInternalVerticesMode = Standard_True);
 
   //! if the boolean <relative> is True, the <br>
   //! deflection used for the polygonalisation of <br>
@@ -81,17 +81,17 @@ public:
   //! <br>
   //! if <inshape> is True, the calculated <br>
   //! triangulation will be stored in the shape. <br>
-  Standard_EXPORT BRepMesh_FastDiscret(
-    const TopoDS_Shape& shape,
-    const Standard_Real defle,
-    const Standard_Real angle,
-    const Bnd_Box& B,
-    const Standard_Boolean withShare = Standard_True,
-    const Standard_Boolean inshape = Standard_False,
-    const Standard_Boolean relative = Standard_False,
-    const Standard_Boolean shapetrigu = Standard_False,
-    const Standard_Boolean isInParallel = Standard_False,
-    const Standard_Boolean isInternalVerticesMode = Standard_True);
+  Standard_EXPORT BRepMesh_FastDiscret(const TopoDS_Shape& shape,
+                                       const Standard_Real defle,
+                                       const Standard_Real angle,
+                                       const Bnd_Box& B,
+                                       const Standard_Boolean withShare = Standard_True,
+                                       const Standard_Boolean inshape = Standard_False,
+                                       const Standard_Boolean relative = Standard_False,
+                                       const Standard_Boolean shapetrigu = Standard_False,
+                                       const Standard_Boolean isInParallel = Standard_False,
+                                       const Standard_Real    theMinSize   = Precision::Confusion(),
+                                       const Standard_Boolean isInternalVerticesMode = Standard_True);
 
   //! Build triangulation on the whole shape.
   Standard_EXPORT void Perform(const TopoDS_Shape& shape);
@@ -366,6 +366,8 @@ private:
   // Fast access to attributes of current face
   Handle(BRepMesh_FaceAttribute)                   myAttribute;
   TopTools_IndexedDataMapOfShapeListOfShape        mySharedFaces;
+
+  Standard_Real                                    myMinSize;
   Standard_Boolean                                 myInternalVerticesMode;
 };
 
index f1d9d50..c071ca1 100644 (file)
@@ -33,6 +33,7 @@
 #include <Geom_Surface.hxx>
 #include <Geom_BSplineSurface.hxx>
 #include <GCPnts_TangentialDeflection.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
 
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_Failure.hxx>
@@ -143,12 +144,12 @@ namespace
 //=======================================================================
 BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace(
   const Standard_Real    theAngle,
+  const Standard_Real    theMinSize,
   const Standard_Boolean isInternalVerticesMode)
 : myAngle(theAngle),
-  myInternalVerticesMode(isInternalVerticesMode)
+  myInternalVerticesMode(isInternalVerticesMode),
+  myMinSize(theMinSize)
 {
-  myAllocator = new NCollection_IncAllocator(
-    BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
 }
 
 //=======================================================================
@@ -175,7 +176,9 @@ void BRepMesh_FastDiscretFace::initDataStructure()
   const Standard_Real deltaX = myAttribute->GetDeltaX();
   const Standard_Real deltaY = myAttribute->GetDeltaY();
 
-  myStructure = new BRepMesh_DataStructureOfDelaun(myAllocator);
+  Handle(NCollection_IncAllocator) aAllocator = 
+    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+  myStructure = new BRepMesh_DataStructureOfDelaun(aAllocator);
   myStructure->Data()->SetCellSize ( uCellSize / deltaX, vCellSize / deltaY);
   myStructure->Data()->SetTolerance( aTolU     / deltaX, aTolV     / deltaY);
 
@@ -367,25 +370,19 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
   if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
   {
     BRepMesh::ListOfVertex aNewVertices;
-    if ( !rajout )
+    if (!rajout)
     {
       aDef = control(aNewVertices, trigu, Standard_True);
-
-      if( aDef > myAttribute->GetDefFace() || aDef < 0.)
-        rajout = Standard_True;
+      rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.);
     }
 
-    if ( !rajout && useUVParam )
+    if (!rajout && useUVParam)
     {
-      if ( myVParam.Extent() > 2 &&
-          (gFace->IsUClosed()    ||
-            gFace->IsVClosed()))
-      {
-        rajout = Standard_True;
-      }
+      rajout = (myVParam.Extent() > 2 && 
+        (gFace->IsUClosed() || gFace->IsVClosed()));
     }
 
-    if ( rajout )
+    if (rajout)
     {
       insertInternalVertices(aNewVertices, trigu);
 
@@ -572,42 +569,38 @@ void BRepMesh_FastDiscretFace::insertInternalVertices(
 void BRepMesh_FastDiscretFace::insertInternalVerticesSphere(
   BRepMesh::ListOfVertex& theNewVertices)
 {
-  const Standard_Real umax = myAttribute->GetUMax();
-  const Standard_Real umin = myAttribute->GetUMin();
-  const Standard_Real vmax = myAttribute->GetVMax();
-  const Standard_Real vmin = myAttribute->GetVMin();
+  Standard_Real aRange[] = {
+    myAttribute->GetVMin(), myAttribute->GetVMax(),
+    myAttribute->GetUMin(), myAttribute->GetUMax()
+  };
 
-  gp_Sphere S = myAttribute->Surface()->Sphere();
-  const Standard_Real R = S.Radius();
+  gp_Sphere aSphere = myAttribute->Surface()->Sphere();
 
   // Calculate parameters for iteration in V direction
-  Standard_Real Dv = 1.0 - (myAttribute->GetDefFace() / R);
-  if (Dv < 0.0) Dv = 0.0;
-  Standard_Real oldDv = 2.0 * ACos(Dv);
-  Dv = .7 * oldDv; //.7 ~= sqrt(2.) - Dv is hypotenuse of triangle when oldDv is legs
-  const Standard_Real sv = vmax - vmin;
-  Dv = sv / ((Standard_Integer)(sv / Dv) + 1);
-  const Standard_Real pasvmax = vmax - Dv*0.5;
+  Standard_Real aStep = 0.7 * GCPnts_TangentialDeflection::ArcAngularStep(
+    aSphere.Radius(), myAttribute->GetDefFace(), myAngle, myMinSize);
 
-  //Du can be defined from relation: 2*r*Sin(Du/2) = 2*R*Sin(Dv/2), r = R*Cos(v)
-  //here approximate relation r*Du = R*Dv is used
+  Standard_Real aDd[2] = {aStep, aStep};
+  Standard_Real aPasMax[2] = {0., 0.};
+  for (Standard_Integer i = 0; i < 2; ++i)
+  {
+    const Standard_Real aMax = aRange[2 * i + 1];
+    const Standard_Real aDiff = aMax - aRange[2 * i + 0];
+    aDd[i] = aDiff / ((Standard_Integer)(aDiff / aDd[i]) + 1);
+    aPasMax[i] = aMax - Precision::PConfusion();
+  }
 
-  Standard_Real Du, pasu, pasv; //, ru;
-  const Standard_Real su = umax - umin;
+  const Standard_Real aHalfDu = aDd[1] * 0.5;
   Standard_Boolean Shift = Standard_False;
-  for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
+  Standard_Real aPasV = aRange[0] + aDd[0];
+  for (; aPasV < aPasMax[0]; aPasV += aDd[0])
   {
-    // Calculate parameters for iteration in U direction
-    // 1.-.365*pasv*pasv is simple approximation of Cos(pasv)
-    // with condition that it gives ~.1 when pasv = pi/2
-    Du = Dv / (1. - .365*pasv*pasv);
-    Du = su / ((Standard_Integer)(su / Du) + 1);
     Shift = !Shift;
-    const Standard_Real d = (Shift) ? Du*.5 : 0.;
-    const Standard_Real pasumax = umax - Du*0.5 + d;
-    for (pasu = umin + Du - d; pasu < pasumax; pasu += Du)
+    const Standard_Real d = (Shift) ? aHalfDu : 0.;
+    Standard_Real aPasU = aRange[2] + d;
+    for (; aPasU < aPasMax[1]; aPasU += aDd[1])
     {
-      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), S, theNewVertices);
+      tryToInsertAnalyticVertex(gp_Pnt2d(aPasU, aPasV), aSphere, theNewVertices);
     }
   }
 }
@@ -624,21 +617,20 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesCylinder(
   const Standard_Real vmax = myAttribute->GetVMax();
   const Standard_Real vmin = myAttribute->GetVMin();
 
-  gp_Cylinder S = myAttribute->Surface()->Cylinder();
-  const Standard_Real R = S.Radius();
+  gp_Cylinder aCylinder = myAttribute->Surface()->Cylinder();
+  const Standard_Real aRadius = aCylinder.Radius();
 
   // Calculate parameters for iteration in U direction
-  Standard_Real Du = 1.0 - (myAttribute->GetDefFace() / R);
-  if (Du < 0.0) Du = 0.0;
-  Du = 2.0 * ACos(Du);
-  if (Du > myAngle) Du = myAngle;
+  Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep(
+    aRadius, myAttribute->GetDefFace(), myAngle, myMinSize);
+
   const Standard_Real su = umax - umin;
   const Standard_Integer nbU = (Standard_Integer)(su / Du);
   Du = su / (nbU + 1);
 
   // Calculate parameters for iteration in V direction
   const Standard_Real sv = vmax - vmin;
-  Standard_Integer nbV = (Standard_Integer)(nbU*sv / (su*R));
+  Standard_Integer nbV = (Standard_Integer)(nbU*sv / (su*aRadius));
   nbV = Min(nbV, 100 * nbU);
   Standard_Real Dv = sv / (nbV + 1);
 
@@ -647,7 +639,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesCylinder(
   {
     for (pasu = umin + Du; pasu < pasumax; pasu += Du)
     {
-      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), S, theNewVertices);
+      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), aCylinder, theNewVertices);
     }
   }
 }
@@ -664,16 +656,17 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesCone(
   const Standard_Real vmax = myAttribute->GetVMax();
   const Standard_Real vmin = myAttribute->GetVMin();
 
-  Standard_Real R, RefR, SAng;
-  gp_Cone C = myAttribute->Surface()->Cone();
-  RefR = C.RefRadius();
-  SAng = C.SemiAngle();
-  R = Max(Abs(RefR + vmin*Sin(SAng)), Abs(RefR + vmax*Sin(SAng)));
-  Standard_Real Du, Dv, pasu, pasv;
-  Du = Max(1.0e0 - (myAttribute->GetDefFace() / R), 0.0e0);
-  Du = (2.0 * ACos(Du));
+  gp_Cone aCone = myAttribute->Surface()->Cone();
+  Standard_Real RefR = aCone.RefRadius();
+  Standard_Real SAng = aCone.SemiAngle();
+  Standard_Real aRadius = Max(Abs(RefR + vmin*Sin(SAng)), Abs(RefR + vmax*Sin(SAng)));
+
+  Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep(
+    aRadius, myAttribute->GetDefFace(), myAngle, myMinSize);
+
+  Standard_Real Dv, pasu, pasv;
   Standard_Integer nbU = (Standard_Integer)((umax - umin) / Du);
-  Standard_Integer nbV = (Standard_Integer)(nbU*(vmax - vmin) / ((umax - umin)*R));
+  Standard_Integer nbV = (Standard_Integer)(nbU*(vmax - vmin) / ((umax - umin)*aRadius));
   Du = (umax - umin) / (nbU + 1);
   Dv = (vmax - vmin) / (nbV + 1);
 
@@ -682,7 +675,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesCone(
   {
     for (pasu = umin + Du; pasu < pasumax; pasu += Du)
     {
-      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), C, theNewVertices);
+      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), aCone, theNewVertices);
     }
   }
 }
@@ -711,20 +704,21 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesTorus(
 
   BRepMesh::SequenceOfReal ParamU, ParamV;
 
-  Standard_Real Du, Dv;//, pasu, pasv;
-  Dv = Max(1.0e0 - (aDefFace / r), 0.0e0);
-  Standard_Real oldDv = 2.0 * ACos(Dv);
-  oldDv = Min(oldDv, myAngle);
-  Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
+  Standard_Real oldDv = GCPnts_TangentialDeflection::ArcAngularStep(
+    r, aDefFace, myAngle, myMinSize);
+
+  Standard_Real Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
   Dv = oldDv;
 
+  Standard_Real Du;
   Standard_Integer nbV = Max((Standard_Integer)((vmax - vmin) / Dv), 2);
   Dv = (vmax - vmin) / (nbV + 1);
   Standard_Real ru = R + r;
   if (ru > 1.e-16)
   {
-    Du = 2.0 * ACos(Max(1.0 - (aDefFace / ru), 0.0));
-    if (myAngle < Du) Du = myAngle;
+    Du = GCPnts_TangentialDeflection::ArcAngularStep(
+      ru, aDefFace, myAngle, myMinSize);
+
     Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
     if (aa < gp::Resolution())
       return;
@@ -854,9 +848,12 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
     if (aDelta[i] < 1.)
       aMinDiff /= aDelta[i];
 
+    aMinDiff = Max(myMinSize, aMinDiff);
+
     Standard_Real aRangeDiff = aRange[i][0] - aRange[i][1];
     Standard_Real aDiffMaxLim = 0.1 * aRangeDiff;
-    Standard_Real aDiff = Min(aDiffMaxLim, Max(0.005 * aRangeDiff, 2. * aRes));
+    Standard_Real aDiffMinLim = Max(0.005 * aRangeDiff, 2. * aRes);
+    Standard_Real aDiff = Max(myMinSize, Min(aDiffMaxLim, aDiffMinLim));
     filterParameters(isU ? myUParam : myVParam, aMinDiff, aDiff, aParams[i]);
   }
 
@@ -893,17 +890,17 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
     for (Standard_Integer i = aStartIndex; i <= aEndIndex; ++i)
     {
       const Standard_Real aParam1 = aParams1(i);
-      Handle(Geom_Curve) aIso = isU ?
-        aBSpline->UIso(aParam1) : aBSpline->VIso(aParam1);
+      GeomAdaptor_Curve aIso(isU ?
+        aBSpline->UIso(aParam1) : aBSpline->VIso(aParam1));
 
       Standard_Real aPrevParam2 = aParams2(1);
-      gp_Pnt aPrevPnt2 = aIso->Value(aPrevParam2);
+      gp_Pnt aPrevPnt2 = aIso.Value(aPrevParam2);
       for (Standard_Integer j = 2; j <= aParams2.Length();)
       {
         Standard_Real aParam2 = aParams2(j);
-        gp_Pnt aPnt2 = aIso->Value(aParam2);
+        gp_Pnt aPnt2 = aIso.Value(aParam2);
         Standard_Real aMidParam = 0.5 * (aPrevParam2 + aParam2);
-        gp_Pnt aMidPnt = aIso->Value(aMidParam);
+        gp_Pnt aMidPnt = aIso.Value(aMidParam);
 
         // 23.03.2010 skl for OCC21645 - change precision for comparison
         Standard_Real aDist;
@@ -915,7 +912,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
         else
           aDist = aPrevPnt2.Distance(aMidPnt);
 
-        if (aDist > aDefFace)
+        if (aDist > aDefFace && aDist > myMinSize)
         {
           // insertion 
           aParams2.InsertBefore(j, aMidParam);
@@ -942,15 +939,25 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
           Standard_Real aAngle = N2.Angle(N1);
           if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle)
           {
-            // insertion 
-            aParams2.InsertBefore(j, aMidParam);
+            Standard_Real aLen = GCPnts_AbscissaPoint::Length(aIso,
+              aPrevParam2, aMidParam, aDefFace);
+
+            if (aLen > myMinSize)
+            {
+              // insertion 
+              aParams2.InsertBefore(j, aMidParam);
+              continue;
+            }
           }
-          else
+
+          aPrevParam2 = aParam2;
+          aPrevPnt2   = aPnt2;
+
+          if (!isU && j < aParams2.Length())
           {
-            aPrevParam2 = aParam2;
-            aPrevPnt2   = aPnt2;
-            ++j;
-          }
+            // Update point parameter.
+            aStPnt1.SetX(aPrevParam2);
+          ++j;
         }
       }
     }
@@ -982,7 +989,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
 void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
   BRepMesh::ListOfVertex& theNewVertices)
 {
-  const Standard_Real aAngle = 0.35;
+  const Standard_Real aAngle = myAngle;//0.35;
   const Standard_Real aRange[2][2] = {
       { myAttribute->GetUMax(), myAttribute->GetUMin() },
       { myAttribute->GetVMax(), myAttribute->GetVMin() }
@@ -1015,7 +1022,7 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
       Standard_Real aLastParam  = Min(aRange2[0], aIso.LastParameter());
 
       aDiscretIso[aIsoIt].Initialize(aIso, aFirstParam, aLastParam, 
-        aAngle, 0.7 * aDefFace, 2);
+        aAngle, 0.7 * aDefFace, 2, Precision::PConfusion(), myMinSize);
 
       const Standard_Integer aPointsNb = aDiscretIso[aIsoIt].NbPoints();
       if (aPointsNb > aMaxPointsNb)
@@ -1056,6 +1063,68 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
   }
 }
 
+//=======================================================================
+//function : checkDeflectionAndInsert
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
+  const gp_Pnt&              thePnt3d,
+  const gp_XY&               theUV,
+  const Standard_Boolean     isDeflectionCheckOnly,
+  const Standard_Real        theTriangleDeflection,
+  const Standard_Real        theFaceDeflection,
+  const BRepMesh_CircleTool& theCircleTool,
+  BRepMesh::ListOfVertex&    theVertices,
+  Standard_Real&             theMaxTriangleDeflection)
+{
+  if (theTriangleDeflection > theMaxTriangleDeflection)
+    theMaxTriangleDeflection = theTriangleDeflection;
+
+  if (theTriangleDeflection < theFaceDeflection)
+    return Standard_True;
+
+  if (myMinSize > Precision::Confusion())
+  {
+    // Iterator in the list of indexes of circles containing the node
+    BRepMesh::ListOfInteger& aCirclesList = 
+      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::ListOfInteger::Iterator aCircleIt(aCirclesList);
+    for (; aCircleIt.More(); aCircleIt.Next())
+    {
+      const BRepMesh_Triangle& aTriangle = 
+        myStructure->GetElement(aCircleIt.Value());
+
+      Standard_Integer aNodes[3];
+      myStructure->ElementNodes(aTriangle, aNodes);
+
+      for (Standard_Integer i = 0; i < 3; ++i)
+      {
+        const Standard_Integer aNodeId = aNodes[i];
+        if (aUsedNodes.Contains(aNodeId))
+          continue;
+
+        aUsedNodes.Add(aNodeId);
+        const BRepMesh_Vertex& aNode = myStructure->GetNode(aNodeId);
+        const gp_Pnt& aPoint = myAttribute->GetPoint(aNode);
+
+        if (thePnt3d.SquareDistance(aPoint) < myMinSize * myMinSize)
+          return Standard_True;
+      }
+    }
+  }
+
+  if (isDeflectionCheckOnly)
+    return Standard_False;
+
+  insertVertex(thePnt3d, theUV, theVertices);
+  return Standard_True;
+}
+
 //=======================================================================
 //function : control
 //purpose  : 
@@ -1064,19 +1133,6 @@ Standard_Real BRepMesh_FastDiscretFace::control(
   BRepMesh::ListOfVertex&  theNewVertices,
   BRepMesh_Delaun&         theTrigu,
   const Standard_Boolean   theIsFirst)
-
-#define CHECK_DEF_AND_INSERT_CURRENT(isSkipped)                 \
-if (aSqDef > aMaxSqDef)                                         \
-  aMaxSqDef = aSqDef;                                           \
-                                                                \
-(isSkipped) = Standard_False;                                   \
-if (aSqDef > aSqDefFace)                                        \
-{                                                               \
-  (isSkipped) = theIsFirst;                                     \
-  if (!(isSkipped))                                             \
-    insertVertex(pDef, mi2d, theNewVertices);                   \
-}                                                               \
-
 {
   Standard_Integer aTrianglesNb = myStructure->ElementsOfDomain().Extent();
   if (aTrianglesNb < 1)
@@ -1099,6 +1155,7 @@ if (aSqDef > aSqDefFace)                                        \
   NCollection_DataMap<Standard_Integer, gp_Dir> aNorMap;
   BRepMesh::MapOfIntegerInteger                 aStatMap;
   NCollection_Map<BRepMesh_OrientedEdge>        aCouples(3 * aTrianglesNb);
+  const BRepMesh_CircleTool& aCircles = theTrigu.Circles();
 
   // Perform refinement passes
   // Define the number of iterations
@@ -1185,7 +1242,9 @@ if (aSqDef > aSqDefFace)                                        \
         aSqDef = Abs(normal * (pDef.XYZ() - p[0]));
         aSqDef *= aSqDef;
 
-        CHECK_DEF_AND_INSERT_CURRENT(isSkipped);
+        isSkipped = !checkDeflectionAndInsert(pDef, mi2d, theIsFirst, 
+          aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef);
+
         if (isSkipped)
           break;
       }
@@ -1221,7 +1280,8 @@ if (aSqDef > aSqDefFace)                                        \
           gp_Lin aLin(p[i], gp_Vec(p[i], p[j]));
           aSqDef = aLin.SquareDistance(pDef);
 
-          CHECK_DEF_AND_INSERT_CURRENT(isSkipped);
+          isSkipped = !checkDeflectionAndInsert(pDef, mi2d, theIsFirst, 
+            aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef);
         }
       }
 
index 4109845..9eac84e 100644 (file)
@@ -56,6 +56,7 @@ public:
   //! vertices mode.
   Standard_EXPORT BRepMesh_FastDiscretFace(
     const Standard_Real    theAngle,
+    const Standard_Real    theMinSize,
     const Standard_Boolean isInternalVerticesMode);
 
   Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute);
@@ -152,6 +153,32 @@ private:
                      const Standard_Integer   theLastNodeId,
                      const TopAbs_Orientation theOrientation);
 
+  //! Inserts new node into a mesh in case if smoothed region build 
+  //! using the given node has better deflection metrics than source state.
+  //! @param thePnt3d 3d point corresponded to the vertex.
+  //! @param theUV UV point corresponded to the vertex.
+  //! @param isDeflectionCheckOnly if TRUE new node will not be added to a mesh
+  //! even if deflection parameter is better.
+  //! @param theTriangleDeflection deflection of a triangle from real geometry.
+  //! @param theFaceDeflection deflection to be achieved.
+  //! @param theCircleTool tool used for fast extraction of triangles 
+  //! touched by the given point.
+  //! @param[out] theVertices list of vertices to be updated.
+  //! @param[in out] theMaxTriangleDeflection maximal deflection of a mesh.
+  //! @return TRUE in case if the given deflection of triangle is fine and
+  //! there is no necessity to insert new node or new node was being inserted
+  //! successfully, FALSE in case if new configuration is better but 
+  //! isDeflectionCheckOnly flag is set.
+  Standard_Boolean checkDeflectionAndInsert(
+    const gp_Pnt&              thePnt3d,
+    const gp_XY&               theUV,
+    const Standard_Boolean     isDeflectionCheckOnly,
+    const Standard_Real        theTriangleDeflection,
+    const Standard_Real        theFaceDeflection,
+    const BRepMesh_CircleTool& theCircleTool,
+    BRepMesh::ListOfVertex&    theVertices,
+    Standard_Real&             theMaxTriangleDeflection);
+
 private:
 
   Standard_Real                          myAngle;
@@ -160,9 +187,10 @@ private:
   BRepMesh::IMapOfReal                   myVParam;
 
   // Fast access to attributes of current face
-  Handle(NCollection_IncAllocator)       myAllocator;
   Handle(BRepMesh_FaceAttribute)         myAttribute;
   Handle(BRepMesh_DataStructureOfDelaun) myStructure;
+
+  Standard_Real                          myMinSize;
 };
 
 DEFINE_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient)
index ba95397..cf1fc73 100644 (file)
@@ -35,12 +35,14 @@ BRepMesh_GeomTool::BRepMesh_GeomTool(
   const Standard_Real      theLastParam,
   const Standard_Real      theLinDeflection,
   const Standard_Real      theAngDeflection,
-  const Standard_Integer   theMinPointsNb)
+  const Standard_Integer   theMinPointsNb,
+  const Standard_Real      theMinSize)
   : myEdge(&theCurve.Edge()),
     myIsoType(GeomAbs_NoneIso)
 {
   myDiscretTool.Initialize(theCurve, theFirstParam, theLastParam,
-    theAngDeflection, theLinDeflection, theMinPointsNb);
+    theAngDeflection, theLinDeflection, theMinPointsNb, 
+    Precision::PConfusion(), theMinSize);
 }
 
 //=======================================================================
@@ -55,7 +57,8 @@ BRepMesh_GeomTool::BRepMesh_GeomTool(
   const Standard_Real                 theLastParam,
   const Standard_Real                 theLinDeflection,
   const Standard_Real                 theAngDeflection,
-  const Standard_Integer              theMinPointsNb)
+  const Standard_Integer              theMinPointsNb,
+  const Standard_Real                 theMinSize)
   : myEdge(NULL),
     myIsoType(theIsoType)
 {
@@ -63,7 +66,8 @@ BRepMesh_GeomTool::BRepMesh_GeomTool(
     theFirstParam, theLastParam);
 
   myDiscretTool.Initialize(aIso, theFirstParam, theLastParam,
-    theAngDeflection, theLinDeflection, theMinPointsNb);
+    theAngDeflection, theLinDeflection, theMinPointsNb,
+    Precision::PConfusion(), theMinSize);
 }
 
 //=======================================================================
index a2b45e4..44f72a7 100644 (file)
@@ -21,6 +21,7 @@
 #include <GeomAbs_IsoType.hxx>
 #include <Handle_BRepAdaptor_HSurface.hxx>
 #include <TopoDS_Edge.hxx>
+#include <Precision.hxx>
 
 class BRepAdaptor_Curve;
 class BRepAdaptor_HSurface;
@@ -65,7 +66,8 @@ public:
                                     const Standard_Real      theLastParam,
                                     const Standard_Real      theLinDeflection,
                                     const Standard_Real      theAngDeflection,
-                                    const Standard_Integer   theMinPointsNb = 2);
+                                    const Standard_Integer   theMinPointsNb = 2,
+                                    const Standard_Real      theMinSize = Precision::Confusion());
   
   //! Constructor.
   //! Initiates discretization of geometric curve corresponding 
@@ -85,7 +87,8 @@ public:
                                     const Standard_Real                 theLastParam,
                                     const Standard_Real                 theLinDeflection,
                                     const Standard_Real                 theAngDeflection,
-                                    const Standard_Integer              theMinPointsNb = 2);
+                                    const Standard_Integer              theMinPointsNb = 2,
+                                    const Standard_Real                 theMinSize = Precision::Confusion());
 
   //! Adds point to already calculated points (or replaces existing).
   //! @param thePoint point to be added.
index 31cbdfc..6a808e2 100644 (file)
@@ -72,8 +72,9 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh, BRepMesh_DiscretRoot)
 //purpose  : 
 //=======================================================================
 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
-: myRelative (Standard_False),
-  myInParallel (Standard_False),
+: myRelative  (Standard_False),
+  myInParallel(Standard_False),
+  myMinSize   (Precision::Confusion()),
   myInternalVerticesMode(Standard_True)
 {
 }
@@ -90,6 +91,7 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh(
   const Standard_Boolean isInParallel)
   : myRelative  (isRelative),
     myInParallel(isInParallel),
+    myMinSize   (Precision::Confusion()),
     myInternalVerticesMode(Standard_True)
 {
   myDeflection  = theLinDeflection;
@@ -144,9 +146,10 @@ void BRepMesh_IncrementalMesh::init()
 
   BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
 
-  myMesh = new BRepMesh_FastDiscret(myDeflection, myAngle, aBox,
-    Standard_True, Standard_True, myRelative, Standard_True,
-    myInParallel, myInternalVerticesMode);
+  myMesh = new BRepMesh_FastDiscret(myDeflection, 
+    myAngle, aBox, Standard_True, Standard_True, 
+    myRelative, Standard_True, myInParallel, myMinSize,
+    myInternalVerticesMode);
 
   myMesh->InitSharedFaces(myShape);
 }
@@ -257,7 +260,7 @@ void BRepMesh_IncrementalMesh::discretizeFreeEdges()
 
     BRepAdaptor_Curve aCurve(aEdge);
     GCPnts_TangentialDeflection aDiscret(aCurve, aCurve.FirstParameter(),
-      aCurve.LastParameter(), myAngle, aEdgeDeflection, 2);
+      aCurve.LastParameter(), myAngle, aEdgeDeflection, 2, myMinSize);
 
     Standard_Integer aNodesNb = aDiscret.NbPoints();
     TColgp_Array1OfPnt   aNodes  (1, aNodesNb);
index a789fe3..d18588b 100644 (file)
@@ -103,6 +103,18 @@ public: //! @name accessing to parameters.
     return myInParallel;
   }
 
+  //! Sets min size parameter.
+  inline void SetMinSize(const Standard_Real theMinSize)
+  {
+    myMinSize = Max(theMinSize, Precision::Confusion());
+  }
+
+  //! Returns min size parameter.
+  inline Standard_Real GetMinSize() const
+  {
+    return myMinSize;
+  }
+
   //! Enables/disables internal vertices mode.
   inline void SetInternalVerticesMode(const Standard_Boolean isEnabled)
   {
@@ -205,6 +217,7 @@ protected:
   Standard_Real                               myMaxShapeSize;
   Standard_Integer                            myStatus;
   NCollection_Vector<TopoDS_Face>             myFaces;
+  Standard_Real                               myMinSize;
   Standard_Boolean                            myInternalVerticesMode;
 };
 
index fc5c30e..a5f37c7 100644 (file)
@@ -79,7 +79,8 @@ is
            AngularDeflection   : Real;         --- Deffault value 0.2; 
            CurvatureDeflection : Real;         --- Deffault value 0.05;
            MinimumOfPoints     : Integer = 2;
-           UTol                : Real    = 1.0e-9)
+           UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     returns TangentialDeflection raises ConstructionError;
 
 
@@ -89,7 +90,8 @@ is
            AngularDeflection   : Real;         --- Deffault value 0.2;   
            CurvatureDeflection : Real;         --- Deffault value 0.05;
            MinimumOfPoints     : Integer = 2;
-           UTol                : Real    = 1.0e-9)
+           UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     returns TangentialDeflection raises ConstructionError;
 
 
@@ -97,7 +99,8 @@ is
            AngularDeflection   : Real;         --- Deffault value 0.2; 
            CurvatureDeflection : Real;         --- Deffault value 0.05;
            MinimumOfPoints     : Integer = 2;
-           UTol                : Real    = 1.0e-9)
+           UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     returns TangentialDeflection raises ConstructionError;
 
 
@@ -107,7 +110,8 @@ is
            AngularDeflection   : Real;         --- Deffault value 0.2;
            CurvatureDeflection : Real;         --- Deffault value 0.05;
            MinimumOfPoints     : Integer = 2;
-           UTol                : Real    = 1.0e-9)
+           UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     returns TangentialDeflection raises ConstructionError;
      
 
@@ -116,7 +120,8 @@ is
                 AngularDeflection   : Real;    --- Deffault value 0.2;
                 CurvatureDeflection : Real;    --- Deffault value 0.05;
                MinimumOfPoints     : Integer = 2;
-               UTol                : Real    = 1.0e-9)
+               UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     raises ConstructionError is static;
                
 
@@ -127,7 +132,8 @@ is
                 AngularDeflection   : Real;    --- Deffault value 0.2;
                CurvatureDeflection : Real;     --- Deffault value 0.05; 
                MinimumOfPoints     : Integer = 2;
-               UTol                : Real    = 1.0e-9)
+               UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     raises ConstructionError is static;
 
 
@@ -136,7 +142,8 @@ is
                 AngularDeflection   : Real;    --- Deffault value 0.2;
                 CurvatureDeflection : Real;    --- Deffault value 0.05;
                MinimumOfPoints     : Integer = 2;
-               UTol                : Real    = 1.0e-9)
+               UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     raises ConstructionError is static;
                
 
@@ -147,7 +154,8 @@ is
                 AngularDeflection   : Real;    --- Deffault value 0.2;
                CurvatureDeflection : Real;     --- Deffault value 0.05; 
                MinimumOfPoints     : Integer = 2;
-               UTol                : Real    = 1.0e-9)
+               UTol                : Real    = 1.0e-9;
+          theMinLen           : Real    = 1.0e-7)
     raises ConstructionError is static;
 
 
@@ -208,6 +216,13 @@ is
     is static private;             
 
 
+    ArcAngularStep(myclass;
+                   theRadius            : Real;
+                   theLinearDeflection  : Real;
+                   theAngularDeflection : Real;
+                   theMinLength         : Real) returns Real;
+    ---Purpose: Computes angular step for the arc using the given parameters.
+
 
 fields
  
@@ -215,6 +230,7 @@ fields
     curvatureDeflection : Real; 
     uTol                : Real;
     minNbPnts           : Integer;
+    myMinLen            : Real;
     lastu               : Real;
     firstu              : Real;
 
index 67be385..7b06efe 100644 (file)
@@ -107,6 +107,33 @@ Standard_Integer GCPnts_TangentialDeflection::AddPoint
   return index;
 }
 
+//=======================================================================
+//function : ArcAngularStep
+//purpose  : 
+//=======================================================================
+Standard_Real GCPnts_TangentialDeflection::ArcAngularStep(
+  const Standard_Real theRadius,
+  const Standard_Real theLinearDeflection,
+  const Standard_Real theAngularDeflection,
+  const Standard_Real theMinLength)
+{
+  Standard_ConstructionError_Raise_if(theRadius < 0.0, "Negative radius");
+
+  const Standard_Real aPrecision = Precision::Confusion();
+
+  Standard_Real Du = 0.0, aMinSizeAng = 0.0;
+  if (theRadius > aPrecision)
+  {
+    Du = Max(1.0 - (theLinearDeflection / theRadius), 0.0);
+
+    // It is not suitable to consider min size greater than 1/4 arc len.
+    if (theMinLength > aPrecision)
+      aMinSizeAng = Min(theMinLength / theRadius, M_PI_2);
+  }
+  Du = 2.0 * ACos(Du);
+  Du = Max(Min(Du, theAngularDeflection), aMinSizeAng);
+  return Du;
+}
 
 #include <Geom_BezierCurve.hxx>
 #include <Geom_BSplineCurve.hxx>
index ec58692..c7b3c81 100644 (file)
@@ -40,7 +40,7 @@ void GCPnts_TangentialDeflection::EvaluateDu (
     Standard_Real Lc = N.CrossMagnitude (T);
     Standard_Real Ln = Lc/Lt;
     if (Ln > LTol) {
-      Du = sqrt (8.0 * curvatureDeflection / Ln);
+      Du = sqrt (8.0 * Max(curvatureDeflection, myMinLen) / Ln);
       NotDone = Standard_False;
     }
   }
@@ -57,10 +57,11 @@ GCPnts_TangentialDeflection::GCPnts_TangentialDeflection (
  const Standard_Real    AngularDeflection,
  const Standard_Real    CurvatureDeflection,
  const Standard_Integer MinimumOfPoints,
- const Standard_Real    UTol)
+ const Standard_Real    UTol,
+ const Standard_Real    theMinLen)
 
 { 
-  Initialize (C,AngularDeflection,CurvatureDeflection,MinimumOfPoints,UTol); 
+  Initialize (C,AngularDeflection,CurvatureDeflection,MinimumOfPoints,UTol,theMinLen); 
 }
 
 
@@ -76,7 +77,8 @@ GCPnts_TangentialDeflection::GCPnts_TangentialDeflection (
  const Standard_Real    AngularDeflection,
  const Standard_Real    CurvatureDeflection,
  const Standard_Integer MinimumOfPoints,
- const Standard_Real    UTol)
+ const Standard_Real    UTol,
+ const Standard_Real    theMinLen)
 
 { 
   Initialize (C, 
@@ -85,7 +87,7 @@ GCPnts_TangentialDeflection::GCPnts_TangentialDeflection (
         AngularDeflection, 
         CurvatureDeflection, 
         MinimumOfPoints,
-        UTol);
+        UTol, theMinLen);
 }
 
 
@@ -100,7 +102,8 @@ void GCPnts_TangentialDeflection::Initialize (
  const Standard_Real    AngularDeflection, 
  const Standard_Real    CurvatureDeflection,
  const Standard_Integer MinimumOfPoints,
- const Standard_Real    UTol)
+ const Standard_Real    UTol,
+ const Standard_Real    theMinLen)
 
 {
   Initialize (C, 
@@ -109,7 +112,7 @@ void GCPnts_TangentialDeflection::Initialize (
               AngularDeflection, 
               CurvatureDeflection,
               MinimumOfPoints,
-              UTol);
+              UTol, theMinLen);
 }
 
 
@@ -125,7 +128,8 @@ void GCPnts_TangentialDeflection::Initialize (
  const Standard_Real    AngularDeflection, 
  const Standard_Real    CurvatureDeflection,
  const Standard_Integer MinimumOfPoints,
- const Standard_Real    UTol)
+ const Standard_Real    UTol,
+ const Standard_Real    theMinLen)
 
 {
   
@@ -145,6 +149,7 @@ void GCPnts_TangentialDeflection::Initialize (
  angularDeflection   = AngularDeflection;
  curvatureDeflection = CurvatureDeflection;
  minNbPnts           = Max (MinimumOfPoints, 2);
+ myMinLen            = Max(theMinLen, Precision::Confusion());
 
  switch (C.GetType()) {
 
@@ -202,7 +207,6 @@ void GCPnts_TangentialDeflection::PerformLinear (const TheCurve& C) {
   points    .Append (P);
 }
 
-
 //=======================================================================
 //function : PerformCircular
 //purpose  : 
@@ -212,18 +216,18 @@ void GCPnts_TangentialDeflection::PerformCircular (const TheCurve& C)
 {
   // akm 8/01/02 : check the radius before divide by it
   Standard_Real dfR = C.Circle().Radius();
-  Standard_Real Du = 0.;
-  if (Abs(dfR) > Precision::Confusion())
-    Du = Max(1.0e0 - (curvatureDeflection/dfR),0.0e0) ;
-  Du  = acos (Du); Du+=Du;
-  Du               = Min (Du, angularDeflection);
-  Standard_Integer NbPoints = (Standard_Integer )((lastu - firstu) / Du);
-  NbPoints         = Max (NbPoints, minNbPnts-1);
-  Du               = (lastu - firstu) / NbPoints;
+  Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep(
+    dfR, curvatureDeflection, angularDeflection, myMinLen);
+    
+  const Standard_Real aDiff = lastu - firstu;
+  Standard_Integer NbPoints = (Standard_Integer)(aDiff / Du);
+  NbPoints = Max(NbPoints, minNbPnts - 1);
+  Du       = aDiff / NbPoints;
 
   gp_Pnt P;
   Standard_Real U = firstu;
-  for (Standard_Integer i = 1; i <= NbPoints; i++) {
+  for (Standard_Integer i = 1; i <= NbPoints; i++)
+  {
     D0 (C, U, P);
     parameters.Append (U);
     points    .Append (P);
@@ -265,22 +269,22 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
   parameters.Append (U1);
   points    .Append (CurrentPoint);
 
-  if (NotDone) {
+  if (NotDone)
+  {
     //C'est soit une droite, soit une singularite :
-    V1 = LastPoint.XYZ ();
-    V1.Subtract (CurrentPoint.XYZ());
+    V1 = (LastPoint.XYZ() - CurrentPoint.XYZ());
     L1 = V1.Modulus ();
-    if (L1 > LTol) {
+    if (L1 > LTol)
+    {
       //Si c'est une droite on verifie en calculant minNbPoints :
       Standard_Boolean IsLine   = Standard_True;
-      Standard_Integer NbPoints = 3;
-      if (minNbPnts > 3) NbPoints = minNbPnts;
+      Standard_Integer NbPoints = (minNbPnts > 3) ? minNbPnts : 3;
       ////
       Standard_Integer NbInterv = const_cast<TheCurve*>(&C)->NbIntervals(GeomAbs_CN);
       TColStd_Array1OfReal Intervs(1, NbInterv+1);
       const_cast<TheCurve*>(&C)->Intervals(Intervs, GeomAbs_CN);
       Standard_Real param = 0.;
-      for (i = 1; i <= NbInterv; i++)
+      for (i = 1; i <= NbInterv && IsLine; ++i)
       {
         // Avoid usage intervals out of [firstu, lastu].
         if ((Intervs(i+1) < firstu) ||
@@ -301,56 +305,44 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
         }
 
         Standard_Real delta = (Intervs(i+1) - Intervs(i))/NbPoints;
-        for (j = 1; j <= NbPoints; j++)
+        for (j = 1; j <= NbPoints && IsLine; ++j)
         {
           param = Intervs(i) + j*delta;
           D0 (C, param, MiddlePoint);
-          V2 = MiddlePoint.XYZ();
-          V2.Subtract (CurrentPoint.XYZ());
+          V2 = (MiddlePoint.XYZ() - CurrentPoint.XYZ());
           L2 = V2.Modulus ();
-          if (L2 > LTol) {
-            if (((V2.CrossMagnitude (V1))/(L1*L2)) >= ATol) {
-              //C'etait une singularite
-              IsLine = Standard_False;
-              break;
-            }
-            if (minNbPnts > 2) {
-              parameters.Append (param);
-              points    .Append (MiddlePoint);
-            }
+          if (L2 > LTol)
+          {
+            const Standard_Real aAngle = V2.CrossMagnitude(V1)/(L1*L2);
+            IsLine = (aAngle < ATol);
           }
         }
-        if (!IsLine)
-          break;
       }
-      ////
-      if (IsLine) {
-        //C'etait une droite (plusieurs poles alignes), Calcul termine :
-        parameters.Append (lastu);
-        points    .Append (LastPoint);
+
+      if (IsLine)
+      {
+        parameters.Clear();
+        points    .Clear();
+
+        PerformLinear(C);
         return;
       }
-      else {
+      else
+      {
         //c'etait une singularite on continue :
-        Standard_Integer pointsLength=points.Length ();
-        for (i = 2; i <= pointsLength; i++) {
-          points    .Remove (i);
-          parameters.Remove (i);
-          pointsLength--;
-        }
         //Du = Dusave;
         EvaluateDu (C, param, MiddlePoint, Du, NotDone);
       }
     }
-    else  {
-      
+    else
+    {
       Du = (lastu-firstu)/2.1;
       MiddleU = firstu + Du;
       D0 (C, MiddleU, MiddlePoint);
-      V1 = MiddlePoint.XYZ ();
-      V1.Subtract (CurrentPoint.XYZ());
+      V1 = (MiddlePoint.XYZ() - CurrentPoint.XYZ());
       L1 = V1.Modulus ();
-      if (L1 < LTol) {
+      if (L1 < LTol)
+      {
         // L1 < LTol C'est une courbe de longueur nulle, calcul termine :
         // on renvoi un segment de 2 points   (protection)
         parameters.Append (lastu);
@@ -401,19 +393,17 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
       MiddleU = (U1+U2)*0.5;                 //Verif / au point milieu
       D0 (C, MiddleU, MiddlePoint);
 
-      V1 = CurrentPoint.XYZ ();              //Critere de fleche
-      V1.Subtract (aPrevPoint.XYZ());
-      V2 = MiddlePoint.XYZ ();
-      V2.Subtract (aPrevPoint.XYZ());
+      V1 = (CurrentPoint.XYZ() - aPrevPoint.XYZ()); //Critere de fleche
+      V2 = (MiddlePoint.XYZ()  - aPrevPoint.XYZ());
       L1 = V1.Modulus ();
-      if (L1 > LTol) FCoef = V1.CrossMagnitude(V2)/(L1*curvatureDeflection);
-      else           FCoef = 0.0;
 
-      V1 = CurrentPoint.XYZ ();              //Critere d'angle
-      V1.Subtract (MiddlePoint.XYZ ());
+      FCoef = (L1 > myMinLen) ? 
+        V1.CrossMagnitude(V2)/(L1*curvatureDeflection) : 0.0;
+
+      V1 = (CurrentPoint.XYZ() - MiddlePoint.XYZ()); //Critere d'angle
       L1 = V1.Modulus ();
       L2 = V2.Modulus ();
-      if (L1 > LTol && L2 > LTol)
+      if (L1 > myMinLen && L2 > myMinLen)
       {
         Standard_Real angg = V1.CrossMagnitude(V2) / (L1 * L2);
         ACoef = angg / AngleMax;
@@ -421,9 +411,8 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
       else
         ACoef = 0.0;
 
-      if (ACoef >= FCoef) Coef = ACoef;      //On retient le plus penalisant
-      else                Coef = FCoef;
-
+      //On retient le plus penalisant
+      Coef = Max(ACoef, FCoef);
 
       if (Coef <= 1.0) {
         if (Abs (lastu-U2) < uTol) {
index 30bdb55..372049d 100644 (file)
@@ -127,9 +127,13 @@ static Standard_Integer incrementalmesh(Draw_Interpretor& di, Standard_Integer n
 Builds triangular mesh for the shape\n\
 usage: incmesh Shape LinearDeflection [options]\n\
 options:\n\
-        -a val          angular deflection in deg (default ~28.64 deg = 0.5 rad)\n\
+        -a val          angular deflection in deg\n\
+                        (default ~28.64 deg = 0.5 rad)\n\n\
+        -min            minimum size parameter limiting size of triangle's\n\
+                        edges to prevent sinking into amplification in case\n\
+                        of distorted curves and surfaces\n\n\
         -relative       notifies that relative deflection is used\n\
-                        (switched off by default)\n\
+                        (switched off by default)\n\n\
         -int_vert_off   disables insertion of internal vertices into mesh\n\
                         (enabled by default)\n\
         -parallel       enables parallel execution (switched off by default)\n";
@@ -145,6 +149,7 @@ options:\n\
 
   Standard_Real aLinDeflection   = Max(Draw::Atof(argv[2]), Precision::Confusion());
   Standard_Real aAngDeflection   = 0.5;
+  Standard_Real aMinSize         = Precision::Confusion();
   Standard_Boolean isRelative    = Standard_False;
   Standard_Boolean isInParallel  = Standard_False;
   Standard_Boolean isIntVertices = Standard_True;
@@ -170,6 +175,8 @@ options:\n\
         Standard_Real aVal = Draw::Atof(argv[i++]);
         if (aOpt == "-a")
           aAngDeflection = aVal * M_PI / 180.;
+        else if (aOpt == "-min")
+          aMinSize = aVal;
         else
           --i;
       }
@@ -180,11 +187,12 @@ options:\n\
      << (isInParallel ? "ON" : "OFF") << "\n";
 
   BRepMesh_IncrementalMesh aMesher;
-  aMesher.SetShape               (aShape);
-  aMesher.SetDeflection          (aLinDeflection);
-  aMesher.SetRelative            (isRelative);
-  aMesher.SetAngle               (aAngDeflection);
-  aMesher.SetParallel            (isInParallel);
+  aMesher.SetShape     (aShape);
+  aMesher.SetDeflection(aLinDeflection);
+  aMesher.SetRelative  (isRelative);
+  aMesher.SetAngle     (aAngDeflection);
+  aMesher.SetParallel  (isInParallel);
+  aMesher.SetMinSize   (aMinSize);
   aMesher.SetInternalVerticesMode(isIntVertices);
   aMesher.Perform();
 
index 4d7a00a..a479b20 100755 (executable)
@@ -143,6 +143,20 @@ proc checkList {List Tolerance D_good Limit_Tol} {
    }
 }
 
+# Check expected time
+proc checktime {value expected tol_rel message} {
+   set t1 [expr ${value} - ${expected}]
+   set t2 [expr ${expected} * abs (${tol_rel})]
+
+   if { abs (${t1}) <= ${t2} } {                                         
+      puts "OK. ${message}, ${value} seconds, is equal to expected time - ${expected} seconds"
+   } elseif {${t1} > ${t2}} {
+      puts "Error. ${message}, ${value} seconds, is more than expected time - ${expected} seconds"
+   } else {
+      puts "Improvement. ${message}, ${value} seconds, is less than expected time - ${expected} seconds"
+   }
+}
+
 # Procedure to check result of nbshapes command
 proc checknbshapes { res nbshapes_expected_s count_locations message} {
 
index 1915098..36e80fa 100644 (file)
@@ -9,13 +9,13 @@ puts ""
 pcone aCone 100 10 100
 
 tclean aCone
-incmesh aCone 0.01 -a 0.4
+incmesh aCone 0.01 -a 10.
 set bug_info [trinfo aCone]
 set NbTrian_1 [lindex $bug_info 3]
 set NbNodes_1 [lindex $bug_info 5]
 
 tclean aCone
-incmesh aCone 0.01 -a 0.3
+incmesh aCone 0.01 -a 1.
 set bug_info [trinfo aCone]
 set NbTrian_2 [lindex $bug_info 3]
 set NbNodes_2 [lindex $bug_info 5]
diff --git a/tests/bugs/mesh/bug25378_1_1 b/tests/bugs/mesh/bug25378_1_1
new file mode 100755 (executable)
index 0000000..cf8775f
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_bad.brep] b
+trinfo b
+
+tclean b
+set t_1 [expr [lindex [time {incmesh b 0.1}] 0]/1000000]
+puts "t_1=${t_1}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_1 75
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_1 25
+  } else {
+    set max_t_1 25
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_1} ${max_t_1} ${tol_percent} "1. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_1_2 b/tests/bugs/mesh/bug25378_1_2
new file mode 100755 (executable)
index 0000000..1c6298f
--- /dev/null
@@ -0,0 +1,32 @@
+puts "TODO OCC25378 Debian60-64: is more than expected time - 120 seconds"
+puts "TODO ?OCC25378    Windows: is more than expected time - 120 seconds"
+
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_bad.brep] b
+trinfo b
+
+tclean b
+set t_01 [expr [lindex [time {incmesh b 0.01}] 0]/1000000]
+puts "t_01=${t_01}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_01 250
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_01 120
+  } else {
+    set max_t_01 120
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_01} ${max_t_01} ${tol_percent} "2. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_1_3 b/tests/bugs/mesh/bug25378_1_3
new file mode 100755 (executable)
index 0000000..b3ae3a4
--- /dev/null
@@ -0,0 +1,35 @@
+puts "TODO OCC25378 Debian60-64: is more than expected time - 700 seconds"
+puts "TODO OCC25378     Windows: is more than expected time - 450 seconds"
+
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+cpulimit 1500
+
+restore [locate_data_file bug25378_Blower_bad.brep] b
+trinfo b
+
+tclean b
+set t_001 [expr [lindex [time {incmesh b 0.001}] 0]/1000000]
+puts "t_001=${t_001}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    cpulimit 2000
+    set max_t_001 1400
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_001 450
+  } else {
+    set max_t_001 700
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_001} ${max_t_001} ${tol_percent} "3. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_2_1 b/tests/bugs/mesh/bug25378_2_1
new file mode 100644 (file)
index 0000000..d5c9aac
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_bad.brep] b
+trinfo b
+
+tclean b
+set t_1 [expr [lindex [time {incmesh b 0.1 -min 0.5}] 0]/1000000]
+puts "t_1=${t_1}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_1 5
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_1 1
+  } else {
+    set max_t_1 1
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_1} ${max_t_1} ${tol_percent} "1. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_2_2 b/tests/bugs/mesh/bug25378_2_2
new file mode 100644 (file)
index 0000000..5bd9130
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_bad.brep] b
+trinfo b
+
+tclean b
+set t_01 [expr [lindex [time {incmesh b 0.01 -min 0.1}] 0]/1000000]
+puts "t_01=${t_01}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_01 30
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_01 10
+  } else {
+    set max_t_01 5
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_01} ${max_t_01} ${tol_percent} "2. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_2_3 b/tests/bugs/mesh/bug25378_2_3
new file mode 100644 (file)
index 0000000..d3826cb
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_bad.brep] b
+trinfo b
+
+tclean b
+set t_001 [expr [lindex [time {incmesh b 0.001 -min 1}] 0]/1000000]
+puts "t_001=${t_001}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_001 30
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_001 10
+  } else {
+    set max_t_001 5
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_001} ${max_t_001} ${tol_percent} "3. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_3_1 b/tests/bugs/mesh/bug25378_3_1
new file mode 100644 (file)
index 0000000..e21bea0
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_good.brep] b
+trinfo b
+
+tclean b
+set t_1 [expr [lindex [time {incmesh b 0.1}] 0]/1000000]
+puts "t_1=${t_1}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_1 3
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_1 1
+  } else {
+    set max_t_1 1
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_1} ${max_t_1} ${tol_percent} "1. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_3_2 b/tests/bugs/mesh/bug25378_3_2
new file mode 100644 (file)
index 0000000..bc2e093
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_good.brep] b
+trinfo b
+
+tclean b
+set t_01 [expr [lindex [time {incmesh b 0.01}] 0]/1000000]
+puts "t_01=${t_01}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_01 3
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_01 1
+  } else {
+    set max_t_01 1
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_01} ${max_t_01} ${tol_percent} "2. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_3_3 b/tests/bugs/mesh/bug25378_3_3
new file mode 100644 (file)
index 0000000..ac81238
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_good.brep] b
+trinfo b
+
+tclean b
+set t_001 [expr [lindex [time {incmesh b 0.001}] 0]/1000000]
+puts "t_001=${t_001}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_001 50
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_001 20
+  } else {
+    set max_t_001 20
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_001} ${max_t_001} ${tol_percent} "3. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_4_1 b/tests/bugs/mesh/bug25378_4_1
new file mode 100644 (file)
index 0000000..3c46a29
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_good.brep] b
+trinfo b
+
+tclean b
+set t_1 [expr [lindex [time {incmesh b 0.1 -min 0.5}] 0]/1000000]
+puts "t_1=${t_1}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_1 5
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_1 2
+  } else {
+    set max_t_1 2
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_1} ${max_t_1} ${tol_percent} "1. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_4_2 b/tests/bugs/mesh/bug25378_4_2
new file mode 100644 (file)
index 0000000..523347f
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_good.brep] b
+trinfo b
+
+tclean b
+set t_01 [expr [lindex [time {incmesh b 0.01 -min 0.1}] 0]/1000000]
+puts "t_01=${t_01}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_01 5
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_01 2
+  } else {
+    set max_t_01 2
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_01} ${max_t_01} ${tol_percent} "2. Time of building of triangulation "
diff --git a/tests/bugs/mesh/bug25378_4_3 b/tests/bugs/mesh/bug25378_4_3
new file mode 100644 (file)
index 0000000..5d91afe
--- /dev/null
@@ -0,0 +1,29 @@
+puts "============"
+puts "CR25378"
+puts "============"
+puts ""
+###################################################################################
+# Building of triangulation for distored surfaces can take very long using BRepMesh_IncrementalMesh
+###################################################################################
+
+restore [locate_data_file bug25378_Blower_good.brep] b
+trinfo b
+
+tclean b
+set t_001 [expr [lindex [time {incmesh b 0.001 -min 1}] 0]/1000000]
+puts "t_001=${t_001}"
+trinfo b
+
+if { [regexp {Debug mode} [dversion]] } {
+    set max_t_001 5
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_t_001 2
+  } else {
+    set max_t_001 2
+  }
+}
+
+set tol_percent 0.05
+
+checktime ${t_001} ${max_t_001} ${tol_percent} "3. Time of building of triangulation "
index 4da6b73..b316d39 100755 (executable)
@@ -1,4 +1,3 @@
-
 puts "========="
 puts "BUC60587"
 puts "========="
@@ -20,11 +19,11 @@ vsetcolor result CYAN3
 set x_coord 120
 set y_coord 180
 
-checkcolor $x_coord $y_coord 0.7 1 0.9
+#checkcolor $x_coord $y_coord 0.7 1 0.9
+checkcolor $x_coord $y_coord 0 0.90980392694473267 0.90980392694473267
 
 if { $stat != 1 } {
    puts "Error : Model has NOT CYAN colour."
 }
 
 set only_screen 1
-
index 7c47739..d20ef3b 100755 (executable)
@@ -1,5 +1,10 @@
 set TheFileName shading_012.brep
 ###set bug_withouttri "OCC22687"
 ###set nbwithouttri(All) 1
-set bug_freelinks "OCC23106"
-set nbfree(All) 4
+if { [string compare $command "shading"] == 0 } {
+   set bug_freelinks "OCC23106"
+   set nbfree(All) 4
+} else {
+   set bug_freelinks "OCC25378"
+   set nbfree(All) 3
+}