~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to release/scripts/lightwave_export.py

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!BPY
 
2
 
 
3
"""
 
4
Name: 'LightWave (.lwo)...'
 
5
Blender: 232
 
6
Group: 'Export'
 
7
Tooltip: 'Export selected meshes to LightWave File Format (.lwo)'
 
8
"""
 
9
 
 
10
__author__ = "Anthony D'Agostino (Scorpius)"
 
11
__url__ = ("blender", "elysiun",
 
12
"Author's homepage, http://www.redrival.com/scorpius")
 
13
__version__ = "Part of IOSuite 0.5"
 
14
 
 
15
__bpydoc__ = """\
 
16
This script exports meshes to LightWave file format.
 
17
 
 
18
LightWave is a full-featured commercial modeling and rendering
 
19
application. The lwo file format is composed of 'chunks,' is well
 
20
defined, and easy to read and write. It is similar in structure to the
 
21
trueSpace cob format.
 
22
 
 
23
Usage:<br>
 
24
        Select meshes to be exported and run this script from "File->Export" menu.
 
25
 
 
26
Supported:<br>
 
27
        UV Coordinates, Meshes, Materials, Material Indices, Specular
 
28
Highlights, and Vertex Colors. For added functionality, each object is
 
29
placed on its own layer.
 
30
 
 
31
Missing:<br>
 
32
        Not too much, I hope! :).
 
33
 
 
34
Known issues:<br>
 
35
        Empty objects crash has been fixed.
 
36
 
 
37
Notes:<br>
 
38
        For compatibility reasons, it also reads lwo files in the old LW
 
39
v5.5 format.
 
40
"""
 
41
 
 
42
# $Id: lightwave_export.py,v 1.6 2005/03/21 05:26:51 ianwill Exp $
 
43
#
 
44
# +---------------------------------------------------------+
 
45
# | Copyright (c) 2002 Anthony D'Agostino                   |
 
46
# | http://www.redrival.com/scorpius                        |
 
47
# | scorpius@netzero.com                                    |
 
48
# | April 21, 2002                                          |
 
49
# | Released under the Blender Artistic Licence (BAL)       |
 
50
# | Import Export Suite v0.5                                |
 
51
# +---------------------------------------------------------+
 
52
# | Read and write LightWave Object File Format (*.lwo)     |
 
53
# +---------------------------------------------------------+
 
54
 
 
55
import Blender, meshtools
 
56
import struct, chunk, os, cStringIO, time, operator
 
57
 
 
58
# ==============================
 
59
# === Write LightWave Format ===
 
60
# ==============================
 
61
def write(filename):
 
62
        start = time.clock()
 
63
        file = open(filename, "wb")
 
64
 
 
65
        objects = Blender.Object.GetSelected()
 
66
        objects.sort(lambda a,b: cmp(a.name, b.name))
 
67
        if not objects:
 
68
                meshtools.print_boxed("No mesh objects are selected.")
 
69
                return
 
70
 
 
71
        if len(objects) > 20 and meshtools.show_progress:
 
72
                meshtools.show_progress = 0
 
73
 
 
74
        text = generate_text()
 
75
        desc = generate_desc()
 
76
        icon = "" #generate_icon()
 
77
 
 
78
        material_names = get_used_material_names(objects)
 
79
        tags = generate_tags(material_names)
 
80
        surfs = generate_surfs(material_names)
 
81
        chunks = [text, desc, icon, tags]
 
82
 
 
83
        meshdata = cStringIO.StringIO()
 
84
        layer_index = 0
 
85
        for object in objects:
 
86
                objname = object.name
 
87
                meshname = object.data.name
 
88
                mesh = Blender.NMesh.GetRaw(meshname)
 
89
                #mesh = Blender.NMesh.GetRawFromObject(meshname)        # for SubSurf
 
90
                obj = Blender.Object.Get(objname)
 
91
                if not mesh: continue
 
92
 
 
93
                layr = generate_layr(objname, layer_index)
 
94
                pnts = generate_pnts(mesh, obj.matrix)
 
95
                bbox = generate_bbox(mesh)
 
96
                pols = generate_pols(mesh)
 
97
                ptag = generate_ptag(mesh, material_names)
 
98
 
 
99
                if mesh.hasFaceUV():
 
100
                        vmad_uv = generate_vmad_uv(mesh)  # per face
 
101
 
 
102
                if meshtools.has_vertex_colors(mesh):
 
