0027362: Meshing performance
authormsv <msv@opencascade.com>
Wed, 4 May 2016 01:12:28 +0000 (04:12 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 7 Jul 2016 11:24:39 +0000 (14:24 +0300)
1) BRepMesh_FastDiscretFace.cxx:
- exclude planes from procedure of inserting internal points.
- localize declaration of the container aNewVertices in each method where it is needed.
- correct the logic of the method insertInternalVerticesOther, so that to separate the processes of removing extra points and addition of new points in different cycles, thus making the code more clear and in addition stable.
- insert useful output of intermediate mesh to a file in control() method for debug purposes (with definition DEBUG_MESH).

2) Add global functions MeshTest_DrawTriangles and MeshTest_DrawLinks to draw mesh data in debug session.

3) BRepMesh_FastDiscret:
- in the method Add calculations of deflections have been simplified for non-relative mode.
- replace the attribute MinDist with Deflection in EdgeAttributes structure. Correct its computation so that later to store this value as deflection of the polygon.

4) Make protection against exception in the method BRepMesh_Delaun::addTriangle() when an added triangle creates a third connection of a mesh edge.

5) BRepMesh_EdgeTessellator.cxx, BRepMesh_EdgeTessellationExtractor.cxx: use Geom2dAdaptor_Curve in order to use b-spline cache while computing value on a curve.

6) In BndLib_Box2dCurve::PerformBSpline, avoid creating new b-spline in case of requested parameter range differ from natural bounds insignificantly.

7) In GeomAdaptor classes, postpone building of cache till the time of its actual usage. So, creation of an adapter to compute intervals of continuity does not lead to creation of internal cache.

8) In the methods BRepAdaptor_Curve::Bezier and BSpline do not call Transformed() if transformation is identity.

9) In the classes Geom_BSplineCurve, Geom_BSplineSurface, Geom_BezierCurve, Geom_BezierSurface, Geom2d_BSplineCurve, Geom2d_BezierCurve change the method Pole() to return the point by const reference.

10) In CPnts_AbscissaPoint.cxx, compute derivative by D1 instead of DN to make use of b-spline cache.

11) Change test cases to actual state:
  - Number of triangles/nodes can grow due to more accurate work with deflection of edges. Now the edge is tessellated using its own tolerance instead of maximal tolerance of all shapes in the face.
  - Accept new numbers of mesh errors (free links, free nodes) for really bad shapes.
  - Correct the test "bugs/mesh/bug25612" to produce stable result.
  - Disable redundant checks in test cases bug25378* (lower limit for computation time).

- Speed up iso-lines computation for offset of bspline surfaces. For that use adaptor instead of original surface in evaluator of approximation.
- Add output of polylines for debug of insertInternalVerticesOther().

Reference data in test case bugs\moddata_2\bug453_3 have been changed to be close to expected theoretical values. This makes the test give stable result on different platforms.

65 files changed:
dox/dev_guides/debug/debug.md
src/BRepAdaptor/BRepAdaptor_Curve.cxx
src/BRepMesh/BRepMesh_Delaun.cxx
src/BRepMesh/BRepMesh_Delaun.hxx
src/BRepMesh/BRepMesh_EdgeTessellationExtractor.cxx
src/BRepMesh/BRepMesh_EdgeTessellationExtractor.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_ShapeTool.cxx
src/BRepMesh/BRepMesh_ShapeTool.hxx
src/BndLib/BndLib_Add2dCurve.cxx
src/CPnts/CPnts_AbscissaPoint.cxx
src/Geom/Geom_BSplineCurve.hxx
src/Geom/Geom_BSplineCurve_1.cxx
src/Geom/Geom_BSplineSurface.hxx
src/Geom/Geom_BSplineSurface_1.cxx
src/Geom/Geom_BezierCurve.cxx
src/Geom/Geom_BezierCurve.hxx
src/Geom/Geom_BezierSurface.cxx
src/Geom/Geom_BezierSurface.hxx
src/Geom/Geom_OffsetSurface.cxx
src/Geom2d/Geom2d_BSplineCurve.hxx
src/Geom2d/Geom2d_BSplineCurve_1.cxx
src/Geom2d/Geom2d_BezierCurve.cxx
src/Geom2d/Geom2d_BezierCurve.hxx
src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx
src/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx
src/GeomAdaptor/GeomAdaptor_Curve.cxx
src/GeomAdaptor/GeomAdaptor_Curve.hxx
src/GeomAdaptor/GeomAdaptor_Surface.cxx
src/GeomAdaptor/GeomAdaptor_Surface.hxx
src/MeshTest/FILES
src/MeshTest/MeshTest_Debug.cxx [new file with mode: 0644]
tests/blend/simple/G6
tests/bugs/iges/bug306
tests/bugs/mesh/bug23631
tests/bugs/mesh/bug25378_1_1
tests/bugs/mesh/bug25378_1_2
tests/bugs/mesh/bug25378_1_3
tests/bugs/mesh/bug25378_3_3
tests/bugs/mesh/bug25519
tests/bugs/mesh/bug25612
tests/bugs/modalg_2/bug264_0
tests/bugs/modalg_2/bug287
tests/bugs/modalg_2/bug292
tests/bugs/moddata_1/bug22759
tests/bugs/moddata_2/bug453_3
tests/bugs/moddata_2/fra62476_2
tests/bugs/moddata_3/bug25737_1
tests/bugs/vis/bug288_5
tests/mesh/data/advanced/A7
tests/mesh/data/standard/C7
tests/mesh/data/standard/J8
tests/mesh/data/standard/L2
tests/mesh/data/standard/L6
tests/mesh/data/standard/U7
tests/mesh/data/standard/V4
tests/mesh/data/standard/W4
tests/mesh/data/standard/X3

index c098467..963957c 100644 (file)
@@ -114,6 +114,17 @@ Stores mesh produced in parametric space to BREP file.
 - *theMeshHandlePtr* -- a pointer to *Handle(BRepMesh_DataStructureOfDelaun)* variable.
 - *theFileNameStr* -- the name of the file where the mesh is stored.
 
+The following functions are provided by *TKTopTest* toolkit:
+
+~~~~~
+const char* MeshTest_DrawLinks(const char* theNameStr, void* theFaceAttr)
+const char* MeshTest_DrawTriangles(const char* theNameStr, void* theFaceAttr)
+~~~~~
+
+Sets the edges or triangles from mesh data structure of type *Handle(BRepMesh_FaceAttribute)* as DRAW interpreter variables, assigning a unique name in the form "<theNameStr>_<index>" to each object.
+- *theNameStr* -- the prefix to use in names of objects.
+- *theFaceAttr* -- a pointer to *Handle(BRepMesh_FaceAttribute)* variable.
+
 The following additional function is provided by *TKGeomBase* toolkit:
 
 ~~~~~
index 61fae26..ca986ab 100644 (file)
@@ -627,7 +627,8 @@ Handle(Geom_BezierCurve) BRepAdaptor_Curve::Bezier() const
   else {
     BC = myConSurf->Bezier();
   }
-  return Handle(Geom_BezierCurve)::DownCast(BC->Transformed(myTrsf));
+  return myTrsf.Form() == gp_Identity
+    ? BC : Handle(Geom_BezierCurve)::DownCast(BC->Transformed(myTrsf));
 }
 
 
@@ -645,5 +646,6 @@ Handle(Geom_BSplineCurve) BRepAdaptor_Curve::BSpline() const
   else {
     BS = myConSurf->BSpline();
   }
-  return Handle(Geom_BSplineCurve)::DownCast(BS->Transformed(myTrsf));
+  return myTrsf.Form() == gp_Identity
+    ? BS : Handle(Geom_BSplineCurve)::DownCast(BS->Transformed(myTrsf));
 }
index 6d10ac5..6c82eb1 100644 (file)
@@ -1086,10 +1086,17 @@ Standard_Boolean BRepMesh_Delaun::checkIntersection(
 //function : addTriangle
 //purpose  : Add a triangle based on the given oriented edges into mesh
 //=======================================================================
-inline void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
-                                          const Standard_Boolean (&theEdgesOri)[3],
-                                          const Standard_Integer (&theNodesId)[3] )
+void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
+                                   const Standard_Boolean (&theEdgesOri)[3],
+                                   const Standard_Integer (&theNodesId)[3])
 {
+  for (Standard_Integer i = 0; i < 3; ++i)
+  {
+    const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(theEdgesId[i]);
+    if (aPair.Extent() == 2)
+      // it is forbidden to have more than two triangles connected to the same link
+      return;
+  }
   Standard_Integer aNewTriangleId = 
     myMeshData->AddElement(BRepMesh_Triangle(theEdgesId, 
       theEdgesOri, BRepMesh_Free));
index 14fa8d4..37db10c 100755 (executable)
@@ -223,9 +223,9 @@ private:
                         BRepMesh::MapOfIntegerInteger& thePoly);
 
   //! Add a triangle based on the given oriented edges into mesh
-  inline void addTriangle (const Standard_Integer (&theEdgesId)[3],
-                           const Standard_Boolean (&theEdgesOri)[3],
-                           const Standard_Integer (&theNodesId)[3]);
+  void addTriangle (const Standard_Integer (&theEdgesId)[3],
+                    const Standard_Boolean (&theEdgesOri)[3],
+                    const Standard_Integer (&theNodesId)[3]);
 
   //! Deletes the triangle with the given index and adds the free edges into the map.
   //! When an edge is suppressed more than one time it is destroyed.
index d85d093..5fbb1bb 100644 (file)
@@ -14,7 +14,7 @@
 // commercial license or contractual agreement.
 
 #include <BRepMesh_EdgeTessellationExtractor.hxx>
-#include <Geom2d_Curve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
 #include <Poly_PolygonOnTriangulation.hxx>
 #include <Poly_Triangulation.hxx>
 #include <BRepMesh_ShapeTool.hxx>
