1
$\begingroup$

So I wish to have a script which creates an object then set's it keyframe at a frame, 'f', before creating another object and setting a keyframe at a new frame, say f+1. However it always sets the keyframe to the first object created and not to the newer ones and using bpy.ops.data.object['Wave'].select = True doesn't work as it just selects the first plane created and not the others (due to the fact the others are named Wave.001 for example. I thought about turning the name into a string but that seemed like an improbable solution. When I ran this script with a more simple example of a plane it seemed to work... Here's the script I'm using for the wave:

import bpy
import math
scn = bpy.context.scene

numY = 10
freq = 1
amp = 1
scale = 1

for numX in range (2, 20):
    scn.frame_current = numX - 2
    verts = []
    faces = []

    for i in range (0, numX):
        for j in range (0, numY):
            x = scale * i
            y = scale * j
            z = scale*((amp*math.cos(i*freq))+(amp*math.sin(j*freq)))

            vert = (x,y,z)
            verts.append(vert)

    count = 0
    for i in range (0, numY*(numX-1)):
        if count < numY-1:
            A = i
            B = i+1
            C = (i+numY)+1
            D = (i+numY)

            face = (A,B,C,D)
            faces.append(face)
            count = count + 1
        else:
            count = 0

    mesh = bpy.data.meshes.new("Wave")
    object = bpy.data.objects.new("Wave",mesh)

    object.location = (0,0,0)
    bpy.context.scene.objects.link(object)

    mesh.from_pydata(verts, [],faces)
    mesh.update(calc_edges=True)
    bpy.ops.data.object['Wave'].select = True
    bpy.ops.anim.keyframe_insert_menu(type='Location')

The strange thing was that without the bpy.ops.data.object['Wave'].select = True the script fails with it outlining bpy.ops.anim.keyframe_insert_menu(type='Location') as the issue. I don't see a difference between this and the simpler cube example though - which works fine without the need of selecting the Plane. Here's the code for the plane example :

import bpy
from mathutils import Vector

scn = bpy.context.scene
scn.frame_start = 0
scn.frame_end = 20
scn.frame_current = 0
for f in range (0, 20):
    bpy.ops.object.add(type='MESH')
    Plane = bpy.context.object
    Plane.name = "Plane"
    PlaneMesh = Plane.data

    verts = [(0,0,0), (0,5,0), (0,5,5), (0,0,5)]
    faces = [(0,1,2,3)]

    PlaneMesh.from_pydata(verts, [], faces)
    PlaneMesh.update()
    scn.frame_current = f
    bpy.ops.anim.keyframe_insert_menu(type='Location')

scn.frame_current = 0

Can anyone please help me understand what's going on...?

$\endgroup$
6
  • 1
    $\begingroup$ Related: blender.stackexchange.com/questions/2848/why-avoid-bpy-ops $\endgroup$ Commented Oct 4, 2017 at 16:49
  • $\begingroup$ @RayMairlot I now see its impracticality but what else would be a solution to insert keyframes then? $\endgroup$ Commented Oct 4, 2017 at 17:10
  • $\begingroup$ In this instance, I don't actually think that's the issue, just something to note, but it's hard to tell if I've got the script working because I'm not sure what it's meant to do. The error in the line where you are selecting your object is because bpy.ops does not store the list of objects (the error was trying to tell you this), the correct command is bpy.data.objects['objectName']. But you can just do object.select = True anyway. $\endgroup$ Commented Oct 4, 2017 at 17:26
  • $\begingroup$ @batFINGER Okay thanks... I've changed all names from object now. By using context.object != context.selected_objects[0] is this deselecting all selected objects? And from that I can select the new object and edit thus? $\endgroup$ Commented Oct 4, 2017 at 18:22
  • $\begingroup$ To make an object the context object need to use scene.objects.active = obj. before calling an operator that works on context object. Anyway, don't use bpy.ops.anim.keyframe_insert use obj.keyframe_insert(data_path, frame=frame) Can be done without any need to set scene frame also. Can write up as answer if you prefer. $\endgroup$
    – batFINGER
    Commented Oct 4, 2017 at 18:23

1 Answer 1

4
$\begingroup$

Here is your script (a) doing what I think you want it to do. It makes a mesh object at each frame, and adds a location keyframe at the frame it was created in script.

If you are using an operator, need to be in, or set the context it requires. Make a new object obj context with context.scene.objects.active = obj. If it works on selected objects, like say join, need to make sure other objects are (de)selected correctly by setting obj.select accordingly on each.

Going to use bpy_struct.keyframe_insert(...) rather than the operator. This will be quicker, especially for high numbers.

import bpy
from math import sin, cos
scn = bpy.context.scene

numY = 10
freq = 1
amp = 1
scale = 1

for numX in range (2, 20):
    verts = []
    faces = []

    for i in range (0, numX):
        x = scale * i
        for j in range (0, numY):                
            y = scale * j
            z = scale * amp * (cos(i * freq) + sin(j * freq))
            vert = (x, y, z)
            verts.append(vert)

    count = 0
    for i in range (0, numY * (numX - 1)):
        if count < numY - 1:
            A = i
            B = i + 1
            C = (i + numY) + 1
            D = (i + numY)

            face = (A, B, C, D)
            faces.append(face)
            count = count + 1
        else:
            count = 0

    mesh = bpy.data.meshes.new("Wave")

    mesh.from_pydata(verts, [], faces)
    mesh.update(calc_edges = True)

    obj = bpy.data.objects.new("Wave", mesh)

    obj.location = (0, 0, 0)
    scn.objects.link(obj)
    obj.keyframe_insert("location", frame=numX, group="Location")
$\endgroup$
2
  • $\begingroup$ Thanks! Works exactly how I wanted it to (even if I didn't explain that very well oops...) $\endgroup$ Commented Oct 4, 2017 at 18:50
  • $\begingroup$ Just so I know what's going on what's happening with the last two lines? $\endgroup$ Commented Oct 4, 2017 at 18:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .