Newer
Older
# SPDX-License-Identifier: GPL-2.0-or-later
"name": "Export Pointcache Format(.pc2)",
"location": "File > Export > Pointcache (.pc2)",
"description": "Export mesh Pointcache data (.pc2)",
"doc_url": "{BLENDER_MANUAL_URL}/addons/import_export/pc2.html",
"category": "Import-Export",
}
CoDEmanX
committed
Related links:
https://developer.blender.org/T34456
https://developer.blender.org/T25408
Usage Notes:
in Maya Mel:
cacheFile -pc2 1 -pcf "<insert filepath of source>" -f "<insert target filename w/o extension>" -dir "<insert directory path for target>" -format "OneFile";
Bastien Montagne
committed
from bpy.props import BoolProperty, IntProperty, EnumProperty
import mathutils
from bpy_extras.io_utils import ExportHelper
Bastien Montagne
committed
import math
import struct
Bastien Montagne
committed
def get_sampled_frames(start, end, sampling):
return [math.modf(start + x * sampling) for x in range(int((end - start) / sampling) + 1)]
def do_export(context, props, filepath):
mat_x90 = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
ob = context.active_object
sc = context.scene
start = props.range_start
end = props.range_end
sampling = float(props.sampling)
apply_modifiers = props.apply_modifiers
depsgraph = None
if apply_modifiers:
depsgraph = context.evaluated_depsgraph_get()
me = ob.evaluated_get(depsgraph).to_mesh()
else:
me = ob.to_mesh()
Bastien Montagne
committed
sampletimes = get_sampled_frames(start, end, sampling)
CoDEmanX
committed
headerStr = struct.pack(headerFormat, b'POINTCACHE2\0',
1, vertCount, start, sampling, sampleCount)
file = open(filepath, "wb")
file.write(headerStr)
CoDEmanX
committed
# stupid modf() gives decimal part first!
sc.frame_set(int(frame[1]), subframe=frame[0])
if apply_modifiers:
me = ob.evaluated_get(depsgraph).to_mesh()
else:
me = ob.to_mesh()
CoDEmanX
committed
bpy.data.meshes.remove(me, do_unlink=True)
file.close()
try:
remove(filepath)
except:
empty = open(filepath, 'w')
empty.write('DUMMIFILE - export failed\n')
empty.close()
print('Export failed. Vertexcount of Object is not constant')
return False
CoDEmanX
committed
if props.world_space:
me.transform(ob.matrix_world)
if props.rot_x90:
me.transform(mat_x90)
CoDEmanX
committed
for v in me.vertices:
thisVertex = struct.pack('<fff', float(v.co[0]),
CoDEmanX
committed
if apply_modifiers:
ob.evaluated_get(depsgraph).to_mesh_clear()
else:
me = ob.to_mesh_clear()
file.flush()
file.close()
return True
"""Export the active Object as a .pc2 Pointcache file"""
bl_idname = "export_shape.pc2"
bl_label = "Export Pointcache (.pc2)"
filename_ext = ".pc2"
CoDEmanX
committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
rot_x90: BoolProperty(
name="Convert to Y-up",
description="Rotate 90 degrees around X to convert to y-up",
default=True,)
world_space: BoolProperty(
name="Export into Worldspace",
description="Transform the Vertexcoordinates into Worldspace",
default=False,)
apply_modifiers: BoolProperty(
name="Apply Modifiers",
description="Applies the Modifiers",
default=True,)
range_start: IntProperty(
name='Start Frame',
description='First frame to use for Export',
default=1,)
range_end: IntProperty(
name='End Frame',
description='Last frame to use for Export',
default=250,)
sampling: EnumProperty(
name='Sampling',
description='Sampling --> frames per sample (0.1 yields 10 samples per frame)',
items=(('0.01', '0.01', ''),
('0.05', '0.05', ''),
('0.1', '0.1', ''),
('0.2', '0.2', ''),
('0.25', '0.25', ''),
('0.5', '0.5', ''),
('1', '1', ''),
('2', '2', ''),
('3', '3', ''),
('4', '4', ''),
('5', '5', ''),
('10', '10', ''),
),
default='1',
)
CoDEmanX
committed
obj is not None
and obj.type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}
def execute(self, context):
start_time = time.time()
print('\n_____START_____')
props = self.properties
filepath = self.filepath
filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
exported = do_export(context, props, filepath)
CoDEmanX
committed
print('finished export in %s seconds' %
((time.time() - start_time)))
CoDEmanX
committed
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
if True:
# File selector
return {'RUNNING_MODAL'}
elif True:
# search the enum
wm.invoke_search_popup(self)
return {'RUNNING_MODAL'}
elif False:
# Redo popup
return wm.invoke_props_popup(self, event)
self.layout.operator(Export_pc2.bl_idname, text="Pointcache (.pc2)")
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export_button)
#bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func_export_button)
Campbell Barton
committed
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export_button)
#bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_func_export_button)
for cls in classes:
bpy.utils.unregister_class(cls)
Campbell Barton
committed
CoDEmanX
committed