103
                        if meshtools.average_vcols:
 
104
                                vmap_vc = generate_vmap_vc(mesh)  # per vert
 
105
                        else:
 
106
                                vmad_vc = generate_vmad_vc(mesh)  # per face
 
107
 
 
108
                write_chunk(meshdata, "LAYR", layr); chunks.append(layr)
 
109
                write_chunk(meshdata, "PNTS", pnts); chunks.append(pnts)
 
110
                write_chunk(meshdata, "BBOX", bbox); chunks.append(bbox)
 
111
                write_chunk(meshdata, "POLS", pols); chunks.append(pols)
 
112
                write_chunk(meshdata, "PTAG", ptag); chunks.append(ptag)
 
113
 
 
114
                if mesh.hasFaceUV():
 
115
                        write_chunk(meshdata, "VMAD", vmad_uv)
 
116
                        chunks.append(vmad_uv)
 
117
 
 
118
                if meshtools.has_vertex_colors(mesh):
 
119
                        if meshtools.average_vcols:
 
120
                                write_chunk(meshdata, "VMAP", vmap_vc)
 
121
                                chunks.append(vmap_vc)
 
122
                        else:
 
123
                                write_chunk(meshdata, "VMAD", vmad_vc)
 
124
                                chunks.append(vmad_vc)
 
125
                layer_index += 1
 
126
 
 
127
        for surf in surfs:
 
128
                chunks.append(surf)
 
129
 
 
130
        write_header(file, chunks)
 
131
        write_chunk(file, "ICON", icon)
 
132
        write_chunk(file, "TEXT", text)
 
133
        write_chunk(file, "DESC", desc)
 
134
        write_chunk(file, "TAGS", tags)
 
135
        file.write(meshdata.getvalue()); meshdata.close()
 
136
        for surf in surfs:
 
137
                write_chunk(file, "SURF", surf)
 
138
 
 
139
        Blender.Window.DrawProgressBar(1.0, "")    # clear progressbar
 
140
        file.close()
 
141
        print '\a\r',
 
142
        end = time.clock()
 
143
        seconds = " in %.2f %s" % (end-start, "seconds")
 
144
        message = "Successfully exported " + os.path.basename(filename) + seconds
 
145
        meshtools.print_boxed(message)
 
146
 
 
147
# =======================================
 
148
# === Generate Null-Terminated String ===
 
149
# =======================================
 
150
def generate_nstring(string):
 
151
        if len(string)%2 == 0:  # even
 
152
                string += "\0\0"
 
153
        else:                                   # odd
 
154
                string += "\0"
 
155
        return string
 
156
 
 
157
# ===============================
 
158
# === Get Used Material Names ===
 
159
# ===============================
 
160
def get_used_material_names(objects):
 
161
        matnames = {}
 
162
        for object in objects:
 
163
                objname = object.name
 
164
                meshname = object.data.name
 
165
                mesh = Blender.NMesh.GetRaw(meshname)
 
166
                if not mesh: continue
 
167
                if (not mesh.materials) and (meshtools.has_vertex_colors(mesh)):
 
168
                        # vcols only
 
169
                        if meshtools.average_vcols:
 
170
                                matnames["\251 Per-Vert Vertex Colors"] = None
 
171
                        else:
 
172
                                matnames["\251 Per-Face Vertex Colors"] = None
 
173
                elif (mesh.materials) and (not meshtools.has_vertex_colors(mesh)):
 
174
                        # materials only
 
175
                        for material in mesh.materials:
 
176
                                matnames[material.name] = None
 
177
                elif (not mesh.materials) and (not meshtools.has_vertex_colors(mesh)):
 
178
                        # neither
 
179
                        matnames["\251 Blender Default"] = None
 
180
                else:
 
181
                        # both
 
182
                        for material in mesh.materials:
 
183
                                matnames[material.name] = None
 
184
        return matnames
 
185
 
 
186
# =========================================
 
187
# === Generate Tag Strings (TAGS Chunk) ===
 
188
# =========================================
 
189
def generate_tags(material_names):
 
190
        material_names = map(generate_nstring, material_names.keys())
 
191
        tags_data = reduce(operator.add, material_names)
 
192
        return tags_data
 
193
 
 
194
# ========================
 
195
# === Generate Surface ===
 
196
# ========================
 
197
def generate_surface(name, mesh):
 
198
        if name.find("\251 Per-") == 0:
 