@@ -28,7 +28,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellationExtractor,BRepMesh_IEdgeTool
 //=======================================================================
 BRepMesh_EdgeTessellationExtractor::BRepMesh_EdgeTessellationExtractor(
   const TopoDS_Edge&                          theEdge,
-  const Handle(Geom2d_Curve)&                 thePCurve,
+  const Handle(Geom2dAdaptor_HCurve)&         thePCurve,
   const TopoDS_Face&                          theFace,
   const Handle(Poly_Triangulation)&           theTriangulation,
   const Handle(Poly_PolygonOnTriangulation)&  thePolygon,
index 5b847d3..d7f20a6 100644 (file)
@@ -28,7 +28,7 @@ class Poly_Triangulation;
 class Poly_PolygonOnTriangulation;
 class TopoDS_Edge;
 class TopoDS_Face;
-class Geom2d_Curve;
+class Geom2dAdaptor_HCurve;
 
 //! Auxiliary class implements functionality retrieving tessellated
 //! representation of an edge stored in polygon.
@@ -40,7 +40,7 @@ public:
   //! Initializes extractor.
   BRepMesh_EdgeTessellationExtractor(
     const TopoDS_Edge&                          theEdge,
-    const Handle(Geom2d_Curve)&                 thePCurve,
+    const Handle(Geom2dAdaptor_HCurve)&         thePCurve,
     const TopoDS_Face&                          theFace,
     const Handle(Poly_Triangulation)&           theTriangulation,
     const Handle(Poly_PolygonOnTriangulation)&  thePolygon,
@@ -76,7 +76,7 @@ private:
 private:
 
   BRepMesh_EdgeParameterProvider myProvider;
-  const Handle(Geom2d_Curve)&    myPCurve;
+  Handle(Geom2dAdaptor_HCurve)   myPCurve;
   const TColgp_Array1OfPnt&      myNodes;
   const TColStd_Array1OfInteger& myIndices;
   const TopLoc_Location          myLoc;
index d189560..b35b3bc 100644 (file)
@@ -17,6 +17,7 @@
 #include <Geom_Surface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom2d_Curve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <BRepAdaptor_HSurface.hxx>
@@ -66,9 +67,11 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
   const GeomAbs_CurveType aCurveType = myCOnS.GetType();
   Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287
 
-  // Get range on 2d curve
+  // Get 2d curve and init geom tool
   Standard_Real aFirstParam, aLastParam;
-  BRep_Tool::Range(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
+  Handle(Geom2d_Curve) aCurve2d =
+    BRep_Tool::CurveOnSurface(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
+  myCurve2d.Load(aCurve2d, aFirstParam, aLastParam);
   myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam, 
     aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
 
@@ -94,7 +97,9 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
           Standard_Real aParam;
           gp_Pnt        aPoint3d;
           gp_Pnt2d      aPoint2d;
-          aDetalizator.Value( aNodeIt, mySurface, aParam, aPoint3d, aPoint2d );
+          aDetalizator.Value( aNodeIt, aParam, aPoint3d);
+          myCurve2d.D0(aParam, aPoint2d);
+
           myTool->AddPoint( aPoint3d, aParam, Standard_False );
         }
       }
@@ -122,11 +127,10 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
     TopTools_ListIteratorOfListOfShape aFaceIt(aSharedFaces);
     for (; aFaceIt.More(); aFaceIt.Next())
     {
-      TopLoc_Location aLoc;
-      const TopoDS_Face&   aFace = TopoDS::Face(aFaceIt.Value());
-      Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
+      const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value());
+      BRepAdaptor_Surface aSurf(aFace, Standard_False);
 
-      if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
+      if (aSurf.GetType() == GeomAbs_Plane)
         continue;
 
       Standard_Real aF, aL;
@@ -136,20 +140,20 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
       {
         continue;
       }
+      Geom2dAdaptor_Curve aGACurve(aCurve2d, aF, aL);
 
       aNodesNb = myTool->NbPoints();
       TColStd_Array1OfReal aParamArray(1, aNodesNb);
       for (Standard_Integer i = 1; i <= aNodesNb; ++i)
       {
-        gp_Pnt2d      aTmpUV;
         gp_Pnt        aTmpPnt;
         Standard_Real aParam;
-        myTool->Value(i, mySurface, aParam, aTmpPnt, aTmpUV);
+        myTool->Value(i, aParam, aTmpPnt);
         aParamArray.SetValue(i, aParam);
       }
 
       for (Standard_Integer i = 1; i < aNodesNb; ++i)
-        splitSegment(aSurf, aCurve2d, aParamArray(i), aParamArray(i + 1), 1);
+        splitSegment(aSurf, aGACurve, aParamArray(i), aParamArray(i + 1), 1);
     }
   }
 
@@ -174,7 +178,8 @@ Standard_Boolean BRepMesh_EdgeTessellator::Value(
   gp_Pnt&                thePoint,
   gp_Pnt2d&              theUV)
 {
-  myTool->Value(theIndex, mySurface, theParameter, thePoint, theUV);
+  myTool->Value(theIndex, theParameter, thePoint);
+  myCurve2d.D0(theParameter, theUV);
 
   // If point coordinates are out of surface range, 
   // it is necessary to re-project point.
@@ -207,8 +212,8 @@ Standard_Boolean BRepMesh_EdgeTessellator::Value(
 //purpose  : 
 //=======================================================================
 void BRepMesh_EdgeTessellator::splitSegment(
-  const Handle(Geom_Surface)& theSurf,
-  const Handle(Geom2d_Curve)& theCurve2d,
+  const Adaptor3d_Surface&    theSurf,
+  const Geom2dAdaptor_Curve&  theCurve2d,
   const Standard_Real         theFirst,
   const Standard_Real         theLast,
   const Standard_Integer      theNbIter)
@@ -224,17 +229,17 @@ void BRepMesh_EdgeTessellator::splitSegment(
   if(Abs(theLast - theFirst) < 2 * Precision::PConfusion())
     return;
 
-  theCurve2d->D0(theFirst, uvf);
-  theCurve2d->D0(theLast,  uvl);
+  theCurve2d.D0(theFirst, uvf);
+  theCurve2d.D0(theLast,  uvl);
 
-  P3dF = theSurf->Value(uvf.X(), uvf.Y());
-  P3dL = theSurf->Value(uvl.X(), uvl.Y());
+  P3dF = theSurf.Value(uvf.X(), uvf.Y());
+  P3dL = theSurf.Value(uvl.X(), uvl.Y());
   
   if(P3dF.SquareDistance(P3dL) < mySquareMinSize)
     return;
 
   uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
-  midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
+  midP3dFromSurf = theSurf.Value(uvm.X(), uvm.Y());
 
   gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
   if(Vec1.SquareModulus() < mySquareMinSize)
index 80b184d..5af1a9e 100644 (file)
 #include <BRepMesh_GeomTool.hxx>
 #include <BRepMesh_FaceAttribute.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 
-class Geom_Surface;
-class Geom2d_Curve;
+class Adaptor3d_Surface;
 class TopoDS_Edge;
 class BRepAdaptor_HSurface;
 
@@ -70,8 +70,8 @@ public:
 private:
 
   //! 
-  void splitSegment(const Handle(Geom_Surface)& theSurf,
-                    const Handle(Geom2d_Curve)& theCurve2d,
+  void splitSegment(const Adaptor3d_Surface&    theSurf,
+                    const Geom2dAdaptor_Curve&  theCurve2d,
                     const Standard_Real         theFirst,
                     const Standard_Real         theLast,
                     const Standard_Integer      theNbIter);
@@ -80,6 +80,7 @@ private:
   NCollection_Handle<BRepMesh_GeomTool> myTool;
   Handle(BRepAdaptor_HSurface)          mySurface;
   BRepAdaptor_Curve                     myCOnS;
+  Geom2dAdaptor_Curve                   myCurve2d;
   Standard_Real                         mySquareEdgeDef;
   Standard_Real                         mySquareMinSize;
   Standard_Real                         myEdgeSqTol;
index 622a3b2..1d45389 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <Precision.hxx>
 #include <Geom2d_Curve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_Plane.hxx>
 #include <GeomAbs_SurfaceType.hxx>
@@ -205,7 +206,10 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 
     Standard_Real defface = 0.;
     if (!myParameters.Relative)
+    {
+      defedge = Max(UVDEFLECTION, defedge);
       defface = Max(myParameters.Deflection, maxdef);
+    }
 
     const TopoDS_Face&                  aFace = myAttribute->Face();
     for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
@@ -215,9 +219,9 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
         const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Value());
         if (aEdge.IsNull())
           continue;
-        if (!myMapdefle.IsBound(aEdge))
+        if (myParameters.Relative)
         {
-          if (myParameters.Relative)
+          if (!myMapdefle.IsBound(aEdge))
           {
             if (myEdges.IsBound(aEdge))
             {
@@ -232,26 +236,26 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 
               myParameters.Angle = savangle * cdef;
             }
-
-            defface += defedge;
-            defface = Max(maxdef, defface);
           }
           else
           {
-            defedge = myParameters.Deflection;
+            defedge = myMapdefle(aEdge);
           }
 
-          defedge = Max(maxdef, defedge);
-          defedge = Max(UVDEFLECTION, defedge);
-          myMapdefle.Bind(aEdge, defedge);
+          defface += defedge;
+          defface = Max(maxdef, defface);
+
+          if (!myMapdefle.IsBound(aEdge))
+          {
+            defedge = Max(UVDEFLECTION, defedge);
+            myMapdefle.Bind(aEdge, defedge);
+          }
         }
         else
         {
-          defedge = myMapdefle(aEdge);
-          if ( myParameters.Relative )
+          if (!myMapdefle.IsBound(aEdge))
           {
-            defface += defedge;
-            defface = Max(maxdef, defface);
+            myMapdefle.Bind(aEdge, defedge);
           }
         }
 
@@ -261,8 +265,8 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 
         if (aCurve2d.IsNull())
           continue;
-
-        EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
+        Handle(Geom2dAdaptor_HCurve) aPCurve =
+          new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
 
         add(aEdge, aPCurve, defedge);
         myParameters.Angle = savangle;
@@ -418,7 +422,8 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
                 if (aCurve2d.IsNull())
                   continue;
 
-                EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
+                Handle(Geom2dAdaptor_HCurve) aPCurve =
+                  new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
                 add(anEdge, aPCurve, defedge);
               }
             }
@@ -590,7 +595,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 //=======================================================================
 Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
   const TopoDS_Edge&                      theEdge,
-  const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
+  const Handle(Geom2dAdaptor_HCurve)&     thePCurve,
   const Standard_Real                     theDefEdge,
   BRepMesh_FastDiscret::EdgeAttributes&   theAttributes) const
 {
@@ -610,35 +615,34 @@ Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
 
   aEAttr.IsSameUV =
     aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
-
-  //Control tolerance of vertices
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-  gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
-  gp_Pnt pLast  = gFace->Value(aEAttr.LastUV.X(),  aEAttr.LastUV.Y());
-
-  aEAttr.MinDist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(aEAttr.FirstVertex)),
-                             pLast .Distance(BRep_Tool::Pnt(aEAttr.LastVertex)));
-
-  if (aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.FirstVertex) ||
-      aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.LastVertex))
-  {
-    aEAttr.MinDist = theDefEdge;
-  }
-
   if (aEAttr.IsSameUV)
   {
     // 1. is it really sameUV without being degenerated
     gp_Pnt2d uvF, uvL;
-    thePCurve.Curve2d->D0(thePCurve.FirstParam, uvF);
-    thePCurve.Curve2d->D0(thePCurve.LastParam,  uvL);
+    thePCurve->D0(thePCurve->FirstParameter(), uvF);
+    thePCurve->D0(thePCurve->LastParameter(),  uvL);
 
     if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
       aEAttr.FirstUV = uvF;
 
     if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
       aEAttr.LastUV = uvL;
+
+    aEAttr.IsSameUV =
+      aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
   }
 
+  //Control tolerance of vertices
+  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+  gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
+  gp_Pnt pLast  = gFace->Value(aEAttr.LastUV.X(),  aEAttr.LastUV.Y());
+
+  Standard_Real aSqDist = pFirst.SquareDistance(BRep_Tool::Pnt(aEAttr.FirstVertex));
+  aSqDist = Max(aSqDist, pLast.SquareDistance(BRep_Tool::Pnt(aEAttr.LastVertex)));
+
+  aEAttr.Deflection = Max(theDefEdge, BRep_Tool::Tolerance(theEdge));
+  aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
+
   return Standard_True;
 }
 
@@ -670,21 +674,30 @@ void BRepMesh_FastDiscret::registerEdgeVertices(
       new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
   }
 
-  gp_XY aTmpUV;
   // Process first vertex
   ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
-  aTmpUV = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aEAttr.FirstVertex, 
-    aEAttr.MinDist, myAttribute);
+  Standard_Real aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.FirstVertex);
+  gp_XY aTmpUV1 = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aMinDist, myAttribute);
 
-  myAttribute->AddNode(ipf, aTmpUV, BRepMesh_Frontier, ivf, isvf);
+  myAttribute->AddNode(ipf, aTmpUV1, BRepMesh_Frontier, ivf, isvf);
 
   // Process last vertex
   ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
     myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
-  aTmpUV = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aEAttr.LastVertex, 
-    aEAttr.MinDist, myAttribute);
+  aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.LastVertex);
+  gp_XY aTmpUV2 = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aMinDist, myAttribute);
+
+  myAttribute->AddNode(ipl, aTmpUV2, BRepMesh_Frontier, ivl, isvl);
 
-  myAttribute->AddNode(ipl, aTmpUV, BRepMesh_Frontier, ivl, isvl);
+  // Update edge deflection
+  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+  gp_Pnt aPntE1 = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
+  gp_Pnt aPntFound1 = gFace->Value(aTmpUV1.X(), aTmpUV1.Y());
+  Standard_Real aSqDist = aPntE1.SquareDistance(aPntFound1);
+  gp_Pnt aPntE2 = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
+  gp_Pnt aPntFound2 = gFace->Value(aTmpUV2.X(), aTmpUV2.Y());
+  aSqDist = Max(aSqDist, aPntE2.SquareDistance(aPntFound2));
+  aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
 }
 
 //=======================================================================
