]> OCCT Git - occt.git/commitdiff
0033665: Data Exchange, Step Import - TransferRoots crashes for invalid STEP files
authordkulikov <dkulikov@opencascade.com>
Sun, 22 Sep 2024 12:33:29 +0000 (12:33 +0000)
committerdpasukhi <dpasukhi@opencascade.com>
Sun, 22 Sep 2024 12:46:54 +0000 (12:46 +0000)
Fixed exception in RWStepShape_RWEdgeCurve::Check() thrown when trying
    to access step entity in Interface_EntityIterator with zero entities.
Fixed a crash in StepToTopoDS_TranslateFace::Init() caused by
    dereferencing nullptr.
RWStepShape_RWEdgeCurve and RWStepShape_RWEdgeCurve are refactored.
Test bug33665 is added to check the fixed behavior.

src/RWStepShape/RWStepShape_RWEdgeCurve.cxx
src/RWStepShape/RWStepShape_RWEdgeCurve.hxx
src/StepToTopoDS/StepToTopoDS_TranslateFace.cxx
src/StepToTopoDS/StepToTopoDS_TranslateFace.hxx
tests/bugs/step/bug33665 [new file with mode: 0644]

index d6c8f9fd047d817141c546fe77b5344adbe7eab0..d5614afd03f05dc31872455b1e23eeaf57510b8a 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <RWStepShape_RWEdgeCurve.hxx>
 
 #include <Interface_EntityIterator.hxx>
 #include <Interface_ShareTool.hxx>
 #include <Precision.hxx>
-#include <RWStepShape_RWEdgeCurve.hxx>
 #include <StepData_StepReaderData.hxx>
 #include <StepData_StepWriter.hxx>
 #include <StepGeom_CartesianPoint.hxx>
 #include <StepShape_Vertex.hxx>
 #include <StepShape_VertexPoint.hxx>
 
-RWStepShape_RWEdgeCurve::RWStepShape_RWEdgeCurve () {}
-
-void RWStepShape_RWEdgeCurve::ReadStep
-       (const Handle(StepData_StepReaderData)& data,
-        const Standard_Integer num,
-        Handle(Interface_Check)& ach,
-        const Handle(StepShape_EdgeCurve)& ent) const
+namespace
 {
+  // ================================================================
+  // Function : GetSharing
+  // Purpose  : Returns a step entity of a type StepShapeType that is
+  //            sharing theStepEntity. If no sharing entity of
+  //            required type is found, returns nullptr.
+  // ================================================================
+  template<typename StepShapeType>
+  Handle (StepShapeType) GetSharing (const Handle (Standard_Transient)& theStepEntity,
+                                     const Interface_ShareTool&         theShareTool)
+  {
+    Interface_EntityIterator aSharedEntitiesIt = theShareTool.Sharings (theStepEntity);
+    aSharedEntitiesIt.SelectType (STANDARD_TYPE (StepShapeType), Standard_True);
+    return aSharedEntitiesIt.NbEntities() == 0
+           ? Handle (StepShapeType){}
+           : Handle (StepShapeType)::DownCast (aSharedEntitiesIt.Value());
+  }
 
+  // ================================================================
+  // Function : GetFaceBoundOrientation
+  // Purpose  : Returns an orientation of face bound sharing
+  //            theOrientedEdge. If face bound cannot be found,
+  //            returns true (to preserve pre-refactoring behavior).
+  // ================================================================
+  Standard_Boolean GetFaceBoundOrientation (const Handle (StepShape_OrientedEdge)& theOrientedEdge,
+                                            const Interface_ShareTool&             theShareTool)
+  {
+    if (!theShareTool.IsShared (theOrientedEdge))
+    {
+      return Standard_True;
+    }
 
-       // --- Number of Parameter Control ---
-
-       if (!data->CheckNbParams(num,5,ach,"edge_curve")) return;
-
-       // --- inherited field : name ---
-
-       Handle(TCollection_HAsciiString) aName;
-       data->ReadString (num,1,"name",ach,aName);
-
-       // --- inherited field : edgeStart ---
-
-       Handle(StepShape_Vertex) aEdgeStart;
-       data->ReadEntity(num, 2,"edge_start", ach, STANDARD_TYPE(StepShape_Vertex), aEdgeStart);
-
-       // --- inherited field : edgeEnd ---
-
-       Handle(StepShape_Vertex) aEdgeEnd;
-       data->ReadEntity(num, 3,"edge_end", ach, STANDARD_TYPE(StepShape_Vertex), aEdgeEnd);
-
-       // --- own field : edgeGeometry ---
-
-       Handle(StepGeom_Curve) aEdgeGeometry;
-       data->ReadEntity(num, 4,"edge_geometry", ach, STANDARD_TYPE(StepGeom_Curve), aEdgeGeometry);
-
-       // --- own field : sameSense ---
+    const Handle (StepShape_EdgeLoop) anEdgeLoop = GetSharing<StepShape_EdgeLoop> (theOrientedEdge,
+                                                                                   theShareTool);
+    if (!theShareTool.IsShared (anEdgeLoop))
+    {
+      return Standard_True;
+    }
 
-       Standard_Boolean aSameSense;
-       data->ReadBoolean (num,5,"same_sense",ach,aSameSense);
+    const Handle (StepShape_FaceBound) aFaceBound = GetSharing<StepShape_FaceBound> (anEdgeLoop,
+                                                                                     theShareTool);
+    return aFaceBound.IsNull() ? Standard_True : aFaceBound->Orientation();
+  }
 
-       //--- Initialisation of the read entity ---
+  // ================================================================
+  // Function : GetFaceBoundOrientation
+  // Purpose  : Returns true if start and end points of theEdgeCurve
+  //            are valid points of the different vertices and are
+  //            equal to each other within Precision::Confusion().
+  // ================================================================
+  Standard_Boolean AreEndsMatch (const Handle (StepShape_EdgeCurve)& theEdgeCurve)
+  {
+    Handle (StepShape_VertexPoint) aStartVertex = Handle (StepShape_VertexPoint)::DownCast (
+      theEdgeCurve->EdgeStart());
+    Handle (StepShape_VertexPoint) anEndVertex = Handle (StepShape_VertexPoint)::DownCast (
+      theEdgeCurve->EdgeEnd());
+    if (aStartVertex == anEndVertex)
+    {
+      return Standard_False;
+    }
 
+    Handle (StepGeom_CartesianPoint) aStartPoint = Handle (StepGeom_CartesianPoint)::DownCast (
+      aStartVertex->VertexGeometry());
+    Handle (StepGeom_CartesianPoint) anEndPoint = Handle (StepGeom_CartesianPoint)::DownCast (
+      anEndVertex->VertexGeometry());
+    if (aStartPoint.IsNull() || anEndPoint.IsNull())
+    {
+      return Standard_False;
+    }
 
-       ent->Init(aName, aEdgeStart, aEdgeEnd, aEdgeGeometry, aSameSense);
+    const Standard_Real aDistance = Sqrt (
+      (aStartPoint->CoordinatesValue (1) - anEndPoint->CoordinatesValue (1))
+        * (aStartPoint->CoordinatesValue (1) - anEndPoint->CoordinatesValue (1))
+      + (aStartPoint->CoordinatesValue (2) - anEndPoint->CoordinatesValue (2))
+          * (aStartPoint->CoordinatesValue (2) - anEndPoint->CoordinatesValue (2))
+      + (aStartPoint->CoordinatesValue (3) - anEndPoint->CoordinatesValue (3))
+          * (aStartPoint->CoordinatesValue (3) - anEndPoint->CoordinatesValue (3)));
+    return aDistance < Precision::Confusion();
+  }
 }
 
