]> OCCT Git - occt.git/commitdiff
0027170: Reading STEP files produces invalid shapes CR27170
authorssafarov <ssafarov@opencascade.com>
Tue, 18 Jan 2022 15:51:30 +0000 (18:51 +0300)
committerssafarov <ssafarov@opencascade.com>
Wed, 9 Feb 2022 08:35:21 +0000 (11:35 +0300)
Added a new GetEdgeCurve() method that returns a 3D curve or a curve on a surface by subtracting the location of the face.

src/BRepCheck/BRepCheck_Edge.cxx
src/BRepCheck/BRepCheck_Edge.hxx
tests/bugs/heal/bug27170 [new file with mode: 0644]

index 32d55b8cd75236a94a0219d87027e3c0cc5fbb4d..f29d4ea144827e9d5eccf115eec78cf75e24584a 100644 (file)
@@ -148,14 +148,15 @@ void BRepCheck_Edge::Minimum()
         BRepCheck::Add(lst,BRepCheck_InvalidRange);
       }
       else {
-        if (myCref->IsCurve3D()) {
+        IsCurve3D = myCref->IsCurve3D();
+        if (IsCurve3D) {
           // eap 6 Jun 2002 occ332
           // better transform C3d instead of transforming Surf upto C3d initial location,
           // on transformed BSpline surface 'same parameter' may seem wrong
           TopLoc_Location L = myShape.Location() * myCref->Location();
           Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast
-            (myCref->Curve3D()->Transformed
-            (/*myCref->Location()*/L.Transformation()));
+              (myCref->Curve3D()->Transformed
+              (/*myCref->Location()*/L.Transformation()));
           Standard_Boolean IsPeriodic = C3d->IsPeriodic();
           Standard_Real aPeriod = RealLast();
           if(IsPeriodic)
@@ -186,9 +187,8 @@ void BRepCheck_Edge::Minimum()
           }
           else
           {
-            GeomAdaptor_Curve GAC3d(C3d, C3d->TransformedParameter(First, L.Transformation()),
-                                       C3d->TransformedParameter(Last, L.Transformation()));
-            myHCurve = new GeomAdaptor_Curve(GAC3d);
+            TopoDS_Shape aShape;
+            myHCurve = GetEdgeCurve(aShape);
           }
         }
         else { // curve on surface
@@ -226,11 +226,8 @@ void BRepCheck_Edge::Minimum()
           }
           else
           {
-            Handle(GeomAdaptor_Surface) GAHSref = new GeomAdaptor_Surface(Sref);
-            Handle(Geom2dAdaptor_Curve) GHPCref = 
-              new Geom2dAdaptor_Curve(PCref,First,Last);
-            Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
-            myHCurve = new Adaptor3d_CurveOnSurface(ACSref);
+            TopoDS_Shape aShape;
+            myHCurve = GetEdgeCurve(aShape);
           }
         }
       }
@@ -301,6 +298,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
         return;
       }
       //  Modified by skv - Tue Apr 27 11:48:14 2004 End
+      myHCurve = GetEdgeCurve(S);
       Standard_Real First = myHCurve->FirstParameter();
       Standard_Real Last  = myHCurve->LastParameter();
 
@@ -372,7 +370,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
             Handle(Geom_Surface) Sb = cr->Surface();
             Sb = Handle(Geom_Surface)::DownCast
               //             (Su->Transformed(L.Transformation()));
-              (Su->Transformed(/*L*/(Floc * TFloc).Transformation()));
+              (Su->Transformed(/*L*/TFloc.Transformation()));
             Handle(Geom2d_Curve) PC = cr->PCurve();
             Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(Sb);
             Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(PC,f,l);
@@ -440,7 +438,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
           // plan en position
           if (myGctrl) {
             P = Handle(Geom_Plane)::
-              DownCast(P->Transformed(/*L*/(Floc * TFloc).Transformation()));// eap occ332
+              DownCast(P->Transformed(/*L*/TFloc.Transformation()));// eap occ332
             //on projette Cref sur ce plan
             Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(P);
 
@@ -548,6 +546,64 @@ Standard_Boolean BRepCheck_Edge::GeometricControls() const
   return myGctrl;
 }
 