@@ -693,7 +706,7 @@ void BRepMesh_FastDiscret::registerEdgeVertices(
 //=======================================================================
 void BRepMesh_FastDiscret::add(
   const TopoDS_Edge&                      theEdge,
-  const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
+  const Handle(Geom2dAdaptor_HCurve)&     thePCurve,
   const Standard_Real                     theDefEdge)
 {
   const TopAbs_Orientation orEdge = theEdge.Orientation();
@@ -706,7 +719,7 @@ void BRepMesh_FastDiscret::add(
 
   if (!myEdges.IsBound(theEdge))
   {
-    update(theEdge, thePCurve.Curve2d, theDefEdge, aEAttr);
+    update(theEdge, thePCurve, theDefEdge, aEAttr);
     return;
   }
 
@@ -743,7 +756,7 @@ void BRepMesh_FastDiscret::add(
       const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
 
       const Standard_Real aParam = aProvider.Parameter(i, aPnt);
-      gp_Pnt2d aUV = thePCurve.Curve2d->Value(aParam);
+      gp_Pnt2d aUV = thePCurve->Value(aParam);
 
       Standard_Integer iv2, isv;
       myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
@@ -756,7 +769,7 @@ void BRepMesh_FastDiscret::add(
   Handle(Poly_PolygonOnTriangulation) P1 = 
     new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
 
-  storePolygon(theEdge, P1, theDefEdge);
+  storePolygon(theEdge, P1, aEAttr.Deflection);
 }
 
 //=======================================================================
@@ -765,7 +778,7 @@ void BRepMesh_FastDiscret::add(
 //=======================================================================
 void BRepMesh_FastDiscret::update(
   const TopoDS_Edge&                                theEdge,
-  const Handle(Geom2d_Curve)&                       theC2d,
+  const Handle(Geom2dAdaptor_HCurve)&               theC2d,
   const Standard_Real                               theDefEdge,
   BRepMesh_FastDiscret::EdgeAttributes&             theAttributes)
 {
@@ -885,8 +898,8 @@ void BRepMesh_FastDiscret::update(
     P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
   }
 
-  storePolygon(theEdge, P1, theDefEdge);
-  storePolygonSharedData(theEdge, P2, theDefEdge);
+  storePolygon(theEdge, P1, aEAttr.Deflection);
+  storePolygonSharedData(theEdge, P2, aEAttr.Deflection);
 }
 
 //=======================================================================
index be02361..3db6fee 100644 (file)
@@ -40,8 +40,8 @@ class Bnd_Box;
 class TopoDS_Shape;
 class TopoDS_Face;
 class TopoDS_Edge;
+class Geom2dAdaptor_HCurve;
 class BRepAdaptor_HSurface;
-class Geom2d_Curve;
 class BRepMesh_Edge;
 class BRepMesh_Vertex;
 class gp_Pnt;
@@ -273,27 +273,18 @@ private:
     gp_Pnt2d                            FirstUV;
     gp_Pnt2d                            LastUV;
 
+    Standard_Real                       Deflection;
     Standard_Boolean                    IsSameUV;
-    Standard_Real                       MinDist;
 
     NCollection_Handle<TopoDSVExplorer> FirstVExtractor;
     NCollection_Handle<TopoDSVExplorer> LastVExtractor;
   };
 
-  //! Structure keeps geometrical parameters of edge's PCurve.
-  //! Used for caching.
-  struct EdgePCurve
-  {
-    Handle(Geom2d_Curve) Curve2d;
-    Standard_Real        FirstParam;
-    Standard_Real        LastParam;
-  };
-
   //! Fills structure of by attributes of the given edge.
   //! @return TRUE on success, FALSE elsewhere.
   Standard_Boolean getEdgeAttributes(
     const TopoDS_Edge&  theEdge,
-    const EdgePCurve&   thePCurve,
+    const Handle(Geom2dAdaptor_HCurve)& thePCurve,
     const Standard_Real theDefEdge,
     EdgeAttributes&     theAttributes) const;
 
@@ -311,7 +302,7 @@ private:
   //! Adds tessellated representation of the given edge to
   //! mesh data structure of currently processed face.
   void add(const TopoDS_Edge&  theEdge,
-           const EdgePCurve&   theCurve2D,
+           const Handle(Geom2dAdaptor_HCurve)& theCurve2D,
            const Standard_Real theEdgeDeflection);
 
   //! Updates tessellated representation of the given edge.
@@ -320,7 +311,7 @@ private:
   //! Computes tessellation using edge's geometry elsewhere.
   void update(
     const TopoDS_Edge&          theEdge,
-    const Handle(Geom2d_Curve)& theCurve2D,
+    const Handle(Geom2dAdaptor_HCurve)& theCurve2D,
     const Standard_Real         theEdgeDeflection,
     EdgeAttributes&             theAttributes);
 
index 0b913ad..2abfe72 100644 (file)
 
 #include <algorithm>
 
+//#define DEBUG_MESH "mesh.tcl"
+#ifdef DEBUG_MESH
+#include <fstream>
+#endif
+
 
 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
 
@@ -393,27 +398,28 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
   Standard_Real aDef = -1;
   if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
   {
-    Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
-    BRepMesh::ListOfVertex aNewVertices(anAlloc);
     if (!rajout)
     {
-      aDef = control(aNewVertices, trigu, Standard_True);
+      // compute maximal deflection
+      aDef = control(trigu, Standard_True);
       rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.);
     }
-
-    if (!rajout && useUVParam)
+    if (thetype != GeomAbs_Plane)
     {
-      rajout = (myVParam.Extent() > 2 && 
-        (gFace->IsUClosed() || gFace->IsVClosed()));
-    }
+      if (!rajout && useUVParam)
+      {
+        rajout = (myVParam.Extent() > 2 &&
+          (gFace->IsUClosed() || gFace->IsVClosed()));
+      }
 
-    if (rajout)
-    {
-      insertInternalVertices(aNewVertices, trigu);
+      if (rajout)
+      {
+        insertInternalVertices(trigu);
 
-      //control internal points
-      if (myIsControlSurfaceDeflection)
-        aDef = control(aNewVertices, trigu, Standard_False);
+        //control internal points
+        if (myIsControlSurfaceDeflection)
+          aDef = control(trigu, Standard_False);
+      }
     }
   }
 
@@ -455,7 +461,7 @@ Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
 }
 
 //=======================================================================
-//function : insertInternalVertices
+//function : filterParameters
 //purpose  : 
 //=======================================================================
 static void filterParameters(const BRepMesh::IMapOfReal& theParams,
@@ -516,35 +522,39 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams,
   theResult.Append(aParamArray(aParamLength));
 }
 
-void BRepMesh_FastDiscretFace::insertInternalVertices(
-  BRepMesh::ListOfVertex&  theNewVertices,
-  BRepMesh_Delaun&         theMeshBuilder)
+//=======================================================================
+//function : insertInternalVertices
+//purpose  : 
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBuilder)
 {
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  BRepMesh::ListOfVertex aNewVertices(anAlloc);
   const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
   switch (gFace->GetType())
   {
   case GeomAbs_Sphere:
-      insertInternalVerticesSphere(theNewVertices);
-      break;
+    insertInternalVerticesSphere(aNewVertices);
+    break;
 
   case GeomAbs_Cylinder:
-      insertInternalVerticesCylinder(theNewVertices);
-      break;
+    insertInternalVerticesCylinder(aNewVertices);
+    break;
 
   case GeomAbs_Cone:
-    insertInternalVerticesCone(theNewVertices);
+    insertInternalVerticesCone(aNewVertices);
     break;
 
   case GeomAbs_Torus:
-    insertInternalVerticesTorus(theNewVertices);
+    insertInternalVerticesTorus(aNewVertices);
     break;
 
   default:
-    insertInternalVerticesOther(theNewVertices);
+    insertInternalVerticesOther(aNewVertices);
     break;
   }
   
-  addVerticesToMesh(theNewVertices, theMeshBuilder);
+  addVerticesToMesh(aNewVertices, theMeshBuilder);
 }
 
 //=======================================================================
@@ -856,162 +866,239 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
 
   // check intermediate isolines
   Handle (Geom_Surface) aSurface = gFace->ChangeSurface ().Surface ().Surface ();
-  const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
 
   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();
+  // insert additional points where it is needed to conform criteria.
+  // precision for normals calculation
+  const Standard_Real aNormPrec = Precision::Confusion();
   for (Standard_Integer k = 0; k < 2; ++k)
   {
     const Standard_Integer aOtherIndex = (k + 1) % 2;
     BRepMesh::SequenceOfReal& aParams1 = aParams[k];
     BRepMesh::SequenceOfReal& aParams2 = aParams[aOtherIndex];
     const Standard_Boolean isU = (k == 0);
-    Standard_Integer aStartIndex, aEndIndex; 
-    if (isU)
-    {
-      aStartIndex = 1;
-      aEndIndex   = aParams1.Length();
-    }
-    else
-    {
-      aStartIndex = 2;
-      aEndIndex   = aParams1.Length() - 1;
-    }
-
-    BRepMesh::MapOfReal& aToRemove2          = aParamsToRemove[aOtherIndex];
-    BRepMesh::MapOfReal& aForbiddenToRemove1 = aParamsForbiddenToRemove[k];
-    BRepMesh::MapOfReal& aForbiddenToRemove2 = aParamsForbiddenToRemove[aOtherIndex];
-    for (Standard_Integer i = aStartIndex; i <= aEndIndex; ++i)
+    for (Standard_Integer i = 2; i < aParams1.Length(); ++i)
     {
       const Standard_Real aParam1 = aParams1(i);
       GeomAdaptor_Curve aIso(isU ?
-        aSurface->UIso (aParam1) : aSurface->VIso (aParam1));
+        aSurface->UIso(aParam1) : aSurface->VIso(aParam1));
 
       Standard_Real aPrevParam2 = aParams2(1);
       gp_Pnt aPrevPnt2;
       gp_Vec aPrevVec2;
-      aIso.D1 (aPrevParam2, aPrevPnt2, aPrevVec2);
+      aIso.D1(aPrevParam2, aPrevPnt2, aPrevVec2);
       for (Standard_Integer j = 2; j <= aParams2.Length();)
       {
         Standard_Real aParam2 = aParams2(j);
         gp_Pnt aPnt2;
         gp_Vec aVec2;
-        aIso.D1 (aParam2, aPnt2, aVec2);
+        aIso.D1(aParam2, aPnt2, aVec2);
 
         Standard_Real aMidParam = 0.5 * (aPrevParam2 + aParam2);
         gp_Pnt aMidPnt = aIso.Value(aMidParam);
 
-        Standard_Real aDist = deflectionOfSegment (aPrevPnt2, aPnt2, aMidPnt);
+        Standard_Real aDist = deflectionOfSegment(aPrevPnt2, aPnt2, aMidPnt);
         if (aDist > aDefFace && aDist > myMinSize)
         {
           // insertion 
           aParams2.InsertBefore(j, aMidParam);
+          continue;
+        }
+        //put regular grig for normals
+        gp_Pnt2d aStPnt1, aStPnt2;
+        if (isU)
+        {
+          aStPnt1 = gp_Pnt2d(aParam1, aPrevParam2);
+          aStPnt2 = gp_Pnt2d(aParam1, aMidParam);
         }
         else
         {
-          //put regular grig for normals
-          gp_Pnt2d aStPnt1, aStPnt2;
-          if (isU)
-          {
-            aStPnt1 = gp_Pnt2d(aParam1, aPrevParam2);
-            aStPnt2 = gp_Pnt2d(aParam1, aMidParam);
-          }
-          else
-          {
-            aStPnt1 = gp_Pnt2d(aPrevParam2, aParam1);
-            aStPnt2 = gp_Pnt2d(aMidParam,   aParam1);
-          }
+          aStPnt1 = gp_Pnt2d(aPrevParam2, aParam1);
+          aStPnt2 = gp_Pnt2d(aMidParam, aParam1);
+        }
 
-          gp_Dir N1(0, 0, 1), N2(0, 0, 1);
-          Standard_Boolean aSt1 = GeomLib::NormEstim (aSurface, aStPnt1, aPrecision, N1);
-          Standard_Boolean aSt2 = GeomLib::NormEstim (aSurface, aStPnt2, aPrecision, N2);
+        gp_Dir N1(0, 0, 1), N2(0, 0, 1);
+        Standard_Integer aSt1 = GeomLib::NormEstim(aSurface, aStPnt1, aNormPrec, N1);
+        Standard_Integer aSt2 = GeomLib::NormEstim(aSurface, aStPnt2, aNormPrec, N2);
 
-          const Standard_Real aAngle = N2.Angle(N1);
-          if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle)
-          {
-            const Standard_Real aLen = GCPnts_AbscissaPoint::Length (
-              aIso, aPrevParam2, aMidParam, aDefFace);
+        const Standard_Real aAngle = N2.Angle(N1);
+        if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle)
+        {
+          const Standard_Real aLen = GCPnts_AbscissaPoint::Length(
+            aIso, aPrevParam2, aMidParam, aDefFace);
 
-            if (aLen > myMinSize)
-            {
-              // insertion 
-              aParams2.InsertBefore(j, aMidParam);
-              continue;
-            }
+          if (aLen > myMinSize)
+          {
+            // insertion 
+            aParams2.InsertBefore(j, aMidParam);
+            continue;
           }
+        }
+        aPrevParam2 = aParam2;
+        aPrevPnt2 = aPnt2;
+        aPrevVec2 = aVec2;
 
-          // Here we should leave at least 3 parameters as far as
-          // we must have at least one parameter related to surface
-          // internals in order to prevent movement of triangle body
-          // outside the surface in case of highly curved ones, e.g.
-          // BSpline springs.
-          if (aDist < aDefFace       &&
-              aParams2.Length () > 3 && 
-              j < aParams2.Length ())
+        ++j;
+      }
+    }
+  }
+#ifdef DEBUG_InsertInternal
+  // output numbers of parameters along U and V
+  cout << "aParams: " << aParams[0].Length() << " " << aParams[1].Length() << endl;
+#endif
+  // try to reduce number of points evaluating of isolines sampling
+  for (Standard_Integer k = 0; k < 2; ++k)
+  {
+    const Standard_Integer aOtherIndex = (k + 1) % 2;
+    BRepMesh::SequenceOfReal& aParams1 = aParams[k];
+    BRepMesh::SequenceOfReal& aParams2 = aParams[aOtherIndex];
+    const Standard_Boolean isU = (k == 0);
+    BRepMesh::MapOfReal& aToRemove2          = aParamsToRemove[aOtherIndex];
+    BRepMesh::MapOfReal& aForbiddenToRemove1 = aParamsForbiddenToRemove[k];
+    BRepMesh::MapOfReal& aForbiddenToRemove2 = aParamsForbiddenToRemove[aOtherIndex];
+    for (Standard_Integer i = 2; i < aParams1.Length(); ++i)
+    {
+      const Standard_Real aParam1 = aParams1(i);
+      GeomAdaptor_Curve aIso(isU ?
+        aSurface->UIso (aParam1) : aSurface->VIso (aParam1));
+#ifdef DEBUG_InsertInternal
+      // write polyline containing initial parameters to the file
+      {
+        ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
+        ff << "polyline " << (k == 0 ? "u" : "v") << i << " ";
+        for (Standard_Integer j = 1; j <= aParams2.Length(); j++)
+        {
+          gp_Pnt aP;
+          aIso.D0(aParams2(j), aP);
+          ff << aP.X() << " " << aP.Y() << " " << aP.Z() << " ";
+        }
+        ff << endl;
+      }
+#endif
+
+      Standard_Real aPrevParam2 = aParams2(1);
+      gp_Pnt aPrevPnt2;
+      gp_Vec aPrevVec2;
+      aIso.D1 (aPrevParam2, aPrevPnt2, aPrevVec2);
+      for (Standard_Integer j = 2; j <= aParams2.Length();)
+      {
+        Standard_Real aParam2 = aParams2(j);
+        gp_Pnt aPnt2;
+        gp_Vec aVec2;
+        aIso.D1 (aParam2, aPnt2, aVec2);
+
+        // Here we should leave at least 3 parameters as far as
+        // we must have at least one parameter related to surface
+        // internals in order to prevent movement of triangle body
+        // outside the surface in case of highly curved ones, e.g.
+        // BSpline springs.
+        if (aParams2.Length() > 3 && j < aParams2.Length())
+        {
+          // Remove too dense points
+          const Standard_Real aNextParam = aParams2(j + 1);
+          gp_Pnt aNextPnt;
+          gp_Vec aNextVec;
+          aIso.D1(aNextParam, aNextPnt, aNextVec);
+
+          // Lets check current parameter.
+          // If it fits deflection, we can remove it.
+          Standard_Real aDist = deflectionOfSegment(aPrevPnt2, aNextPnt, aPnt2);
+          if (aDist < aDefFace)
           {
-            // Remove too dense points
-            const Standard_Real aTmpParam = aParams2 (j + 1);
-            gp_Pnt aTmpPnt;
-            gp_Vec aTmpVec;
-            aIso.D1 (aTmpParam, aTmpPnt, aTmpVec);
-
-            Standard_Real aTmpMidParam = 0.5 * (aPrevParam2 + aTmpParam);
-            gp_Pnt        aTmpMidPnt = aIso.Value (aTmpMidParam);
-
-            // Lets check next parameter.
-            // If it also fits deflection, we can remove previous parameter.
-            aDist = deflectionOfSegment (aPrevPnt2, aTmpPnt, aTmpMidPnt);
-            if (aDist < aDefFace)
+            // Lets check parameters for angular deflection.
+            if (aPrevVec2.Angle(aNextVec) < myAngle)
             {
-              // Lets check parameters for angular deflection.
-              if (aPrevVec2.SquareMagnitude() < gp::Resolution() ||
-                  aTmpVec.SquareMagnitude()   < gp::Resolution() ||
-                  aPrevVec2.Angle (aTmpVec)   < myAngle)
+              // For current Iso line we can remove this parameter.
+#ifdef DEBUG_InsertInternal
+              // write point of removed parameter
               {
-                // For current Iso line we can remove this parameter.
-                aToRemove2.Add (aParam2);
-                aParam2 = aTmpParam;
-                aPnt2   = aTmpPnt;
-                aVec2   = aTmpVec;
-                ++j;
+                ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
+                ff << "point " << (k == 0 ? "u" : "v") << i << "r_" << j << " "
+                  << aPnt2.X() << " " << aPnt2.Y() << " " << aPnt2.Z() << endl;
               }
-              else {
-                // We have found a place on the surface refusing 
-                // removement of this parameter.
-                aForbiddenToRemove1.Add (aParam1);
-                aForbiddenToRemove2.Add (aParam2);
+#endif
+              aToRemove2.Add(aParam2);
+              aPrevParam2 = aNextParam;
+              aPrevPnt2 = aNextPnt;
+              aPrevVec2 = aNextVec;
+              j += 2;
+              continue;
+            }
+            else {
+              // We have found a place on the surface refusing 
+              // removement of this parameter.
+#ifdef DEBUG_InsertInternal
+              // write point of forbidden to remove parameter
+              {
+                ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
+                ff << "vertex " << (k == 0 ? "u" : "v") << i << "f_" << j << " "
+                  << aPnt2.X() << " " << aPnt2.Y() << " " << aPnt2.Z() << endl;
               }
+#endif
+              aForbiddenToRemove1.Add(aParam1);
+              aForbiddenToRemove2.Add(aParam2);
             }
           }
-
-          aPrevParam2 = aParam2;
-          aPrevPnt2   = aPnt2;
-          aPrevVec2   = aVec2;
-
-          ++j;
         }
+        aPrevParam2 = aParam2;
+        aPrevPnt2 = aPnt2;
+        aPrevVec2 = aVec2;
+        ++j;
+      }
+    }
+  }
+  // remove filtered out parameters
+  for (Standard_Integer k = 0; k < 2; ++k)
+  {
+    BRepMesh::SequenceOfReal& aParamsk = aParams[k];
+    for (Standard_Integer i = 1; i <= aParamsk.Length();)
+    {
+      const Standard_Real aParam = aParamsk.Value(i);
+      if (aParamsToRemove[k].Contains(aParam) &&
+        !aParamsForbiddenToRemove[k].Contains(aParam))
+      {
+        aParamsk.Remove(i);
+      }
+      else
+        i++;
+    }
+  }
+#ifdef DEBUG_InsertInternal
+  // write polylines containing remaining parameters
+  {
+    ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
+    for (Standard_Integer k = 0; k < 2; ++k)
+    {
+      for (Standard_Integer i = 1; i <= aParams[k].Length(); i++)
+      {
+        ff << "polyline " << (k == 0 ? "uo" : "vo") << i << " ";
+        for (Standard_Integer j = 1; j <= aParams[1 - k].Length(); j++)
+        {
+          gp_Pnt aP;
+          if (k == 0)
+            gFace->D0(aParams[k](i), aParams[1 - k](j), aP);
+          else
+            gFace->D0(aParams[1 - k](j), aParams[k](i), aP);
+          ff << aP.X() << " " << aP.Y() << " " << aP.Z() << " ";
+        }
+        ff << endl;
       }
     }
   }
+#endif
 
   // insert nodes of the regular grid
+  const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
   for (Standard_Integer i = 1; i <= aParams[0].Length(); ++i)
   {
     const Standard_Real aParam1 = aParams[0].Value (i);
-    if (aParamsToRemove[0].Contains (aParam1) && !aParamsForbiddenToRemove[0].Contains (aParam1))
-      continue;
-
     for (Standard_Integer j = 1; j <= aParams[1].Length(); ++j)
     {
       const Standard_Real aParam2 = aParams[1].Value (j);
-      if (aParamsToRemove[1].Contains (aParam2) && !aParamsForbiddenToRemove[1].Contains (aParam2))
-        continue;
-
       gp_Pnt2d aPnt2d(aParam1, aParam2);
 
       // Classify intersection point
@@ -1091,7 +1178,6 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
 //purpose  : 
 //=======================================================================
 Standard_Real BRepMesh_FastDiscretFace::control(
-  BRepMesh::ListOfVertex&  theNewVertices,
   BRepMesh_Delaun&         theTrigu,
   const Standard_Boolean   theIsFirst)
 {
@@ -1115,7 +1201,7 @@ Standard_Real BRepMesh_FastDiscretFace::control(
     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);
+  NCollection_Map<BRepMesh_Edge>                aCouples(3 * aTrianglesNb, anAlloc);
   const BRepMesh_CircleTool& aCircles = theTrigu.Circles();
 
   // Perform refinement passes
@@ -1131,7 +1217,7 @@ Standard_Real BRepMesh_FastDiscretFace::control(
   for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass)
   {
     aTempAlloc->Reset(Standard_False);
-    theNewVertices.Clear();
+    BRepMesh::ListOfVertex aNewVertices(aTempAlloc);
 
     // Reset stop condition
     aInsertedNb      = 0;
@@ -1206,7 +1292,7 @@ Standard_Real BRepMesh_FastDiscretFace::control(
       aSqDef *= aSqDef;
 
       isSkipped = !checkDeflectionAndInsert(pDef, aCenter2d, theIsFirst, 
-        aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef, aTempAlloc);
+        aSqDef, aSqDefFace, aCircles, aNewVertices, aMaxSqDef, aTempAlloc);
 
       if (isSkipped)
         break;
@@ -1217,30 +1303,18 @@ Standard_Real BRepMesh_FastDiscretFace::control(
         if (m[i]) // is a boundary
           continue;
 
-        Standard_Integer j = (i + 1) % 3;
         // Check if this link was already processed
-        Standard_Integer aFirstVertex, aLastVertex;
-        if (v[i] < v[j])
-        { 
-          aFirstVertex = v[i];
-          aLastVertex = v[j];
-        }
-        else
-        {
-          aFirstVertex = v[j];
-          aLastVertex = v[i];
-        }
-
-        if (aCouples.Add(BRepMesh_OrientedEdge(aFirstVertex, aLastVertex)))
+        if (aCouples.Add(myStructure->GetLink(e[i])))
         {
           // Check deflection on edge 1
+          Standard_Integer j = (i + 1) % 3;
           gp_XY mi2d = (xy[i] + xy[j]) * 0.5;
           gFace->D0(mi2d.X(), mi2d.Y(), pDef);
           gp_Lin aLin(p[i], gp_Vec(p[i], p[j]));
           aSqDef = aLin.SquareDistance(pDef);
 
           isSkipped = !checkDeflectionAndInsert(pDef, mi2d, theIsFirst, 
-            aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef, aTempAlloc);
+            aSqDef, aSqDefFace, aCircles, aNewVertices, aMaxSqDef, aTempAlloc);
         }
       }
 
@@ -1286,7 +1360,43 @@ Standard_Real BRepMesh_FastDiscretFace::control(
     if (theIsFirst)
       continue;
 
-    if (addVerticesToMesh(theNewVertices, theTrigu))
+#ifdef DEBUG_MESH
+    // append to the file triangles in the form of polyline commands;
+    // so the file can be sourced in draw to analyze triangles on each pass of the algorithm.
+    // write triangles
+    ofstream ftt(DEBUG_MESH, std::ios_base::app);
+    Standard_Integer nbElem = myStructure->NbElements();
+    for (Standard_Integer i = 1; i <= nbElem; i++)
+    {
+      const BRepMesh_Triangle& aTri = myStructure->GetElement(i);
+      if (aTri.Movability() == BRepMesh_Deleted)
+        continue;
+      Standard_Integer n[3];
+      myStructure->ElementNodes(aTri, n);
+      const BRepMesh_Vertex& aV1 = myStructure->GetNode(n[0]);
+      const BRepMesh_Vertex& aV2 = myStructure->GetNode(n[1]);
+      const BRepMesh_Vertex& aV3 = myStructure->GetNode(n[2]);
+      const gp_Pnt& aP1 = myAttribute->GetPoint(aV1);
+      const gp_Pnt& aP2 = myAttribute->GetPoint(aV2);
+      const gp_Pnt& aP3 = myAttribute->GetPoint(aV3);
+      ftt << "polyline t" << aPass << "_" << i << " "
+        << aP1.X() << " " << aP1.Y() << " " << aP1.Z() << " "
+        << aP2.X() << " " << aP2.Y() << " " << aP2.Z() << " "
+        << aP3.X() << " " << aP3.Y() << " " << aP3.Z() << " "
+        << aP1.X() << " " << aP1.Y() << " " << aP1.Z() << endl;
+    }
+    // write points to insert on the current pass
+    BRepMesh::ListOfVertex::Iterator it(aNewVertices);
+    for (Standard_Integer i=1; it.More(); it.Next(), i++)
+    {
+      const BRepMesh_Vertex& aVertex = it.Value();
+      const gp_Pnt& aP = myAttribute->GetPoint(aVertex);
+      ftt << "vertex vt" << aPass << "_" << i << " "
+        << aP.X() << " " << aP.Y() << " " << aP.Z() << endl;
+    }
+#endif
+
+    if (addVerticesToMesh(aNewVertices, theTrigu))
       ++aInsertedNb;
   }
 
@@ -1314,7 +1424,7 @@ void BRepMesh_FastDiscretFace::add(const TopoDS_Vertex& theVertex)
     NCollection_Handle<FixedVExplorer> aFixedVExplorer = new FixedVExplorer(theVertex);
     Standard_Integer aIndex = myAttribute->GetVertexIndex(aFixedVExplorer);
     gp_XY anUV = BRepMesh_ShapeTool::FindUV(aIndex, aPnt2d,
-      theVertex, BRep_Tool::Tolerance(theVertex), myAttribute);
+      BRep_Tool::Tolerance(theVertex), myAttribute);
 
     Standard_Integer aTmpId1, aTmpId2;
     anUV = myAttribute->Scale(anUV, Standard_True);
index 01a36a7..76b00e1 100644 (file)
@@ -69,8 +69,7 @@ private:
   void add(const Handle(BRepMesh_FaceAttribute)& theAttribute);
   void add(const TopoDS_Vertex& theVertex);
 
-  Standard_Real control(BRepMesh::ListOfVertex&  theNewVertices,
-                        BRepMesh_Delaun&         theMeshBuilder,
+  Standard_Real control(BRepMesh_Delaun&         theMeshBuilder,
                         const Standard_Boolean   theIsFirst);
 
   //! Registers the given nodes in mesh data structure and
@@ -84,11 +83,9 @@ private:
     BRepMesh_Delaun&              theMeshBuilder);
 
   //! Calculates nodes lying on face's surface and inserts them to a mesh.
-  //! @param theNewVertices list of vertices to be extended and added to mesh.
   //! @param theMeshBuilder initialized tool refining mesh 
   //! in respect to inserting nodes.
-  void insertInternalVertices(BRepMesh::ListOfVertex&  theNewVertices,
-                              BRepMesh_Delaun&         theMeshBuilder);
+  void insertInternalVertices(BRepMesh_Delaun&         theMeshBuilder);
 
   //! Calculates nodes lying on spherical surface.
   //! @param theNewVertices list of vertices to be extended and added to mesh.
index 3733f6a..16c3433 100644 (file)
@@ -76,10 +76,8 @@ BRepMesh_GeomTool::BRepMesh_GeomTool(
 //=======================================================================
 Standard_Boolean BRepMesh_GeomTool::Value(
   const Standard_Integer              theIndex,
-  const Handle(BRepAdaptor_HSurface)& theSurface,
   Standard_Real&                      theParam,
-  gp_Pnt&                             thePoint,
-  gp_Pnt2d&                           theUV) const
+  gp_Pnt&                             thePoint) const
 {
   if (theIndex < 1 || theIndex > NbPoints())
     return Standard_False;
@@ -90,14 +88,6 @@ Standard_Boolean BRepMesh_GeomTool::Value(
   thePoint = myDiscretTool.Value(theIndex);
   theParam = myDiscretTool.Parameter(theIndex);
 
-  const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
-
-  Standard_Real aFirst, aLast;
-  Handle(Geom2d_Curve) aCurve = 
-    BRep_Tool::CurveOnSurface(*myEdge, aFace, aFirst, aLast);
-
-  aCurve->D0(theParam, theUV);
-
   return Standard_True;
 }
 
index 54fbd48..047cb18 100644 (file)
@@ -124,16 +124,12 @@ public:
   
   //! Gets parameters of discretization point with the given index.
   //! @param theIndex index of discretization point.
-  //! @param theSurface surface the curve is lying onto.
   //! @param theParam[out] parameter of the point on the curve.
   //! @param thePoint[out] discretization point.
-  //! @param theUV[out] discretization point in parametric space of the surface.
   //! @return TRUE on success, FALSE elsewhere.
   Standard_EXPORT Standard_Boolean Value(const Standard_Integer              theIndex,
-                                         const Handle(BRepAdaptor_HSurface)& theSurface,
                                          Standard_Real&                      theParam,
-                                         gp_Pnt&                             thePoint,
-                                         gp_Pnt2d&                           theUV) const;
+                                         gp_Pnt&                             thePoint) const;
   
 public: //! @name static API
 
index 9ac6957..ebd837b 100644 (file)
@@ -130,7 +130,6 @@ Standard_Real BRepMesh_ShapeTool::RelativeEdgeDeflection(
 gp_XY BRepMesh_ShapeTool::FindUV(
   const Standard_Integer                theIndexOfPnt3d,
   const gp_Pnt2d&                       thePnt2d,
-  const TopoDS_Vertex&                  theVertex,
   const Standard_Real                   theMinDistance,
   const Handle(BRepMesh_FaceAttribute)& theFaceAttribute)
 {
@@ -164,8 +163,7 @@ gp_XY BRepMesh_ShapeTool::FindUV(
     }
   }
 
-  const Standard_Real aTolerance = 
-    Min(2. * BRep_Tool::Tolerance(theVertex), theMinDistance);
+  const Standard_Real aTolerance = theMinDistance;
 
   // Get face limits
   Standard_Real aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
index 35192a6..e1883d7 100644 (file)
@@ -67,12 +67,8 @@ public:
   //! representation should be associated.
   //! @param thePnt2d 2d representation of the point with the 
   //! given index.
-  //! @param theVertex vertex corresponded to 3d point with the 
-  //! given index. Used to extract vertex tolerance in 3d space.
   //! @param theMinDistance minimum distance between vertices 
   //! regarding which they could be treated as distinct ones.
-  //! This value is defined by mesher using parameters given by
-  //! user in connection with shape metrics.
   //! @param theFaceAttribute attributes contining data calculated
   //! according to face geomtry and define limits of face in parametric 
   //! space. If defined, will be used instead of surface parameter.
@@ -83,7 +79,6 @@ public:
   Standard_EXPORT static gp_XY FindUV(
     const Standard_Integer                theIndexOfPnt3d,
     const gp_Pnt2d&                       thePnt2d,
-    const TopoDS_Vertex&                  theVertex,
     const Standard_Real                   theMinDistance,
     const Handle(BRepMesh_FaceAttribute)& theFaceAttribute);
 
index 58db970..13ee2b2 100644 (file)
@@ -496,7 +496,8 @@ void BndLib_Box2dCurve::PerformBSpline()
   }
 
   //
-  if (!(aT1==aTb[0] && aT2==aTb[1])) {
+  const Standard_Real eps = Precision::PConfusion();
+  if (fabs(aT1-aTb[0]) > eps || fabs(aT2-aTb[1]) > eps) {
     aG=aCBS->Copy();
     //
     aCBSs=Handle(Geom2d_BSplineCurve)::DownCast(aG);
@@ -799,7 +800,6 @@ void BndLib_Box2dCurve::GetInfoBase()
     return;
   }
   //
-  aC2DB=myCurve;
   while(!bIsTypeBase) {
     iTrimmed=0;
     iOffset=0;
index 5af6f17..22a9e6f 100644 (file)
 // auxiliary functions to compute the length of the derivative
 static Standard_Real f3d(const Standard_Real X, const Standard_Address C)
 {
-  gp_Vec V = ((Adaptor3d_Curve*)C)->DN(X,1);
+  gp_Pnt P;
+  gp_Vec V;
+  ((Adaptor3d_Curve*)C)->D1(X,P,V);
   return V.Magnitude();
 }
 
 static Standard_Real f2d(const Standard_Real X, const Standard_Address C)
 {
-  gp_Vec2d V = ((Adaptor2d_Curve2d*)C)->DN(X,1);
+  gp_Pnt2d P;
+  gp_Vec2d V;
+  ((Adaptor2d_Curve2d*)C)->D1(X,P,V);
   return V.Magnitude();
 }
 
index 63e612b..dc28c43 100644 (file)
@@ -729,7 +729,7 @@ public:
   
   //! Returns the pole of range Index.
   //! Raised if Index < 1 or Index > NbPoles.
-  Standard_EXPORT gp_Pnt Pole (const Standard_Integer Index) const;
+  Standard_EXPORT const gp_Pnt& Pole(const Standard_Integer Index) const;
   
   //! Returns the poles of the B-spline curve;
   //!
index 2cb0abe..0354196 100644 (file)
@@ -665,7 +665,7 @@ Standard_Integer Geom_BSplineCurve::NbPoles () const
 //purpose  : 
 //=======================================================================
 
-gp_Pnt Geom_BSplineCurve::Pole (const Standard_Integer Index) const
+const gp_Pnt& Geom_BSplineCurve::Pole (const Standard_Integer Index) const
 {
   Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
                                "Geom_BSplineCurve::Pole");
index 52e2585..9a54bf0 100644 (file)
@@ -899,7 +899,7 @@ public:
   //!
   //! Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 or
   //! VIndex > NbVPoles.
-  Standard_EXPORT gp_Pnt Pole (const Standard_Integer UIndex, const Standard_Integer VIndex) const;
+  Standard_EXPORT const gp_Pnt& Pole(const Standard_Integer UIndex, const Standard_Integer VIndex) const;
   
   //! Returns the poles of the B-spline surface.
   //!
index 0d75f68..3a768cc 100644 (file)
@@ -426,7 +426,7 @@ gp_Vec Geom_BSplineSurface::LocalDN  (const Standard_Real    U,
 //purpose  : 
 //=======================================================================
 
-gp_Pnt Geom_BSplineSurface::Pole (const Standard_Integer UIndex,
+const gp_Pnt& Geom_BSplineSurface::Pole(const Standard_Integer UIndex,
                                  const Standard_Integer VIndex) const
 {
   Standard_OutOfRange_Raise_if
index c379a60..6cba548 100644 (file)
@@ -655,7 +655,7 @@ Standard_Integer Geom_BezierCurve::NbPoles () const
 //purpose  : 
 //=======================================================================
 
-gp_Pnt Geom_BezierCurve::Pole (const Standard_Integer Index) const
+const gp_Pnt& Geom_BezierCurve::Pole (const Standard_Integer Index) const
 {
   if(Index < 1 || Index > poles->Length()) 
     Standard_OutOfRange::Raise("Geom_BezierCurve::Pole");
index b186aa2..38cf013 100644 (file)
@@ -288,7 +288,7 @@ public:
   
   //! Returns the pole of range Index.
   //! Raised if Index is not in the range [1, NbPoles]
-  Standard_EXPORT gp_Pnt Pole (const Standard_Integer Index) const;
+  Standard_EXPORT const gp_Pnt& Pole (const Standard_Integer Index) const;
   
   //! Returns all the poles of the curve.
   //!
index 587d612..9d5364f 100644 (file)
@@ -1587,7 +1587,7 @@ Standard_Integer Geom_BezierSurface::NbVPoles () const
 //purpose  : 
 //=======================================================================
 
-gp_Pnt Geom_BezierSurface::Pole (const Standard_Integer UIndex,
+const gp_Pnt& Geom_BezierSurface::Pole (const Standard_Integer UIndex,
                                 const Standard_Integer VIndex) const
 {
   Standard_OutOfRange_Raise_if
index 351121e..0519edf 100644 (file)
@@ -466,7 +466,7 @@ public:
   //! Returns the pole of range UIndex, VIndex
   //! Raised if UIndex < 1 or UIndex > NbUPoles, or
   //! VIndex < 1 or VIndex > NbVPoles.
-  Standard_EXPORT gp_Pnt Pole (const Standard_Integer UIndex, const Standard_Integer VIndex) const;
+  Standard_EXPORT const gp_Pnt& Pole(const Standard_Integer UIndex, const Standard_Integer VIndex) const;
   
   //! Returns the poles of the Bezier surface.
   //!
index ac6c3cd..13f019c 100644 (file)
@@ -49,6 +49,7 @@
 #include <GeomAbs_CurveType.hxx>
 #include <GeomAbs_IsoType.hxx>
 #include <GeomAbs_Shape.hxx>
+#include <GeomAdaptor_Surface.hxx>
 #include <GeomEvaluator_OffsetSurface.hxx>
 #include <gp.hxx>
 #include <gp_Dir.hxx>
@@ -456,7 +457,7 @@ public:
     Standard_Integer *ErrorCode);
 
 private:
-  Handle(Geom_Surface) CurrentSurface;
+  GeomAdaptor_Surface CurrentSurface;
   Standard_Real IsoPar;
 };
 
@@ -469,14 +470,14 @@ void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
 { 
   gp_Pnt P;
   if (*DerivativeRequest == 0) {
-    P = CurrentSurface->Value(IsoPar,*Parameter);
+    P = CurrentSurface.Value(IsoPar,*Parameter);
     Result[0] = P.X();
     Result[1] = P.Y();
     Result[2] = P.Z();
   }
   else {
     gp_Vec DU,DV;
-    CurrentSurface->D1(IsoPar,*Parameter,P,DU,DV);
+    CurrentSurface.D1(IsoPar,*Parameter,P,DU,DV);
     Result[0] = DV.X();
     Result[1] = DV.Y();
     Result[2] = DV.Z();
index 08aab57..948a01f 100644 (file)
@@ -762,7 +762,7 @@ public:
   
   //! Returns the pole of range Index.
   //! Raised if Index < 1 or Index > NbPoles.
-  Standard_EXPORT gp_Pnt2d Pole (const Standard_Integer Index) const;
+  Standard_EXPORT const gp_Pnt2d& Pole (const Standard_Integer Index) const;
   
   //! Returns the poles of the B-spline curve;
   //!
index 2253cf6..a4142a5 100644 (file)
@@ -678,7 +678,7 @@ Standard_Integer Geom2d_BSplineCurve::NbPoles () const
 //purpose  : 
 //=======================================================================
 
-gp_Pnt2d Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const
+const gp_Pnt2d& Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const
 {
   Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
                                "Geom2d_BSplineCurve::Pole");
index 8ee3af9..76e4e68 100644 (file)
@@ -656,7 +656,7 @@ Standard_Integer Geom2d_BezierCurve::NbPoles () const
 //purpose  : 
 //=======================================================================
 
-gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
+const gp_Pnt2d& Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
 {
   Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
                                "Geom2d_BezierCurve::Pole");
index 62c51e0..0d61dc4 100644 (file)
@@ -266,7 +266,7 @@ public:
   
   //! Returns the pole of range Index.
   //! Raised if Index is not in the range [1, NbPoles]
-  Standard_EXPORT gp_Pnt2d Pole (const Standard_Integer Index) const;
+  Standard_EXPORT const gp_Pnt2d& Pole (const Standard_Integer Index) const;
   
   //! Returns all the poles of the curve.
   //!
index 047faa2..b025ffe 100644 (file)
@@ -180,10 +180,10 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
 {
   myFirst = UFirst;
   myLast  = ULast;
+  myCurveCache.Nullify();
 
   if ( myCurve != C) {
     myCurve = C;
-    myCurveCache.Nullify();
     myNestedEvaluator.Nullify();
     myBSplineCurve.Nullify();
 
@@ -209,20 +209,10 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
     }
     else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
       myTypeCurve = GeomAbs_BezierCurve;
-      // Create cache for Bezier
-      Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve);
-      Standard_Integer aDeg = aBezier->Degree();
-      TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
-      myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
-          aBezier->Poles(), aBezier->Weights());
     }
     else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
       myTypeCurve = GeomAbs_BSplineCurve;
-      // Create cache for B-spline
-      Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(myCurve);
-      myBSplineCurve = aBspl;
-      myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(),
-          aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights());
+      myBSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(myCurve);
     }
     else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
     {
@@ -237,8 +227,6 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
       myTypeCurve = GeomAbs_OtherCurve;
     }
   }
-  else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same
-    RebuildCache(myFirst);
 }
 
 //    --
@@ -569,14 +557,22 @@ void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
 {
   if (myTypeCurve == GeomAbs_BezierCurve)
   {
+    // Create cache for Bezier
     Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve);
     Standard_Integer aDeg = aBezier->Degree();
     TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
+    if (myCurveCache.IsNull())
+      myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
+        aBezier->Poles(), aBezier->Weights());
     myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
       aBezier->Poles(), aBezier->Weights());
   }
   else if (myTypeCurve == GeomAbs_BSplineCurve)
   {
+    // Create cache for B-spline
+    if (myCurveCache.IsNull())
+      myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
+        myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
     myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(),
       myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(),
       myBSplineCurve->Poles(), myBSplineCurve->Weights());
@@ -643,14 +639,13 @@ void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
     {
       myBSplineCurve->LocalD0(U, aStart, aFinish, P);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D0(U, P);
     }
-    else
-      myCurve->D0(U, P);
     break;
   }
 
@@ -681,14 +676,13 @@ void Geom2dAdaptor_Curve::D1(const Standard_Real U,
     {
       myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D1(U, P, V);
     }
-    else
-      myCurve->D1(U, P, V);
     break;
   }
 
@@ -719,14 +713,13 @@ void Geom2dAdaptor_Curve::D2(const Standard_Real U,
     {
       myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D2(U, P, V1, V2);
     }
-    else
-      myCurve->D2(U, P, V1, V2);
     break;
   }
 
@@ -758,14 +751,13 @@ void Geom2dAdaptor_Curve::D3(const Standard_Real U,
     {
       myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D3(U, P, V1, V2, V3);
     }
-    else
-      myCurve->D3(U, P, V1, V2, V3);
     break;
   }
 
index 1bf3d2a..6ecbf6a 100644 (file)
@@ -198,7 +198,7 @@ private:
   Standard_Real myLast;
 
   Handle(Geom2d_BSplineCurve) myBSplineCurve; ///< B-spline representation to prevent castings
-  Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve
+  mutable Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve
   Handle(Geom2dEvaluator_Curve) myNestedEvaluator; ///< Calculates value of offset curve
 
 
index 6408cab..5be1665 100644 (file)
@@ -136,10 +136,10 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
 {
   myFirst = UFirst;
   myLast  = ULast;
+  myCurveCache.Nullify();
 
   if ( myCurve != C) {
     myCurve = C;
-    myCurveCache.Nullify();
     myNestedEvaluator.Nullify();
     myBSplineCurve.Nullify();
 
@@ -164,20 +164,10 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
     }
     else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) {
       myTypeCurve = GeomAbs_BezierCurve;
-      // Create cache for Bezier
-      Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
-      Standard_Integer aDeg = aBezier->Degree();
-      TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
-      myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
-          aBezier->Poles(), aBezier->Weights());
     }
     else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
       myTypeCurve = GeomAbs_BSplineCurve;
-      // Create cache for B-spline
-      Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve);
-      myBSplineCurve = aBspl;
-      myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(),
-          aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights());
+      myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve);
     }
     else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
       myTypeCurve = GeomAbs_OffsetCurve;
