0023620: Follow up of 0022939 - make Bezier curve/surface evaluation thread-safe
[occt.git] / src / GeomAdaptor / GeomAdaptor_Surface.cxx
index c7ad0b6..f3423df 100644 (file)
@@ -20,8 +20,6 @@
 
 #define No_Standard_RangeError
 #define No_Standard_OutOfRange
-#define PosTol (Precision::PConfusion()*0.5)
-
 
 #include <Adaptor3d_HCurve.hxx>
 #include <Adaptor3d_HSurface.hxx>
@@ -70,6 +68,8 @@
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 
+static const Standard_Real PosTol = Precision::PConfusion()*0.5;
+
 //=======================================================================
 //function : LocalContinuity
 //purpose  : 
@@ -139,9 +139,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
     myNestedEvaluator = Handle(GeomEvaluator_Surface)();
 
     const Handle(Standard_Type)& TheType = S->DynamicType();
-    if ( TheType == STANDARD_TYPE(Geom_BezierSurface))
-      mySurfaceType = GeomAbs_BezierSurface;
-    else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+    if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
       Load(Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(),
            UFirst,ULast,VFirst,VLast);
     }
@@ -155,7 +153,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
       mySurfaceType = GeomAbs_Sphere;
     else if ( TheType == STANDARD_TYPE(Geom_ToroidalSurface))
       mySurfaceType = GeomAbs_Torus;
-    else if (TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
+    else if ( TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
     {
       mySurfaceType = GeomAbs_SurfaceOfRevolution;
       Handle(Geom_SurfaceOfRevolution) myRevSurf =
@@ -168,7 +166,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
           Handle(Adaptor3d_HCurve)::DownCast(aBaseAdaptor),
           myRevSurf->Direction(), myRevSurf->Location());
     }
-    else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
+    else if ( TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
     {
       mySurfaceType = GeomAbs_SurfaceOfExtrusion;
       Handle(Geom_SurfaceOfLinearExtrusion) myExtSurf =
@@ -180,16 +178,30 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
       myNestedEvaluator = new GeomEvaluator_SurfaceOfExtrusion(
           Handle(Adaptor3d_HCurve)::DownCast(aBaseAdaptor), myExtSurf->Direction());
     }
-    else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
+    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);
       // Create cache for B-spline
-      mySurfaceCache = new BSplSLib_Cache(
+      mySurfaceCache = new BSplSLib_Cache( 
         myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), 
         myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), 
         myBspl->Poles(), myBspl->Weights());
     }
-    else if (TheType == STANDARD_TYPE(Geom_OffsetSurface))
+    else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
     {
       mySurfaceType = GeomAbs_OffsetSurface;
       Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
@@ -668,11 +680,26 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const
 void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
                                        const Standard_Real theV) const
 {
-  Handle(Geom_BSplineSurface) myBspl = Handle(Geom_BSplineSurface)::DownCast(mySurface);
-  mySurfaceCache->BuildCache(theU, theV,
-    myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), 
-    myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), 
-    myBspl->Poles(), myBspl->Weights());
+  if (mySurfaceType == GeomAbs_BezierSurface)
+  {
+    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->BuildCache(theU, theV,
+      aDegU, aBezier->IsUPeriodic(), aFlatKnotsU,
+      aDegV, aBezier->IsVPeriodic(), aFlatKnotsV,
+      aBezier->Poles(), aBezier->Weights());
+  }
+  else if (mySurfaceType == GeomAbs_BSplineSurface)
+  {
+    Handle(Geom_BSplineSurface) myBspl = Handle(Geom_BSplineSurface)::DownCast(mySurface);
+      mySurfaceCache->BuildCache(theU, theV,
+        myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
+        myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
+        myBspl->Poles(), myBspl->Weights());
+  }
 }
 
 //=======================================================================
@@ -698,6 +725,7 @@ void GeomAdaptor_Surface::D0(const Standard_Real U,
 {
   switch (mySurfaceType)
   {
+  case GeomAbs_BezierSurface:
   case GeomAbs_BSplineSurface:
     if (!mySurfaceCache.IsNull())
     {
@@ -742,9 +770,11 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
   else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
 
   switch(mySurfaceType) {
+  case GeomAbs_BezierSurface:
   case GeomAbs_BSplineSurface: {
     Handle(Geom_BSplineSurface) myBspl = Handle(Geom_BSplineSurface)::DownCast(mySurface);
-    if ((USide != 0 || VSide != 0) &&
+    if (!myBspl.IsNull() &&
+        (USide != 0 || VSide != 0) && 
         IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
       myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
     else if (!mySurfaceCache.IsNull())
@@ -754,7 +784,7 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
       mySurfaceCache->D1(U, V, P, D1U, D1V);
     }
     else
-      myBspl->D1(u, v, P, D1U, D1V);
+      mySurface->D1(u, v, P, D1U, D1V);
     break;
     }
 
@@ -793,9 +823,11 @@ void GeomAdaptor_Surface::D2(const Standard_Real U,
   else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
 
   switch(mySurfaceType) {
+  case GeomAbs_BezierSurface:
   case  GeomAbs_BSplineSurface: {
     Handle(Geom_BSplineSurface) myBspl = Handle(Geom_BSplineSurface)::DownCast(mySurface);
-    if ((USide != 0 || VSide != 0) &&
+    if (!myBspl.IsNull() &&
+        (USide != 0 || VSide != 0) && 
         IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
       myBspl->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV);
     else if (!mySurfaceCache.IsNull())
@@ -804,12 +836,13 @@ void GeomAdaptor_Surface::D2(const Standard_Real U,
         RebuildCache(U, V);
       mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
     }
-    else myBspl->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV);
+    else
+      mySurface->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV);
     break;
   }
 
-  case GeomAbs_SurfaceOfExtrusion:
-  case GeomAbs_SurfaceOfRevolution:
+  case GeomAbs_SurfaceOfExtrusion  :
+  case GeomAbs_SurfaceOfRevolution :
   case  GeomAbs_OffsetSurface :
     Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(),
         "GeomAdaptor_Surface::D2: evaluator is not initialized");
@@ -854,9 +887,9 @@ void GeomAdaptor_Surface::D3(const Standard_Real U, const Standard_Real V,
     }
     break;
   }
-
-  case GeomAbs_SurfaceOfExtrusion:
-  case GeomAbs_SurfaceOfRevolution:
+    
+  case GeomAbs_SurfaceOfExtrusion  :
+  case GeomAbs_SurfaceOfRevolution :
   case  GeomAbs_OffsetSurface:
     Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(),
         "GeomAdaptor_Surface::D3: evaluator is not initialized");
@@ -864,7 +897,7 @@ void GeomAdaptor_Surface::D3(const Standard_Real U, const Standard_Real V,
     break;
 
   default : {  mySurface->D3(u,v,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); 
-                break;}
+    break;}
   }
 }