Skip to content

Commit 310c63f

Browse files
committed
Performance pass for blender animation export.
1 parent a2c0f32 commit 310c63f

File tree

3 files changed

+91
-39
lines changed

3 files changed

+91
-39
lines changed

plugins/blender/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
bl_info = {
1010
"name": "Cast Support",
1111
"author": "DTZxPorter",
12-
"version": (1, 9, 0),
12+
"version": (1, 9, 1),
1313
"blender": (3, 6, 0),
1414
"location": "File > Import",
1515
"description": "Import & Export Cast",

plugins/blender/export_cast.py

Lines changed: 89 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ def exportAction(self, context, root, objects, action):
351351
animation.SetLooping(self.is_looped)
352352

353353
curves = {}
354+
uniqueKeyframes = set()
355+
uniqueCurves = []
354356

355357
with ProgressReport(context.window_manager) as progress:
356358
progress.enter_substeps(len(action.fcurves))
@@ -371,59 +373,66 @@ def exportAction(self, context, root, objects, action):
371373

372374
poseBone = target.data
373375

376+
# Precompute a list of keyframes for export.
377+
keyframes = [int(x.co[0]) for x in curve.keyframe_points]
378+
# Update the unique keyframe list so we only iterate once.
379+
uniqueKeyframes.update(keyframes)
380+
374381
if target == poseBone.location.owner:
375382
result = curves.get(poseBone, [])
376-
result.append(
377-
(curve, "location", curve.array_index))
383+
result.append((curve,
384+
"location",
385+
curve.array_index,
386+
keyframes))
387+
378388
curves[poseBone] = result
379389
elif target == poseBone.rotation_quaternion.owner or target == poseBone.rotation_euler.owner:
380390
result = curves.get(poseBone, [])
381-
result.append(
382-
(curve, "rotation_quaternion", curve.array_index))
391+
result.append((curve,
392+
"rotation_quaternion",
393+
curve.array_index,
394+
keyframes))
395+
383396
curves[poseBone] = result
384397
elif target == poseBone.scale.owner:
385398
result = curves.get(poseBone, [])
386-
result.append(
387-
(curve, "scale", curve.array_index))
399+
result.append((curve,
400+
"scale",
401+
curve.array_index,
402+
keyframes))
403+
388404
curves[poseBone] = result
389405

390406
progress.step()
391407

392408
progress.leave_substeps()
393409
progress.enter_substeps(len(curves.keys()))
394410

395-
# Iterate on the target/curves and generate the proper cast curves.
396411
for target, curves in curves.items():
397-
# We must handle quaternions separately, and key them together.
412+
# Quaternions are combined into their own curve.
398413
rotationQuaternion = [
399414
x for x in curves if x[1] == "rotation_quaternion"]
400415

401-
if len(rotationQuaternion) > 0:
416+
if rotationQuaternion:
402417
curveNode = animation.CreateCurve()
403418
curveNode.SetNodeName(target.name)
404419
curveNode.SetKeyPropertyName("rq")
405420
curveNode.SetMode("absolute")
406421

407-
keyframes = []
422+
keyframes = set()
408423

409424
for curve in rotationQuaternion:
410-
keyframes.extend([int(x.co[0])
411-
for x in curve[0].keyframe_points])
412-
413-
keyframes = list(set(keyframes))
414-
415-
curveNode.SetKeyFrameBuffer(keyframes)
425+
keyframes.update(curve[3])
416426

417-
keyvalues = []
427+
uniqueCurves.append((curveNode,
428+
target,
429+
"rotation_quaternion",
430+
0,
431+
keyframes,
432+
[],
433+
[]))
418434

419-
for keyframe in keyframes:
420-
context.scene.frame_set(keyframe)
421-
quat = utilityGetQuatKeyValue(target)
422-
keyvalues.append((quat.x, quat.y, quat.z, quat.w))
423-
424-
curveNode.SetVec4KeyValueBuffer(keyvalues)
425-
426-
for (curve, property, index) in curves:
435+
for (curve, property, index, keyframes) in curves:
427436
switcherProperty = {
428437
"location": ["tx", "ty", "tz"],
429438
"scale": ["sx", "sy", "sz"]
@@ -432,27 +441,70 @@ def exportAction(self, context, root, objects, action):
432441
if property not in switcherProperty:
433442
continue
434443

444+
propertyName = switcherProperty[property][index]
445+
435446
curveNode = animation.CreateCurve()
436447
curveNode.SetNodeName(target.name)
437-
curveNode.SetKeyPropertyName(switcherProperty[property][index])
448+
curveNode.SetKeyPropertyName(propertyName)
438449
curveNode.SetMode("absolute")
439450

440-
keyframes = [int(x.co[0]) for x in curve.keyframe_points]
451+
uniqueCurves.append((curveNode,
452+
target,
453+
property,
454+
index,
455+
keyframes,
456+
[],
457+
[]))
441458

442-
curveNode.SetKeyFrameBuffer(keyframes)
459+
progress.step()
443460

444-
keyvalues = []
461+
progress.leave_substeps()
462+
progress.enter_substeps(len(uniqueKeyframes))
463+
464+
# Iterate over the keyframes in this animation.
465+
for keyframe in uniqueKeyframes:
466+
context.scene.frame_set(keyframe)
467+
468+
for (_,
469+
target,
470+
property,
471+
index,
472+
frames,
473+
keyframes,
474+
keyvalues) in uniqueCurves:
475+
if keyframe not in frames:
476+
continue
445477

446-
if property == "location":
447-
scale = self.scale
448-
else:
449-
scale = 1.0
478+
keyframes.append(keyframe)
450479

451-
for keyframe in keyframes:
452-
context.scene.frame_set(keyframe)
453-
keyvalues.append(utilityGetSimpleKeyValue(
454-
target, property)[index] * scale)
480+
if property == "rotation_quaternion":
481+
quat = utilityGetQuatKeyValue(target)
482+
keyvalues.append((quat.x, quat.y, quat.z, quat.w))
483+
elif property == "location":
484+
simple = utilityGetSimpleKeyValue(target, property)[index]
485+
keyvalues.append(simple * self.scale)
486+
elif property == "scale":
487+
simple = utilityGetSimpleKeyValue(target, property)[index]
488+
keyvalues.append(simple)
455489

490+
progress.step()
491+
492+
progress.leave_substeps()
493+
progress.enter_substeps(len(uniqueCurves))
494+
495+
# Apply the keyframe and keyvalue buffers to the curve.
496+
for (curveNode,
497+
_,
498+
property,
499+
_,
500+
_,
501+
keyframes,
502+
keyvalues) in uniqueCurves:
503+
curveNode.SetKeyFrameBuffer(keyframes)
504+
505+
if property == "rotation_quaternion":
506+
curveNode.SetVec4KeyValueBuffer(keyvalues)
507+
else:
456508
curveNode.SetFloatKeyValueBuffer(keyvalues)
457509

458510
progress.step()

plugins/maya/castplugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
}
4646

4747
# Shared version number
48-
version = "1.90"
48+
version = "1.91"
4949

5050
# Time unit to framerate map
5151
framerateMap = {

0 commit comments

Comments
 (0)