]> OCCT Git - occt.git/commitdiff
0030747: Modeling Algorithms - 2d Curves concatenator doesn't properly process closed...
authorabulyche <abulyche@opencascade.com>
Mon, 4 Oct 2021 01:00:55 +0000 (04:00 +0300)
committersmoskvin <smoskvin@opencascade.com>
Thu, 14 Oct 2021 17:19:22 +0000 (20:19 +0300)
Corrected Geom2dConvert_CompCurveToBSplineCurve::Add in Geom2dConvert_CompCurveToBSplineCurve.cxx;
Added the test for this problem;
Corrected "gluing" curves in ProjLib_ProjectedCurve.cxx.

src/Geom2dConvert/Geom2dConvert_CompCurveToBSplineCurve.cxx
src/ProjLib/ProjLib_ProjectedCurve.cxx
src/QABugs/QABugs_20.cxx
tests/bugs/modalg_7/bug30747 [new file with mode: 0644]

index f68c1f4ddce4893ce8f918dac2e0b3b3c898e68d..f70189dd0c6b5ad26dc1265abb99e4213aef0876 100644 (file)
@@ -84,59 +84,53 @@ Add(const Handle(Geom2d_BoundedCurve)& NewCurve,
   }
 
   myTol = Tolerance;
+  const Standard_Real aSqTol = Tolerance * Tolerance;
 
   Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
+  Standard_Real d1 = myCurve->Pole(1).SquareDistance(Bs->Pole(1));
+  Standard_Real d2 = myCurve->Pole(1).SquareDistance(Bs->Pole(LBs));
+
+  Standard_Boolean isBeforeReversed = (myCurve->Pole(1).SquareDistance(Bs->Pole(1)) < aSqTol) && (d1 < d2);
+  Standard_Boolean isBefore = (myCurve->Pole(1).SquareDistance(Bs->Pole(LBs)) < aSqTol) || isBeforeReversed;
+
+  d1 = myCurve->Pole(LCb).SquareDistance(Bs->Pole(1));
+  d2 = myCurve->Pole(LCb).SquareDistance(Bs->Pole(LBs));
+
+  Standard_Boolean isAfterReversed = (myCurve->Pole(LCb).SquareDistance(Bs->Pole(LBs)) < aSqTol) && (d2 < d1);
+  Standard_Boolean isAfter = (myCurve->Pole(LCb).SquareDistance(Bs->Pole(1)) < aSqTol) || isAfterReversed;
   
