FBX: reformat props.
[blender-addons.git] / io_export_pc2.py
blob663f3a5f8a59ef023c8942f80f0a86f5c5f3a92f
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 "category": "Import-Export"}
31 """
32 Related links:
33 https://developer.blender.org/T34456
34 https://developer.blender.org/T25408
36 Usage Notes:
38 in Maya Mel:
39 cacheFile -pc2 1 -pcf "<insert filepath of source>" -f "<insert target filename w/o extension>" -dir "<insert directory path for target>" -format "OneFile";
41 """
43 import bpy
44 from bpy.props import *
45 import mathutils, math, struct
46 from os import remove
47 import time
48 from bpy_extras.io_utils import ExportHelper
50 def getSampling(start, end, sampling):
51 samples = [start + x * sampling
52 for x in range(int((end - start) / sampling) + 1)]
53 return samples
55 def do_export(context, props, filepath):
56 mat_x90 = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
57 ob = context.active_object
58 sc = context.scene
59 start = props.range_start
60 end = props.range_end
61 sampling = float(props.sampling)
62 apply_modifiers = props.apply_modifiers
63 me = ob.to_mesh(sc, apply_modifiers, 'PREVIEW')
64 vertCount = len(me.vertices)
65 sampletimes = getSampling(start, end, sampling)
66 sampleCount = len(sampletimes)
68 # Create the header
69 headerFormat='<12siiffi'
70 headerStr = struct.pack(headerFormat, b'POINTCACHE2\0',
71 1, vertCount, start, sampling, sampleCount)
73 file = open(filepath, "wb")
74 file.write(headerStr)
76 for frame in sampletimes:
77 sc.frame_set(frame)
78 me = ob.to_mesh(sc, apply_modifiers, 'PREVIEW')
80 if len(me.vertices) != vertCount:
81 file.close()
82 try:
83 remove(filepath)
84 except:
85 empty = open(filepath, 'w')
86 empty.write('DUMMIFILE - export failed\n')
87 empty.close()
88 print('Export failed. Vertexcount of Object is not constant')
89 return False
91 if props.world_space:
92 me.transform(ob.matrix_world)
93 if props.rot_x90:
94 me.transform(mat_x90)
96 for v in me.vertices:
97 thisVertex = struct.pack('<fff', float(v.co[0]),
98 float(v.co[1]),
99 float(v.co[2]))
100 file.write(thisVertex)
102 file.flush()
103 file.close()
104 return True
107 ###### EXPORT OPERATOR #######
108 class Export_pc2(bpy.types.Operator, ExportHelper):
109 """Export the active Object as a .pc2 Pointcache file"""
110 bl_idname = "export_shape.pc2"
111 bl_label = "Export Pointcache (.pc2)"
113 filename_ext = ".pc2"
115 rot_x90 = BoolProperty(name="Convert to Y-up",
116 description="Rotate 90 degrees around X to convert to y-up",
117 default=True,
119 world_space = BoolProperty(name="Export into Worldspace",
120 description="Transform the Vertexcoordinates into Worldspace",
121 default=False,
123 apply_modifiers = BoolProperty(name="Apply Modifiers",
124 description="Applies the Modifiers",
125 default=True,
127 range_start = IntProperty(name='Start Frame',
128 description='First frame to use for Export',
129 default=1,
131 range_end = IntProperty(name='End Frame',
132 description='Last frame to use for Export',
133 default=250,
135 sampling = EnumProperty(name='Sampling',
136 description='Sampling --> frames per sample (0.1 yields 10 samples per frame)',
137 items=(('0.01', '0.01', ''),
138 ('0.05', '0.05', ''),
139 ('0.1', '0.1', ''),
140 ('0.2', '0.2', ''),
141 ('0.25', '0.25', ''),
142 ('0.5', '0.5', ''),
143 ('1', '1', ''),
144 ('2', '2', ''),
145 ('3', '3', ''),
146 ('4', '4', ''),
147 ('5', '5', ''),
148 ('10', '10', ''),
150 default='1',
153 @classmethod
154 def poll(cls, context):
155 return context.active_object.type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}
157 def execute(self, context):
158 start_time = time.time()
159 print('\n_____START_____')
160 props = self.properties
161 filepath = self.filepath
162 filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
164 exported = do_export(context, props, filepath)
166 if exported:
167 print('finished export in %s seconds' %((time.time() - start_time)))
168 print(filepath)
170 return {'FINISHED'}
172 def invoke(self, context, event):
173 wm = context.window_manager
175 if True:
176 # File selector
177 wm.fileselect_add(self) # will run self.execute()
178 return {'RUNNING_MODAL'}
179 elif True:
180 # search the enum
181 wm.invoke_search_popup(self)
182 return {'RUNNING_MODAL'}
183 elif False:
184 # Redo popup
185 return wm.invoke_props_popup(self, event)
186 elif False:
187 return self.execute(context)
190 ### REGISTER ###
192 def menu_func(self, context):
193 self.layout.operator(Export_pc2.bl_idname, text="Pointcache (.pc2)")
196 def register():
197 bpy.utils.register_module(__name__)
199 bpy.types.INFO_MT_file_export.append(menu_func)
200 #bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func)
202 def unregister():
203 bpy.utils.unregister_module(__name__)
205 bpy.types.INFO_MT_file_export.remove(menu_func)
206 #bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_func)
208 if __name__ == "__main__":
209 register()