199
                return generate_vcol_surf(mesh)
 
200
        elif name == "\251 Blender Default":
 
201
                return generate_default_surf()
 
202
        else:
 
203
                return generate_surf(name)
 
204
 
 
205
# ======================
 
206
# === Generate Surfs ===
 
207
# ======================
 
208
def generate_surfs(material_names):
 
209
        keys = material_names.keys()
 
210
        values = material_names.values()
 
211
        surfaces = map(generate_surface, keys, values)
 
212
        return surfaces
 
213
 
 
214
# ===================================
 
215
# === Generate Layer (LAYR Chunk) ===
 
216
# ===================================
 
217
def generate_layr(name, idx):
 
218
        data = cStringIO.StringIO()
 
219
        data.write(struct.pack(">h", idx))          # layer number
 
220
        data.write(struct.pack(">h", 0))            # flags
 
221
        data.write(struct.pack(">fff", 0, 0, 0))    # pivot
 
222
        data.write(generate_nstring(name))                      # name
 
223
        return data.getvalue()
 
224
 
 
225
# ===================================
 
226
# === Generate Verts (PNTS Chunk) ===
 
227
# ===================================
 
228
def generate_pnts(mesh, matrix):
 
229
        data = cStringIO.StringIO()
 
230
        for i in range(len(mesh.verts)):
 
231
                if not i%100 and meshtools.show_progress:
 
232
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
 
233
                x, y, z = meshtools.apply_transform(mesh.verts[i].co, matrix)
 
234
                data.write(struct.pack(">fff", x, z, y))
 
235
        return data.getvalue()
 
236
 
 
237
# ==========================================
 
238
# === Generate Bounding Box (BBOX Chunk) ===
 
239
# ==========================================
 
240
def generate_bbox(mesh):
 
241
        data = cStringIO.StringIO()
 
242
        # need to transform verts here
 
243
        nv = map(getattr, mesh.verts, ["co"]*len(mesh.verts))
 
244
        xx = map(operator.getitem, nv, [0]*len(nv))
 
245
        yy = map(operator.getitem, nv, [1]*len(nv))
 
246
        zz = map(operator.getitem, nv, [2]*len(nv))
 
247
        data.write(struct.pack(">6f", min(xx), min(zz), min(yy), max(xx), max(zz), max(yy)))
 
248
        return data.getvalue()
 
249
 
 
250
# ========================================
 
251
# === Average All Vertex Colors (Fast) ===
 
252
# ========================================
 
253
def average_vertexcolors(mesh):
 
254
        vertexcolors = {}
 
255
        vcolor_add = lambda u, v: [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]]
 
256
        vcolor_div = lambda u, s: [u[0]/s, u[1]/s, u[2]/s, u[3]/s]
 
257
        for i in range(len(mesh.faces)):        # get all vcolors that share this vertex
 
258
                if not i%100 and meshtools.show_progress:
 
259
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors")
 
260
                for j in range(len(mesh.faces[i].v)):
 
261
                        index = mesh.faces[i].v[j].index
 
262
                        color = mesh.faces[i].col[j]
 
263
                        r,g,b,a = color.r, color.g, color.b, color.a
 
264
                        vertexcolors.setdefault(index, []).append([r,g,b,a])
 
265
        for i in range(len(vertexcolors)):      # average them
 
266
                if not i%100 and meshtools.show_progress:
 
267
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
 
268
                vcolor = [0,0,0,0]      # rgba
 
269
                for j in range(len(vertexcolors[i])):
 
270
                        vcolor = vcolor_add(vcolor, vertexcolors[i][j])
 
271
                shared = len(vertexcolors[i])
 
272
                vertexcolors[i] = vcolor_div(vcolor, shared)
 
273
        return vertexcolors
 
274
 
 
275
# ====================================================
 
276
# === Generate Per-Vert Vertex Colors (VMAP Chunk) ===
 
277
# ====================================================
 
278
def generate_vmap_vc(mesh):
 
279
        data = cStringIO.StringIO()
 
280
        data.write("RGB ")                                      # type
 
281
        data.write(struct.pack(">H", 3))                        # dimension
 
282
        data.write(generate_nstring("Blender's Vertex Colors")) # name
 
283
        vertexcolors = average_vertexcolors(mesh)
 
284
        for i in range(len(vertexcolors)):
 
285
                r, g, b, a = vertexcolors[i]
 