@@ -192,8 +182,6 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
       myTypeCurve = GeomAbs_OtherCurve;
     }
   }
-  else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same
-    RebuildCache(myFirst);
 }
 
 //    --
@@ -544,14 +532,22 @@ void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
 {
   if (myTypeCurve == GeomAbs_BezierCurve)
   {
+    // Create cache for Bezier
     Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve);
     Standard_Integer aDeg = aBezier->Degree();
     TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1));
-    myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
+    if (myCurveCache.IsNull())
+      myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots,
         aBezier->Poles(), aBezier->Weights());
+    myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots,
+      aBezier->Poles(), aBezier->Weights());
   }
   else if (myTypeCurve == GeomAbs_BSplineCurve)
   {
+    // Create cache for B-spline
+    if (myCurveCache.IsNull())
+      myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(),
+        myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights());
     myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(),
         myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(),
         myBSplineCurve->Poles(), myBSplineCurve->Weights());
@@ -618,14 +614,13 @@ void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
     {
       myBSplineCurve->LocalD0(U, aStart, aFinish, P);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D0(U, P);
     }
-    else
-      myCurve->D0(U, P);
     break;
   }
 
@@ -655,14 +650,13 @@ void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
     {
       myBSplineCurve->LocalD1(U, aStart, aFinish, P, V);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D1(U, P, V);
     }
