0030389: Data Exchange - StlAPI_Writer does not check if the face has triangulation
authoremv <emv@opencascade.com>
Thu, 29 Nov 2018 07:20:23 +0000 (10:20 +0300)
committerapn <apn@opencascade.com>
Fri, 30 Nov 2018 10:38:25 +0000 (13:38 +0300)
When merging triangulation of the faces skip those having no triangulation.
Test case for the issue.

src/StlAPI/StlAPI_Writer.cxx
tests/bugs/stlvrml/bug30389 [new file with mode: 0644]

index 57ac659..6433b31 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <Bnd_Box.hxx>
 #include <BRepBndLib.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
 #include <OSD_Path.hxx>
 #include <OSD_OpenFile.hxx>
 #include <RWStl.hxx>
@@ -56,16 +58,29 @@ Standard_Boolean StlAPI_Writer::Write (const TopoDS_Shape&    theShape,
     }
   }
 
+  if (aNbTriangles == 0)
+  {
+    // No triangulation on the shape
+    return Standard_False;
+  }
+
   // create temporary triangulation
   Handle(Poly_Triangulation) aMesh = new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False);
-
+  // count faces missing triangulation
+  Standard_Integer aNbFacesNoTri = 0;
   // fill temporary triangulation
   Standard_Integer aNodeOffset = 0;
   Standard_Integer aTriangleOffet = 0;
   for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
   {
+    const TopoDS_Shape& aFace = anExpSF.Current();
     TopLoc_Location aLoc;
-    Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc);
+    Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (aFace), aLoc);
+    if (aTriangulation.IsNull())
+    {
+      ++aNbFacesNoTri;
+      continue;
+    }
 
     const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
     const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
@@ -109,7 +124,20 @@ Standard_Boolean StlAPI_Writer::Write (const TopoDS_Shape&    theShape,
   }
 
   OSD_Path aPath (theFileName);
-  return myASCIIMode
+  Standard_Boolean isDone = (myASCIIMode
        ? RWStl::WriteAscii  (aMesh, aPath)
-       : RWStl::WriteBinary (aMesh, aPath);
+       : RWStl::WriteBinary (aMesh, aPath));
+
+  if (isDone && (aNbFacesNoTri > 0))
+  {
+    // Print warning with number of faces missing triangulation
+    TCollection_AsciiString aWarningMsg =
+      TCollection_AsciiString ("Warning: ") +
+      TCollection_AsciiString (aNbFacesNoTri) +
+      TCollection_AsciiString ((aNbFacesNoTri == 1) ? " face has" : " faces have") +
+      TCollection_AsciiString (" been skipped due to null triangulation");
+    Message::DefaultMessenger()->Send (aWarningMsg, Message_Warning);
+  }
+
+  return isDone;
 }
diff --git a/tests/bugs/stlvrml/bug30389 b/tests/bugs/stlvrml/bug30389
new file mode 100644 (file)
index 0000000..383d895
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "0030389: Data Exchange - StlAPI_Writer does not check if the face has triangulation"
+puts "========"
+puts ""
+
+box b 1 1 1 
+
+# mesh only 5 faces of the box
+eval compound [lrange [explode b f] 0 4] cf
+incmesh cf 0.1
+
+# save box into stl
+writestl b $imagedir/${casename}.stl
+
+# read stl
+readstl result $imagedir/${casename}.stl -brep
+
+# check that it contains only 10 triangles
+checknbshapes result -face 10