286
                data.write(struct.pack(">H", i)) # vertex index
 
287
                data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0))
 
288
        return data.getvalue()
 
289
 
 
290
# ====================================================
 
291
# === Generate Per-Face Vertex Colors (VMAD Chunk) ===
 
292
# ====================================================
 
293
def generate_vmad_vc(mesh):
 
294
        data = cStringIO.StringIO()
 
295
        data.write("RGB ")                                      # type
 
296
        data.write(struct.pack(">H", 3))                        # dimension
 
297
        data.write(generate_nstring("Blender's Vertex Colors")) # name
 
298
        for i in range(len(mesh.faces)):
 
299
                if not i%100 and meshtools.show_progress:
 
300
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Vertex Colors")
 
301
                numfaceverts = len(mesh.faces[i].v)
 
302
                for j in range(numfaceverts-1, -1, -1):                         # Reverse order
 
303
                        r = mesh.faces[i].col[j].r
 
304
                        g = mesh.faces[i].col[j].g
 
305
                        b = mesh.faces[i].col[j].b
 
306
                        v = mesh.faces[i].v[j].index
 
307
                        data.write(struct.pack(">H", v)) # vertex index
 
308
                        data.write(struct.pack(">H", i)) # face index
 
309
                        data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0))
 
310
        return data.getvalue()
 
311
 
 
312
# ================================================
 
313
# === Generate Per-Face UV Coords (VMAD Chunk) ===
 
314
# ================================================
 
315
def generate_vmad_uv(mesh):
 
316
        data = cStringIO.StringIO()
 
317
        data.write("TXUV")                                       # type
 
318
        data.write(struct.pack(">H", 2))                         # dimension
 
319
        data.write(generate_nstring("Blender's UV Coordinates")) # name
 
320
        for i in range(len(mesh.faces)):
 
321
                if not i%100 and meshtools.show_progress:
 
322
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coordinates")
 
323
                numfaceverts = len(mesh.faces[i].v)
 
324
                for j in range(numfaceverts-1, -1, -1):                         # Reverse order
 
325
                        U,V = mesh.faces[i].uv[j]
 
326
                        v = mesh.faces[i].v[j].index
 
327
                        data.write(struct.pack(">H", v)) # vertex index
 
328
                        data.write(struct.pack(">H", i)) # face index
 
329
                        data.write(struct.pack(">ff", U, V))
 
330
        return data.getvalue()
 
331
 
 
332
# ======================================
 
333
# === Generate Variable-Length Index ===
 
334
# ======================================
 
335
def generate_vx(index):
 
336
        if index < 0xFF00:
 
337
                value = struct.pack(">H", index)                 # 2-byte index
 
338
        else:
 
339
                value = struct.pack(">L", index | 0xFF000000)    # 4-byte index
 
340
        return value
 
341
 
 
342
# ===================================
 
343
# === Generate Faces (POLS Chunk) ===
 
344
# ===================================
 
345
def generate_pols(mesh):
 
346
        data = cStringIO.StringIO()
 
347
        data.write("FACE")  # polygon type
 
348
        for i in range(len(mesh.faces)):
 
349
                if not i%100 and meshtools.show_progress:
 
350
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
 
351
                data.write(struct.pack(">H", len(mesh.faces[i].v))) # numfaceverts
 
352
                numfaceverts = len(mesh.faces[i].v)
 
353
                for j in range(numfaceverts-1, -1, -1):                         # Reverse order
 
354
                        index = mesh.faces[i].v[j].index
 
355
                        data.write(generate_vx(index))
 
356
        return data.getvalue()
 
357
 
 
358
# =================================================
 
359
# === Generate Polygon Tag Mapping (PTAG Chunk) ===
 
360
# =================================================
 
361
def generate_ptag(mesh, material_names):
 
362
        data = cStringIO.StringIO()
 
363
        data.write("SURF")  # polygon tag type
 
364
        for i in range(len(mesh.faces)): # numfaces
 
365
                if not i%100 and meshtools.show_progress:
 
366
                        Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Surface Indices")
 
367
                data.write(generate_vx(i))
 
368
                if (not mesh.materials) and (meshtools.has_vertex_colors(mesh)):                # vcols only
 
369
                        if meshtools.average_vcols:
 
370
                                name = "\251 Per-Vert Vertex Colors"
 
371
                        else:
 
372
                                name = "\251 Per-Face Vertex Colors"
 
