3

I want to duplicate objects. I want them to have the same geometry, with many polygons, so I do not want to create copies, I'd like to create instances. Then I want them to have different scale animations

but when I'm duplicating objects with command:

bpy.ops.object.duplicate(linked=True)

and then creating an animation of scale of duplicated object the source object has the same animation, how can I change that?

Ray Mairlot
  • 29,192
  • 11
  • 103
  • 125
Kowalski Paweł
  • 511
  • 5
  • 15

2 Answers2

1

This has been tested in 2.8:

If the original (template) object is named 'Original':

original_mesh_data = bpy.data.objects['Original'].data
# Create new object with linked mesh data
new_object = bpy.data.objects.new('CopiedMesh', original_mesh_data)

# Create animation data for new object
new_object.animation_data_create()

# Copy (do not link) original object’s action into new object’s action
new_object.animation_data.action = template_object.animation_data.action.copy()

# Renamed action if desired
new_object.animation_data.action.name = ‘NewAction’
Dazotaro
  • 901
  • 1
  • 9
  • 20
1

Here is a test script, select an object(s) and run. It will add the selected objects to a group, remove any animation already on those objects. Then using the group create 20 group instances with random locations.

Using code similar to here to create a simple 2 keyframe random scale action

2.8x

import bpy
from random import uniform

def random_scale_action(): action = bpy.data.actions.new("RandomScaleAction") data_path = "scale" # (frame, value) for keyframe point for axis in [0, 1, 2]: # new fcurve fc = action.fcurves.new(data_path, index=axis) # add a new keyframe point fc.keyframe_points.add(count=2) for kfp in fc.keyframe_points: kfp.co = (uniform(1,100), uniform(0, 1))

return action

context = bpy.context scene = context.scene

create a group and add the selected objects to it.

collection = bpy.data.collections.new("CubeGroup") scene.collection.children.link(collection)

for obj in context.selected_objects: # remove any animation data. if obj.animation_data: obj.animation_data.clear() collection.objects.link(obj)

create 20 randomly located dupli_groups.

for i in range(20): obj = context.active_object
me = obj.data me_copy = me.copy()

ob = bpy.data.objects.new("Mesh Copy", me_copy)
ob.location = [uniform(0,10) for i in range(3)]
context.collection.objects.link(ob)

# Add action to instanced object
ob.animation_data_create()
ob.animation_data.action = random_scale_action()

bpy.data.collections[collection.name].objects.link(ob)

context.view_layer.update()


2.7x


    import bpy
    from random import uniform
def random_scale_action():
    action = bpy.data.actions.new("RandomScaleAction")
    data_path = "scale"
    # (frame, value) for keyframe point
    for axis in [0, 1, 2]:
        # new fcurve
        fc = action.fcurves.new(data_path, index=axis)
        # add a new keyframe point
        fc.keyframe_points.add(count=2)
        for kfp in fc.keyframe_points:
            kfp.co = (uniform(1,100), uniform(0, 1))

    return action

context = bpy.context
scene = context.scene 

# create a group and add the selected objects to it.    
group = bpy.data.groups.new("CubeGroup")
for obj in context.selected_objects:
    # remove any animation data.
    if obj.animation_data:
        obj.animation_data.clear()
    group.objects.link(obj)
# create 20 randomly located dupli_groups.
for i in range(20):     
    instance = bpy.data.objects.new('dupli_group', None)
    instance.location = [uniform(0,10) for i in range(3)]
    instance.dupli_type = 'GROUP'
    instance.dupli_group = group
    scene.objects.link(instance)
    instance.animation_data_create()
    # give a random scale action
    instance.animation_data.action = random_scale_action()

Rug
  • 833
  • 9
  • 26
batFINGER
  • 84,216
  • 10
  • 108
  • 233