362ecdc0d60e6e32d58adcbdabbba68f3c01533f
[blender.git] / release / scripts / videoscape_export.py
1 #!BPY
2
3 """
4 Name: 'VideoScape with Vertex Colors (.obj)...'
5 Blender: 232
6 Group: 'Export'
7 Tooltip: 'Export selected mesh to VideoScape File Format (.obj)'
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 (including vertex colors) to VideoScape File Format.
17
18 Usage:
19
20 Select meshes to be exported and run this script from "File->Export" menu.
21 """
22
23
24 # $Id$
25 #
26 # +---------------------------------------------------------+
27 # | Copyright (c) 2001 Anthony D'Agostino                   |
28 # | http://www.redrival.com/scorpius                        |
29 # | scorpius@netzero.com                                    |
30 # | June 5, 2001                                            |
31 # | Released under the Blender Artistic Licence (BAL)       |
32 # | Import Export Suite v0.5                                |
33 # +---------------------------------------------------------+
34 # | Write Videoscape File Format (*.obj NOT WAVEFRONT OBJ)  |
35 # | Includes a *fast* algorithm for averaging vertex colors |
36 # | Blender's a|w doesn't export proper vertex colors       |
37 # +---------------------------------------------------------+
38
39 import Blender, mod_meshtools
40 #import time
41
42 # =====================================
43 # ====== Write VideoScape Format ======
44 # =====================================
45 def write(filename):
46         #start = time.clock()
47         file = open(filename, "wb")
48
49         objects = Blender.Object.GetSelected()
50         objname = objects[0].name
51         meshname = objects[0].data.name
52         mesh = Blender.NMesh.GetRaw(meshname)
53         obj = Blender.Object.Get(objname)
54
55         if not mod_meshtools.has_vertex_colors(mesh):
56                 message = "Please assign vertex colors before exporting.\n"
57                 message += objname + " object was not saved."
58                 mod_meshtools.print_boxed(message)
59                 return
60
61         vcols = average_vertexcolors(mesh)
62
63         # === Write Videoscape Header ===
64         file.write("GOUR\n")
65         file.write("%d\n" % len(mesh.verts))
66
67         # === Write Vertex List & Vertex Colors ===
68         for i in range(len(mesh.verts)):
69                 if not i%100 and mod_meshtools.show_progress:
70                         Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
71                 file.write("% f % f % f 0x" % tuple(mesh.verts[i].co))
72                 for j in range(len(vcols[i])):
73                         file.write("%02X" % vcols[i][j])
74                 file.write("\n")
75
76         # === Write Face List ===
77         for i in range(len(mesh.faces)):
78                 if not i%100 and mod_meshtools.show_progress:
79                         Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
80                 file.write("%d " % len(mesh.faces[i].v)) # numfaceverts
81                 for j in range(len(mesh.faces[i].v)):
82                         file.write("%d " % mesh.faces[i].v[j].index)
83                 file.write("\n")
84
85         Blender.Window.DrawProgressBar(1.0, '')    # clear progressbar
86         file.close()
87         #end = time.clock()
88         #seconds = " in %.2f %s" % (end-start, "seconds")
89         message = "Successfully exported " + Blender.sys.basename(filename)# + seconds
90         mod_meshtools.print_boxed(message)
91
92 # ===========================================
93 # === Vector Operations for Vertex Colors ===
94 # ===========================================
95 vcolor_add = lambda u, v: [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]]
96 vcolor_div = lambda u, s: [u[0]/s, u[1]/s, u[2]/s, u[3]/s]
97
98 # ========================================
99 # === Average All Vertex Colors (Fast) ===
100 # ========================================
101 def average_vertexcolors(mesh, debug=0):
102         vertexcolors = {}
103         for i in range(len(mesh.faces)):        # get all vcolors that share this vertex
104                 if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors")
105                 for j in range(len(mesh.faces[i].v)):
106                         index = mesh.faces[i].v[j].index
107                         color = mesh.faces[i].col[j]
108                         r,g,b,a = color.r, color.g, color.b, color.a
109                         vertexcolors.setdefault(index, []).append([r,g,b,a])
110         if debug: print 'before'; vcprint(vertexcolors)
111
112         for i in range(len(vertexcolors)):      # average them
113                 if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
114                 vcolor = [0,0,0,0]      # rgba
115                 for j in range(len(vertexcolors[i])):
116                         vcolor = vcolor_add(vcolor, vertexcolors[i][j])
117                 shared = len(vertexcolors[i])
118                 vertexcolors[i] = vcolor_div(vcolor, shared)
119         if debug: print 'after'; vcprint(vertexcolors)
120         return vertexcolors
121
122 # ========================================
123 # === Average all Vertex Colors Slow 1 ===
124 # ========================================
125 def average_vertexcolors_slow_1(mesh, debug=0):
126         vertexcolors = []
127         i = 0
128         for vertex in mesh.verts:
129                 if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
130                 i += 1
131                 vcolor = [0,0,0,0]      # rgba
132                 shared = 0
133                 for face in mesh.faces:
134                         if vertex in face.v:
135                                 index = face.v.index(vertex)
136                                 color = face.col[index]
137                                 r,g,b,a = color.r, color.g, color.b, color.a
138                                 vcolor = vcolor_add(vcolor, [r,g,b,a])
139                                 shared += 1
140                 if not shared: print "Error, vertex %d is not shared." % i; shared += 1
141                 vertexcolors.append(vcolor_div(vcolor, shared))
142         if debug: print 'after'; vcprint(vertexcolors)
143         return vertexcolors
144
145 # ========================================
146 # === Average all Vertex Colors Slow 2 ===
147 # ========================================
148 def average_vertexcolors_slow_2(mesh, debug=0):
149         vertexcolors = []
150         for i in range(len(mesh.verts)):
151                 if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
152                 vcolor = [0,0,0,0]      # rgba
153                 shared = 0
154                 for j in range(len(mesh.faces)):
155                         if mesh.verts[i] in mesh.faces[j].v:
156                                 index = mesh.faces[j].v.index(mesh.verts[i])
157                                 color = mesh.faces[j].col[index]
158                                 r,g,b,a = color.r, color.g, color.b, color.a
159                                 vcolor = vcolor_add(vcolor, [r,g,b,a])
160                                 shared += 1
161                 vertexcolors.append(vcolor_div(vcolor, shared))
162         if debug: print 'after'; vcprint(vertexcolors)
163         return vertexcolors
164
165 # ========================================
166 # === Average all Vertex Colors Slow 3 ===
167 # ========================================
168 def average_vertexcolors_slow_3(mesh, debug=0):
169         vertexcolors = []
170         for i in range(len(mesh.verts)):
171                 if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
172                 vcolor = [0,0,0,0]      # rgba
173                 shared = 0
174                 for j in range(len(mesh.faces)):
175                         if len(mesh.faces[j].v) == 4:
176                                 v1,v2,v3,v4 = mesh.faces[j].v
177                                 faceverts = v1.index, v2.index, v3.index, v4.index
178                         else:
179                                 v1,v2,v3 = mesh.faces[j].v
180                                 faceverts = v1.index, v2.index, v3.index
181
182                         if i in faceverts:
183                                 index = mesh.faces[j].v.index(mesh.verts[i])
184                                 color = mesh.faces[j].col[index]
185                                 r,g,b,a = color.r, color.g, color.b, color.a
186                                 vcolor = vcolor_add(vcolor, [r,g,b,a])
187                                 shared += 1
188                 vertexcolors.append(vcolor_div(vcolor, shared))
189         if debug: print 'after'; vcprint(vertexcolors)
190         return vertexcolors
191
192 def fs_callback(filename):
193         if filename.find('.obj', -4) <= 0: filename += '.VIDEOSCAPE.obj'
194         write(filename)
195
196 Blender.Window.FileSelector(fs_callback, "Export VideoScape")
197
198
199 # filename = "VIDEOSCAPE_" + objname + ".obj"
200 # filename = 'nul'
201 # file = open(filename, "wb")
202 # debug = 0
203 # time_functions = 1
204 # time_loop = 0
205 #
206 # if time_functions:
207 #         funcs = [ average_vertexcolors,
208 #                               average_vertexcolors_slow_1,
209 #                               average_vertexcolors_slow_2,
210 #                               average_vertexcolors_slow_3 ]
211 #
212 #         print
213 #         for func in funcs:
214 #                 start = time.clock()
215 #                 vcols = func(mesh, debug)
216 #                 end = time.clock()
217 #                 seconds = "in %.2f %s" % (end-start, "seconds")
218 #                 print func.__name__, "finished in", seconds
219 #
220 # elif time_loop:
221 #         total = 0
222 #         loops = 6
223 #         for i in range(loops):
224 #                 start = time.clock()
225 #                 vcols = average_vertexcolors(mesh, debug)
226 #                 end = time.clock()
227 #                 total += (end-start)
228 #         print "Total: %5.2f Avg: %.2f " % (total, total/loops)
229 # else:
230 #         start = time.clock()
231 #         vcols = average_vertexcolors(mesh, debug)
232
233 # # =====================================
234 # # === Print Vertex Colors for Debug ===
235 # # =====================================
236 # def vcprint(data):
237 #         print type(data)
238 #         for i in range(len(data)):
239 #                 print "%2d" % i,
240 #                 for j in range(len(data[i])):
241 #                         try:
242 #                                 print "[%3d %3d %3d %3d]" % tuple(data[i][j]),  # before
243 #                         except:
244 #                                 print "[%3d]" % data[i][j],                     # after
245 #                 print
246 #         print
247 #