]> OCCT Git - occt.git/commitdiff
0032719: Modelling Algorithms - UnifySameDomain result has incorrect triangulation V7_5_3p2
authorjgv <jgv@opencascade.com>
Sat, 12 Mar 2022 19:35:55 +0000 (22:35 +0300)
committerjfa <jfa@opencascade.com>
Mon, 14 Mar 2022 12:33:43 +0000 (15:33 +0300)
Correct method ShapeUpgrade_UnifySameDomain::UnionPCurves: reparametrize unified pcurves to fit the new range of 3D-curve.

src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
tests/bugs/heal/bug32719 [new file with mode: 0644]

index 730565f5c4bae686db0a0bd3e965dbda3015eb12..8b4e5ccf98fcb3cde2c20dc14b3416d16d117aff 100644 (file)
@@ -22,6 +22,7 @@
 #include <BRepTopAdaptor_TopolTool.hxx>
 #include <GC_MakeCircle.hxx>
 #include <Geom2d_Line.hxx>
+#include <Geom2d_Circle.hxx>
 #include <GCE2d_MakeLine.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <Geom2dConvert.hxx>
@@ -1601,9 +1602,6 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
     if (isFound)
       continue;
     
-    Standard_Real aFirst, aLast;
-    Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, aFirst, aLast);
-
     aFaceSeq.Append (aFace);
   }
   
@@ -1648,6 +1646,9 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
 
       if (aPCurveSeq.IsEmpty()) {
         Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
+        if (aCopyPCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+          aCopyPCurve = (Handle(Geom2d_TrimmedCurve)::DownCast(aCopyPCurve))->BasisCurve();
+        
         aPCurveSeq.Append(aCopyPCurve);
         aFirstsSeq.Append(aFirst);
         aLastsSeq.Append(aLast);
@@ -1722,6 +1723,9 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
       else
       {
         Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
+        if (aCopyPCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+          aCopyPCurve = (Handle(Geom2d_TrimmedCurve)::DownCast(aCopyPCurve))->BasisCurve();
+        
         aPCurveSeq.Append(aCopyPCurve);
         aFirstsSeq.Append(aFirst);
         aLastsSeq.Append(aLast);
@@ -1842,57 +1846,53 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
     }
   }
 
-  //Reparametrize 3d curve if needed
+  //Reparametrize pcurves if needed
   if (!ResPCurves.IsEmpty())
   {
-    if (Abs (aFirst3d - ResFirsts(1)) > aMaxTol ||
-        Abs (aLast3d  - ResLasts(1))  > aMaxTol)
+    for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
     {
-      GeomAdaptor_Curve aGAcurve (aCurve);
-      GeomAbs_CurveType aType = aGAcurve.GetType();
-      if (aType == GeomAbs_Line)
-      {
-        gp_Lin aLin = aGAcurve.Line();
-        gp_Dir aDir = aLin.Direction();
-        gp_Pnt aPnt = aGAcurve.Value (aFirst3d);
-        gp_Vec anOffset = -aDir;
-        anOffset *= ResFirsts(1);
-        aPnt.Translate (anOffset);
-        Handle(Geom_Line) aLine = new Geom_Line (aPnt, aDir);
-        aBuilder.UpdateEdge (theEdge, aLine, aTolEdge);
-        aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
-      }
-      else if (aType == GeomAbs_Circle)
-      {
-        gp_Circ aCirc = aGAcurve.Circle();
-        Standard_Real aRadius = aCirc.Radius();
-        gp_Ax2 aPosition = aCirc.Position();
-        gp_Ax1 anAxis = aPosition.Axis();
-        Standard_Real anOffset = aFirst3d - ResFirsts(1);
-        aPosition.Rotate (anAxis, anOffset);
-        Handle(Geom_Circle) aCircle = new Geom_Circle (aPosition, aRadius);
-        aBuilder.UpdateEdge (theEdge, aCircle, aTolEdge);
-        aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
-      }
-      else //general case
+      if (Abs (aFirst3d - ResFirsts(ii)) > aMaxTol ||
+          Abs (aLast3d  - ResLasts(ii))  > aMaxTol)
       {
-        for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
+        Geom2dAdaptor_Curve aGAcurve (ResPCurves(ii));
+        GeomAbs_CurveType aType = aGAcurve.GetType();
+        if (aType == GeomAbs_Line)
         {
-          if (Abs (aFirst3d - ResFirsts(ii)) > Precision::Confusion() ||
-              Abs (aLast3d  - ResLasts(ii))  > Precision::Confusion())
-          {
-            Handle(Geom2d_TrimmedCurve) aTrPCurve =
-              new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii),  ResLasts(ii));
-            Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
-            TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots());
-            aBSplinePCurve->Knots (aKnots);
-            BSplCLib::Reparametrize (aFirst3d, aLast3d, aKnots);
-            aBSplinePCurve->SetKnots (aKnots);
-            ResPCurves(ii) = aBSplinePCurve;
-          }
+          gp_Lin2d aLin2d = aGAcurve.Line();
+          gp_Dir2d aDir2d = aLin2d.Direction();
+          gp_Pnt2d aPnt2d = aGAcurve.Value(ResFirsts(ii));
+          gp_Vec2d anOffset = -aDir2d;
+          anOffset *= aFirst3d;
+          aPnt2d.Translate (anOffset);
+          Handle(Geom2d_Line) aNewLine2d = new Geom2d_Line (aPnt2d, aDir2d);
+          ResPCurves(ii) = aNewLine2d;
         }
-      }
-    }
+        else if (aType == GeomAbs_Circle)
+        {
+          gp_Circ2d aCirc2d = aGAcurve.Circle();
+          Standard_Real aRadius = aCirc2d.Radius();
+          gp_Ax22d aPosition = aCirc2d.Position();
+          gp_Pnt2d aLocation = aCirc2d.Location();
+          Standard_Real anOffset = ResFirsts(ii) - aFirst3d;
+          aPosition.Rotate (aLocation, anOffset);
+          Handle(Geom2d_Circle) aNewCircle2d = new Geom2d_Circle (aPosition, aRadius);
+          ResPCurves(ii) = aNewCircle2d;
+        }
+        else //general case
+        {
+          Handle(Geom2d_TrimmedCurve) aTrPCurve =
+            new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii),  ResLasts(ii));
+          Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
+          TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots());
+          aBSplinePCurve->Knots (aKnots);
+          BSplCLib::Reparametrize (aFirst3d, aLast3d, aKnots);
+          aBSplinePCurve->SetKnots (aKnots);
+          ResPCurves(ii) = aBSplinePCurve;
+        }
+        ResFirsts(ii)  = aFirst3d;
+        ResLasts(ii)   = aLast3d;
+      } //if ranges > aMaxTol
+    } //for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
   }
 
   for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++)
diff --git a/tests/bugs/heal/bug32719 b/tests/bugs/heal/bug32719
new file mode 100644 (file)
index 0000000..69d6292
--- /dev/null
@@ -0,0 +1,20 @@
+puts "============================================================"
+puts "OCC32719: UnifySameDomain result has incorrect triangulation"
+puts "============================================================"
+puts ""
+
+restore [locate_data_file bug32719.brep] a
+
+unifysamedom result a
+
+checkshape result
+
+checknbshapes result -t -solid 4 -shell 4 -face 20 -wire 20 -edge 32 -vertex 16
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 6.e-6} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -s 0.0222593 -v 5.17261e-05