What's wrong with this OBJ-File ?

I’m testing a Script from laubwerk.com which creates an OBJ-File.

When I import the generated OBJ-File I get this Error:

The genereted OBJ-File ist here:
http://archiviz.DiskStation.me:5000/fbsharing/QyVbsfqf

The Script looks like this:

#
# Loads a plant model, creates the geometry and stores it in obj format according to this documentation
# http://paulbourke.net/dataformats/obj/
#
# Copyright Laubwerk GmbH
#

import laubwerk

plant = laubwerk.load("C:\\Program Files\\Laubwerk\\Plants\\Acer_campestre\\Acer_campestre.lbw.gz")
model = plant.models[0]
mesh = model.getMesh("summer")

objfile = open("Acer_campestre.obj", "w")

objfile.write("# obj file written by laubwerk python example")
objfile.write("o " + mesh.name)

# write vertices
for point in mesh.points:
    objfile.write("v " + str(point[0]) + " " + str(point[1]) + " " + str(point[2]) + "
")
    
objfile.write("
")

# write texture vertices
for uv in mesh.uvs:
    objfile.write("vt " + str(uv[0]) + " " + str(uv[1]) + " 0
")
    
objfile.write("
")

# write vertex normals
for normal in mesh.normals:
    objfile.write("vn " + str(normal[0]) + " " + str(normal[1]) + " " + str(normal[2]) + "
")

objfile.write("
")

# write polygons in format f v/vt/vn v/vt/vn v/vt/vn v/vt/vn
for polygon, texverts in zip(mesh.polygons, mesh.texverts):
    objfile.write("f")
    for idx, texidx in zip(polygon, texverts):
        objfile.write(" " + str(idx) + "/" + str(texidx) + "/" + str(idx))
    objfile.write("
")
    

Does someone know what’s wrong ?
Is it the OBJ-Filesstructure ?

Kind regards
Alain

looks to me like there are vertices missing, maybe faces reference vertex indices but the vertices are never defined

Did you check the OBJ-File ?

There are definitions for the Vertices at the beginning.
But I’m not sure if the faces are connected the right way because there are some face defined by 4 and some by 3 vertices. Could be quadface or triangleface. But I guess this doesn’t matter, right ?

Kind regards
Alain

The file loads in Ultimate Unwrap 3D. But the geometry looks a bit destroyed here and there. The vertices seems to be connected in a wrong way. And the mapping is definitely shot down. It goes into the negative range too.

But the geometry itself shouldn’t matter. Blender should at least load the file. So I would say submit it as a bug.

Hi there,

I just looked at the result and there seems to be something weird going on indeed. I tried importing your OBJ into CINEMA 4D which did go through, but looks broken. However, when I tried it on my computer, it went through and the mesh looked just fine. However, after a little investigation I did find two mistakes in the example script that caused the OBJ file to be broken. I attached a correct file to this post, for everyone who’s interested. We will also correct this mistake in our distribution as soon as possible.


#
# Loads a plant model, creates the geometry and stores it in obj format according to this
# documentation: http://paulbourke.net/dataformats/obj/
# This example intentionally doesn't do a lot of error checking, as it's meant to be minimal and
# clearly only serve as a basic example of how to use the laubwerk module.
#
# Copyright Laubwerk GmbH
#


import sys, laubwerk


# check for the command line arguments to be present
if len(sys.argv) < 2:
    print 'Please provide the path to a Laubwerk plant file as command line argument
'
    print 'Example:
'
    print 'lbwtoobj.py C:\Program Files\Laubwerk\Plants\Acer_campestre\Acer_campestre.lbw.gz
'
    sys.exit()


# load the plant model
plant = laubwerk.load(sys.argv[1])


# pick the default model in the plant file (all models can be accessed through plant.models)
model = plant.defaultModel


# generate the actual model geometry with default quality settings and the default (season) qualifier
# a list of valid qualifiers can be retrieved through plant.qualifiers
mesh = model.getMesh(model.defaultQualifier)


objfile = open("Acer_campestre.obj", "w")


objfile.write("# obj file written by laubwerk python example
")
if len(mesh.name) > 0:
	objfile.write("o " + mesh.name + "
")
else:
	objfile.write("o mesh
")


# write vertices
for point in mesh.points:
	objfile.write("v " + str(point[0]) + " " + str(point[1]) + " " + str(point[2]) + "
")
	
objfile.write("
")


# write texture vertices
for uv in mesh.uvs:
	objfile.write("vt " + str(uv[0]) + " " + str(uv[1]) + " 0
")
	
objfile.write("
")


# write vertex normals
for normal in mesh.normals:
	objfile.write("vn " + str(normal[0]) + " " + str(normal[1]) + " " + str(normal[2]) + "
")


objfile.write("
")


# write polygons in format f v/vt/vn v/vt/vn v/vt/vn v/vt/vn
for polygon, texverts in zip(mesh.polygons, mesh.texverts):
	objfile.write("f")
	for idx, texidx in zip(polygon, texverts):
		objfile.write(" " + str(idx+1) + "/" + str(texidx+1) + "/" + str(idx+1))
	objfile.write("
")

For those who are interested, one of the problems was that we just passed the internal vertex index numbering (which is 0-based) to the obj file (which is 1-based). That introduced an offset which made things look broken. My own local version of the file was older than the one in the distribution and had an additional missing line break, which turned the first vertex into a comment and that kinda “fixed” the indices again.

I do agree with Tiles that Blender still shouldn’t choke on the file, even though it had a problem, so it’s probably a good idea to still submit it as a bug.

Regarding the negative texture coordinates: The texture on the branches is tiled in uv space, so the coordinates typically run out of the [0…1] range in v direction. While it can be argued that this is not good style (and we are working on improving texturing), it should work.

Best
Timm Dapper
CTO Laubwerk GmbH