-    else
-      myCurve->D1(U, P, V);
     break;
   }
 
@@ -693,14 +687,13 @@ void GeomAdaptor_Curve::D2(const Standard_Real U,
     {
       myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D2(U, P, V1, V2);
     }
-    else
-      myCurve->D2(U, P, V1, V2);
     break;
   }
 
@@ -732,14 +725,13 @@ void GeomAdaptor_Curve::D3(const Standard_Real U,
     {
       myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3);
     }
-    else if (!myCurveCache.IsNull()) // use cached data
+    else
     {
-      if (!myCurveCache->IsCacheValid(U))
+      // use cached data
+      if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U))
         RebuildCache(U);
       myCurveCache->D3(U, P, V1, V2, V3);
     }
-    else
-      myCurve->D3(U, P, V1, V2, V3);
     break;
   }
 
index 62f981a..1cc735c 100644 (file)
@@ -237,7 +237,7 @@ private:
   Standard_Real myLast;
   
   Handle(Geom_BSplineCurve) myBSplineCurve; ///< B-spline representation to prevent castings
-  Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve
+  mutable Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve
   Handle(GeomEvaluator_Curve) myNestedEvaluator; ///< Calculates value of offset curve
 
 
index dc479cc..c043cfa 100644 (file)
@@ -132,10 +132,10 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
   myULast  = ULast;
   myVFirst = VFirst;
   myVLast  = VLast;
