]> OCCT Git - occt.git/commitdiff
0030272: Modeling Algorithms - Incorrect work of gproject
authorknosulko <knosulko@opencascade.com>
Thu, 14 Oct 2021 17:15:02 +0000 (20:15 +0300)
committersmoskvin <smoskvin@opencascade.com>
Tue, 7 Dec 2021 19:32:14 +0000 (22:32 +0300)
-fix TolU/V for approximation;
-fix cutting tool for approximation;
-add method Adaptor3d_HSurfaceTool::IsSurfG1.
-add test bugs/moddata_3/bug30272

src/Adaptor3d/Adaptor3d_HSurfaceTool.cxx
src/Adaptor3d/Adaptor3d_HSurfaceTool.hxx
src/AdvApprox/AdvApprox_PrefAndRec.cxx
src/Approx/Approx_CurveOnSurface.cxx
src/BRepAlgo/BRepAlgo_NormalProjection.cxx
src/BRepTest/BRepTest_BasicCommands.cxx
src/ProjLib/ProjLib_CompProjectedCurve.cxx
src/ProjLib/ProjLib_CompProjectedCurve.hxx
tests/bugs/moddata_3/bug30272 [new file with mode: 0644]

index 673acbaa737a10531fed1d00f19b7c9a65b30b17..83c6bb217049ec2b550a09dfab7019573b070873 100644 (file)
 
 #include <Adaptor3d_Curve.hxx>
 #include <Adaptor3d_Surface.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
 #include <Geom_BezierSurface.hxx>
+#include <Geom_BSplineCurve.hxx>
 #include <Geom_BSplineSurface.hxx>
+#include <Geom_OffsetCurve.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Vec.hxx>
 #include <Standard_NoSuchObject.hxx>
@@ -98,3 +101,79 @@ Standard_Integer Adaptor3d_HSurfaceTool::NbSamplesV(const Handle(Adaptor3d_Surfa
   }
   return n;
 }
+
+Standard_Boolean Adaptor3d_HSurfaceTool::IsSurfG1(const Handle(Adaptor3d_Surface)& theSurf,
+                                                  const Standard_Boolean theAlongU,
+                                                  const Standard_Real theAngTol)
+{
+  Standard_Real aUf, aUl, aVf, aVl;
+  aUf = theSurf->FirstUParameter();
+  aUl = theSurf->LastUParameter();
+  aVf = theSurf->FirstVParameter();
+  aVl = theSurf->LastVParameter();
+
+  Handle(Adaptor3d_Surface) aS = theSurf;
+  Handle(Adaptor3d_Curve) aC;
+
+  Handle(Geom_BSplineSurface) aBS;
+  Handle(Geom_BSplineCurve) aBC;
+
+  if (aS->GetType() == GeomAbs_OffsetSurface)
+  {
+    aS = aS->BasisSurface();
+  }
+
+  if (aS->GetType() == GeomAbs_SurfaceOfRevolution ||
+      aS->GetType() == GeomAbs_SurfaceOfExtrusion)
+  {
+    aC = aS->BasisCurve();
+  }
+
+  if (!aC.IsNull())
+  {
+    if (aC->GetType() == GeomAbs_OffsetCurve)
+    {
+      Handle(Geom_OffsetCurve) aOC = aC->OffsetCurve();
+      aC = new GeomAdaptor_Curve(aOC->BasisCurve());
+    }
+
+    if (aC->GetType() == GeomAbs_BSplineCurve)
+    {
+      if ((theAlongU && aS->GetType() == GeomAbs_SurfaceOfExtrusion) ||
+          (!theAlongU && aS->GetType() == GeomAbs_SurfaceOfRevolution))
+      {
+        aBC = aC->BSpline();
+      }
+    }
+  }
+
+  if (aS->GetType() == GeomAbs_BSplineSurface)
+  {
+    aBS = aS->BSpline();
+
+    if (theAlongU)
+    {
+      const Standard_Real anIsoPar = (aVf + aVl) / 2.0;
+      aBC = Handle(Geom_BSplineCurve)::DownCast(aBS->VIso(anIsoPar));
+    }
+    else
+    {
+      const Standard_Real anIsoPar = (aUf + aUl) / 2.0;
+      aBC = Handle(Geom_BSplineCurve)::DownCast(aBS->UIso(anIsoPar));
+    }
+  }
+
+  if(!aBC.IsNull())
+  {
+    if (theAlongU)
+    {
+      return aBC->IsG1(aUf, aUl, theAngTol);
+    }
+    else
+    {
+      return aBC->IsG1(aVf, aVl, theAngTol);
+    }
+  }
+
+  return Standard_False;
+}
index 9ec2f392685e7b67584ef079d7731e4af2a1fc28..57766af1ed2d83b58168aa74cce7d7fff7f4a974 100644 (file)
@@ -165,6 +165,10 @@ public:
 
   static Standard_Real OffsetValue (const Handle(Adaptor3d_Surface)& theSurf) { return theSurf->OffsetValue(); }
 