-  // myCurve est elle fermee ?
-  if (myCurve->Pole(LCb).Distance(myCurve->Pole(1)) < myTol){
-    if(After){
-      // Ajout Apres ?
-      Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
-      Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
-      if (d2 < d1) {
-        Bs->Reverse();
-        d1 = d2;
-      }
-      if (d1 < myTol) {
-       Add(myCurve, Bs, Standard_True);
-       return Standard_True;
-      }
+  // myCurve and NewCurve together form a closed curve
+  if (isBefore && isAfter)
+  {
+    if (After)
+    {
+      isBefore = Standard_False;
     }
-    else{
-      // Ajout avant ?  
-      Standard_Real d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
-      Standard_Real d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
-      if (d1 < d2) {
-        Bs->Reverse();
-        d2 = d1;
-      }
-      if (d2 < myTol) {
-       Add(Bs, myCurve, Standard_False);
-       return Standard_True;
-      }
+    else
+    {
+      isAfter = Standard_False;
     }
   }
-  // Ajout Apres ?
-  else {
-
-    Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
-    Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
-    if (( d1  < myTol) || ( d2 < myTol)) {
-      if (d2 < d1) {Bs->Reverse();}
-      Add(myCurve, Bs, Standard_True);
-      return Standard_True;
+  if (isAfter)
+    {
+    if (isAfterReversed)
+    {
+      Bs->Reverse();
     }
-  // Ajout avant ?  
-    else { 
-      d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
-      d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
-      if ( (d1 < myTol) || (d2 < myTol)) {
-       if (d1 < d2) {Bs->Reverse();}
-       Add(Bs, myCurve, Standard_False );
-       return Standard_True;
-      }
+    Add(myCurve, Bs, Standard_True);
+    return Standard_True;
+    
+  }
+  else if (isBefore)
+  {
+    if (isBeforeReversed)
+    {
+      Bs->Reverse();
     }
-  }  
+    Add(Bs, myCurve, Standard_False);
+    return Standard_True;
+  }
+
   return Standard_False;
 }
 
index 875caf9e46bdecdfb50081328dacbbfab3285767..e21bda00e0c72854e4a140c0054cec32326e7bd4 100644 (file)
@@ -262,8 +262,9 @@ static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes,
   aSegment = (FirstOrLast == 0)?
     new Geom2d_TrimmedCurve(aSegLine, ParOnLin, 0.) :
     new Geom2d_TrimmedCurve(aSegLine, 0., ParOnLin);
-
-  aCompCurve.Add(aSegment, aTol);
+  
+  Standard_Boolean anAfter = FirstOrLast != 0;
+  aCompCurve.Add(aSegment, aTol, anAfter);
   aRes = aCompCurve.BSplineCurve();
 }
 
index d7098ec4bf29b67c49d3e98577fe2ce9cd2bba38..d6dfa3974a206e72e3718625ceac012e942a0ed8 100644 (file)
@@ -3514,6 +3514,53 @@ static Standard_Integer OCC30708_2 (Draw_Interpretor& di, Standard_Integer, cons
   return 0;
 }
 
+//=======================================================================
+//function : OCC30747
+//purpose  :
+//=======================================================================
+#include <Geom2d_Circle.hxx>
+#include <GCE2d_MakeCircle.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
+static Standard_Integer OCC30747(Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgV)
+{
+  if (theArgc < 2)
+  {
+    return 1;
+  }
+
+  const Handle(Geom2d_Circle) aCirc = GCE2d_MakeCircle(gp_Pnt2d(0, 0), 50);
+
+  Standard_Real aF = aCirc->FirstParameter();
+  Standard_Real aL = aCirc->LastParameter();
+  Standard_Real aNb = 10;
+  Standard_Real aDelta = (aF + aL) / aNb;
+  Handle(Geom2d_TrimmedCurve) aFTrim = new Geom2d_TrimmedCurve(aCirc, aF, aDelta);
+  Geom2dConvert_CompCurveToBSplineCurve aRes(aFTrim);
+  for (Standard_Integer anId = 1; anId < aNb; anId++)
+  {
+    Handle(Geom2d_TrimmedCurve) aLTrim;
+    if (anId == (aNb - 1))
+    {
+      aLTrim = new Geom2d_TrimmedCurve(aCirc, anId * aDelta, aF);
+    }
+    else
+    {
+      aLTrim = new Geom2d_TrimmedCurve(aCirc, anId * aDelta, (anId + 1) * aDelta);
+    }
+    aRes.Add(aLTrim, Precision::PConfusion());
+  }
+
+  if (!aRes.BSplineCurve()->IsClosed())
+  {
+    theDI << "Error: curve isn't closed";
+    return 1;
+  }
+
+  DrawTrSurf::Set(theArgV[1], aRes.BSplineCurve());
+  return 0;
+}
+
 //=======================================================================
 //function : OCC30869
 //purpose  :
@@ -4042,6 +4089,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC30391", "OCC30391 result face LenBeforeUfirst LenAfterUlast LenBeforeVfirst LenAfterVlast", __FILE__, OCC30391, group);
   theCommands.Add("OCC29195", "OCC29195 [nbRep] doc1 [doc2 [doc3 [doc4]]]", __FILE__, OCC29195, group);
   theCommands.Add("OCC30435", "OCC30435 result curve inverse nbit", __FILE__, OCC30435, group);
+  theCommands.Add("OCC30747", "OCC30747: create a closed curve", __FILE__, OCC30747, group);
   theCommands.Add("OCC30990", "OCC30990 surface", __FILE__, OCC30990, group);
 
   theCommands.Add("QAStartsWith",
diff --git a/tests/bugs/modalg_7/bug30747 b/tests/bugs/modalg_7/bug30747
new file mode 100644 (file)
index 0000000..f2d76dd
--- /dev/null
@@ -0,0 +1,8 @@
+puts "================================================================="
+puts "OCC30747: Modeling Algorithms - 2d Curves concatenator doesn't properly process closed contours."
+puts "================================================================="
+puts ""
+
+pload QAcommands
+
+OCC30747 res
\ No newline at end of file