@@ -69,6 +69,8 @@ def draw(self,context):
69
69
if bpy .context .scene .camera != None :
70
70
col .prop (scene .smear ,"cameraPOV" )
71
71
72
+ col .operator (UnbakeSmearOperator .bl_idname )
73
+
72
74
col .operator (BakeDeltasTrajectoriesOperator .bl_idname )
73
75
74
76
class EffectControlPanel (Panel ,bpy .types .Panel ):
@@ -178,6 +180,30 @@ def clear_attributes(obj):
178
180
for name in to_remove :
179
181
obj .data .attributes .remove (obj .data .attributes [name ])
180
182
183
+ class UnbakeSmearOperator (bpy .types .Operator ):
184
+ bl_idname = "scene.unbake_smear"
185
+ bl_label = "Unbake Smears"
186
+
187
+ def execute (self ,context ):
188
+ obj = bpy .context .active_object
189
+
190
+ # unlink node network
191
+ if "Smear Control Panel" in obj .modifiers :
192
+ obj .modifiers .remove (obj .modifiers .get ("Smear Control Panel" ))
193
+
194
+ # remove all "delta_X" attributes
195
+ att_names = [att .name for att in obj .data .attributes ]
196
+ for att_name in att_names :
197
+ if att_name .startswith ("delta_" ):
198
+ att = obj .data .attributes [att_name ]
199
+ obj .data .attributes .remove (att )
200
+
201
+ # delete aggregated animation
202
+ if f"aggregated_animation_{ obj .name } " in bpy .data .objects :
203
+ bpy .data .objects .remove (bpy .data .objects [f"aggregated_animation_{ obj .name } " ])
204
+
205
+ return {"FINISHED" }
206
+
181
207
class BakeDeltasTrajectoriesOperator (bpy .types .Operator ):
182
208
bl_idname = "scene.bake_deltas_and_trajectories"
183
209
bl_label = "Bake Smears"
@@ -226,6 +252,9 @@ def execute(self,context):
226
252
if len (keyframe_frames ) > 0 :
227
253
frame_start = keyframe_frames [0 ]
228
254
frame_end = keyframe_frames [- 1 ]
255
+ else :
256
+ print ("No animation found" )
257
+ return {"FINISHED" }
229
258
230
259
if bpy .context .scene .camera != None :
231
260
keyframe_frames = get_keyframe_frames (bpy .context .scene .camera )
@@ -245,7 +274,8 @@ def execute(self,context):
245
274
for frame in animation_deltas :
246
275
dname = f"delta_{ frame } "
247
276
obj .data .attributes .new (name = dname ,type = "FLOAT" ,domain = "POINT" )
248
- obj .data .attributes [dname ].data .foreach_set ("value" ,animation_deltas [frame ])
277
+ for i in range (len (animation_deltas [frame ])):
278
+ setattr (obj .data .attributes [dname ].data [i ],"value" ,animation_deltas [frame ][i ])
249
279
250
280
251
281
pos_aggregated = np .concatenate ([positions [frame ] for frame in positions ])
@@ -327,6 +357,9 @@ def set_node_tree(obj,frame_start,frame_end,cameraPOV):
327
357
camera_identifier = mod .node_group .interface .items_tree ["Camera" ].identifier
328
358
mod [camera_identifier ] = bpy .context .scene .camera
329
359
360
+ manual_weights_group_identifier = mod .node_group .interface .items_tree ["Manual Weights Group" ].identifier
361
+ bpy .ops .object .geometry_nodes_input_attribute_toggle (input_name = manual_weights_group_identifier , modifier_name = "Smear Control Panel" )
362
+
330
363
class SmearPropertyGroup (bpy .types .PropertyGroup ):
331
364
fullBody : bpy .props .BoolProperty (name = "Ignore Skeleton" ,default = False )
332
365
discardedBone : bpy .props .StringProperty (name = "Bones" ,search = get_bone_names )
@@ -339,6 +372,7 @@ def register():
339
372
340
373
bpy .utils .register_class (SmearControlPanel )
341
374
bpy .utils .register_class (BakeDeltasTrajectoriesOperator )
375
+ bpy .utils .register_class (UnbakeSmearOperator )
342
376
343
377
bpy .utils .register_class (ElongatedInbetweensControlPanel )
344
378
bpy .utils .register_class (MotionLinesControlPanel )
@@ -350,6 +384,7 @@ def unregister():
350
384
351
385
bpy .utils .unregister_class (SmearControlPanel )
352
386
bpy .utils .unregister_class (BakeDeltasTrajectoriesOperator )
387
+ bpy .utils .unregister_class (UnbakeSmearOperator )
353
388
354
389
bpy .utils .unregister_class (ElongatedInbetweensControlPanel )
355
390
bpy .utils .unregister_class (MotionLinesControlPanel )
0 commit comments