]> OCCT Git - occt-copy.git/commitdiff
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 c0984673ea59a243f988f9916097787b63f97f7c..963957c46c4230ffd78db7ab8572aa5550d90bbc 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 61fae26445a39cc601fa8473783d24fc85990a7a..ca986abac388e4e716d4ca6acfed9d6785f7adde 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 6d10ac50876b7d39f4f957f50ceb5b8ffaa92b3d..6c82eb11aa5b44790b038ecc457c7406af916421 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 14fa8d4d0607d02a9b61fae8f221b9ec326b6212..37db10c277bcf95706a67ef4df3db4477e313b49 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 d85d0934bdf8169f4adf61a7d21dee99b0ba84d8..5fbb1bba33a83577436f94bb9aa0e47916411cdf 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 5b847d39ddd404208ef78dca6f11a2b48bdc8064..d7f20a6146f2f7ef6cd4a2bce1e3997ec13d76af 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 d1895602c1dd1ec67d0953de28c85b53ff9620ce..b35b3bccd682845f9ba9e8da18509307f985279b 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 80b184d3dd5068fccbeb9c7618014aa5a41e6026..5af1a9e43278525937c133d6c9b14e5170e47727 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 622a3b2c04a3a0b8f4b85c0dfbaeb17e2f0afe53..1d453897ff34488535ab856926a24707482749f5 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 be0236145a8b250954e5fce0bd30d49321baa97d..3db6feeae21d616f11b26435674a6ab62dfd82cb 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 0b913ada87be0224234f696e3aa90632fcb6102c..2abfe722c780763fce467aea35ab266b225852f3 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 01a36a793836e7cefd289dab7feaeba4819e4a74..76b00e1914d75028e6e350247d1824b666370735 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 3733f6a9ba7f5c4513ad6a17e906dad5654a93f9..16c34331b216d262d81e6836ccbe2b41150687eb 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 54fbd48014d3d44586e74a4e17e4603968a1cb79..047cb188c0104bc74de52ad474184a79da76338d 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 9ac69574640a5538dc6a989b77a51d1ce68ed4ac..ebd837bd7aa6e8838f725aa28507747c67a37407 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 35192a6fdc25177f3941147e48623b3d28c77979..e1883d774691ba60e9d6b6cf271c9a646b637b42 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 58db9703e7f5779aad837fc1f710f02db7461c74..13ee2b28435a02412771826de2f081460112162c 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 5af6f170ee3793b5681df7b6c9258ea8bafcc616..22a9e6f9660e4aee8436d84a3900ae9c46dec3b2 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 63e612b41eefa4bc5ee9ea21b7b768947bf6cc1a..dc28c43f1bde78092d9a86c6dc198d5ebd257061 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 2cb0abe3d0f8d7ca43335fdf844c16e690c9ee7e..0354196746074d2553f01b6ec8af2ed123e86252 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 52e25850cc68739f6bd87e2e7fa6e7b534b8bd5d..9a54bf071dbdd0a4e219cd3e2cf590120054208c 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 0d75f681f7adaaa0c1e3713452b8990fca5bef3d..3a768cc522325224ffb489c8407ad3a034b76435 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 c379a605977edcdc963804c3303554778b8ba6e0..6cba54802f2239344aa7ffb9516ea77f6d14ad5f 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 b186aa256a0a412ae673da3f1975094276199b6f..38cf01356641a744915f487dfc775395e72eac4e 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 587d6121b5496ae8bb9aad4f2ec2d1b00cfd89a7..9d5364ffa75c27bfaff51df3ef820dd3d4e190ac 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 351121e09db572a2e0bbb563011a618d229a6aeb..0519edf9bcfbfde188d4775ec02d4aebef9b122c 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 ac6c3cd32b21167329fffba1ac3e7954e61300a0..13f019c9d33f8d5bda0f87e388954cfed5933746 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 08aab574070100a870b45a13dd9085dd68a89f42..948a01f849f0d8cdec03136cb06fae22b94ce546 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 2253cf69899745b78ae5e997b507c49bffa985f8..a4142a5b2f4940169788fcbdf466f6c4498dc952 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 8ee3af99f22405d4c6a6ff9ee0e36264a5ba4cc6..76e4e680d52eaa8637d2f12ba3264fdca3654448 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 62c51e07f88a969cd266852f6f95c9299b8f832c..0d61dc4b45881f9daca8e9559b8348dd6f94da3f 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 047faa2b2b159e2e6d6ad58989cc84fb4f8b05f7..b025ffe8f73c521b06bf704f6e6fc5ca6a8d4c2b 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 1bf3d2aa6b4bd02cc0999954b25ab35e72329062..6ecbf6a5c44e4a9270d87cfb6f772fc492a8b1ed 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 6408cab9c4a11bf2e809c94f9935dfb677b6969e..5be1665b1d813bfcb27f347f312db6607650f586 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 62f981a7e06c4786d55c5d5904e5609fd1cbc241..1cc735c78f312decf99d26c299fb279a854121aa 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 dc479ccb5df65484774d67e2948887039feec449..c043cfacdafa432e888228bce46cd36467a9e4e1 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 bef6e8a392d32d4f31b67da0decc4ff2542bf668..2f0d4838c3e49cad4beada9282aa7f0547888c62 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 2dbafbe0b1abfb4fa94b5c45ecf3f673dfc17ae0..5ae491e3f328aabb254a6d154f40e903caf75a70 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 26e50ded7a711d1e4cb5f0c666ad599af9f9fe20..12572656617c1771b08697c06f3cc2ea2717d784 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 83a670511c1b063765841ab712b676f4a2c602d1..30ca1814f44e70c9c313edd7c3c994774265a9e7 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 edd27501294d6330029e8da8a90e2c1fde66e63a..84563aaf8521e332fd107b1610292460f80fec65 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 3ab8cef57cb7804388a18a28c48f1702b8e1a864..6036829a96f506fe1197cd0d1ae4241e8f5fdb0d 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 a29de1caadea10af7494b759560e057d5d289af8..696e3a7f4b5702c7290f87409dd1b6df95a41d29 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 a216c15494c3c8a3ffd13ccbb2aeefe04d2a7043..fb834de728cf93045f0d991893cb567cfb4b1aec 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 274598f445e2c5aa5b677734a115e80a0206d09c..45489a7f7ca5119203b3d0834256b23849097224 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 48d0d7c7932e789056db42a9c368319cbe29e645..2501ae389fa0aad2317ba52412f9fc3773d82333 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 3cee3d0aef52b09ab58affba106e8c129a4c892a..db0cc9ba0cc4bc3fbb5206f57dc4ea825f4bb488 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 8346596003b0ac18d7a71846b96d252082a1494b..40abec633dd392e9d020e89644bf1ba1410fd6bf 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 143941e983418f71a6d7375876b6e77762afc6b2..62ddd97749ed8bad8207a043d9eab066dbbd3fd6 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 f4b2c78c00ad641e3f221f800cb75f298a4033da..d57ecb3691f26dd814f7bcd059b7788d53f37b66 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 5e1dbf075ebb093ac21f4314278e35ad839e2a18..ee0042c42d7185b57d8d1bdc3c1df7a072df97c5 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 9445f94b93b503455d7b2738f39c7ff001a75f69..b0b20a9b4c6665873bd2859da904811ac1a26de0 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 7e4f0fc089471a13b3ca46d6a2c0e4ce81e4b68d..fb3f59325759fc75d47428ef2f79cc150cb8927b 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 9b4834836a94f45e9dbf0b66d61a37d1580e163c..4681550bb13b395b1361afeae2f287bd5e312ab7 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 8e6961a46f546ce663e439435f76e7efe428e6c7..7612d607a993bf8044f0010d54e02e3dafb224df 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 45b1b6a0ca80441b346c1ed0bcc83ab4d214c242..0f5b4b5b5fe105c6c5610f798f1d364de3b5e7a2 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 a7ae54ceae6ebd281986854689fbda739c4c0971..1e1cbc02d73e38f880785ced607f8e6cc777a1e6 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 92f29bcc48a6eb8bdf902dc39c9cbd33164a866c..c3b441454a545a5c9648cdfebad3fb5bdadfa5da 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 46e62ea3f34458cebf11bb78225b6cc28f2e61d7..0595a0f37bbc0b640d56a42ff5d2a67a892824de 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 d7b4b791b906aa5245a91fd317f4c48e16fff87f..46e682643448b6f68fd98ccc7fb45bcc6b734bad 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 00637a9fd601c6706914433ebbe47ef9304aacd3..dda24459c326b8bfb144eeca19eadfe751629221 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 d89a624ef4f581a9bfa98874ece1788a67603cd4..3042513f7adaa990a34d9e523aa19702dbd122fe 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 3ba08c8363e46db84eae2c07c3fb25700d24bd34..9d3de035def5c37fabe3b5f75d075b018e649ef0 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 60426d2e874912efb933f6f96f451c935d95d663..11372ae97eba89d1656c218c9fa9137f56de3b2f 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