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