0029979: Data Exchange - Crash by reading STEP file
authorabv <abv@opencascade.com>
Tue, 9 Jul 2019 11:47:21 +0000 (14:47 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 6 Sep 2019 16:23:19 +0000 (19:23 +0300)
Added work-around against specific problem of ORIENTED_EDGE referring to another ORIENTED_EDGE instead of EDGE_CURVE.
Added handling of edges with null EDGE_CURVE, to allow passing the translation further instead of exception.

Off-topic: text of warning message is corrected in genproj

Added test bugs step bug29979

adm/genproj.tcl
src/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx
tests/bugs/step/bug29979 [new file with mode: 0644]

index f2ce1b1..0c99871 100644 (file)
@@ -936,7 +936,7 @@ proc osutils:collectinc {theModules theIncPath} {
   set anIncFiles [glob -tails -nocomplain -dir ${anIncPath} "*"]
   foreach anIncFile ${anIncFiles} {
     if { [lsearch -exact ${allHeaderFiles} ${anIncFile}] == -1 } {
-      puts "Warning: file ${anIncPath}/${anIncFile} is not presented in the sources and will be removed from ${theIncPath}!"
+      puts "Warning: file ${anIncPath}/${anIncFile} is not present in the sources and will be removed from ${theIncPath}"
       file delete -force "${theIncPath}/${anIncFile}"
     }
   }
index 0202c5c..e7f0e65 100644 (file)
@@ -238,7 +238,6 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
 
   Standard_Boolean isSeam, isLikeSeam;
 
-  Handle(StepShape_Edge)         StepEdge, StepEdge1;
   Handle(StepShape_OrientedEdge) OrEdge1, OrEdge2;
   Handle(StepGeom_Curve) StepCurve, StepCurve1, StepCurve2;
   Handle(StepRepr_DefinitionalRepresentation) DRI, Dri1, Dri2;
@@ -284,10 +283,18 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
 
   for (j=1; j<=NbEdge; j++) {
     OrEdge1  = EL->EdgeListValue(j);
-    StepEdge = OrEdge1->EdgeElement();
-    //    if(j>1 && StepEdge == StepEdge1) theSame++; //gka 15.12.98
-    StepEdge1 = StepEdge;                         //
-    Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(StepEdge);
+
+    // see bug #29979: oriented edge contains another oriented edge
+    if (OrEdge1->EdgeElement()->IsKind (STANDARD_TYPE(StepShape_OrientedEdge)))
+      OrEdge1 = Handle(StepShape_OrientedEdge)::DownCast (OrEdge1->EdgeElement());
+
+    Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(OrEdge1->EdgeElement());
+    if (EC.IsNull())
+    {
+      TP->AddWarning (OrEdge1, "Edge does not contain EDGE_CURVE, skipped");
+      continue;
+    }
+
     Handle(StepGeom_Curve) C = EC->EdgeGeometry();
     if (!C.IsNull()) {
       if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) {
@@ -366,6 +373,10 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
       Handle(StepShape_EdgeCurve)::DownCast (OrEdge1->EdgeElement());
     Handle(StepShape_EdgeCurve) EC2 =
       Handle(StepShape_EdgeCurve)::DownCast (OrEdge2->EdgeElement());
+    if (EC1.IsNull() || EC2.IsNull()) // see #29979
+    {
+      continue;
+    }
 
     Handle(StepShape_Vertex) Vs1, Vs2, Vs11, Vs22;
     Vs1 = (OrEdge1->Orientation() ? EC1->EdgeEnd() : EC1->EdgeStart());
@@ -413,8 +424,16 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
 #endif
 
     OrEdge1  = EL->EdgeListValue(j);
-    StepEdge = OrEdge1->EdgeElement();
-    Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(StepEdge);
+
+    // see bug #29979: oriented edge contains another oriented edge
+    if (OrEdge1->EdgeElement()->IsKind (STANDARD_TYPE(StepShape_OrientedEdge)))
+      OrEdge1 = Handle(StepShape_OrientedEdge)::DownCast (OrEdge1->EdgeElement());
+
+    Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(OrEdge1->EdgeElement());
+    if (EC.IsNull())
+    {
+      continue;
+    }
 
     // ----------------
     // Map the StepEdge
@@ -491,9 +510,9 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
         // ---        or is like a seam curve      ---
         // ---         (see CATIA cylinder)        ---
         // -------------------------------------------
-        isLikeSeam = StepToTopoDS_GeometricTool::IsLikeSeam(SurfCurve, StepSurf, StepEdge, EL);
+        isLikeSeam = StepToTopoDS_GeometricTool::IsLikeSeam(SurfCurve, StepSurf, EC, EL);
 
-        isSeam = StepToTopoDS_GeometricTool::IsSeamCurve(SurfCurve, StepSurf, StepEdge, EL);
+        isSeam = StepToTopoDS_GeometricTool::IsSeamCurve(SurfCurve, StepSurf, EC, EL);
 
         if (isSeam || isLikeSeam) {
           // isLikeSeam = Two faces on the same Surface
@@ -570,7 +589,7 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
           Standard_Integer forwardPC =
             ShapeAnalysis_Curve().SelectForwardSeam(C2d1, C2d2);
           if (forwardPC == 0) {
-            TP->AddFail(StepEdge, " Seam curve not mapped");
+            TP->AddFail(EC, " Seam curve not mapped");
             done = Standard_False;
             myError = StepToTopoDS_TranslateEdgeLoopOther;
             continue;
@@ -602,7 +621,7 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
           }
         }
         else {
-          TP->AddFail(StepEdge, " Seam curve not mapped");
+          TP->AddFail(EC, " Seam curve not mapped");
           done = Standard_False;
           myError = StepToTopoDS_TranslateEdgeLoopOther;
           continue;
@@ -619,7 +638,7 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
             B.UpdateEdge(E, C2d, Face, 0.);
           }
           else {
-            TP->AddFail(StepEdge, " Edge: Trimming of 2D curve failed");
+            TP->AddFail(EC, " Edge: Trimming of 2D curve failed");
             done = Standard_False;
             myError = StepToTopoDS_TranslateEdgeLoopOther;
             continue;
@@ -628,13 +647,13 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
       }
 
       if (E.IsNull()) {
-        TP->AddFail(StepEdge, " an Edge not mapped");
+        TP->AddFail(EC, " an Edge not mapped");
         done = Standard_False;
         myError = StepToTopoDS_TranslateEdgeLoopOther;
       }
     }
     else { // The Edge is Not mapped => switch to next wire ?
-      TP->AddFail(StepEdge, " an Edge not mapped");
+      TP->AddFail(EC," an Edge not mapped");
       done = Standard_False;
       myError = StepToTopoDS_TranslateEdgeLoopOther;
     }
@@ -642,8 +661,8 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac
     if (done) B.Add (W, E);  // on le fait ici. Sauf si erreur rencontree ... !
     else {
       Handle(StepShape_Vertex) Vs1, Vs2;
-      Vs1 = StepEdge->EdgeStart();
-      Vs2 = StepEdge->EdgeEnd();
+      Vs1 = EC->EdgeStart();
+      Vs2 = EC->EdgeEnd();
       if (!Vs1.IsNull() && !Vs2.IsNull() && Vs1==Vs2) {
         done = Standard_True;
         TP->AddFail(EL, " Edge with equal vertices failed, scipped");
diff --git a/tests/bugs/step/bug29979 b/tests/bugs/step/bug29979
new file mode 100644 (file)
index 0000000..478c71f
--- /dev/null
@@ -0,0 +1,11 @@
+puts "==============================================================="
+puts "0029979: Data Exchange - Crash by reading STEP file"
+puts "==============================================================="
+puts ""
+
+puts "Read only the solid that contains broken edges"
+stepread [locate_data_file bug29979_firetherm_12.step] a #10154
+tpstat c
+
+puts "\nCheck that result is not empty"
+checknbshapes a_1 -solid 1 -face 1565