+  mySurfaceCache.Nullify();
 
   if ( mySurface != S) {
     mySurface = S;
-    mySurfaceCache.Nullify();
     myNestedEvaluator.Nullify();
     myBSplineSurface.Nullify();
 
@@ -181,26 +181,10 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
     else if (TheType == STANDARD_TYPE(Geom_BezierSurface))
     {
       mySurfaceType = GeomAbs_BezierSurface;
-      // Create cache for Bezier
-      Handle(Geom_BezierSurface) aBezier = Handle(Geom_BezierSurface)::DownCast(mySurface);
-      Standard_Integer aDegU = aBezier->UDegree();
-      Standard_Integer aDegV = aBezier->VDegree();
-      TColStd_Array1OfReal aFlatKnotsU(BSplCLib::FlatBezierKnots(aDegU), 1, 2 * (aDegU + 1));
-      TColStd_Array1OfReal aFlatKnotsV(BSplCLib::FlatBezierKnots(aDegV), 1, 2 * (aDegV + 1));
-      mySurfaceCache = new BSplSLib_Cache(
-        aDegU, aBezier->IsUPeriodic(), aFlatKnotsU,
-        aDegV, aBezier->IsVPeriodic(), aFlatKnotsV,
-        aBezier->Poles(), aBezier->Weights());
     }
     else if (TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
       mySurfaceType = GeomAbs_BSplineSurface;
-      Handle(Geom_BSplineSurface) myBspl = Handle(Geom_BSplineSurface)::DownCast(mySurface);
-      myBSplineSurface = myBspl;
-      // Create cache for B-spline
-      mySurfaceCache = new BSplSLib_Cache( 
-        myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), 
-        myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), 
-        myBspl->Poles(), myBspl->Weights());
+      myBSplineSurface = Handle(Geom_BSplineSurface)::DownCast(mySurface);
     }
     else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
     {
@@ -216,8 +200,6 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
     else
       mySurfaceType = GeomAbs_OtherSurface;
   }
