583e57191e6cb688b12f4d5cefd5b5fbd9db38d8
[blender.git] / release / scripts / lightwave_import.py
1 #!BPY
2
3 """
4 Name: 'LightWave...'
5 Blender: 232
6 Group: 'Import'
7 Tooltip: 'Import LightWave Object File Format (*.lwo)'
8 """
9
10 # $Id$
11 #
12 # +---------------------------------------------------------+
13 # | Copyright (c) 2002 Anthony D'Agostino                   |
14 # | http://www.redrival.com/scorpius                        |
15 # | scorpius@netzero.com                                    |
16 # | April 21, 2002                                          |
17 # | Released under the Blender Artistic Licence (BAL)       |
18 # | Import Export Suite v0.5                                |
19 # +---------------------------------------------------------+
20 # | Read and write LightWave Object File Format (*.lwo)     |
21 # +---------------------------------------------------------+
22
23 import Blender, mod_meshtools
24 import struct, chunk, os, cStringIO, time, operator
25
26 # =============================
27 # === Read LightWave Format ===
28 # =============================
29 def read(filename):
30         start = time.clock()
31         file = open(filename, "rb")
32
33         # === LWO header ===
34         form_id, form_size, form_type = struct.unpack(">4s1L4s",  file.read(12))
35         if (form_type != "LWOB") and (form_type != "LWO2"):
36                 print "Can't read a file with the form_type:", form_type
37                 return
38
39         objname = os.path.splitext(os.path.basename(filename))[0]
40
41         while 1:
42                 try:
43                         lwochunk = chunk.Chunk(file)
44                 except EOFError:
45                         break
46                 if lwochunk.chunkname == "LAYR":
47                         objname = read_layr(lwochunk)
48                 elif lwochunk.chunkname == "PNTS":                         # Verts
49                         verts = read_verts(lwochunk)
50                 elif lwochunk.chunkname == "POLS" and form_type == "LWO2": # Faces v6.0
51                         faces = read_faces_6(lwochunk)
52                         mod_meshtools.create_mesh(verts, faces, objname)
53                 elif lwochunk.chunkname == "POLS" and form_type == "LWOB": # Faces v5.5
54                         faces = read_faces_5(lwochunk)
55                         mod_meshtools.create_mesh(verts, faces, objname)
56                 else:                                                                                                      # Misc Chunks
57                         lwochunk.skip()
58
59         Blender.Window.DrawProgressBar(1.0, "")    # clear progressbar
60         file.close()
61         end = time.clock()
62         seconds = " in %.2f %s" % (end-start, "seconds")
63         if form_type == "LWO2": fmt = " (v6.0 Format)"
64         if form_type == "LWOB": fmt = " (v5.5 Format)"
65         message = "Successfully imported " + os.path.basename(filename) + fmt + seconds
66         mod_meshtools.print_boxed(message)
67
68 # ==================
69 # === Read Verts ===
70 # ==================
71 def read_verts(lwochunk):
72         data = cStringIO.StringIO(lwochunk.read())
73         numverts = lwochunk.chunksize/12
74         #$verts = []
75         verts = [None] * numverts
76         for i in range(numverts):
77                 if not i%100 and mod_meshtools.show_progress:
78                         Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
79                 x, y, z = struct.unpack(">fff", data.read(12))
80                 #$verts.append((x, z, y))
81                 verts[i] = (x, z, y)
82         return verts
83
84 # =================
85 # === Read Name ===
86 # =================
87 def read_name(file):
88         name = ""
89         while 1:
90                 char = file.read(1)
91                 if char == "\0": break
92                 else: name += char
93         return name
94
95 # ==================
96 # === Read Layer ===
97 # ==================
98 def read_layr(lwochunk):
99         data = cStringIO.StringIO(lwochunk.read())
100         idx, flags = struct.unpack(">hh", data.read(4))
101         pivot = struct.unpack(">fff", data.read(12))
102         layer_name = read_name(data)
103         if not layer_name: layer_name = "No Name"
104         return layer_name
105
106 # ======================
107 # === Read Faces 5.5 ===
108 # ======================
109 def read_faces_5(lwochunk):
110         data = cStringIO.StringIO(lwochunk.read())
111         faces = []
112         i = 0
113         while i < lwochunk.chunksize:
114                 if not i%100 and mod_meshtools.show_progress:
115                    Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
116                 facev = []
117                 numfaceverts, = struct.unpack(">H", data.read(2))
118                 for j in range(numfaceverts):
119                         index, = struct.unpack(">H", data.read(2))
120                         facev.append(index)
121                 facev.reverse()
122                 faces.append(facev)
123                 surfaceindex, = struct.unpack(">H", data.read(2))
124                 if surfaceindex < 0:
125                         print "detail polygons follow, error."
126                         return
127                 i += (4+numfaceverts*2)
128         return faces
129
130 # ==================================
131 # === Read Variable-Length Index ===
132 # ==================================
133 def read_vx(data):
134         byte1, = struct.unpack(">B", data.read(1))
135         if byte1 != 0xFF:       # 2-byte index
136                 byte2, = struct.unpack(">B", data.read(1))
137                 index = byte1*256 + byte2
138                 index_size = 2
139         else:                           # 4-byte index
140                 byte2, byte3, byte4 = struct.unpack(">3B", data.read(3))
141                 index = byte2*65536 + byte3*256 + byte4
142                 index_size = 4
143         return index, index_size
144
145 # ======================
146 # === Read Faces 6.0 ===
147 # ======================
148 def read_faces_6(lwochunk):
149         data = cStringIO.StringIO(lwochunk.read())
150         faces = []
151         polygon_type = data.read(4)
152         if polygon_type != "FACE":
153                 print "No Faces Were Found. Polygon Type:", polygon_type
154                 return ""
155         i = 0
156         while(i < lwochunk.chunksize-4):
157                 if not i%100 and mod_meshtools.show_progress:
158                    Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
159                 facev = []
160                 numfaceverts, = struct.unpack(">H", data.read(2))
161                 i += 2
162
163                 for j in range(numfaceverts):
164                         index, index_size = read_vx(data)
165                         i += index_size
166                         facev.append(index)
167                 facev.reverse()
168                 faces.append(facev)
169         return faces
170
171 def fs_callback(filename):
172         read(filename)
173
174 Blender.Window.FileSelector(fs_callback, "LWO Import")