]> git.tdb.fi Git - libs/gl.git/blob - blender/io_mspgl/export_scene.py
Refactor scene data preparation to its own class
[libs/gl.git] / blender / io_mspgl / export_scene.py
1 import math
2 import os
3
4 class SceneExporter:
5         def __init__(self):
6                 self.selected_only = False
7                 self.visible_only = True
8                 self.collection = True
9                 self.skip_existing = True
10                 self.show_progress = True
11
12         def export_to_file(self, context, out_fn):
13                 from .scene import create_scene_from_current
14                 scene = create_scene_from_current(context, selected_only=self.selected_only, visible_only=self.visible_only)
15
16                 path, base = os.path.split(out_fn)
17                 base, ext = os.path.splitext(base)
18
19                 export_names = {}
20                 used_names = set()
21                 for p in scene.prototypes:
22                         clones = [i for i in scene.instances if i.prototype==p.name]
23
24                         prefix = p.name
25                         for c in clones:
26                                 while not c.name.startswith(prefix):
27                                         pos = max(prefix.rfind(' '), prefix.rfind('.'))
28                                         if pos<0:
29                                                 break;
30                                         prefix = prefix[:pos]
31
32                         if prefix:
33                                 export_names[p.name+".object"] = prefix.strip(" .")
34                         else:
35                                 used_names.add(p.name)
36
37                 for n, e in export_names.items():
38                         if e in used_names:
39                                 number = 1
40                                 while "{}_{}".format(e, number) in used_names:
41                                         number += 1
42                                 e += "_{}".format(number)
43                         export_names[n] = e+".object"
44                         used_names.add(e)
45
46                 from .util import Progress
47                 progress = Progress(self.show_progress and context)
48
49                 from .export import DataExporter
50                 data_exporter = DataExporter()
51
52                 resources = {}
53                 data_exporter.export_resources(context, scene.prototypes, resources, None, progress)
54                 for n, r in resources.items():
55                         if r.name in export_names:
56                                 r.name = export_names[r.name]
57
58                 scene_res = self.export_scene(scene, resources, progress)
59                 refs = scene_res.collect_references()
60
61                 if self.collection:
62                         existing = None
63                         if self.skip_existing:
64                                 existing = lambda r: not os.path.exists(os.path.join(path, r.name))
65                         scene_res.write_collection(out_fn, filter=existing)
66                 else:
67                         scene_res.write_to_file(out_fn)
68                         for r in refs:
69                                 r.write_to_file(os.path.join(path, r.name))
70
71         def export_scene(self, scene, resources, progress):
72                 from .datafile import Resource, Statement, Token
73                 scene_res = Resource(scene.name+".scene", "scene")
74
75                 scene_res.statements.append(Statement("type", Token(scene.scene_type.lower())))
76
77                 for i in scene.instances:
78                         obj_res = resources[i.prototype+".object"]
79                         st = scene_res.create_reference_statement("object", obj_res, i.name)
80
81                         ss = Statement("transform")
82
83                         loc = i.matrix_world.to_translation()
84                         ss.sub.append(Statement("position", *tuple(loc)))
85
86                         quat = i.matrix_world.to_quaternion()
87                         if i.rotation_mode in ('XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'):
88                                 angles = [a*180/math.pi for a in quat.to_euler()]
89                                 ss.sub.append(Statement("euler", *angles));
90                         else:
91                                 ss.sub.append(Statement("rotation", quat.angle*180/math.pi, *tuple(quat.axis)))
92
93                         scale = i.matrix_world.to_scale()
94                         ss.sub.append(Statement("scale", *tuple(scale)))
95
96                         st.sub.append(ss)
97                         scene_res.statements.append(st)
98
99                 progress.set_progress(1.0)
100
101                 return scene_res