373
                elif (mesh.materials) and (not meshtools.has_vertex_colors(mesh)):              # materials only
 
374
                        idx = mesh.faces[i].mat #erialIndex
 
375
                        name = mesh.materials[idx].name
 
376
                elif (not mesh.materials) and (not meshtools.has_vertex_colors(mesh)):  # neither
 
377
                        name = "\251 Blender Default"
 
378
                else:                                                                                                                                           # both
 
379
                        idx = mesh.faces[i].mat
 
380
                        name = mesh.materials[idx].name
 
381
                names = material_names.keys()
 
382
                surfidx = names.index(name)
 
383
                data.write(struct.pack(">H", surfidx)) # surface index
 
384
        return data.getvalue()
 
385
 
 
386
# ===================================================
 
387
# === Generate VC Surface Definition (SURF Chunk) ===
 
388
# ===================================================
 
389
def generate_vcol_surf(mesh):
 
390
        data = cStringIO.StringIO()
 
391
        if meshtools.average_vcols and meshtools.has_vertex_colors(mesh):
 
392
                surface_name = generate_nstring("\251 Per-Vert Vertex Colors")
 
393
        else:
 
394
                surface_name = generate_nstring("\251 Per-Face Vertex Colors")
 
395
        data.write(surface_name)
 
396
        data.write("\0\0")
 
397
 
 
398
        data.write("COLR")
 
399
        data.write(struct.pack(">H", 14))
 
400
        data.write(struct.pack(">fffH", 1, 1, 1, 0))
 
401
 
 
402
        data.write("DIFF")
 
403
        data.write(struct.pack(">H", 6))
 
404
        data.write(struct.pack(">fH", 0.0, 0))
 
405
 
 
406
        data.write("LUMI")
 
407
        data.write(struct.pack(">H", 6))
 
408
        data.write(struct.pack(">fH", 1.0, 0))
 
409
 
 
410
        data.write("VCOL")
 
411
        data.write(struct.pack(">H", 34))
 
412
        data.write(struct.pack(">fH4s", 1.0, 0, "RGB "))  # intensity, envelope, type
 
413
        data.write(generate_nstring("Blender's Vertex Colors")) # name
 
414
 
 
415
        data.write("CMNT")  # material comment
 
416
        comment = "Vertex Colors: Exported from Blender\256 " + meshtools.blender_version_str
 
417
        comment = generate_nstring(comment)
 
418
        data.write(struct.pack(">H", len(comment)))
 
419
        data.write(comment)
 
420
        return data.getvalue()
 
421
 
 
422
# ================================================
 
423
# === Generate Surface Definition (SURF Chunk) ===
 
424
# ================================================
 
425
def generate_surf(material_name):
 
426
        data = cStringIO.StringIO()
 
427
        data.write(generate_nstring(material_name))
 
428
        data.write("\0\0")
 
429
 
 
430
        material = Blender.Material.Get(material_name)
 
431
        R,G,B = material.R, material.G, material.B
 
432
        data.write("COLR")
 
433
        data.write(struct.pack(">H", 14))
 
434
        data.write(struct.pack(">fffH", R, G, B, 0))
 
435
 
 
436
        data.write("DIFF")
 
437
        data.write(struct.pack(">H", 6))
 
438
        data.write(struct.pack(">fH", material.ref, 0))
 
439
 
 
440
        data.write("LUMI")
 
441
        data.write(struct.pack(">H", 6))
 
442
        data.write(struct.pack(">fH", material.emit, 0))
 
443
 
 
444
        data.write("SPEC")
 
445
        data.write(struct.pack(">H", 6))
 
446
        data.write(struct.pack(">fH", material.spec, 0))
 
447
 
 
448
        data.write("GLOS")
 
449
        data.write(struct.pack(">H", 6))
 
450
        gloss = material.hard / (255/2.0)
 
451
        gloss = round(gloss, 1)
 
452
        data.write(struct.pack(">fH", gloss, 0))
 
453
 
 
454
        data.write("CMNT")  # material comment
 
455
        comment = material_name + ": Exported from Blender\256 " + meshtools.blender_version_str
 
456
        comment = generate_nstring(comment)
 
457
        data.write(struct.pack(">H", len(comment)))
 
458
        data.write(comment)
 
459
        return data.getvalue()
 
460
 
 
461
# =============================================
 
462
# === Generate Default Surface (SURF Chunk) ===
 
