//! Creates Poly_Triangulation from collected data
Handle(Poly_Triangulation) GetTriangulation()
{
+ if (myTriangles.IsEmpty())
+ return Handle(Poly_Triangulation)();
+
Handle(Poly_Triangulation) aPoly = new Poly_Triangulation (myNodes.Length(), myTriangles.Length(), Standard_False);
for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
{
const Handle(Message_ProgressIndicator)& theProgress)
{
Reader aReader;
- if (!aReader.Read (theFile, theProgress))
- {
- return Handle(Poly_Triangulation)();
- }
+ aReader.Read (theFile, theProgress);
+ // note that returned bool value is ignored intentionally -- even if something went wrong,
+ // but some data have been read, we at least will return these data
return aReader.GetTriangulation();
}
//function : Write
//purpose :
//=============================================================================
-Standard_Boolean RWStl::WriteBinary (const Handle(Poly_Triangulation)& aMesh,
+Standard_Boolean RWStl::WriteBinary (const Handle(Poly_Triangulation)& theMesh,
const OSD_Path& thePath,
const Handle(Message_ProgressIndicator)& theProgInd)
{
+ if (theMesh.IsNull() || theMesh->NbTriangles() <= 0)
+ {
+ return Standard_False;
+ }
+
TCollection_AsciiString aPath;
thePath.SystemName (aPath);
return Standard_False;
}
- Standard_Boolean isOK = writeBinary (aMesh, aFile, theProgInd);
+ Standard_Boolean isOK = writeBinary (theMesh, aFile, theProgInd);
fclose (aFile);
return isOK;
const OSD_Path& thePath,
const Handle(Message_ProgressIndicator)& theProgInd)
{
+ if (theMesh.IsNull() || theMesh->NbTriangles() <= 0)
+ {
+ return Standard_False;
+ }
+
TCollection_AsciiString aPath;
thePath.SystemName (aPath);
std::streampos theEnd = aStream.tellg();
aStream.seekg (0, aStream.beg);
- while (!aStream.eof() && !aStream.bad())
+ // binary STL files cannot be shorter than 134 bytes
+ // (80 bytes header + 4 bytes facet count + 50 bytes for one facet);
+ // thus assume files shorter than 134 as Ascii without probing
+ // (probing may bring stream to fail state if EOF is reached)
+ bool isAscii = ((size_t)theEnd < THE_STL_MIN_FILE_SIZE || IsAscii (aStream));
+
+ while (aStream.good())
{
- if (IsAscii (aStream))
+ if (isAscii)
{
if (!ReadAscii (aStream, theEnd, theProgress))
{
}
aStream >> std::ws; // skip any white spaces
}
- return !aStream.bad();
+ return ! aStream.fail();
}
//==============================================================================
// read first 134 bytes to detect file format
char aBuffer[THE_STL_MIN_FILE_SIZE];
std::streamsize aNbRead = theStream.read (aBuffer, THE_STL_MIN_FILE_SIZE).gcount();
- if (!theStream)
+ if (! theStream)
{
Message::DefaultMessenger()->Send ("Error: Cannot read file", Message_Fail);
- return false;
+ return true;
}
// put back the read symbols
// use method seekpos() to get true 64-bit offset to enable
// handling of large files (VS 2010 64-bit)
const int64_t aStartPos = GETPOS(theStream.tellg());
- const int64_t aEndPos = (theUntilPos > 0 ? GETPOS(theUntilPos) : std::numeric_limits<int64_t>::max());
+ // Note: 1 is added to theUntilPos to be sure to read the last symbol (relevant for files without EOL at the end)
+ const int64_t aEndPos = (theUntilPos > 0 ? 1 + GETPOS(theUntilPos) : std::numeric_limits<int64_t>::max());
// skip header "solid ..."
theStream.ignore (aEndPos - aStartPos, '\n');
--- /dev/null
+puts "\n#======================================================================"
+puts "# Check reading empty or small STL files"
+puts "#======================================================================\n"
+
+set minimal_ascii_stl {solid
+facet normal 0 0 1
+outer loop
+vertex 0 0 0
+vertex 1 0 0
+vertex 0 1 0
+endloop
+endfacet
+endsolid}
+
+puts "\n#======================================================================"
+puts "# Ascii file with single facet, CRLF"
+puts "#======================================================================"
+set fd [open ${imagedir}/${casename}_one_ascii_dos.stl w]
+fconfigure $fd -translation crlf
+puts $fd $minimal_ascii_stl
+close $fd
+readstl res_one_ascii_dos ${imagedir}/${casename}_one_ascii_dos.stl
+checknbshapes res_one_ascii_dos -face 1
+
+puts "\n#======================================================================"
+puts "# Ascii file with single facet, LF"
+puts "#======================================================================"
+set fd [open ${imagedir}/${casename}_one_ascii_unix.stl w]
+fconfigure $fd -translation lf
+puts $fd $minimal_ascii_stl
+close $fd
+readstl res_one_ascii_unix ${imagedir}/${casename}_one_ascii_unix.stl
+checknbshapes res_one_ascii_unix -face 1
+
+puts "\n#======================================================================"
+puts "# Ascii file with single facet, LF, no EOL at the last line"
+puts "#======================================================================"
+set fd [open ${imagedir}/${casename}_one_ascii_noeol.stl w]
+fconfigure $fd -translation lf
+puts -nonewline $fd $minimal_ascii_stl
+close $fd
+readstl res_one_ascii_noeol ${imagedir}/${casename}_one_ascii_noeol.stl
+checknbshapes res_one_ascii_noeol -face 1
+
+puts "\n#======================================================================"
+puts "# Ascii file with no facets, CRLF"
+puts "#======================================================================"
+set fd [open ${imagedir}/${casename}_zero_ascii_dos.stl w]
+fconfigure $fd -translation crlf
+puts $fd "solid \nendsolid"
+close $fd
+readstl res_zero_ascii_dos ${imagedir}/${casename}_zero_ascii_dos.stl
+
+puts "\n#======================================================================"
+puts "# Ascii file with no facets, LF"
+puts "#======================================================================"
+set fd [open ${imagedir}/${casename}_zero_ascii_unix.stl w]
+fconfigure $fd -translation lf
+puts $fd "solid \nendsolid"
+close $fd
+readstl res_zero_ascii_unix ${imagedir}/${casename}_zero_ascii_unix.stl
+
+puts "\n#======================================================================"
+puts "# Binary file with single facet"
+puts "#======================================================================"
+set fd [open ${imagedir}/${casename}_one_binary.stl w]
+fconfigure $fd -translation binary
+puts -nonewline $fd "stl [string repeat { } 76]"
+puts -nonewline $fd [binary format if3f3f3f3t 1 {0 0 1} {0 0 0} {1 0 0} {0 1 0} 0]
+close $fd
+readstl res_one_binary ${imagedir}/${casename}_one_binary.stl
+checknbshapes res_one_binary -face 1
+
+puts "\n#======================================================================"
+puts "# Binary file with no facets -- will be treated as Ascii and generate e r r o r"
+puts "#======================================================================"
+puts "REQUIRED ALL: Error: unexpected format of facet at line 2"
+set fd [open ${imagedir}/${casename}_zero_binary.stl w]
+fconfigure $fd -translation binary
+puts -nonewline $fd "stl [string repeat { } 76][binary format i 0]"
+close $fd
+readstl res_zero_binary ${imagedir}/${casename}_zero_binary.stl
+
+puts "\n#======================================================================"
+puts "# Empty file"
+puts "#======================================================================"
+puts "REQUIRED ALL: Error: unexpected format of facet at line 2"
+set fd [open ${imagedir}/${casename}_empty.stl w]
+close $fd
+readstl res_empty ${imagedir}/${casename}_empty.stl
+