-
-void RWStepShape_RWEdgeCurve::WriteStep
-       (StepData_StepWriter& SW,
-        const Handle(StepShape_EdgeCurve)& ent) const
+// ================================================================
+// Function : ReadStep
+// Purpose  :
+// ================================================================
+void RWStepShape_RWEdgeCurve::ReadStep (const Handle (StepData_StepReaderData)& theStepData,
+                                        const Standard_Integer                  theRecordID,
+                                        Handle (Interface_Check)&               theMessageTool,
+                                        const Handle (StepShape_EdgeCurve)&     theEdgeCurve) const
 {
+  // --- Number of Parameter Control ---
+  if (!theStepData->CheckNbParams (theRecordID, 5, theMessageTool, "edge_curve"))
+  {
+    return;
+  }
 
-       // --- inherited field name ---
-
-       SW.Send(ent->Name());
-
-       // --- inherited field edgeStart ---
-
-       SW.Send(ent->EdgeStart());
-
-       // --- inherited field edgeEnd ---
+  // --- inherited field : name ---
+  Handle (TCollection_HAsciiString) aName;
+  theStepData->ReadString (theRecordID, 1, "name", theMessageTool, aName);
+
+  // --- inherited field : edgeStart ---
+  Handle (StepShape_Vertex) anEdgeStart;
+  theStepData->ReadEntity (theRecordID,
+                           2,
+                           "edge_start",
+                           theMessageTool,
+                           STANDARD_TYPE (StepShape_Vertex),
+                           anEdgeStart);
+
+  // --- inherited field : edgeEnd ---
+  Handle (StepShape_Vertex) anEdgeEnd;
+  theStepData->ReadEntity (theRecordID,
+                           3,
+                           "edge_end",
+                           theMessageTool,
+                           STANDARD_TYPE (StepShape_Vertex),
+                           anEdgeEnd);
+
+  // --- own field : edgeGeometry ---
+  Handle (StepGeom_Curve) anEdgeGeometry;
+  theStepData->ReadEntity (theRecordID,
+                           4,
+                           "edge_geometry",
+                           theMessageTool,
+                           STANDARD_TYPE (StepGeom_Curve),
+                           anEdgeGeometry);
+
+  // --- own field : sameSense ---
+  Standard_Boolean aSameSense;
+  theStepData->ReadBoolean (theRecordID, 5, "same_sense", theMessageTool, aSameSense);
+
+  //--- Initialisation of the read entity ---
+  theEdgeCurve->Init (aName, anEdgeStart, anEdgeEnd, anEdgeGeometry, aSameSense);
+}
 
-       SW.Send(ent->EdgeEnd());
+// ================================================================
+// Function : WriteStep
+// Purpose  :
+// ================================================================
+void RWStepShape_RWEdgeCurve::WriteStep (StepData_StepWriter&                theStepWriter,
+                                         const Handle (StepShape_EdgeCurve)& theEdgeCurve) const
+{
+  // --- inherited field name ---
+  theStepWriter.Send (theEdgeCurve->Name());
 
-       // --- own field : edgeGeometry ---
+  // --- inherited field edgeStart ---
+  theStepWriter.Send (theEdgeCurve->EdgeStart());
 
-       SW.Send(ent->EdgeGeometry());
+  // --- inherited field edgeEnd ---
+  theStepWriter.Send (theEdgeCurve->EdgeEnd());
 
-       // --- own field : sameSense ---
+  // --- own field : edgeGeometry ---
+  theStepWriter.Send (theEdgeCurve->EdgeGeometry());
 
-       SW.SendBoolean(ent->SameSense());
+  // --- own field : sameSense ---
+  theStepWriter.SendBoolean (theEdgeCurve->SameSense());
 }
 
-
-void RWStepShape_RWEdgeCurve::Share(const Handle(StepShape_EdgeCurve)& ent, Interface_EntityIterator& iter) const
+// ================================================================
+// Function : Share
+// Purpose  :
+// ================================================================
+void RWStepShape_RWEdgeCurve::Share (const Handle (StepShape_EdgeCurve)& theEdgeCurve,
+                                     Interface_EntityIterator&           theSharedEntitiesIt) const
 {
+  theSharedEntitiesIt.GetOneItem (theEdgeCurve->EdgeStart());
 
-       iter.GetOneItem(ent->EdgeStart());
-
+  theSharedEntitiesIt.GetOneItem (theEdgeCurve->EdgeEnd());
 
-       iter.GetOneItem(ent->EdgeEnd());
-
-
-       iter.GetOneItem(ent->EdgeGeometry());
+  theSharedEntitiesIt.GetOneItem (theEdgeCurve->EdgeGeometry());
 }
 