-  else // rebuild cache of Bezier and B-spline surface even if the loaded surface is same
-    RebuildCache(myUFirst, myVFirst);
 }
 
 //    --
@@ -679,11 +661,17 @@ void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
 {
   if (mySurfaceType == GeomAbs_BezierSurface)
   {
+    // Create cache for Bezier
     Handle(Geom_BezierSurface) aBezier = Handle(Geom_BezierSurface)::DownCast(mySurface);
     Standard_Integer aDegU = aBezier->UDegree();
     Standard_Integer aDegV = aBezier->VDegree();
     TColStd_Array1OfReal aFlatKnotsU(BSplCLib::FlatBezierKnots(aDegU), 1, 2 * (aDegU + 1));
     TColStd_Array1OfReal aFlatKnotsV(BSplCLib::FlatBezierKnots(aDegV), 1, 2 * (aDegV + 1));
+    if (mySurfaceCache.IsNull())
+      mySurfaceCache = new BSplSLib_Cache(
+        aDegU, aBezier->IsUPeriodic(), aFlatKnotsU,
+        aDegV, aBezier->IsVPeriodic(), aFlatKnotsV,
+        aBezier->Poles(), aBezier->Weights());
     mySurfaceCache->BuildCache(theU, theV,
       aDegU, aBezier->IsUPeriodic(), aFlatKnotsU,
       aDegV, aBezier->IsVPeriodic(), aFlatKnotsV,
@@ -691,10 +679,16 @@ void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
   }
   else if (mySurfaceType == GeomAbs_BSplineSurface)
   {
-      mySurfaceCache->BuildCache(theU, theV,
+    // Create cache for B-spline
+    if (mySurfaceCache.IsNull())
+      mySurfaceCache = new BSplSLib_Cache(
         myBSplineSurface->UDegree(), myBSplineSurface->IsUPeriodic(), myBSplineSurface->UKnotSequence(),
         myBSplineSurface->VDegree(), myBSplineSurface->IsVPeriodic(), myBSplineSurface->VKnotSequence(),
         myBSplineSurface->Poles(), myBSplineSurface->Weights());
+    mySurfaceCache->BuildCache(theU, theV,
+      myBSplineSurface->UDegree(), myBSplineSurface->IsUPeriodic(), myBSplineSurface->UKnotSequence(),
+      myBSplineSurface->VDegree(), myBSplineSurface->IsVPeriodic(), myBSplineSurface->VKnotSequence(),
+      myBSplineSurface->Poles(), myBSplineSurface->Weights());
   }
 }
 
@@ -723,14 +717,9 @@ void GeomAdaptor_Surface::D0(const Standard_Real U,
   {
   case GeomAbs_BezierSurface:
   case GeomAbs_BSplineSurface:
-    if (!mySurfaceCache.IsNull())
-    {
-      if (!mySurfaceCache->IsCacheValid(U, V))
-        RebuildCache(U, V);
-      mySurfaceCache->D0(U, V, P);
-    }
-    else
-      mySurface->D0(U, V, P);
+    if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V))
+      RebuildCache(U, V);
+    mySurfaceCache->D0(U, V, P);
     break;
 
   case GeomAbs_OffsetSurface:
@@ -772,14 +761,12 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
         (USide != 0 || VSide != 0) && 
         IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
       myBSplineSurface->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
-    else if (!mySurfaceCache.IsNull())
+    else
     {
-      if (!mySurfaceCache->IsCacheValid(U, V))
+      if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V))
         RebuildCache(U, V);
       mySurfaceCache->D1(U, V, P, D1U, D1V);
     }
-    else
-      mySurface->D1(u, v, P, D1U, D1V);
     break;
     }
 
@@ -824,14 +811,12 @@ void GeomAdaptor_Surface::D2(const Standard_Real U,
         (USide != 0 || VSide != 0) && 
         IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
       myBSplineSurface->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV);
-    else if (!mySurfaceCache.IsNull())
+    else
     {
-      if (!mySurfaceCache->IsCacheValid(U, V))
+      if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V))
         RebuildCache(U, V);
       mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
     }
-    else
-      mySurface->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV);
     break;
   }
 
index bef6e8a..2f0d483 100644 (file)
@@ -272,7 +272,7 @@ private:
   Standard_Real myTolV;
   
   Handle(Geom_BSplineSurface) myBSplineSurface; ///< B-spline representation to prevent downcasts
-  Handle(BSplSLib_Cache) mySurfaceCache; ///< Cached data for B-spline or Bezier surface
+  mutable Handle(BSplSLib_Cache) mySurfaceCache; ///< Cached data for B-spline or Bezier surface
 
 protected:
   GeomAbs_SurfaceType mySurfaceType;
index 2dbafbe..5ae491e 100755 (executable)
@@ -5,3 +5,4 @@ MeshTest_CheckTopology.hxx
 MeshTest_DrawableMesh.cxx
 MeshTest_DrawableMesh.hxx
 MeshTest_PluginCommands.cxx
+MeshTest_Debug.cxx
diff --git a/src/MeshTest/MeshTest_Debug.cxx b/src/MeshTest/MeshTest_Debug.cxx
new file mode 100644 (file)
index 0000000..d801433
--- /dev/null
@@ -0,0 +1,109 @@
+// Created on: 2016-05-31
+// Created by: Mikhail Sazonov
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_FaceAttribute.hxx>
+#include <Draw_Segment3D.hxx>
+#include <DrawTrSurf_Polygon3D.hxx>
+#include <Draw.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <Poly_Polygon3D.hxx>
+
+// This file defines global functions not declared in any public header,
+// intended for use from debugger prompt (Command Window in Visual Studio)
+
+//=======================================================================
+//function : MeshTest_DrawLinks
+//purpose  : Draw links from mesh data structure of type BRepMesh_FaceAttribute
+//=======================================================================
+Standard_EXPORT const char* MeshTest_DrawLinks(const char* theNameStr, void* theFaceAttr)
+{
+  if (theNameStr == 0 || theFaceAttr == 0)
+  {
+    return "Error: name or face attribute is null";
+  }
+  try {
+    const Handle(BRepMesh_FaceAttribute)& aFaceAttr = *(Handle(BRepMesh_FaceAttribute)*)theFaceAttr;
+    const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = aFaceAttr->ChangeStructure();
+    if (aMeshData.IsNull())
+      return "Null mesh data structure";
+    Standard_Integer nbLinks = aMeshData->NbLinks();
+    cout << "nblink=" << nbLinks << endl;
+    TCollection_AsciiString aName(theNameStr);
+    for (Standard_Integer i = 1; i <= nbLinks; i++)
+    {
+      const BRepMesh_Edge& aLink = aMeshData->GetLink(i);
+      if (aLink.Movability() == BRepMesh_Deleted)
+        continue;
+      Standard_Integer n1 = aLink.FirstNode();
+      Standard_Integer n2 = aLink.LastNode();
+      const BRepMesh_Vertex& aV1 = aMeshData->GetNode(n1);
+      const BRepMesh_Vertex& aV2 = aMeshData->GetNode(n2);
+      const gp_Pnt& aP1 = aFaceAttr->GetPoint(aV1);
+      const gp_Pnt& aP2 = aFaceAttr->GetPoint(aV2);
+      Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aP1, aP2, Draw_bleu);
+      Draw::Set((aName + "_" + i).ToCString(), aSeg);
+    }
+    return theNameStr;
+  }
+  catch (Standard_Failure)
+  {
+    return Standard_Failure::Caught()->GetMessageString();
+  }
+}
+
+//=======================================================================
+//function : MeshTest_DrawTriangles
+//purpose  : Draw triangles from mesh data structure of type BRepMesh_FaceAttribute
+//=======================================================================
+Standard_EXPORT const char* MeshTest_DrawTriangles(const char* theNameStr, void* theFaceAttr)
+{
+  if (theNameStr == 0 || theFaceAttr == 0)
+  {
+    return "Error: name or face attribute is null";
+  }
+  try {
+    const Handle(BRepMesh_FaceAttribute)& aFaceAttr =
+      *(Handle(BRepMesh_FaceAttribute)*)theFaceAttr;
+    const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = aFaceAttr->ChangeStructure();
+    if (aMeshData.IsNull())
+      return "Null mesh data structure";
+    Standard_Integer nbElem = aMeshData->NbElements();
+    cout << "nbelem=" << nbElem << endl;
+    TCollection_AsciiString aName(theNameStr);
+    for (Standard_Integer i = 1; i <= nbElem; i++)
+    {
+      const BRepMesh_Triangle& aTri = aMeshData->GetElement(i);
+      if (aTri.Movability() == BRepMesh_Deleted)
+        continue;
+      Standard_Integer n[3];
+      aMeshData->ElementNodes(aTri, n);
+      const BRepMesh_Vertex& aV1 = aMeshData->GetNode(n[0]);
+      const BRepMesh_Vertex& aV2 = aMeshData->GetNode(n[1]);
+      const BRepMesh_Vertex& aV3 = aMeshData->GetNode(n[2]);
+      gp_Pnt aP[4] = { aFaceAttr->GetPoint(aV1), aFaceAttr->GetPoint(aV2), 
+                       aFaceAttr->GetPoint(aV3), aFaceAttr->GetPoint(aV1) };
+      TColgp_Array1OfPnt aPnts(aP[0], 1, 4);
+      Handle(Poly_Polygon3D) aPoly = new Poly_Polygon3D(aPnts);
+      Handle(DrawTrSurf_Polygon3D) aDPoly = new DrawTrSurf_Polygon3D(aPoly);
+      Draw::Set((aName + "_" + i).ToCString(), aDPoly);
+    }
+    return theNameStr;
+  }
+  catch (Standard_Failure)
+  {
+    return Standard_Failure::Caught()->GetMessageString();
+  }
+}
index 26e50de..1257265 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC26932 Linux: Faulty shapes in variables faulty_1 to faulty"
-
 beziercurve w1 5 0 0 0 20 0 0 20 5 0 25 10 0 10 20 0
 mkedge w1 w1 
 polyline w2 10 20 0 0 0 0
