3d42f4bfc51a17b794b33bff55e13fec8366f9c2
[blender.git] / release / scripts / nendo_import.py
1 #!BPY
2
3 """
4 Name: 'Nendo...'
5 Blender: 232
6 Group: 'Import'
7 Tooltip: 'Import Nendo Object File Format (*.ndo)'
8 """
9
10 # $Id$
11 #
12 # +---------------------------------------------------------+
13 # | Copyright (c) 2001 Anthony D'Agostino                   |
14 # | http://www.redrival.com/scorpius                        |
15 # | scorpius@netzero.com                                    |
16 # | September 25, 2001                                      |
17 # | Released under the Blender Artistic Licence (BAL)       |
18 # | Import Export Suite v0.5                                |
19 # +---------------------------------------------------------+
20 # | Read and write Nendo File Format (*.nendo)              |
21 # +---------------------------------------------------------+
22
23 import Blender, mod_meshtools
24 import struct, time, sys, os
25
26 # =============================
27 # === Read Nendo 1.x Format ===
28 # =============================
29 def read(filename):
30         start = time.clock()
31         file = open(filename, "rb")
32         version, numobjs = read_header(file)
33
34         for object in range(numobjs):
35                 good, = struct.unpack(">B",  file.read(1))
36                 if not good: continue   # an empty object
37                 objname = read_object_flags(file)
38                 edge_table = read_edge_table(file, version)
39                 face_table = read_face_table(file)
40                 vert_table = read_vert_table(file)
41                 uv = read_uv(file)
42                 verts = make_verts(vert_table)
43                 faces = make_faces(edge_table)
44                 mod_meshtools.create_mesh(verts, faces, objname)
45
46         Blender.Window.DrawProgressBar(1.0, "Done")    # clear progressbar
47         file.close()
48         end = time.clock()
49         seconds = " in %.2f %s" % (end-start, "seconds")
50         message = "Successfully imported " + os.path.basename(filename) + seconds
51         message += " (%s)" % version.title()
52         mod_meshtools.print_boxed(message)
53
54 # =======================
55 # === Read The Header ===
56 # =======================
57 def read_header(file):
58         version, = struct.unpack(">9s", file.read(9))
59         misc,    = struct.unpack(">H",  file.read(2))
60         numobjs, = struct.unpack(">B",  file.read(1))
61         if (version != "nendo 1.0") and (version != "nendo 1.1"):
62                 mod_meshtools.print_boxed(file.name, "is not a Nendo file")
63                 return
64         return version, numobjs
65
66 # =========================
67 # === Read Object Flags ===
68 # =========================
69 def read_object_flags(file):
70         namelen, = struct.unpack(">H",  file.read(2))
71         objname  = file.read(namelen)
72         visible, = struct.unpack(">B", file.read(1))
73         sensity, = struct.unpack(">B", file.read(1))
74         other,   = struct.unpack(">H", file.read(2))    # or 2 more flags?
75         misc     = struct.unpack(">18f", file.read(72))
76         return objname
77
78 # =======================
79 # === Read Edge Table ===
80 # =======================
81 def read_edge_table(file, version):
82         numedges, = struct.unpack(">H", file.read(2))
83         edge_table = {}
84         for i in range(numedges):
85                 if not i%100 and mod_meshtools.show_progress:
86                         Blender.Window.DrawProgressBar(float(i)/numedges, "Reading Edge Table")
87                 edge = struct.unpack(">8H", file.read(16))
88                 if version == "nendo 1.1":
89                         hard, = struct.unpack(">B",  file.read(1))  # edge hardness flag
90                 color = struct.unpack(">8B", file.read(8))
91                 edge_table[i] = edge
92         return edge_table
93
94 # =======================
95 # === Read Face Table ===
96 # =======================
97 def read_face_table(file):
98         numfaces, = struct.unpack(">H", file.read(2))
99         face_table = {}
100         for i in range(numfaces):
101                 if not i%100 and mod_meshtools.show_progress:
102                         Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Face Table")
103                 face_table[i] = struct.unpack(">H", file.read(2))[0]
104         return face_table
105
106 # =======================
107 # === Read Vert Table ===
108 # =======================
109 def read_vert_table(file):
110         numverts, = struct.unpack(">H", file.read(2))
111         vert_table = []
112         for i in range(numverts):
113                 if not i%100 and mod_meshtools.show_progress:
114                         Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Vertex Table")
115                 w, x, y, z = struct.unpack(">H3f", file.read(14))
116                 vert_table.append((w,(x, y, z)))
117         return vert_table
118
119 # ====================
120 # === Read Texture ===
121 # ====================
122 def read_uv(file):
123         numuvs, = struct.unpack(">H", file.read(2))
124         uvlist  = struct.unpack(">"+`numuvs`+"H", file.read(numuvs*2))
125         numfacesT, = struct.unpack(">H", file.read(2))
126         facesT = struct.unpack(">"+`numfacesT`+"H", file.read(numfacesT*2))
127         textureflag, = struct.unpack(">B", file.read(1))
128         if textureflag:
129                 xres, yres = struct.unpack(">2H", file.read(4))
130                 print "%ix%i" % (xres, yres)
131                 pixel = 0
132                 while pixel < (xres*yres):
133                         if not pixel%100 and mod_meshtools.show_progress:
134                                 Blender.Window.DrawProgressBar(float(pixel)/xres*yres, "Reading Texture")
135                         count, = struct.unpack(">B", file.read(1))
136                         rgb = file.read(3)
137                         pixel = pixel+count
138         return numuvs
139
140 # ==================
141 # === Make Verts ===
142 # ==================
143 def make_verts(vert_table):
144         matrix = [ # Rotate 90*x and Scale 0.1
145         [0.1, 0.0, 0.0, 0.0],
146         [0.0, 0.0, 0.1, 0.0],
147         [0.0,-0.1, 0.0, 0.0],
148         [0.0, 0.0, 0.0, 1.0]]
149         verts = []
150         for i in range(len(vert_table)):
151                 vertex = vert_table[i][1]
152                 vertex = mod_meshtools.apply_transform(vertex, matrix)
153                 verts.append(vertex)
154         return verts
155
156 # =======================
157 # === Make Face Table ===
158 # =======================
159 def make_face_table(edge_table): # For Nendo
160         face_table = {}
161         for i in range(len(edge_table)):
162                 Lf = edge_table[i][2]
163                 Rf = edge_table[i][3]
164                 face_table[Lf] = i
165                 face_table[Rf] = i
166         return face_table
167
168 # =======================
169 # === Make Vert Table ===
170 # =======================
171 def make_vert_table(edge_table): # For Nendo
172         vert_table = {}
173         for i in range(len(edge_table)):
174                 Sv = edge_table[i][1]
175                 Ev = edge_table[i][0]
176                 vert_table[Sv] = i
177                 vert_table[Ev] = i
178         return vert_table
179
180 # ==================
181 # === Make Faces ===
182 # ==================
183 def make_faces(edge_table): # For Nendo
184         face_table = make_face_table(edge_table)
185         faces=[]
186         #for i in range(len(face_table)):
187         for i in face_table.keys(): # avoids a whole class of errors
188                 face_verts = []
189                 current_edge = face_table[i]
190                 while(1):
191                         if i == edge_table[current_edge][3]:
192                                 next_edge = edge_table[current_edge][5] # Right successor edge
193                                 next_vert = edge_table[current_edge][1]
194                         else:
195                                 next_edge = edge_table[current_edge][4] # Left successor edge
196                                 next_vert = edge_table[current_edge][0]
197                         face_verts.append(next_vert)
198                         current_edge = next_edge
199                         if current_edge == face_table[i]: break
200                 face_verts.reverse() # Flip all face normals
201                 faces.append(face_verts)
202         return faces
203
204 def fs_callback(filename):
205         read(filename)
206
207 Blender.Window.FileSelector(fs_callback, "Nendo Import")