Remove workaround for uuid, resolved with the Python3.4x and MSVC2013 move.
[blender-addons.git] / io_export_pc2.py
blob80f74dc3aa7059bdb676f296f917b949a6063cd9
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 bl_info = {
20 "name": "Export Pointcache Format(.pc2)",
21 "author": "Florian Meyer (tstscr)",
22 "version": (1, 0),
23 "blender": (2, 57, 0),
24 "location": "File > Export > Pointcache (.pc2)",
25 "description": "Export mesh Pointcache data (.pc2)",
26 "warning": "",
27 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
28 "Scripts/Import-Export/PC2_Pointcache_export",
29 "tracker_url": "",
30 "category": "Import-Export"}
32 """
33 Related links:
34 https://developer.blender.org/T34456
35 https://developer.blender.org/T25408
37 Usage Notes:
39 in Maya Mel:
40 cacheFile -pc2 1 -pcf "<insert filepath of source>" -f "<insert target filename w/o extension>" -dir "<insert directory path for target>" -format "OneFile";
42 """
44 import bpy
45 from bpy.props import *
46 import mathutils, math, struct
47 from os import remove
48 import time
49 from bpy_extras.io_utils import ExportHelper
51 def getSampling(start, end, sampling):
52 samples = [start + x * sampling
53 for x in range(int((end - start) / sampling) + 1)]
54 return samples
56 def do_export(context, props, filepath):
57 mat_x90 = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
58 ob = context.active_object
59 sc = context.scene
60 start = props.range_start
61 end = props.range_end
62 sampling = float(props.sampling)
63 apply_modifiers = props.apply_modifiers
64 me = ob.to_mesh(sc, apply_modifiers, 'PREVIEW')
65 vertCount = len(me.vertices)
66 sampletimes = getSampling(start, end, sampling)
67 sampleCount = len(sampletimes)
69 # Create the header
70 headerFormat='<12siiffi'
71 headerStr = struct.pack(headerFormat, b'POINTCACHE2\0',
72 1, vertCount, start, sampling, sampleCount)
74 file = open(filepath, "wb")
75 file.write(headerStr)
77 for frame in sampletimes:
78 sc.frame_set(frame)
79 me = ob.to_mesh(sc, apply_modifiers, 'PREVIEW')
81 if len(me.vertices) != vertCount:
82 file.close()
83 try:
84 remove(filepath)
85 except:
86 empty = open(filepath, 'w')
87 empty.write('DUMMIFILE - export failed\n')
88 empty.close()
89 print('Export failed. Vertexcount of Object is not constant')
90 return False
92 if props.world_space:
93 me.transform(ob.matrix_world)
94 if props.rot_x90:
95 me.transform(mat_x90)
97 for v in me.vertices:
98 thisVertex = struct.pack('<fff', float(v.co[0]),
99 float(v.co[1]),
100 float(v.co[2]))
101 file.write(thisVertex)
103 file.flush()
104 file.close()
105 return True
108 ###### EXPORT OPERATOR #######
109 class Export_pc2(bpy.types.Operator, ExportHelper):
110 """Export the active Object as a .pc2 Pointcache file"""
111 bl_idname = "export_shape.pc2"
112 bl_label = "Export Pointcache (.pc2)"
114 filename_ext = ".pc2"
116 rot_x90 = BoolProperty(name="Convert to Y-up",
117 description="Rotate 90 degrees around X to convert to y-up",
118 default=True,
120 world_space = BoolProperty(name="Export into Worldspace",
121 description="Transform the Vertexcoordinates into Worldspace",
122 default=False,
124 apply_modifiers = BoolProperty(name="Apply Modifiers",
125 description="Applies the Modifiers",
126 default=True,
128 range_start = IntProperty(name='Start Frame',
129 description='First frame to use for Export',
130 default=1,
132 range_end = IntProperty(name='End Frame',
133 description='Last frame to use for Export',
134 default=250,
136 sampling = EnumProperty(name='Sampling',
137 description='Sampling --> frames per sample (0.1 yields 10 samples per frame)',
138 items=(('0.01', '0.01', ''),
139 ('0.05', '0.05', ''),
140 ('0.1', '0.1', ''),
141 ('0.2', '0.2', ''),
142 ('0.25', '0.25', ''),
143 ('0.5', '0.5', ''),
144 ('1', '1', ''),
145 ('2', '2', ''),
146 ('3', '3', ''),
147 ('4', '4', ''),
148 ('5', '5', ''),
149 ('10', '10', ''),
151 default='1',
154 @classmethod
155 def poll(cls, context):
156 return context.active_object.type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}
158 def execute(self, context):
159 start_time = time.time()
160 print('\n_____START_____')
161 props = self.properties
162 filepath = self.filepath
163 filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
165 exported = do_export(context, props, filepath)
167 if exported:
168 print('finished export in %s seconds' %((time.time() - start_time)))
169 print(filepath)
171 return {'FINISHED'}
173 def invoke(self, context, event):
174 wm = context.window_manager
176 if True:
177 # File selector
178 wm.fileselect_add(self) # will run self.execute()
179 return {'RUNNING_MODAL'}
180 elif True:
181 # search the enum
182 wm.invoke_search_popup(self)
183 return {'RUNNING_MODAL'}
184 elif False:
185 # Redo popup
186 return wm.invoke_props_popup(self, event)
187 elif False:
188 return self.execute(context)
191 ### REGISTER ###
193 def menu_func(self, context):
194 self.layout.operator(Export_pc2.bl_idname, text="Pointcache (.pc2)")
197 def register():
198 bpy.utils.register_module(__name__)
200 bpy.types.INFO_MT_file_export.append(menu_func)
201 #bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func)
203 def unregister():
204 bpy.utils.unregister_module(__name__)
206 bpy.types.INFO_MT_file_export.remove(menu_func)
207 #bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_func)
209 if __name__ == "__main__":
210 register()