463
# =============================================
 
464
def generate_default_surf():
 
465
        data = cStringIO.StringIO()
 
466
        material_name = "\251 Blender Default"
 
467
        data.write(generate_nstring(material_name))
 
468
        data.write("\0\0")
 
469
 
 
470
        data.write("COLR")
 
471
        data.write(struct.pack(">H", 14))
 
472
        data.write(struct.pack(">fffH", 1, 1, 1, 0))
 
473
 
 
474
        data.write("DIFF")
 
475
        data.write(struct.pack(">H", 6))
 
476
        data.write(struct.pack(">fH", 0.8, 0))
 
477
 
 
478
        data.write("LUMI")
 
479
        data.write(struct.pack(">H", 6))
 
480
        data.write(struct.pack(">fH", 0, 0))
 
481
 
 
482
        data.write("SPEC")
 
483
        data.write(struct.pack(">H", 6))
 
484
        data.write(struct.pack(">fH", 0.5, 0))
 
485
 
 
486
        data.write("GLOS")
 
487
        data.write(struct.pack(">H", 6))
 
488
        gloss = 50 / (255/2.0)
 
489
        gloss = round(gloss, 1)
 
490
        data.write(struct.pack(">fH", gloss, 0))
 
491
 
 
492
        data.write("CMNT")  # material comment
 
493
        comment = material_name + ": Exported from Blender\256 " + meshtools.blender_version_str
 
494
 
 
495
        # vals = map(chr, range(164,255,1))
 
496
        # keys = range(164,255,1)
 
497
        # keys = map(lambda x: `x`, keys)
 
498
        # comment = map(None, keys, vals)
 
499
        # comment = reduce(operator.add, comment)
 
500
        # comment = reduce(operator.add, comment)
 
501
 
 
502
        comment = generate_nstring(comment)
 
503
        data.write(struct.pack(">H", len(comment)))
 
504
        data.write(comment)
 
505
        return data.getvalue()
 
506
 
 
507
# ============================================
 
508
# === Generate Object Comment (TEXT Chunk) ===
 
509
# ============================================
 
510
def generate_text():
 
511
        comment  = "Lightwave Export Script for Blender "
 
512
        comment +=      meshtools.blender_version_str + "\n"
 
513
        comment += "by Anthony D'Agostino\n"
 
514
        comment += "scorpius@netzero.com\n"
 
515
        comment += "http://ourworld.compuserve.com/homepages/scorpius\n"
 
516
        return generate_nstring(comment)
 
517
 
 
518
# ==============================================
 
519
# === Generate Description Line (DESC Chunk) ===
 
520
# ==============================================
 
521
def generate_desc():
 
522
        comment = "Copyright 2002 Scorpius Entertainment"
 
523
        return generate_nstring(comment)
 
524
 
 
525
# ==================================================
 
526
# === Generate Thumbnail Icon Image (ICON Chunk) ===
 
527
# ==================================================
 
528
def generate_icon():
 
529
        data = cStringIO.StringIO()
 
530
        file = open("f:/obj/radiosity/lwo2_icon.tga", "rb") # 60x60 uncompressed TGA
 
531
        file.read(18)
 
532
        icon_data = file.read(3600) # ?
 
533
        file.close()
 
534
        data.write(struct.pack(">HH", 0, 60))
 
535
        data.write(icon_data)
 
536
        #print len(icon_data)
 
537
        return data.getvalue()
 
538
 
 
539
# ===================
 
540
# === Write Chunk ===
 
541
# ===================
 
542
def write_chunk(file, name, data):
 
543
        file.write(name)
 
544
        file.write(struct.pack(">L", len(data)))
 
545
        file.write(data)
 
546
 
 
547
# =============================
 
548
# === Write LWO File Header ===
 
549
# =============================
 
550
def write_header(file, chunks):
 
551
        chunk_sizes = map(len, chunks)
 
552
        chunk_sizes = reduce(operator.add, chunk_sizes)
 
553
        form_size = chunk_sizes + len(chunks)*8 + len("FORM")
 
554
        file.write("FORM")
 
555
        file.write(struct.pack(">L", form_size))
 
556
        file.write("LWO2")
 
557
 
 
558
def fs_callback(filename):
 
559
        if filename.find('.lwo', -4) <= 0: filename += '.lwo'
 
560
        write(filename)
 
561
 
 
562
Blender.Window.FileSelector(fs_callback, "Export LWO")