+
+//=======================================================================
+//function : GetEdgeCurve
+//purpose  : 
+//=======================================================================
+
+Handle(Adaptor3d_Curve) BRepCheck_Edge::GetEdgeCurve(const TopoDS_Shape& theShape)
+{
+  Handle(Adaptor3d_Curve) aLocalCurve;
+  Handle(BRep_GCurve) GCref(Handle(BRep_GCurve)::DownCast(myCref));
+  Standard_Real First, Last;
+  GCref->Range(First, Last);
+  if (IsCurve3D)
+  {
+
+    TopLoc_Location L = myShape.Location() * myCref->Location();
+    Handle(Geom_Curve) C3d;
+    if (!theShape.IsNull())
+    {
+      C3d = Handle(Geom_Curve)::DownCast
+        (myCref->Curve3D()->Transformed
+        (/*myCref->Location()*/L.Predivided(theShape.Location()).Transformation()));
+    }
+    else
+    {
+      C3d = Handle(Geom_Curve)::DownCast
+        (myCref->Curve3D()->Transformed
+        (/*myCref->Location()*/L.Transformation()));
+    }
+    GeomAdaptor_Curve GAC3d(C3d, C3d->TransformedParameter(First, L.Transformation()),
+                               C3d->TransformedParameter(Last, L.Transformation()));
+    aLocalCurve = new GeomAdaptor_Curve(GAC3d);
+  }
+  else
+  {
+    Handle(Geom_Surface) Sref = myCref->Surface();
+    if (!theShape.IsNull())
+    {
+      Sref = Handle(Geom_Surface)::DownCast
+        (Sref->Transformed(myCref->Location().Predivided(theShape.Location()).Transformation()));
+    }
+    else
+    {
+      Sref = Handle(Geom_Surface)::DownCast
+        (Sref->Transformed(myCref->Location().Transformation()));
+    }
+    const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
+    Handle(GeomAdaptor_Surface) GAHSref = new GeomAdaptor_Surface(Sref);
+    Handle(Geom2dAdaptor_Curve) GHPCref =
+      new Geom2dAdaptor_Curve(PCref, First, Last);
+    Adaptor3d_CurveOnSurface ACSref(GHPCref, GAHSref);
+    aLocalCurve = new Adaptor3d_CurveOnSurface(ACSref);
+  }
+
+  return aLocalCurve;
+}
+
+
 //=======================================================================
 //function :   SetStatus
 //purpose  : 
index 3a8ef877c821c3db8296fe4dc66ec05800ce716a..c737a6e9bfdee8c87bed36906c36460f5f5156ef 100644 (file)
@@ -45,6 +45,11 @@ public:
   
   Standard_EXPORT Standard_Boolean GeometricControls() const;
   
+  //! Creates a 3d curve or surface on a curve by subtracting the location of the face
+  //! @param[in] theShape input shape to get the location from it
+  //! @return a 3d curve or curve on a surface
+  Standard_EXPORT Handle(Adaptor3d_Curve) GetEdgeCurve(const TopoDS_Shape& theShape);
+  
   Standard_EXPORT void GeometricControls (const Standard_Boolean B);
   
   Standard_EXPORT Standard_Real Tolerance();
@@ -81,6 +86,7 @@ private:
   Handle(Adaptor3d_Curve) myHCurve;
   Standard_Boolean myGctrl;
   Standard_Boolean myIsExactMethod;
+  Standard_Boolean IsCurve3D;
 };
 
 #endif // _BRepCheck_Edge_HeaderFile
diff --git a/tests/bugs/heal/bug27170 b/tests/bugs/heal/bug27170
new file mode 100644 (file)
index 0000000..6856d25
--- /dev/null
@@ -0,0 +1,10 @@
+puts "============"
+puts "0027170: Reading STEP files produces invalid shapes"
+puts "============"
+
+restore [locate_data_file bug27170_f.brep] f
+
+fixshape result f
+
+ttranslate result 9.68119149294e-13 217.938944319 299.700009766
+checkshape result
\ No newline at end of file