+  Standard_EXPORT static Standard_Boolean IsSurfG1 (const Handle(Adaptor3d_Surface)& theSurf,
+                                                    const Standard_Boolean theAlongU,
+                                                    const Standard_Real theAngTol = Precision::Angular());
+
   Standard_EXPORT static Standard_Integer NbSamplesU (const Handle(Adaptor3d_Surface)& S);
 
   Standard_EXPORT static Standard_Integer NbSamplesV (const Handle(Adaptor3d_Surface)& S);
index 2f85ed4da8f4939118ead438540905309eea041c..be5e8ba9c281d57f59dc5c1c13f3b93d1241d9eb 100644 (file)
@@ -39,6 +39,7 @@ Standard_Boolean AdvApprox_PrefAndRec::Value(const Standard_Real a,
   Standard_Real lgmin = 10 * Precision::PConfusion();
   Standard_Integer i;
   Standard_Real cut, mil=(a+b)/2, dist;
+  Standard_Boolean isfound = Standard_False;
 
   cut = mil;
 
@@ -48,15 +49,19 @@ Standard_Boolean AdvApprox_PrefAndRec::Value(const Standard_Real a,
     if ( dist > Abs(mil-myPrefCutting.Value(i))) {
       cut = myPrefCutting.Value(i);
       dist = Abs(mil-cut);
+      isfound = Standard_True;
     }
   }
 
 // Recheche d'une decoupe recommende
-  dist = Abs((a-b)/2);
-  for ( i=1; i<=myRecCutting.Length(); i++) {
-    if ((dist-lgmin) > Abs(mil-myRecCutting.Value(i))) {
-      cut = myRecCutting.Value(i);
-      dist = Abs(mil-cut);
+  if (!isfound)
+  {
+    dist = Abs((a-b)/2);
+    for ( i=1; i<=myRecCutting.Length(); i++) {
+      if ((dist-lgmin) > Abs(mil-myRecCutting.Value(i))) {
+        cut = myRecCutting.Value(i);
+        dist = Abs(mil-cut);
+      }
     }
   }
     
index e6121710465e955a78f4d9feea9ea8bbf8ba94ea..bf3d1b05dd4ebc3cad7dfde53f4c19214e064838 100644 (file)
@@ -20,6 +20,7 @@
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <Adaptor3d_Curve.hxx>
 #include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor3d_HSurfaceTool.hxx>
 #include <Adaptor3d_Surface.hxx>
 #include <AdvApprox_ApproxAFunction.hxx>
 #include <AdvApprox_DichoCutting.hxx>
@@ -373,6 +374,14 @@ void Approx_CurveOnSurface::Perform(const Standard_Integer theMaxSegments,
 
   if(theOnly3d && theOnly2d) throw Standard_ConstructionError();
 
+  GeomAbs_Shape aContinuity = theContinuity;
+  if (aContinuity == GeomAbs_G1)
+    aContinuity = GeomAbs_C1;
+  else if (aContinuity == GeomAbs_G2)
+    aContinuity = GeomAbs_C2;
+  else if (aContinuity > GeomAbs_C2)
+    aContinuity = GeomAbs_C2; //Restriction of AdvApprox_ApproxAFunction
+
   Handle( Adaptor2d_Curve2d ) TrimmedC2D = myC2D->Trim( myFirst, myLast, Precision::PConfusion() );
 
   Standard_Boolean isU, isForward;
@@ -410,8 +419,24 @@ void Approx_CurveOnSurface::Perform(const Standard_Integer theMaxSegments,
 
     Standard_Real TolU, TolV;
 
-    TolU = mySurf->UResolution(myTol)/2;
-    TolV = mySurf->VResolution(myTol)/2;
+    TolU = mySurf->UResolution(myTol) / 2.;
+    TolV = mySurf->VResolution(myTol) / 2.;
+
+    if (mySurf->UContinuity() == GeomAbs_C0)
+    {
+      if (!Adaptor3d_HSurfaceTool::IsSurfG1(mySurf, Standard_True, Precision::Angular()))
+        TolU = Min(1.e-3, 1.e3 * TolU);
+      if (!Adaptor3d_HSurfaceTool::IsSurfG1(mySurf, Standard_True, Precision::Confusion()))
+        TolU = Min(1.e-3, 1.e2 * TolU);
+    }
+
+    if (mySurf->VContinuity() == GeomAbs_C0)
+    {
+      if (!Adaptor3d_HSurfaceTool::IsSurfG1(mySurf, Standard_False, Precision::Angular()))
+        TolV = Min(1.e-3, 1.e3 * TolV);
+      if (!Adaptor3d_HSurfaceTool::IsSurfG1(mySurf, Standard_False, Precision::Confusion()))
+        TolV = Min(1.e-3, 1.e2 * TolV);
+    }
 
     OneDTol->SetValue(1,TolU);
     OneDTol->SetValue(2,TolV);
@@ -423,20 +448,44 @@ void Approx_CurveOnSurface::Perform(const Standard_Integer theMaxSegments,
     ThreeDTol->Init(myTol/2);
   }
 
+  AdvApprox_Cutting* CutTool;
+
+  if (aContinuity <= myC2D->Continuity() &&
+      aContinuity <= mySurf->UContinuity() &&
+      aContinuity <= mySurf->VContinuity())
+  {
+    CutTool = new AdvApprox_DichoCutting();
+  }
+  else if (aContinuity == GeomAbs_C1)
+  {
+    Standard_Integer NbInterv_C1 = HCOnS->NbIntervals(GeomAbs_C1);
+    TColStd_Array1OfReal CutPnts_C1(1, NbInterv_C1 + 1);
+    HCOnS->Intervals(CutPnts_C1, GeomAbs_C1);
+    Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
+    TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
+    HCOnS->Intervals(CutPnts_C2, GeomAbs_C2);
+    
+    CutTool = new AdvApprox_PrefAndRec (CutPnts_C1, CutPnts_C2);
+  }
+  else
+  {
+    Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
+    TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
+    HCOnS->Intervals(CutPnts_C2, GeomAbs_C2);
+    Standard_Integer NbInterv_C3 = HCOnS->NbIntervals(GeomAbs_C3);
+    TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3 + 1);
+    HCOnS->Intervals(CutPnts_C3, GeomAbs_C3);
+    
+    CutTool = new AdvApprox_PrefAndRec (CutPnts_C2, CutPnts_C3);
+  }
 
-  Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
-  TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
-  HCOnS->Intervals(CutPnts_C2, GeomAbs_C2);
-  Standard_Integer NbInterv_C3 = HCOnS->NbIntervals(GeomAbs_C3);
-  TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3 + 1);
-  HCOnS->Intervals(CutPnts_C3, GeomAbs_C3);
-  
-  AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
   AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS, 
                                     OneDTol, TwoDTolNul, ThreeDTol,
-                                    myFirst, myLast, theContinuity,
+                                    myFirst, myLast, aContinuity,
                                     theMaxDegree, theMaxSegments,
-                                    *EvalPtr, CutTool);
+                                    *EvalPtr, *CutTool);
+
+  delete CutTool;
 
   myIsDone = aApprox.IsDone();
   myHasResult = aApprox.HasResult();
index f94dab3b0009365f86ee11c6c3f1b9cf0aa560b3..2fb121ddf2459143b8cd6dd9fe1d4913d1229c06 100644 (file)
@@ -152,7 +152,7 @@ void BRepAlgo_NormalProjection::SetDefaultParams()
 {
   myTol3d = 1.e-4;
   myTol2d = Pow(myTol3d, 2./3);
-  myContinuity = GeomAbs_C2;
+  myContinuity = GeomAbs_C1;
   myMaxDegree = 14;
   myMaxSeg    = 16;
 }
index aecc356a0cba05e8aca1f2c18fe934d1f738878d..89574e30080b0aac36dc697e19d2e53fbf1a7a88 100644 (file)
@@ -1225,7 +1225,7 @@ static Standard_Integer vecdc(Draw_Interpretor& di,Standard_Integer ,const char*
   Standard_Real Tol = 1.e-4;        
   Standard_Real Tol2d;
   Standard_Real MaxDistance = 1.e-3;
-  GeomAbs_Shape Continuity = GeomAbs_C2;  
+  GeomAbs_Shape Continuity = GeomAbs_C1;  
   Standard_Integer MaxDeg = 14;           
   Standard_Integer MaxSeg = 16;           
 
@@ -1259,7 +1259,7 @@ static Standard_Integer vecdc(Draw_Interpretor& di,Standard_Integer ,const char*
 
   if(n > arg) {
     if (Draw::Atoi(a[arg]) == 0) Continuity = GeomAbs_C0;
-    else if (Draw::Atoi(a[arg]) == 1) Continuity = GeomAbs_C1;
+    else if (Draw::Atoi(a[arg]) == 2) Continuity = GeomAbs_C2;
     arg++;
   }
 
index 7c9deded7948652f2765a5192fbb5bed8e9951a1..44e5d0042c325dfc9d8657a5936a0fb8ce57c17e 100644 (file)
@@ -1784,6 +1784,22 @@ Standard_Real ProjLib_CompProjectedCurve::LastParameter() const
   return myCurve->LastParameter();
 }
 
+//=======================================================================
+//function : Continuity
+//purpose  : 
+//=======================================================================
+
+GeomAbs_Shape ProjLib_CompProjectedCurve::Continuity() const
+{
+  GeomAbs_Shape ContC  = myCurve->Continuity();
+  GeomAbs_Shape ContSu = mySurface->UContinuity();
+  if ( ContSu < ContC) ContC = ContSu;
+  GeomAbs_Shape ContSv = mySurface->VContinuity();
+  if ( ContSv < ContC) ContC = ContSv;
+
+  return ContC;
+}
+
 //=======================================================================
 //function : MaxDistance
 //purpose  : 
index 8c5fa21640fe0a25746fbaf737cd0f29620df52a..6b93a8d5f0b77c0aa40a17eebd2c51fbf5eda0c1 100644 (file)
@@ -158,6 +158,9 @@ public:
   //! which  has  a  projection  on  S.
   Standard_EXPORT Standard_Real LastParameter() const Standard_OVERRIDE;
   
+  //! Returns the Continuity used in the approximation.
+  Standard_EXPORT GeomAbs_Shape Continuity() const Standard_OVERRIDE;
+
   //! Returns  the number  of  intervals which  define
   //! an  S  continuous  part  of  the  projected  curve
   Standard_EXPORT Standard_Integer NbIntervals (const GeomAbs_Shape S) const Standard_OVERRIDE;
diff --git a/tests/bugs/moddata_3/bug30272 b/tests/bugs/moddata_3/bug30272
new file mode 100644 (file)
index 0000000..a546567
--- /dev/null
@@ -0,0 +1,48 @@
+puts "================"
+puts "0030272: Modeling Algorithms - Incorrect work of gproject"
+puts "================"
+puts ""
+
+set BugNumber OCC30272
+
+set tol_abs 1.0e-4
+set tol_rel 0.0001
+
+restore [locate_data_file bug30272_cur.brep] c
+restore [locate_data_file bug30272_sur.brep] s
+
+set result_C0 [gproject result_C0 c s 1.0e-3 -3d 1 -c C0]
+regexp {2d is ([-0-9.+eE]+);..([-0-9.+eE]+)} $result_C0 full 2dUError_C0 2dVError_C0
+regexp {3d is ([-0-9.+eE]+)} $result_C0 full 3dError_C0
+
+set expected_2dUError_C0 8.5166415968648575e-06
+set expected_2dVError_C0 1.9383641349197776e-07
+set expected_3dError_C0 0.00039481100189762405
+
+checkreal "2dUError_C0" ${2dUError_C0} ${expected_2dUError_C0} ${tol_abs} ${tol_rel}
+checkreal "2dVError_C0" ${2dVError_C0} ${expected_2dVError_C0} ${tol_abs} ${tol_rel}
+checkreal "3dError_C0" ${3dError_C0} ${expected_3dError_C0} ${tol_abs} ${tol_rel}
+
+set result_C1 [gproject result_C1 c s 1.0e-3 -3d 1 -c C1]
+regexp {2d is ([-0-9.+eE]+);..([-0-9.+eE]+)} $result_C1 full 2dUError_C1 2dVError_C1
+regexp {3d is ([-0-9.+eE]+)} $result_C1 full 3dError_C1
+
+set expected_2dUError_C1 1.1207913216250422e-05
+set expected_2dVError_C1 1.9546900926719333e-07
+set expected_3dError_C1 0.00029305148512110709
+
+checkreal "2dUError_C1" ${2dUError_C1} ${expected_2dUError_C1} ${tol_abs} ${tol_rel}
+checkreal "2dVError_C1" ${2dVError_C1} ${expected_2dVError_C1} ${tol_abs} ${tol_rel}
+checkreal "3dError_C1" ${3dError_C1} ${expected_3dError_C1} ${tol_abs} ${tol_rel}
+
+set result_C2 [gproject result_C2 c s 1.0e-3 -3d 1 -c C2]
+regexp {2d is ([-0-9.+eE]+);..([-0-9.+eE]+)} $result_C2 full 2dUError_C2 2dVError_C2
+regexp {3d is ([-0-9.+eE]+)} $result_C2 full 3dError_C2
+
+set expected_2dUError_C2 1.1368572775344132e-05
+set expected_2dVError_C2 1.8525211887318316e-07
+set expected_3dError_C2 0.00024049581776618967
+
+checkreal "2dUError_C2" ${2dUError_C2} ${expected_2dUError_C2} ${tol_abs} ${tol_rel}
+checkreal "2dVError_C2" ${2dVError_C2} ${expected_2dVError_C2} ${tol_abs} ${tol_rel}
+checkreal "3dError_C2" ${3dError_C2} ${expected_3dError_C2} ${tol_abs} ${tol_rel}