index 83a6705..30ca181 100755 (executable)
@@ -20,7 +20,7 @@ vsetdispmode result 1
 vdisplay result
 vfit
 
-checktrinfo result -tri 9243 -nod 7586
+checktrinfo result -tri 9250 -nod 7593
 
 checkmaxtol result -ref 0.92213088179312575
 checknbshapes result -shell 1
index edd2750..84563aa 100644 (file)
@@ -13,7 +13,7 @@ restore [locate_data_file OCC396_f2903.brep] result
 incmesh result 0.01
 triangles result 
 
-checktrinfo result -tri 39 -nod 41
+checktrinfo result -tri 79 -nod 81
 
 vinit
 vdisplay result
index 3ab8cef..6036829 100755 (executable)
@@ -30,7 +30,8 @@ if { [regexp {Debug mode} [dversion]] } {
   }
 }
 
-if {${max_t_1} > ${t_1}} {
-   puts "Error. Time of building of triangulation, ${t_1} seconds, is less than expected minimum time - ${max_t_1} seconds"
-}
+# this test case is redundant, as we must not set lower limit for computation time
+#if {${max_t_1} > ${t_1}} {
+#   puts "Error. Time of building of triangulation, ${t_1} seconds, is less than expected minimum time - ${max_t_1} seconds"
+#}
 
index a29de1c..696e3a7 100755 (executable)
@@ -26,6 +26,7 @@ if { [regexp {Debug mode} [dversion]] } {
   set max_t_01 1
 }
 
-if {${max_t_01} > ${t_01}} {
-   puts "Error. Time of building of triangulation, ${t_01} seconds, is less than expected minimum time - ${max_t_01} seconds"
-}
+# this test case is redundant, as we must not set lower limit for computation time
+#if {${max_t_01} > ${t_01}} {
+#   puts "Error. Time of building of triangulation, ${t_01} seconds, is less than expected minimum time - ${max_t_01} seconds"
+#}
index a216c15..fb834de 100755 (executable)
@@ -31,6 +31,7 @@ if { [regexp {Debug mode} [dversion]] } {
   }
 }
 
-if {${max_t_001} > ${t_001}} {
-   puts "Error. Time of building of triangulation, ${t_001} seconds, is less than expected minimum time - ${max_t_001} seconds"
-}
\ No newline at end of file
+# this test case is redundant, as we must not set lower limit for computation time
+#if {${max_t_001} > ${t_001}} {
+#   puts "Error. Time of building of triangulation, ${t_001} seconds, is less than expected minimum time - ${max_t_001} seconds"
+#}
\ No newline at end of file
index 274598f..45489a7 100644 (file)
@@ -18,7 +18,7 @@ if { [regexp {Debug mode} [dversion]] } {
     set max_t_001 50
 } else {
   if { [regexp {Windows} [dversion]] } {
-    set max_t_001 20
+    set max_t_001 30
   } else {
     set max_t_001 55
   }
index 48d0d7c..2501ae3 100755 (executable)
@@ -15,5 +15,5 @@ fit
 isos a 0
 triangles a
 
-checktrinfo a -tri 1874 -nod 983 -defl 0.26446929234386068 -tol_rel_defl 0.05 -tol_rel_tri 0.05 -tol_rel_nod 0.05
+checktrinfo a -tri 3347 -nod 1780 -defl 0.08541878790375132 -tol_rel_defl 0.05 -tol_rel_tri 0.05 -tol_rel_nod 0.05
 checkview -screenshot -2d -path ${imagedir}/${test_image}.png
index 3cee3d0..db0cc9b 100644 (file)
@@ -9,13 +9,13 @@ puts ""
 restore [locate_data_file bug25519_testtriangulation.brep] a
 
 tclean a
-incmesh a 0.001
+incmesh a 0.01 -a 50
 set bug_info [trinfo a]
 set TNumber_1 [lindex $bug_info 3]
 set NNumber_1 [lindex $bug_info 5]
 
 tclean a
-incmesh a 0.001 -surf_def_off
+incmesh a 0.01 -a 50 -surf_def_off
 set bug_info [trinfo a]
 set TNumber_2 [lindex $bug_info 3]
 set NNumber_2 [lindex $bug_info 5]
index 8346596..40abec6 100755 (executable)
@@ -15,6 +15,6 @@ vclear
 isos result 0
 triangles result
 
-checktrinfo result -tri 8 -nod 10
+checktrinfo result -tri 11 -nod 13
 checkprops result -s 1.3135 
 checkview -display result -3d -path ${imagedir}/${test_image}.png
index 143941e..62ddd97 100755 (executable)
@@ -14,7 +14,7 @@ isos result 0
 incmesh result .1
 triangles result
 
-checktrinfo result -tri !604 -nod !363
+checktrinfo result -tri !1315 -nod !784
 checkprops result -s 0 
 checkshape result
 checkview -display result -3d -path ${imagedir}/${test_image}.png
index f4b2c78..d57ecb3 100755 (executable)
@@ -19,6 +19,6 @@ vsetdispmode result 1
 isos result 0
 triangles result
 
-checktrinfo result -tri 8 -nod 10
+checktrinfo result -tri 11 -nod 13
 checkprops result -s 1.3135 
 checkview -display result -3d -path ${imagedir}/${test_image}.png
index 5e1dbf0..ee0042c 100755 (executable)
@@ -22,7 +22,7 @@ tclean result
 set Deflection 0.001
 incmesh result ${Deflection}
 
-checktrinfo result -tri 311280 -nod 159373 -defl 0.0092442421472206764 -tol_rel_defl 0.001 -tol_rel_tri 0.001 -tol_rel_nod 0.001
+checktrinfo result -tri 394128 -nod 201035 -defl 0.0092442421472207319 -tol_rel_defl 0.001 -tol_rel_tri 0.001 -tol_rel_nod 0.001
 
 vinit
 vdisplay result
index 9445f94..b0b20a9 100755 (executable)
@@ -1,7 +1,7 @@
 puts "TODO OCC24156 MacOS: Tcl Exception: tolerance ang"
 puts "TODO OCC24156 MacOS: TEST INCOMPLETE"
 puts "TODO OCC27203 ALL: Error: Max tolerance" 
-puts "TODO OCC27203 Linux: Error : The area of result shape is"
+puts "TODO OCC27203 All: Error : The area of result shape is"
 
 puts "========"
 puts "OCC453"
@@ -38,11 +38,12 @@ if { $z2 > 85 } {
     puts "Elapsed time is less then 85 seconds - OK"      
 }
 
+# Note: The reference values of area and tolerance are wanted theoretical values
 # Properties check
-checkprops result -s 5.48216e+006
+checkprops result -s 3.51e+006
 
 # Tolerance check
-checkmaxtol result -ref 1628.2217761833963
+checkmaxtol result -ref 1.
 
 # Visual check
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index 7e4f0fc..fb3f593 100755 (executable)
@@ -13,5 +13,5 @@ tclean result
 incmesh result .1
 triangles result
 
-checktrinfo result -tri 559 -nod 329
+checktrinfo result -tri 424 -nod 266
 checkview -display result -3d -path ${imagedir}/${test_image}.png
index 9b48348..4681550 100755 (executable)
@@ -24,7 +24,7 @@ if {$report != ""} {
 
 # Checking triangulation area (triarea command)...
 set max_rel_tol_diff 1
-set rel_tol 0.42
+set rel_tol 0.56
 set area_eps 0
 
 smallview
index 8e6961a..7612d60 100755 (executable)
@@ -13,5 +13,5 @@ isos result 0
 triangles result
 vfit
 
-checktrinfo result -tri 7984 -nod 8350
+checktrinfo result -tri 8000 -nod 8358
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
index 45b1b6a..0f5b4b5 100755 (executable)
@@ -1,7 +1,8 @@
 set TheFileName bug22025_s.brep
-set bug_area "OCC22687"
 set rel_tol 1.3
+set max_rel_tol_diff 0.1
 if { [string compare $command "shading"] == 0 } {
+  set bug_area "OCC22687"
   set bug_withouttri "OCC22687"
   set nbwithouttri(ALL) 74
 }
index a7ae54c..1e1cbc0 100755 (executable)
@@ -3,18 +3,7 @@ set bug_freenodes "OCC22687"
 if { [string compare $command "shading"] == 0 } {
    set nbfreenodes(All) 3
 } else {
-   set bug_withouttri "OCC27226"
    set bug_freelinks "OCC23105"
-   ###set nbfree(ALL) 4
-   if { [string compare $command "mesh"] == 0 } {
-###     set nbfree(ALL) 8  ### OCC23106
-     set nbfree(ALL) 2
-     set nbwithouttri(All) 1
-     set nbfreenodes(All) 37
-   } else {
-     set nbfree(ALL) 2
-     set nbwithouttri(All) 1
-     set nbfreenodes(All) 37
-   }
-   ###set nbfreenodes(All) 37
+   set nbfree(ALL) 2
+   set nbfreenodes(All) 4
 }
index 92f29bc..c3b4414 100755 (executable)
@@ -1,5 +1,6 @@
 set TheFileName shading_089.brep
 if { [string compare $command "shading"] != 0 } {
-   set bug_area "OCC22687"
-   set rel_tol 1.42
+   #set bug_area "OCC22687"
+   set max_rel_tol_diff 1
+   set rel_tol 4
 }
index 46e62ea..0595a0f 100755 (executable)
@@ -1 +1,5 @@
 set TheFileName shading_101.brep
+if { [string compare $command "shading"] != 0 } {
+   set max_rel_tol_diff 0.1
+   set rel_tol 0.5
+}
index d7b4b79..46e6826 100755 (executable)
@@ -4,5 +4,5 @@ set max_rel_tol_diff 1
 if { [string compare $command "shading"] == 0 } {
   set rel_tol 2.64
 } else {
-  set rel_tol 2.55
+  set rel_tol 2.59
 }
index 00637a9..dda2445 100755 (executable)
@@ -18,7 +18,7 @@ if { [string compare $command "shading"] == 0 } {
 ##set nbt 14
   set nbt 8
   set nbn 60
-  set nbl 12
+  set nbl 11
   set nbwithouttri([checkplatform]) $nbt
   set nbfree([checkplatform]) $nbl
   set nbfreenodes([checkplatform]) $nbn
index d89a624..3042513 100755 (executable)
@@ -2,6 +2,6 @@ set TheFileName shading_wrongshape_015.brep
 set bug_withouttri "OCC22687"
 if { [string compare $command "shading"] != 0 } {
    set bug_freenodes "OCC23105"
-#   set nbfreenodes(ALL) 4
+   set nbfreenodes(ALL) 3
 }
 set nbwithouttri(All) 7
index 3ba08c8..9d3de03 100755 (executable)
@@ -2,12 +2,10 @@ set TheFileName shading_wrongshape_024.brep
 
 set bug_cross "OCC22687"
 set nbcross(All) 1
-
+set bug_area "OCC22687"
 set bug_freenodes "OCC22687"
-
 set bug_withouttri "OCC22687"
 if { [string compare $command "shading"] == 0 } {
-  set bug_area "OCC22687"
   set rel_tol 1.2
   set nbwithouttri(ALL) 6
   set nbfreenodes(ALL) 1
index 60426d2..11372ae 100644 (file)
@@ -8,7 +8,7 @@ set bug_area "OCC358"
 set max_rel_tol_diff 1
 puts $command
 if { [string compare $command "shading"] == 0 } {
-  set rel_tol 2.07
+  set rel_tol 0.43
 } else {
   set rel_tol 0.676
 }
\ No newline at end of file