]> OCCT Git - occt.git/commitdiff
0032857: Error when finding the intersection between a new face made after a draft... CR32857
authornmanchen <nmanchen@opencascade.com>
Wed, 19 Oct 2022 12:57:45 +0000 (15:57 +0300)
committernmanchen <nmanchen@opencascade.com>
Thu, 3 Nov 2022 22:05:59 +0000 (01:05 +0300)
Intersection surface cone is calculated for the part of the cone that corresponds to the draft plane.

src/Draft/Draft_Modification_1.cxx
tests/bugs/modalg_8/bug32857 [new file with mode: 0644]

index f965a8648edb223c630c7c457d69cd5c24f951fa..34671427a5abe646814cc72d5e5412685d393531 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor3d_TopolTool.hxx>
 #include <GeomAdaptor_SurfaceOfLinearExtrusion.hxx>
 #include <Approx_CurveOnSurface.hxx>
 #include <BRep_Builder.hxx>
@@ -898,8 +899,29 @@ void Draft_Modification::Perform ()
             // 1 - If ProjLib should make an Approx, it is stupid to approximate the 
             //     entire intersection curve.
             // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
-            i2s.Perform(S1,S2,Precision::Confusion(),
-              Standard_True,Standard_False,Standard_False);
+            Handle(GeomAdaptor_Surface) HS[2] = {new GeomAdaptor_Surface(S1), new GeomAdaptor_Surface(S2)};
+            for (Standard_Integer i = 0; i < 2; ++i) 
+            {
+              Handle(Geom_Surface) S = (i == 0 ? S1 : S2);
+              if (S->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
+              {
+                Standard_Real aVs, aVe;
+                Adaptor3d_TopolTool::GetConeApexParam(Handle(Geom_ConicalSurface)::DownCast(S)->Cone(), aVs, aVe);
+                if (aVe < 0.)
+                {
+                  aVs = aVe;
+                  aVe = Precision::Infinite();
+                }
+                else
+                {
+                  aVs = -Precision::Infinite();
+                  aVe = aVe;
+                }
+                HS[i]->Load(S, 0., 2 * M_PI, aVs, aVe, 0., 0.);
+              }
+            }
+            i2s.Perform(HS[0], HS[1], Precision::Confusion(),
+              Standard_True, Standard_False, Standard_False);
 
             if (!i2s.IsDone() || i2s.NbLines() <= 0) {
               errStat = Draft_EdgeRecomputation;
@@ -1108,8 +1130,9 @@ void Draft_Modification::Perform ()
                 for (i = 1; i <= Candidates.Length(); i++)
                 {
                   Handle( Geom_Curve ) aCurve = Candidates(i);
-                  gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
-                  const Standard_Real Dist = Pnt.Distance( pfv );
+                  GeomAPI_ProjectPointOnCurve Projector(pfv, aCurve );
+                  gp_Pnt aPnt = Projector.NbPoints() ? Projector.NearestPoint() : aCurve->Value(aCurve->FirstParameter());
+                  const Standard_Real Dist = aPnt.Distance( pfv );
                   if (Dist - DistMin < -Precision::Confusion())
                   {
                     DistMin = Dist;
diff --git a/tests/bugs/modalg_8/bug32857 b/tests/bugs/modalg_8/bug32857
new file mode 100644 (file)
index 0000000..3b90c7f
--- /dev/null
@@ -0,0 +1,72 @@
+puts "================"
+puts "0032857: Problem when finding the intersection between a new face made after a draft and the inner face of body"
+puts "================"
+puts ""
+# Script reproducing the problematic draft case in FreeCAD issue #2497
+#Category: Modeling
+#Title: OCCT Tutorial pocketed ring
+
+pload MODELING VISUALIZATION
+
+# Set basic dimensions. Problems appear when inner_rad < pocket_center.
+dset height 10
+dset inner_rad 39
+dset outer_rad 50
+dset pocket_center 40
+dset pocket_rad 20
+dset pocket_depth 5
+
+# Construct base profile (the "my_ring")
+puts "Constructing my_ring..."
+
+circle c_inner 0 0 0 0 0 1 inner_rad
+circle c_outer 0 0 0 0 0 1 outer_rad
+mkedge e_inner c_inner
+mkedge e_outer c_outer
+wire w_inner e_inner
+wire w_outer e_outer
+
+plane p0
+mkface my_ring_inner_base p0 w_inner
+mkface my_ring_outer_base p0 w_outer
+
+prism my_ring_inner my_ring_inner_base 0 0 height
+prism my_ring_outer my_ring_outer_base 0 0 height
+
+bcut my_ring my_ring_outer my_ring_inner
+
+# Make the pocket
+puts "Constructing pocket..."
+
+circle pocket_base pocket_center 0 0 0 0 1 pocket_rad
+mkedge pocket_base pocket_base
+wire pocket_base pocket_base
+
+mkface pocket_base p0 pocket_base
+
+prism my_pocket pocket_base 0 0 pocket_depth
+
+# Make the cut
+puts "Making the cut"
+
+bcut slotted_ring my_ring my_pocket
+
+explode slotted_ring F
+
+# Make the draft
+puts "Drafting the face"
+
+# Found face by trial and error: slotted_ring_3
+# Perform the draft
+depouille slotted_ring_with_draft slotted_ring 0 0 -1 slotted_ring_3 44 0 1 0 0 0 1
+
+#checking result
+checkshape slotted_ring_with_draft
+checknbshapes slotted_ring_with_draft -shape 48 -vertex 12 -edge 18 -face 7 -wire 8
+checkprops slotted_ring_with_draft -s 11466.5 -v 28662.9
+
+puts "Showing result..."
+
+# Display result
+checkview -display slotted_ring_with_draft -2d -path ${imagedir}/${test_image}.png
+