OCCT
OCCT copied to clipboard
OBJ file fails to load
Description
The attached OBJ file fails to load in DRAW test harness: test.obj.zip
The attached OBJ file was exported from Wings3D and only contains f elements of the format f <index>// [...] where <index> is the vertex index and the two slashes indicate absence of any UV of normal data. There is no normal index specified anywhere.
Expected Behavior
OBJ file loaded correctly, without any warning in DRAWEXE command interpreter.
With FreeCad:
Actual Behavior
The OBJ file fails to load(empty 3D view) and many warnings are reported:
...
Warning: invalid OBJ syntax at line 23523: Normal index is specified but no Normals nodes are defined
Warning: invalid OBJ syntax at line 23524: Normal index is specified but no Normals nodes are defined
Warning: invalid OBJ syntax at line 23525: Normal index is specified but no Normals nodes are defined
Warning: invalid OBJ syntax at line 23526: Normal index is specified but no Normals nodes are defined
Warning: invalid OBJ syntax at line 23527: Normal index is specified but no Normals nodes are defined
Mesh C:/PathToFile/test.obj
[0 nodes] [0 2d elements]
Sample Code or DRAW Tcl Script
pload ALL vinit ReadObj Doc C:/PathToFile/test.obj XDisplay -dispMode 1 Doc vfit
Operating System
Windows
Compiler
MSVC
Bitness
64-bit
OCCT Version
7.8
Additional Files
No response
The FreeCAD screenshot also shows an issue (possibly in FreeCAD). It is missing a lot of quad faces. Here is a screenshot from re-importing this OBJ into Wings3D:
Test model defines facets like this:
f 1// 3115// 9783// 3114//
which are not recognized by OCCT as a valid syntax. OBJ format specifications like this one do not mention this syntax as valid one. Although the meaning of the syntax could be deduced, application writing such file just wastes disk space for no reason by writing a pair of // slashes with no extra indices for both texture coordinates and vertex normal.
Anyhow, the patch for handling such files in OCCT might look like this:
0001-Data-Exchange-RWObj_Reader-fix-reading-facets-with-e.patch
--- a/src/RWObj/RWObj_Reader.cxx
+++ b/src/RWObj/RWObj_Reader.cxx
@@ -339,15 +339,21 @@ void RWObj_Reader::pushIndices (const char* thePos)
if (*thePos == '/')
{
++thePos;
- a3Indices[1] = int(strtol (thePos, &aNext, 10) - 1);
- thePos = aNext;
+ if (*thePos != '/')
+ {
+ a3Indices[1] = int(strtol (thePos, &aNext, 10) - 1);
+ thePos = aNext;
+ }
// parse Normal index
if (*thePos == '/')
{
++thePos;
- a3Indices[2] = int(strtol (thePos, &aNext, 10) - 1);
- thePos = aNext;
+ if (!IsSpace(*thePos))
+ {
+ a3Indices[2] = int(strtol (thePos, &aNext, 10) - 1);
+ thePos = aNext;
+ }
}
}
OBJ format specifications like this one do not mention this syntax as valid one
But neither does the above spec. mention it as an invalid one (I believe Bourke's page has a copy of the original Wavefront spec. that shipped with The Advanced Visualizer).
I think a robust reader would read either version, w. or w/o. additional slashes.
Any reader I came across "in the wild" in the last 30 years does but that may also be because of how a straightforward OBJ parser would work for these statements.
I.e. just fill the resp. index arrays, one by one, while / are encountered or go back to filling the vertex index array as soon as a space is encountered.
My 'wild' is the visual effects ecosystem of software though, where this format originated, not CAD & co.
Quote from above linked page:
`f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 . . .`
Polygonal geometry statement.
Specifies a face element and its vertex reference number. You can
optionally include the texture vertex and vertex normal reference
numbers.
The reference numbers for the vertices, texture vertices, and
vertex normals must be separated by slashes (/). There is no space
between the number and the slash.
`v` is the reference number for a vertex in the face element. A
minimum of three vertices are required.
`vt` is an optional argument.
`vt` is the reference number for a texture vertex in the face
element. It always follows the first slash.
`vn` is an optional argument.
vn is the reference number for a vertex normal in the face element.
It must always follow the second slash.
The above text says vt and vn are optional; it does not say the / separators must not be specified when they are superfluous.
The above text says vt and vn are optional; it does not say the / separators must not be specified when they are superfluous.
OK.
Any reader I came across "in the wild" in the last 30 years does but that may also be because of how a straightforward OBJ parser would work for these statements.
I didn't say that reader shouldn't read such files. The readers usually evolve when new sample files appear.