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