19 |
# |
# |
20 |
# $Id$ |
# $Id$ |
21 |
|
|
22 |
|
# TODO |
23 |
|
# * Convert writer to use xml.sax.writer.PrettyPrinter |
24 |
|
# * Add save feedback |
25 |
|
# * Add more GUI controls |
26 |
|
|
27 |
__author__ = "Chong Kai Xiong" |
__author__ = "Chong Kai Xiong" |
28 |
__version__ = "0.1" |
__version__ = "0.1" |
29 |
__email__ = "descender@phreaker.net" |
__email__ = "descender@phreaker.net" |
30 |
__url__ = "http://www.nongnu.org/usata" |
__url__ = "http://www.nongnu.org/usata" |
31 |
|
|
32 |
import Blender |
import Blender |
33 |
|
|
34 |
from Blender.BGL import * |
from Blender.BGL import * |
35 |
|
from xml.sax.xmlreader import AttributesImpl |
36 |
|
from xml.sax.saxutils import XMLGenerator |
37 |
|
|
38 |
|
|
39 |
# event numbers |
# event numbers |
40 |
|
|
41 |
evNone = 0 |
EV_NONE = 0 |
42 |
evSave = 100 |
EV_SAVE = 100 |
43 |
evQuit = 101 |
EV_QUIT = 101 |
44 |
|
|
45 |
OutputName = Blender.Draw.Create("untitled.xml") |
output_name = Blender.Draw.Create("untitled.xml") |
46 |
|
output_charset = 'utf-8' |
47 |
|
|
48 |
|
fp_format = '%.8f' |
49 |
|
|
50 |
class XmlExporter: |
class XmlExporter: |
|
|
|
|
def __init__(self, FileName): |
|
|
self.FileName = FileName |
|
|
self.File = None |
|
51 |
|
|
52 |
|
def __init__(self, filename): |
53 |
def WriteVertexList(self, VertexList): |
self.filename = filename |
54 |
|
self.file = None |
55 |
# print vertex list |
self.writer = None |
56 |
|
|
57 |
self.File.write("VertexList {\n") |
def write_vertex(self, vertex): |
58 |
|
self.writer.startElement("vertex", {}) |
59 |
|
|
60 |
|
self.writer.startElement("position", |
61 |
|
{"x": fp_format % vertex.co[0], |
62 |
|
"y": fp_format % vertex.co[1], |
63 |
|
"z": fp_format % vertex.co[2]} |
64 |
|
) |
65 |
|
self.writer.endElement("position") |
66 |
|
|
67 |
|
self.writer.startElement("texture", |
68 |
|
{"u": fp_format % vertex.uvco[0], |
69 |
|
"v": fp_format % vertex.uvco[1]} |
70 |
|
) |
71 |
|
self.writer.endElement("texture") |
72 |
|
|
73 |
|
self.writer.startElement("normal", |
74 |
|
{"x": fp_format % vertex.no[0], |
75 |
|
"y": fp_format % vertex.no[1], |
76 |
|
"z": fp_format % vertex.no[2]} |
77 |
|
) |
78 |
|
self.writer.endElement("normal") |
79 |
|
|
80 |
|
self.writer.endElement("vertex") |
81 |
|
|
82 |
|
def write_vertex_list(self, vertices): |
83 |
|
self.writer.startElement("vertices", {}) |
84 |
|
|
85 |
|
for vertex in vertices: |
86 |
|
self.write_vertex(vertex) |
87 |
|
|
88 |
|
self.writer.endElement("vertices") |
89 |
|
|
90 |
|
def write_vertex_index_list(self, vertices): |
91 |
|
self.writer.startElement("vertex_indices", {}) |
92 |
|
|
93 |
|
for vertex in vertices: |
94 |
|
self.writer.startElement("index", {}) |
95 |
|
self.writer.characters("%d" % vertex.index) |
96 |
|
self.writer.endElement("index") |
97 |
|
|
98 |
|
self.writer.endElement("vertex_indices") |
99 |
|
|
100 |
|
def write_face(self, face): |
101 |
|
self.writer.startElement("face", {}) |
102 |
|
|
103 |
for Vertex in VertexList: |
self.write_vertex_index_list(face.v) |
|
self.File.write(" Vertex {\n") |
|
|
self.File.write(" Position [ %.8f %.8f %.8f ]\n" % |
|
|
(Vertex.co[0], Vertex.co[1], Vertex.co[2])) |
|
|
self.File.write(" Texture [ %.8f %.8f ]\n" % |
|
|
(Vertex.uvco[0], Vertex.uvco[1])) |
|
|
self.File.write(" Normal [ %.8f %.8f %.8f ]\n" % |
|
|
(Vertex.no[0], Vertex.no[1], Vertex.no[2])) |
|
|
self.File.write(" } # Vertex\n") |
|
104 |
|
|
105 |
self.File.write(" } # vertex list\n") |
self.writer.startElement("material", {}) |
106 |
|
self.writer.characters("%d" % face.mat) |
107 |
|
self.writer.endElement("material") |
108 |
|
|
109 |
|
self.writer.endElement("face") |
110 |
|
|
111 |
def WriteVertexIndexList(self, VertexList): |
def write_face_list(self, faces): |
112 |
|
|
113 |
self.File.write("VertexList [ ") |
self.writer.startElement("faces", {}) |
114 |
|
|
115 |
for i in range(len(VertexList)-1): |
for face in faces: |
116 |
self.File.write("%d, " % VertexList[i].index) |
self.write_face(face) |
117 |
|
|
118 |
self.File.write("%d ]\n" % VertexList[-1].index) |
self.writer.endElement("faces") |
119 |
|
|
120 |
|
def write_camera(self, camera): |
121 |
|
|
122 |
def WriteFaceList(self, FaceList): |
camera_obj = Blender.Object.Get(camera.getName()) |
|
|
|
|
# print face list |
|
123 |
|
|
124 |
self.File.write("FaceList {\n") |
self.writer.startElement("camera", {}) |
125 |
|
|
126 |
for Face in FaceList: |
self.writer.startElement("name", {}) |
127 |
self.File.write(" Face {\n") |
self.writer.characters(camera.getName()); |
128 |
|
self.writer.endElement("name") |
|
self.WriteVertexIndexList(Face.v) |
|
|
|
|
|
self.File.write(" Material %d\n" % Face.mat) |
|
|
|
|
|
self.File.write(" } # Face\n") |
|
129 |
|
|
130 |
self.File.write("} # Face List\n") |
self.writer.startElement("position", |
131 |
|
{"x": fp_format % camera_obj.loc[0], |
132 |
|
"y": fp_format % camera_obj.loc[1], |
133 |
|
"z": fp_format % camera_obj.loc[2]} |
134 |
|
) |
135 |
|
self.writer.endElement("position") |
136 |
|
|
137 |
|
self.writer.startElement("lens", {}) |
138 |
def WriteCamera(self, Camera): |
self.writer.characters(fp_format % camera.getLens()) |
139 |
|
self.writer.endElement("lens") |
140 |
|
|
141 |
CameraObj = Blender.Object.Get(Camera.getName()) |
self.writer.startElement("near", {}) |
142 |
|
self.writer.characters(fp_format % camera.getClipStart()) |
143 |
self.File.write("Camera {\n") |
self.writer.endElement("near") |
144 |
|
|
145 |
self.File.write(" Name '%s'\n" % Camera.getName()) |
self.writer.startElement("far", {}) |
146 |
|
self.writer.characters(fp_format % camera.getClipEnd()) |
147 |
|
self.writer.endElement("far") |
148 |
|
|
149 |
self.File.write(" Position [%.8f, %.8f, %.8f]\n" % |
self.writer.endElement("camera") |
|
(CameraObj.loc[0], |
|
|
CameraObj.loc[1], |
|
|
CameraObj.loc[2])) |
|
150 |
|
|
151 |
self.File.write(" Lens %.8f\n" % Camera.getLens()) |
def write_mesh(self, mesh): |
|
self.File.write(" Near %.8f\n" % Camera.getClipStart()) |
|
|
self.File.write(" Far %.8f\n" % Camera.getClipEnd()) |
|
|
|
|
|
self.File.write("} # Camera\n") |
|
152 |
|
|
153 |
|
self.write_vertex_list(mesh.verts) |
154 |
|
self.write_face_list(mesh.faces) |
155 |
|
|
|
def WriteMesh(self, Mesh): |
|
156 |
|
|
157 |
self.WriteVertexList(Mesh.verts) |
def write_object(self, object): |
158 |
self.WriteFaceList(Mesh.faces) |
self.writer.startElement("object", {}) |
159 |
|
|
160 |
|
self.writer.startElement("name", {}) |
161 |
def WriteObject(self, Object): |
self.writer.characters(object.name) |
162 |
|
self.writer.endElement("name") |
|
self.File.write("Object {\n") |
|
|
self.File.write(" Name '%s'\n" % Object.name) |
|
|
self.WriteMesh(Blender.NMesh.GetRaw(Object.name)) |
|
|
self.File.write("} # Object\n") |
|
163 |
|
|
164 |
|
self.write_mesh(Blender.NMesh.GetRaw(object.name)) |
|
def Write(self): |
|
|
print "Writing...", self.FileName |
|
165 |
|
|
166 |
self.File = open(self.FileName, "w") |
self.writer.endElement("object") |
167 |
|
|
168 |
self.File.write("Scene {\n") |
def write_scene(self): |
169 |
|
self.writer.startElement("scene", {}) |
|
# write all cameras |
|
170 |
|
|
171 |
print "Writing cameras..." |
# write all cameras |
172 |
|
|
173 |
Cameras = Blender.Camera.Get() |
print "Writing cameras..." |
174 |
|
|
175 |
print "..." |
cameras = Blender.Camera.Get() |
|
|
|
|
for Camera in Cameras: |
|
|
self.WriteCamera(Camera) |
|
176 |
|
|
177 |
# write mesh objects |
print "..." |
178 |
|
|
179 |
print "Writing objects..." |
for camera in cameras: |
180 |
|
self.write_camera(camera) |
181 |
|
|
182 |
Objects = Blender.Object.Get() |
# write mesh objects |
183 |
|
|
184 |
for Object in Objects: |
print "Writing objects..." |
|
# check if object is a mesh |
|
185 |
|
|
186 |
Mesh = Blender.NMesh.GetRaw(Object.name) |
objects = Blender.Object.Get() |
|
if (Mesh == None): |
|
|
continue |
|
187 |
|
|
188 |
self.WriteObject(Object) |
for object in objects: |
189 |
|
# check if object is a mesh |
190 |
|
|
191 |
|
mesh = Blender.NMesh.GetRaw(object.name) |
192 |
|
if (mesh == None): |
193 |
|
continue |
194 |
|
|
195 |
|
self.write_object(object) |
196 |
|
|
197 |
|
self.writer.endElement("scene") |
198 |
|
|
199 |
|
def write(self): |
200 |
|
print "Writing...", self.filename |
201 |
|
|
202 |
|
self.file = open(self.filename, "wt") |
203 |
|
self.writer = XMLGenerator(self.file, output_charset) |
204 |
|
|
205 |
|
self.writer.startDocument() |
206 |
|
self.write_scene() |
207 |
|
self.writer.endDocument() |
208 |
|
|
209 |
|
self.file.close() |
210 |
|
|
|
self.File.write("} # Scene\n") |
|
211 |
|
|
|
self.File.close() |
|
|
|
|
|
|
|
212 |
|
|
213 |
def Draw(): |
def Draw(): |
214 |
global OutputName |
global output_name |
215 |
|
|
216 |
# clear window |
# clear window |
217 |
glClearColor(0.6, 0.6, 0.65, 1.0) |
glClearColor(0.6, 0.6, 0.65, 1.0) |
218 |
glClear(GL_COLOR_BUFFER_BIT) |
glClear(GL_COLOR_BUFFER_BIT) |
223 |
Blender.Draw.Text("Blender XML file exporter") |
Blender.Draw.Text("Blender XML file exporter") |
224 |
|
|
225 |
# filename entry button |
# filename entry button |
226 |
OutputName = Blender.Draw.String("File: ", evNone, |
output_name = Blender.Draw.String("File: ", EV_NONE, |
227 |
50, 400, 400, 20, |
50, 400, 400, 20, |
228 |
OutputName.val, 255, |
output_name.val, 255, |
229 |
"filename") |
"filename") |
230 |
|
|
231 |
# save button |
# save button |
232 |
Blender.Draw.Button("Save", evSave, 50, 350, 50, 20, |
Blender.Draw.Button("Save", EV_SAVE, 50, 350, 50, 20, |
233 |
"save file") |
"save file") |
234 |
|
|
235 |
# quit button |
# quit button |
236 |
Blender.Draw.Button("Quit", evQuit, 110, 350, 50, 20, |
Blender.Draw.Button("Quit", EV_QUIT, 110, 350, 50, 20, |
237 |
"exit script") |
"exit script") |
238 |
|
|
239 |
|
|
240 |
def HandleWidgetEvent(Event): |
def handle_widget_event(event): |
241 |
global evSave, evQuit |
if event == EV_SAVE: |
242 |
|
export_scene() |
243 |
if (Event == evSave): |
elif event == EV_QUIT: |
244 |
ExportScene() |
Blender.Draw.Exit() |
245 |
elif (Event == evQuit): |
|
246 |
Blender.Draw.Exit() |
|
247 |
|
def export_scene(): |
|
|
|
|
def ExportScene(): |
|
|
global OutputName |
|
|
|
|
248 |
print "Exporting scene..." |
print "Exporting scene..." |
249 |
Exporter = XmlExporter(OutputName.val) |
exporter = XmlExporter(output_name.val) |
250 |
Exporter.Write() |
exporter.write() |
251 |
|
|
252 |
def main(): |
def main(): |
253 |
Blender.Draw.Register(Draw, None, HandleWidgetEvent) |
Blender.Draw.Register(Draw, None, handle_widget_event) |
254 |
|
|
255 |
if __name__ == "__main__": |
if __name__ == "__main__": |
256 |
main() |
main() |