-
-
-void RWStepShape_RWEdgeCurve::Check
-  (const Handle(StepShape_EdgeCurve)& ent,
-   const Interface_ShareTool& aShto,
-   Handle(Interface_Check)& ach) const
+// ================================================================
+// Function : Check
+// Purpose  :
+// ================================================================
+void RWStepShape_RWEdgeCurve::Check (const Handle (StepShape_EdgeCurve)& theEdgeCurve,
+                                     const Interface_ShareTool&          theShareTool,
+                                     Handle (Interface_Check)&           theMessageTool) const
 {
-//  std::cout << "------ calling CheckEdgeCurve ------" << std::endl;
-  
-  Handle(StepShape_OrientedEdge) theOE1, theOE2;
-  Handle(StepShape_FaceBound)    theFOB1, theFOB2;
-  //Handle(StepShape_FaceSurface)  theFS1, theFS2;
-
-  Standard_Boolean theOEOri1 = Standard_True;
-  Standard_Boolean theOEOri2 = Standard_True;
-  Standard_Boolean theFBOri1 = Standard_True;
-  Standard_Boolean theFBOri2 = Standard_True;
-  //Standard_Boolean theFSOri1 = Standard_True;
-  //Standard_Boolean theFSOri2 = Standard_True;
-  Standard_Boolean Cumulated1, Cumulated2;
-
   // 1- First Vertex != LastVertex but First VertexPoint == Last VertexPoint
-  // Remark : time consuming process but useful !
-  // If this append, we can drop one of the two vertices and replace it 
-  // everywhere it is referenced. Side effect : tolerance problem !!!
-
-  Handle(StepShape_VertexPoint) StartVertex = 
-    Handle(StepShape_VertexPoint)::DownCast(ent->EdgeStart());
-  Handle(StepShape_VertexPoint) EndVertex   = 
-    Handle(StepShape_VertexPoint)::DownCast(ent->EdgeEnd());
-
-  if (StartVertex != EndVertex) {
-
-    Handle(StepGeom_CartesianPoint) StartPoint = 
-      Handle(StepGeom_CartesianPoint)::DownCast(StartVertex->VertexGeometry());
-    Handle(StepGeom_CartesianPoint) EndPoint   = 
-      Handle(StepGeom_CartesianPoint)::DownCast(EndVertex->VertexGeometry());
-
-    // it can also be a degenerated pcurve
+  // Remark: time consuming process but useful.
+  // If this append, we can drop one of the two vertices and replace it
+  // everywhere it is referenced. Side effect: tolerance problem.
+  if (AreEndsMatch (theEdgeCurve))
+  {
+    theMessageTool->AddWarning (
+      "Two instances of Vertex have equal (within uncertainty) coordinates");
+  }
 
-    if (!StartPoint.IsNull() && !EndPoint.IsNull()) {
-      Standard_Real Dist = Sqrt
-       ((StartPoint->CoordinatesValue(1) - EndPoint->CoordinatesValue(1)) *
-        (StartPoint->CoordinatesValue(1) - EndPoint->CoordinatesValue(1)) +
-        (StartPoint->CoordinatesValue(2) - EndPoint->CoordinatesValue(2)) *
-        (StartPoint->CoordinatesValue(2) - EndPoint->CoordinatesValue(2)) +
-        (StartPoint->CoordinatesValue(3) - EndPoint->CoordinatesValue(3)) *
-        (StartPoint->CoordinatesValue(3) - EndPoint->CoordinatesValue(3)));
-      if (Dist < Precision::Confusion() ) {
-       ach->AddWarning("Two instances of Vertex have equal (within uncertainty) coordinates");
-      }
-    }
+  if (!theShareTool.IsShared (theEdgeCurve))
+  {
+    theMessageTool->AddFail ("ERROR: EdgeCurve not referenced");
+    return;
   }
-  
-  // 2- Two-Manifold Topology
 
-  Standard_Boolean sharEC = aShto.IsShared(ent);
-  Standard_Integer nbRef;
-  if(!sharEC){
-    ach->AddFail("ERROR: EdgeCurve not referenced");
+  // 2- Two-Manifold Topology
+  Interface_EntityIterator aSharedEntitiesIt = theShareTool.Sharings (theEdgeCurve);
+  aSharedEntitiesIt.SelectType (STANDARD_TYPE (StepShape_OrientedEdge), Standard_True);
+  if (aSharedEntitiesIt.NbEntities() != 2)
+  {
+    return;
   }
-  else {
-    Interface_EntityIterator myShRef = aShto.Sharings(ent);
-    myShRef.SelectType (STANDARD_TYPE(StepShape_OrientedEdge),Standard_True);
-    nbRef = myShRef.NbEntities();
-    if (nbRef ==2) {
-      theOE1 = Handle(StepShape_OrientedEdge)::DownCast(myShRef.Value());
-      theOEOri1 = theOE1->Orientation();
-      myShRef.Next();
-      theOE2 = Handle(StepShape_OrientedEdge)::DownCast(myShRef.Value());
-      theOEOri2 = theOE2->Orientation();
-      
-      // get the FaceBound orientation for theOE1
-      
-      Standard_Boolean sharOE1 = aShto.IsShared(theOE1);
-      if(!sharOE1){
-#ifdef OCCT_DEBUG
-       std::cout << "OrientedEdge1 not shared" <<std::endl;
-#endif
-      }
-      else {
-       myShRef = aShto.Sharings(theOE1);
-       myShRef.SelectType (STANDARD_TYPE(StepShape_EdgeLoop),Standard_True);
-       nbRef = myShRef.NbEntities();
-       if (nbRef == 1) {
-         myShRef.Start();
-         Handle(StepShape_EdgeLoop) theEL1 =
-           Handle(StepShape_EdgeLoop)::DownCast(myShRef.Value());
-         Standard_Boolean sharEL1 = aShto.IsShared(theEL1);
-         if(!sharEL1) {
-#ifdef OCCT_DEBUG
-           std::cout << "EdgeLoop1 not shared" <<std::endl;
-#endif
-         }
-         else {
-           myShRef = aShto.Sharings(theEL1);
-           myShRef.SelectType (STANDARD_TYPE(StepShape_FaceBound),Standard_True);
-#ifdef OCCT_DEBUG
-           nbRef = 
-#endif
-             myShRef.NbEntities();
-           myShRef.Start();
-           theFOB1 = Handle(StepShape_FaceBound)::DownCast(myShRef.Value());
-           if (!theFOB1.IsNull()) {
-             theFBOri1 = theFOB1->Orientation();
-           }
-           else {
-#ifdef OCCT_DEBUG
-             std::cout << "EdgeLoop not referenced by FaceBound" << std::endl;
-#endif
-           }
-         }
-       }
-       else {
-         if (nbRef == 0) {
-#ifdef OCCT_DEBUG
-           std::cout << "OrientedEdge not referenced" << std::endl;
-#endif
-          }
-         else {
-           if (aShto.NbTypedSharings(theOE1,
-                                     STANDARD_TYPE(StepShape_EdgeLoop)) > 1) {
-#ifdef OCCT_DEBUG
-             std::cout << "OrientedEdge referenced more than once" << std::endl;
-#endif
-            }
-          }
-       }
-      }
 
-      // get the FaceBound orientation for theOE2
+  const Handle (StepShape_OrientedEdge) anOrientedEdge1 =
+    Handle (StepShape_OrientedEdge)::DownCast (aSharedEntitiesIt.Value());
+  const Standard_Boolean aFaceBoundOrientation1 = GetFaceBoundOrientation (anOrientedEdge1,
+                                                                           theShareTool);
+  const Standard_Boolean anIsCumulated1 = aFaceBoundOrientation1 != anOrientedEdge1->Orientation();
 
-      Standard_Boolean sharOE2 = aShto.IsShared(theOE2);
-      if(!sharOE2){
-#ifdef OCCT_DEBUG
-       std::cout << "OrientedEdge2 not shared" <<std::endl;
-#endif
-      }
-      else {
-       myShRef = aShto.Sharings(theOE2);
-#ifdef OCCT_DEBUG
-//     Standard_Integer nbRef = 
-#endif
-// unused        myShRef.NbEntities(); 
-       myShRef.Start();
-       Handle(StepShape_EdgeLoop) theEL2 =
-         Handle(StepShape_EdgeLoop)::DownCast(myShRef.Value());
-       Standard_Boolean sharEL2 = aShto.IsShared(theEL2);
-       if(!sharEL2){
-#ifdef OCCT_DEBUG
-         std::cout << "EdgeLoop2 not shared" <<std::endl;
-#endif
-       }
-       else {
-         myShRef = aShto.Sharings(theEL2);
-          // unused Standard_Integer nbRef = myShRef.NbEntities();     
-         myShRef.Start();
-         theFOB2 = Handle(StepShape_FaceBound)::DownCast(myShRef.Value());
-         if (!theFOB2.IsNull()) {
-           theFBOri2 = theFOB2->Orientation();
-         }
-         else {
-#ifdef OCCT_DEBUG
-           std::cout << "EdgeLoop not referenced by FaceBound" << std::endl;
-#endif
-         }
-       }
-      }
-        
-        // "cumulate" the FaceBound and the OrientedEdge orientation
-        
-        Cumulated1 = theFBOri1 ^ theOEOri1;
-      Cumulated2 = theFBOri2 ^ theOEOri2;
-      
-      // the orientation of the OrientedEdges must be opposite
-      
-      if (Cumulated1 == Cumulated2) {
-       ach->AddFail("ERROR: non 2-manifold topology");
-      }
-    }
+  aSharedEntitiesIt.Next();
+
+  const Handle (StepShape_OrientedEdge) anOrientedEdge2 =
+    Handle (StepShape_OrientedEdge)::DownCast (aSharedEntitiesIt.Value());
+  const Standard_Boolean aFaceBoundOrientation2 = GetFaceBoundOrientation (anOrientedEdge2,
+                                                                           theShareTool);
+  const Standard_Boolean anIsCumulated2 = aFaceBoundOrientation2 != anOrientedEdge2->Orientation();
+
+  // the orientation of the OrientedEdges must be opposite
+  if (anIsCumulated1 == anIsCumulated2)
+  {
+    theMessageTool->AddFail ("ERROR: non 2-manifold topology");
   }
 }
-
index 69e767325f04bc42c5f56652f96eb9b38c7d07e1..6cd8e32430e6077ac9d148f3aaa415acbbb45fc0 100644 (file)
@@ -20,8 +20,8 @@
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
-
 #include <Standard_Integer.hxx>
+
 class StepData_StepReaderData;
 class Interface_Check;
 class StepShape_EdgeCurve;
@@ -29,47 +29,30 @@ class StepData_StepWriter;
 class Interface_EntityIterator;
 class Interface_ShareTool;
 
-
 //! Read & Write Module for EdgeCurve
 //! Check added by CKY , 7-OCT-1996
-class RWStepShape_RWEdgeCurve 
+class RWStepShape_RWEdgeCurve
 {
 public:
-
   DEFINE_STANDARD_ALLOC
 
-  
-  Standard_EXPORT RWStepShape_RWEdgeCurve();
-  
-  Standard_EXPORT void ReadStep (const Handle(StepData_StepReaderData)& data, const Standard_Integer num, Handle(Interface_Check)& ach, const Handle(StepShape_EdgeCurve)& ent) const;
-  
-  Standard_EXPORT void WriteStep (StepData_StepWriter& SW, const Handle(StepShape_EdgeCurve)& ent) const;
-  
-  Standard_EXPORT void Share (const Handle(StepShape_EdgeCurve)& ent, Interface_EntityIterator& iter) const;
-  
-  Standard_EXPORT void Check (const Handle(StepShape_EdgeCurve)& ent, const Interface_ShareTool& shares, Handle(Interface_Check)& ach) const;
-
-
-
-
-protected:
-
-
-
-
-
-private:
-
+public:
+  RWStepShape_RWEdgeCurve() = default;
 
+  Standard_EXPORT void ReadStep (const Handle (StepData_StepReaderData)& theStepData,
+                                 const Standard_Integer                  theRecordID,
+                                 Handle (Interface_Check)&               theMessageTool,
+                                 const Handle (StepShape_EdgeCurve)&     theEdgeCurve) const;
 
+  Standard_EXPORT void WriteStep (StepData_StepWriter&                theStepWriter,
+                                  const Handle (StepShape_EdgeCurve)& theEdgeCurve) const;
 
+  Standard_EXPORT void Share (const Handle (StepShape_EdgeCurve)& theEdgeCurve,
+                              Interface_EntityIterator&           theSharedEntitiesIt) const;
 
+  Standard_EXPORT void Check (const Handle (StepShape_EdgeCurve)& theEdgeCurve,
+                              const Interface_ShareTool&          theShareTool,
+                              Handle (Interface_Check)&           theMessageTool) const;
 };
 
-
-
-
-
-
-
 #endif // _RWStepShape_RWEdgeCurve_HeaderFile
index c33ac4a3bd9b53543bb59042cac296b03e7d1e7f..1141cc3ce15d12302cd5032b235bcff4c332aed6 100644 (file)
@@ -433,264 +433,283 @@ StepToTopoDS_TranslateFace::StepToTopoDS_TranslateFace(const Handle(StepVisual_T
 // ============================================================================
 static inline Standard_Boolean isReversed(const Handle(StepGeom_Surface)& theStepSurf)
 {
-  Handle(StepGeom_ToroidalSurface) aStepTorSur;
   if(theStepSurf->IsKind(STANDARD_TYPE(StepGeom_RectangularTrimmedSurface)))
+  {
     return isReversed(Handle(StepGeom_RectangularTrimmedSurface)::DownCast(theStepSurf)->BasisSurface());
-  
+  }
   else
-    aStepTorSur = Handle(StepGeom_ToroidalSurface)::DownCast(theStepSurf);
-  
-  return (!aStepTorSur.IsNull() && aStepTorSur->MajorRadius() < 0 ? Standard_True : Standard_False);
+  {
+    Handle(StepGeom_ToroidalSurface) aStepTorSur =
+        Handle(StepGeom_ToroidalSurface)::DownCast(theStepSurf);
+    return !aStepTorSur.IsNull() && aStepTorSur->MajorRadius() < 0.;
+  }
 }
 
 // ============================================================================
 // Method  : Init
 // Purpose : Init with a FaceSurface and a Tool
 // ============================================================================
-void StepToTopoDS_TranslateFace::Init(const Handle(StepShape_FaceSurface)& FS,
-                                      StepToTopoDS_Tool& aTool,
-                                      StepToTopoDS_NMTool& NMTool,
-                                      const StepData_Factors& theLocalFactors)
+void StepToTopoDS_TranslateFace::Init (const Handle (StepShape_FaceSurface)& theFaceSurface,
+                                       StepToTopoDS_Tool&                    theTopoDSTool,
+                                       StepToTopoDS_NMTool&                  theTopoDSToolNM,
+                                       const StepData_Factors&               theLocalFactors)
 {
   done = Standard_True;
-  if (aTool.IsBound(FS)) {
-    myResult = TopoDS::Face(aTool.Find(FS));
-    myError = StepToTopoDS_TranslateFaceDone;
-    done = Standard_True;
+  if (theTopoDSTool.IsBound (theFaceSurface))
+  {
+    myResult = TopoDS::Face (theTopoDSTool.Find (theFaceSurface));
+    myError  = StepToTopoDS_TranslateFaceDone;
+    done     = Standard_True;
     return;
   }
-  
-  Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
-  
+
+  // Within a context of this method this object is used for message handling only.
+  Handle (Transfer_TransientProcess) aMessageHandler = theTopoDSTool.TransientProcess();
+
   // ----------------------------------------------
   // Map the Face Geometry and create a TopoDS_Face
   // ----------------------------------------------
-  Handle(StepGeom_Surface) StepSurf = FS->FaceGeometry();
-
-   // sln 01.10.2001 BUC61003. If corresponding entity was read with error StepSurface may be NULL. In this case we exit from function
-  if ( StepSurf.IsNull() ) {
-    TP->AddFail(StepSurf," Surface has not been created");
+  Handle (StepGeom_Surface) aStepGeomSurface = theFaceSurface->FaceGeometry();
+  // sln 01.10.2001 BUC61003. If corresponding entity was read with error StepSurface may be NULL.
+  // In this case we exit from function
+  if (aStepGeomSurface.IsNull())
+  {
+    aMessageHandler->AddFail (aStepGeomSurface, " Surface has not been created");
     myError = StepToTopoDS_TranslateFaceOther;
-    done = Standard_False;
+    done    = Standard_False;
     return;
   }
 
   // [BEGIN] Added to process non-manifold topology (ssv; 14.11.2010)
-  if ( NMTool.IsActive() && NMTool.IsBound(StepSurf) ) {
-    TopoDS_Shape existingShape = NMTool.Find(StepSurf);
+  if (theTopoDSToolNM.IsActive() && theTopoDSToolNM.IsBound (aStepGeomSurface))
+  {
+    TopoDS_Shape anExistingShape = theTopoDSToolNM.Find (aStepGeomSurface);
     // Reverse shape's orientation for the next shell
-    existingShape.Reverse();
-    myResult = existingShape;
+    anExistingShape.Reverse();
+    myResult = anExistingShape;
     myError  = StepToTopoDS_TranslateFaceDone;
-    done = Standard_True;
+    done     = Standard_True;
     return;
   }
   // [END] Added to process non-manifold topology (ssv; 14.11.2010)
 
-  if (StepSurf->IsKind(STANDARD_TYPE(StepGeom_OffsetSurface))) //:d4 abv 12 Mar 98
-    TP->AddWarning(StepSurf," Type OffsetSurface is out of scope of AP 214");
-  Handle(Geom_Surface) GeomSurf = StepToGeom::MakeSurface (StepSurf, theLocalFactors);
-  if (GeomSurf.IsNull())
+  if (aStepGeomSurface->IsKind (STANDARD_TYPE (StepGeom_OffsetSurface))) //: d4 abv 12 Mar 98
+  {
+    aMessageHandler->AddWarning (aStepGeomSurface, " Type OffsetSurface is out of scope of AP 214");
+  }
+
+  Handle (Geom_Surface) aGeomSurface = StepToGeom::MakeSurface (aStepGeomSurface, theLocalFactors);
+  if (aGeomSurface.IsNull())
   {
-    TP->AddFail(StepSurf," Surface has not been created");
+    aMessageHandler->AddFail (aStepGeomSurface, " Surface has not been created");
     myError = StepToTopoDS_TranslateFaceOther;
-    done = Standard_False;
+    done    = Standard_False;
     return;
   }
+
   // pdn to force bsplsurf to be periodic
-  Handle(StepGeom_BSplineSurface) sgbss = Handle(StepGeom_BSplineSurface)::DownCast(StepSurf);
-  if (!sgbss.IsNull()) {
-    Handle(Geom_Surface) periodicSurf = ShapeAlgo::AlgoContainer()->ConvertToPeriodic(GeomSurf);
-    if (!periodicSurf.IsNull()) {
-      TP->AddWarning(StepSurf, "Surface forced to be periodic");
-      GeomSurf = periodicSurf;
+  if (!Handle (StepGeom_BSplineSurface)::DownCast (aStepGeomSurface).IsNull())
+  {
+    Handle (Geom_Surface) periodicSurf = ShapeAlgo::AlgoContainer()->ConvertToPeriodic (
+      aGeomSurface);
+    if (!periodicSurf.IsNull())
+    {
+      aMessageHandler->AddWarning (aStepGeomSurface, "Surface forced to be periodic");
+      aGeomSurface = periodicSurf;
     }
   }
-    
-  Standard_Boolean sameSenseFace = FS->SameSense();
 
-  //fix for bug 0026376 Solid Works wrote face based on toroidal surface having negative major radius
-  //seems that such case is interpreted  by "Solid Works" and "ProE" as face having reversed orientation.
-  Standard_Boolean sameSense = (isReversed(StepSurf) ? !sameSenseFace : sameSenseFace);
-  
+  // fix for bug 0026376 Solid Works wrote face based on toroidal surface having negative major radius
+  // seems that such case is interpreted  by "Solid Works" and "ProE" as face having reversed orientation.
+  const Standard_Boolean aSameSense = isReversed (aStepGeomSurface) ? !theFaceSurface->SameSense()
+                                                                    : theFaceSurface->SameSense();
+
   // -- Statistics --
-  aTool.AddContinuity (GeomSurf);
-  
-  TopoDS_Face   F;
-  BRep_Builder B;
-  B.MakeFace ( F, GeomSurf, Precision::Confusion() );
-  
+  theTopoDSTool.AddContinuity (aGeomSurface);
+
+  TopoDS_Face  aResultFace;
+  BRep_Builder aFaceBuilder;
+  aFaceBuilder.MakeFace (aResultFace, aGeomSurface, Precision::Confusion());
+
   // ----------------------------------
   // Iterate on each FaceBounds (Wires)
   // ----------------------------------
-  Handle(StepShape_FaceBound) FaceBound;
-  Handle(StepShape_Loop)      Loop;
-  
-  StepToTopoDS_TranslateVertexLoop myTranVL;
-  StepToTopoDS_TranslatePolyLoop   myTranPL;
-  StepToTopoDS_TranslateEdgeLoop   myTranEdgeLoop;
-  
-  Standard_Integer NbBnd = FS->NbBounds();
-
-  // --  Critere de couture simple (CKY, JAN97)
-  // surface periodique (typiquement un cylindre)
-  // 2 face bounds, chacun avec un edge loop d une seule edge
-  //  cette edge est fermee, c-a-d vtx-deb = vtx-fin (pour les deux edges)
-  // est-ce suffisant (verifier que ce sont deux outer-bounds ... ?? comment ?)
-  // Alors on peut dire : face a deux bords dont la couture manque
-  // La couture est entre les deux vertex
-
-  for (Standard_Integer i = 1; i <= NbBnd; i ++) {
-
-#ifdef OCCT_DEBUG
-    std::cout << "    Processing Wire : " << i << std::endl;
-#endif    
-    FaceBound = FS->BoundsValue(i);
-    Loop      = FaceBound->Bound();
-    if (Loop.IsNull())
+  // - Simple sewing criterion (CKY, Jan97)
+  // Periodic surface (typically a cylinder)
+  // 2 face bounds, each with an edge loop from a single edge.
+  // This edge is closed, c-a-d vertex-begin = vertex-end (for the two edges)
+  // Is it sufficient (check that these are two outer-bounds... ?? How?)
+  // Then we can say: face with two edges whose seam is missing
+  // The seam is between the two vertex
+  for (Standard_Integer aBoundIndex = 1; aBoundIndex <= theFaceSurface->NbBounds(); ++aBoundIndex)
+  {
+    Handle (StepShape_FaceBound) aFaceBound = theFaceSurface->BoundsValue (aBoundIndex);
+    if (aFaceBound.IsNull())
     {
       continue;
     }
+    Handle (StepShape_Loop) aFaceLoop = aFaceBound->Bound();
+    if (aFaceLoop.IsNull())
+    {
+      continue;
+    }
+
     // ------------------------
     // The Loop is a VertexLoop
     // ------------------------
-    
-    if (Loop->IsKind(STANDARD_TYPE(StepShape_VertexLoop))) {
-//:S4136      STF.Closed() = Standard_False;
-//  PROBLEME si SPHERE ou TORE
-//  Il faudra faire un wire complet, a condition que le point porte sur la face
-//  En attendant, on ne fait rien
-      Handle(StepShape_VertexLoop) VL = Handle(StepShape_VertexLoop)::DownCast(Loop);
+    if (aFaceLoop->IsKind (STANDARD_TYPE (StepShape_VertexLoop)))
+    {
+      //: S4136      STF.Closed() = Standard_False;
+      //  PROBLEM if SPHERE or TORE
+      // It will be necessary to make a complete wire, provided that the point carries on the face
+      // In the meantime, we do nothing
 
       // abv 10.07.00 pr1sy.stp: vertex_loop can be wrong; so just make natural bounds
-      if (GeomSurf->IsKind (STANDARD_TYPE(Geom_SphericalSurface)) ||
-          GeomSurf->IsKind (STANDARD_TYPE(Geom_BSplineSurface)) || 
-          GeomSurf->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution)))
+      if ((aGeomSurface->IsKind (STANDARD_TYPE (Geom_SphericalSurface))
+           || aGeomSurface->IsKind (STANDARD_TYPE (Geom_BSplineSurface))
+           || aGeomSurface->IsKind (STANDARD_TYPE (Geom_SurfaceOfRevolution)))
+          && (theFaceSurface->NbBounds() == 1))
       {
-
-        //  Modification to create natural bounds for face based on the spherical and Bspline surface and having only one bound represented by Vertex loop was made.
-        //  According to the specification of ISO - 10303 part 42:
-        //  "If the face has only one bound and this is of type vertex_loop, then the interior of the face is the domain of the face_surface.face_geometry.
-        //   In such a case the underlying surface shall be closed (e.g. a spherical_surface.)"
-        //  - natural bounds are applied only in case if VertexLoop is only the one  defined face bound.
-        if (NbBnd == 1)
+        // Modification to create natural bounds for face based on the spherical and Bspline
+        // surface and having only one bound represented by Vertex loop was made.
+        // According to the specification of ISO - 10303 part 42:
+        // "If the face has only one bound and this is of type vertex_loop, then the interior of
+        // the face is the domain of the face_surface.face_geometry. In such a case the underlying
+        // surface shall be closed (e.g. a spherical_surface.)"
+        // - natural bounds are applied only in case if VertexLoop is only the one defined face bound.
+        BRepBuilderAPI_MakeFace anAuxiliaryFaceBuilder (aGeomSurface, Precision());
+        for (TopoDS_Iterator aFaceIt (anAuxiliaryFaceBuilder); aFaceIt.More(); aFaceIt.Next())
         {
-          BRepBuilderAPI_MakeFace mf(GeomSurf, Precision());
-          for (TopoDS_Iterator it(mf); it.More(); it.Next())
-          {
-            B.Add(F, it.Value());
-          }
-          continue;
+          aFaceBuilder.Add (aResultFace, aFaceIt.Value());
         }
+        continue;
       }
 
-    if (GeomSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
-      continue;
-    }
-    if (GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
-      TP->AddWarning(VL, "VertexLoop on plane is ignored");
-      continue; //smh : BUC60809
-    }
-    myTranVL.SetPrecision(Precision());//gka
-    myTranVL.SetMaxTol(MaxTol());
-    myTranVL.Init(VL, aTool, NMTool, theLocalFactors);
-    if (myTranVL.IsDone()) {
-      B.Add(F, myTranVL.Value());
-    }
-    else {
-      TP->AddWarning(VL, " a VertexLoop not mapped to TopoDS");
+      if (aGeomSurface->IsKind (STANDARD_TYPE (Geom_ToroidalSurface)))
+      {
+        continue;
+      }
+
+      Handle (StepShape_VertexLoop) aVertexLoop = Handle (StepShape_VertexLoop)::DownCast (
+        aFaceLoop);
+      if (aGeomSurface->IsKind (STANDARD_TYPE (Geom_Plane)))
+      {
+        aMessageHandler->AddWarning (aVertexLoop, "VertexLoop on plane is ignored");
+        continue; // smh : BUC60809
+      }
+
+      StepToTopoDS_TranslateVertexLoop aVertexLoopTranslator;
+      aVertexLoopTranslator.SetPrecision (Precision()); // gka
+      aVertexLoopTranslator.SetMaxTol (MaxTol());
+      aVertexLoopTranslator.Init (aVertexLoop, theTopoDSTool, theTopoDSToolNM, theLocalFactors);
+      if (aVertexLoopTranslator.IsDone())
+      {
+        aFaceBuilder.Add (aResultFace, aVertexLoopTranslator.Value());
+      }
+      else
+      {
+        aMessageHandler->AddWarning (aVertexLoop, " a VertexLoop not mapped to TopoDS");
+      }
     }
-  }
-    
-  // ----------------------
-  // The Loop is a PolyLoop
-  // ----------------------
-    else if (Loop->IsKind(STANDARD_TYPE(StepShape_PolyLoop))) {
-//:S4136      STF.Closed() = Standard_False;
-      Handle(StepShape_PolyLoop) PL = Handle(StepShape_PolyLoop)::DownCast(Loop);
-      F.Orientation ( FS->SameSense() ? TopAbs_FORWARD : TopAbs_REVERSED);
-      myTranPL.SetPrecision(Precision()); //gka
-      myTranPL.SetMaxTol(MaxTol());
-      myTranPL.Init(PL, aTool, GeomSurf, F, theLocalFactors);
-      if (myTranPL.IsDone()) {
-        TopoDS_Wire W = TopoDS::Wire(myTranPL.Value());
-        W.Orientation(FaceBound->Orientation() ? TopAbs_FORWARD : TopAbs_REVERSED);
-        B.Add(F, W);
+    // ----------------------
+    // The Loop is a PolyLoop
+    // ----------------------
+    else if (aFaceLoop->IsKind (STANDARD_TYPE (StepShape_PolyLoop)))
+    {
+      Handle (StepShape_PolyLoop) aPolyLoop = Handle (StepShape_PolyLoop)::DownCast (aFaceLoop);
+      aResultFace.Orientation (theFaceSurface->SameSense() ? TopAbs_FORWARD : TopAbs_REVERSED);
+      StepToTopoDS_TranslatePolyLoop aPolyLoopTranslator;
+      aPolyLoopTranslator.SetPrecision (Precision()); // gka
+      aPolyLoopTranslator.SetMaxTol (MaxTol());
+      aPolyLoopTranslator.Init (aPolyLoop,
+                                theTopoDSTool,
+                                aGeomSurface,
+                                aResultFace,
+                                theLocalFactors);
+      if (aPolyLoopTranslator.IsDone())
+      {
+        TopoDS_Wire aPolyLoopWire = TopoDS::Wire (aPolyLoopTranslator.Value());
+        aPolyLoopWire.Orientation (aFaceBound->Orientation() ? TopAbs_FORWARD : TopAbs_REVERSED);
+        aFaceBuilder.Add (aResultFace, aPolyLoopWire);
       }
-      else {
-        TP->AddWarning(PL, " a PolyLoop not mapped to TopoDS");
+      else
+      {
+        aMessageHandler->AddWarning (aPolyLoop, " a PolyLoop not mapped to TopoDS");
       }
     }
-    
     // -----------------------
     // The Loop is an EdgeLoop
     // -----------------------
-  else if (Loop->IsKind(STANDARD_TYPE(StepShape_EdgeLoop))) {
-    //:S4136      if (STF.Closed()) {
-    //:S4136   Handle(StepShape_EdgeLoop) EL = 
-    //:S4136     Handle(StepShape_EdgeLoop)::DownCast(FaceBound->Bound());
-    //:S4136   if (EL->NbEdgeList() != 1) STF.Closed() = Standard_False;
-    //:S4136      }
-
-    TopoDS_Wire   W;
-    myTranEdgeLoop.SetPrecision(Precision());  //gka
-    myTranEdgeLoop.SetMaxTol(MaxTol());
-    myTranEdgeLoop.Init(FaceBound, F, GeomSurf, StepSurf, sameSense, aTool, NMTool, theLocalFactors);
-
-    if (myTranEdgeLoop.IsDone()) {
-      W = TopoDS::Wire(myTranEdgeLoop.Value());
-
-      // STEP Face_Surface orientation :
-      // if the topological orientation is opposite to the geometric
-      // orientation of the surface => the underlying topological 
-      // orientation are not implicitly reversed
-      // this is the case in CAS.CADE => If the face_surface is reversed,
-      // the wire orientation has to be explicitly reversed
-      if (FaceBound->Orientation()) {
-        // *DTH*         if (sameSense || GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
-        W.Orientation(sameSense ? TopAbs_FORWARD : TopAbs_REVERSED);
-      }
-      else {
-        // *DTH*         if (sameSense || GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
-        W.Orientation(sameSense ? TopAbs_REVERSED : TopAbs_FORWARD);
+    else if (aFaceLoop->IsKind (STANDARD_TYPE (StepShape_EdgeLoop)))
+    {
+      StepToTopoDS_TranslateEdgeLoop anEdgeLoopTranslator;
+      anEdgeLoopTranslator.SetPrecision (Precision()); // gka
+      anEdgeLoopTranslator.SetMaxTol (MaxTol());
+      anEdgeLoopTranslator.Init (aFaceBound,
+                                 aResultFace,
+                                 aGeomSurface,
+                                 aStepGeomSurface,
+                                 aSameSense,
+                                 theTopoDSTool,
+                                 theTopoDSToolNM,
+                                 theLocalFactors);
+
+      if (anEdgeLoopTranslator.IsDone())
+      {
+        TopoDS_Wire anEdgeLoopWire = TopoDS::Wire (anEdgeLoopTranslator.Value());
+
+        // STEP Face_Surface orientation :
+        // if the topological orientation is opposite to the geometric
+        // orientation of the surface => the underlying topological
+        // orientation are not implicitly reversed
+        // this is the case in CAS.CADE => If the face_surface is reversed,
+        // the wire orientation has to be explicitly reversed
+        if (aFaceBound->Orientation())
+        {
+          anEdgeLoopWire.Orientation (aSameSense ? TopAbs_FORWARD : TopAbs_REVERSED);
+        }
+        else
+        {
+          anEdgeLoopWire.Orientation (aSameSense ? TopAbs_REVERSED : TopAbs_FORWARD);
+        }
+        // -----------------------------
+        // The Wire is added to the Face
+        // -----------------------------
+        aFaceBuilder.Add (aResultFace, anEdgeLoopWire);
       }
-      // -----------------------------
-      // The Wire is added to the Face      
-      // -----------------------------
-      B.Add(F, W);
-    }
-    else {
-      // Il y a eu un probleme dans le mapping : On perd la Face
-      // (facon de parler ...) Pas de moyen aujourd hui de recuperer
-      // au moins toutes les geometries (Points, Courbes 3D, Surface)
-      TP->AddFail(Loop, " EdgeLoop not mapped to TopoDS");
-
-      // CKY JAN-97 : un Wire manque, eh bien on continue quand meme !!
-      //  sauf si OuterBound : la c est quand meme pas bien normal ...
-      if (FaceBound->IsKind(STANDARD_TYPE(StepShape_FaceOuterBound))) {
-        TP->AddWarning(FS, "No Outer Bound : Face not done");
+      else
+      {
+        // There was a problem in the mapping: We lost Face (so to speak...).
+        // No way today to recover at least all the geometries (Points, 3D Curves, Surface).
+        aMessageHandler->AddFail (aFaceLoop, " EdgeLoop not mapped to TopoDS");
+
+        // CKY JAN-97: a Wire is missing, well we continue anyway
+        // unless OuterBound: that's still not quite normal...
+        if (aFaceBound->IsKind (STANDARD_TYPE (StepShape_FaceOuterBound)))
+        {
+          aMessageHandler->AddWarning (theFaceSurface, "No Outer Bound : Face not done");
+        }
+        continue;
       }
-      continue;
     }
-    }    
-    else { 
+    else
+    {
       // Type not yet implemented or non sens
-      TP->AddFail(Loop," Type of loop not yet implemented");
-#ifdef OCCT_DEBUG
-      std::cout << Loop->DynamicType() << std::endl;
-#endif
+      aMessageHandler->AddFail (aFaceLoop, " Type of loop not yet implemented");
       continue;
     }
   }
 
-  F.Orientation ( FS->SameSense() ? TopAbs_FORWARD : TopAbs_REVERSED);
-  aTool.Bind(FS,F);
+  aResultFace.Orientation (theFaceSurface->SameSense() ? TopAbs_FORWARD : TopAbs_REVERSED);
+  theTopoDSTool.Bind (theFaceSurface, aResultFace);
 
   // Register face in NM tool (ssv; 14.11.2010)
-  if ( NMTool.IsActive() )
-    NMTool.Bind(StepSurf, F);
+  if (theTopoDSToolNM.IsActive())
+  {
+    theTopoDSToolNM.Bind (aStepGeomSurface, aResultFace);
+  }
 
-  myResult = F;
+  myResult = aResultFace;
   myError  = StepToTopoDS_TranslateFaceDone;
   done     = Standard_True;
 }
index c58b56745da47ab6ededdf0cf9fa60ead5264ae1..af78de0c45c0daf33334ff46c5290b51eddf7b27 100644 (file)
@@ -60,9 +60,9 @@ public:
                                              StepToTopoDS_NMTool& theNMTool,
                                              const StepData_Factors& theLocalFactors = StepData_Factors());
   
-  Standard_EXPORT void Init (const Handle(StepShape_FaceSurface)& FS,
-                             StepToTopoDS_Tool& T,
-                             StepToTopoDS_NMTool& NMTool,
+  Standard_EXPORT void Init (const Handle(StepShape_FaceSurface)& theFaceSurface,
+                             StepToTopoDS_Tool& theTopoDSTool,
+                             StepToTopoDS_NMTool& theTopoDSToolNM,
                              const StepData_Factors& theLocalFactors = StepData_Factors());
   
   Standard_EXPORT void Init (const Handle(StepVisual_TessellatedFace)& theTF,
diff --git a/tests/bugs/step/bug33665 b/tests/bugs/step/bug33665
new file mode 100644 (file)
index 0000000..b1b20e7
--- /dev/null
@@ -0,0 +1,12 @@
+puts "# ====================================================================="
+puts "# 0033665: Data Exchange, Step Import - TransferRoots crashes for"
+puts "# invalid STEP files."
+puts "# ====================================================================="
+
+# Step entity #18 is intentionally removed from test file,
+# but it is still referenced by other step entities.
+# Parsing and root transfer should not cause crash for such invalid file.
+
+set aFilePath [locate_data_file bug33665.step]
+testreadstep "$aFilePath" aShape
+checkshape aShape