-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlbwtoobjvue.py
185 lines (140 loc) · 6.43 KB
/
lbwtoobjvue.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#
# Loads a plant model, creates the geometry and stores it in obj format according to this
# documentation:
# http://paulbourke.net/dataformats/obj/
# http://paulbourke.net/dataformats/mtl/
# 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, argparse, glob, os, laubwerk
def linearToSrgb(color):
"""Convert a color from linear to sRGB
"""
retCol = [0, 0, 0]
for i in range(3):
if color[i] > 0.0031308:
retCol[i] = 1.055 * (pow(color[i], (1.0 / 2.4))) - 0.055;
else:
retCol[i] = 12.92 * color[i];
return retCol
def writeObjByHandle(plant, model, qualifier, objfile, scale = 1.0, mtlfile = None, mtlTexFullPath = False, leafDensity = 1.0):
# 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(qualifier, leafDensity=leafDensity)
objfile.write("# obj file written by laubwerk python example\n")
# do an initial run through the mesh to determine the used materials
matidSet = set()
for matid in mesh.matids:
matidSet.add(matid)
if mtlfile:
objfile.write('mtllib ' + mtlfile.name + '\n')
if len(mesh.name) > 0:
objfile.write("o " + mesh.name + "\n")
else:
objfile.write("o mesh\n")
# write vertices
for point in mesh.points:
objfile.write("v " + str(point[0] * scale) + " " + str(point[1] * scale) + " " + str(point[2] * scale) + "\n")
objfile.write("\n")
# write texture vertices
for uv in mesh.uvs:
objfile.write("vt " + str(uv[0]) + " " + str(1.0 - uv[1]) + " 0\n")
objfile.write("\n")
# write vertex normals
for normal in mesh.normals:
objfile.write("vn " + str(normal[0]) + " " + str(normal[1]) + " " + str(normal[2]) + "\n")
objfile.write("\n")
# write polygons in format f v/vt/vn v/vt/vn v/vt/vn v/vt/vn
# reorder the faces in material groups
for matid in matidSet:
# find and specify material
materialName = ""
for material in plant.materials:
if material.matid == matid:
if mtlfile:
objfile.write('usemtl ' + material.name + '\n')
objfile.write('g ' + material.name + '\n')
materialName = material.name
break
nFaces = 0
for polygon, texverts, polyMatid in zip(mesh.polygons, mesh.texverts, mesh.matids):
if polyMatid == matid:
objfile.write("f")
for idx, texidx in zip(polygon, texverts):
objfile.write(" " + str(idx+1) + "/" + str(texidx+1) + "/" + str(idx+1))
objfile.write("\n")
nFaces = nFaces + 1
#print str(matid) + ' ' + materialName + ' ' + str(nFaces)
if mtlfile:
# write mtl file
mtlfile.write("# mtl file written by laubwerk python example\n")
for material, i in zip(plant.materials, range(len(plant.materials))):
if material.matid in matidSet:
#print material.name
mtlfile.write('newmtl ' + material.name + '\n')
mtlFront = material.getFront()
myKd = linearToSrgb(mtlFront.diffuseColor)
mtlfile.write('\tKd ' + str(myKd[0]) + ' ' + str(myKd[1]) + ' ' + str(myKd[2]) + '\n')
mtlfile.write('\tNi 1.3333\n') # ior
if len(mtlFront.diffuseTexture):
mtlfile.write('\tmap_Kd ' + (mtlFront.diffuseTexture if mtlTexFullPath else os.path.basename(mtlFront.diffuseTexture))+ '\n')
if len(mtlFront.bumpTexture) > 0:
mtlfile.write('\tbump ' + (mtlFront.bumpTexture if mtlTexFullPath else os.path.basename(mtlFront.bumpTexture)) + '\n')
if len(material.alphaTexture) > 0:
atsplit = os.path.splitext(material.alphaTexture if mtlTexFullPath else os.path.basename(material.alphaTexture))
mtlfile.write('\tmap_d ' + atsplit[0] + '_a' + atsplit[1] + '\n')
#if len(material.alphaTexture) > 0:
# mtlfile.write('\tmap_Tf ' + os.path.basename(material.alphaTexture) + '\n')
def writeObjByName(plant, model, qualifier, objFileName, scale = 1.0, mtlFileName = None, mtlTexFullPath = False):
objfile = open(objFileName, "w")
mtlfile = None
if mtlFileName:
mtlfile = open(mtlFileName, "w")
writeObjByHandle(plant, model, qualifier, objfile, scale, mtlfile, mtlTexFullPath)
def main():
#
# prepare command line arguments
#
argParse = argparse.ArgumentParser(description='Convert LBW file(s) to OBJ.')
argParse.add_argument('inPath', metavar='path', type=str, nargs=1, help='The path or filename to convert (accepts wildcards).')
argParse.add_argument('--qualifier', '-q', dest='qualifier', default='all', type=str, help='The qualifier name to use, accepts wildcards. If not specified or special keyword "all" is used, all qualifiers get exported. The special keyword "default" will cause the default qualifier to be used.')
argParse.add_argument('--model', '-m', type=str, dest='model', default='all', help='The name of the model to export. If not specified or special keyword "all" is used all models get exported. The special keyword "default" will export only the default model.')
argParse.add_argument('--scale', '-s', type=float, dest='scale', default=1.0, help='A scale multiplier to use when writing the vertices of the OBJ file.')
#argParse.add_argument('--info', '-i', type)
#
# process command line arguments
#
args = argParse.parse_args()
#
# find the file(s) to export
#
inFileList = glob.glob(args.inPath[0])
#
# iterate through all input files
#
for inFile in inFileList:
inFileBase = os.path.basename(inFile)
print 'Exporting ' + inFileBase + '...'
# load the plant model
plant = laubwerk.load(inFile)
# pick the default model in the plant file (all models can be accessed through plant.models)
#model = plant.defaultModel
for model in plant.models:
if not args.model == 'all' and model.name != args.model and not (args.model == 'default' and model == plant.defaultModel):
continue
print '\t' + model.name + '...'
# run through the available qualifiers
for qualifier in model.qualifiers:
if not args.qualifier == 'all' and qualifier != args.qualifier and not (args.qualifier == 'default' and qualifier == model.defaultQualifier):
continue
print '\t\t' + qualifier + '...'
objFileName = inFileBase
while not os.path.splitext(objFileName)[1] == '':
objFileName = os.path.splitext(objFileName)[0]
objFileName = objFileName + '_' + model.name + '_' + qualifier + '.obj'
mtlFileName = os.path.splitext(objFileName)[0] + '.mtl'
writeObjByName(plant, model, qualifier, objFileName, args.scale, mtlFileName)
if __name__ == "__main__":
main()