1
$\begingroup$

I'd like to write a python script can change (not delete and re-create) the geometry of an object AFTER the initial object has already been loaded by blender.

To clarify, here are the 3 basic steps:

  1. I write a python file (import bpy, time, ...) that includes some geometric object.
  2. Through the command line, I open blender and import the python file into blender.

~/tools/Blender-2.79-CellBlender/blender -P ~/src4/.../filename.py

  1. blender opens, the initial geometry loads, then the geometry periodically changes as the python file runs through a time delayed function that changes the geometry of that object.

I don't want blender to open a new window every time the geometry changes, it should just update the existing model.

I believe this is called periodic display, but I couldn't find any helpful resources online.

I'm running Debian 8, Blender 2.79, python 3.7.3.

In case it's relevent, here's my python code that I'm importing in:

import bpy, time

#remove all default objects
bpy.data.objects['Cube'].select = True
bpy.data.objects['Camera'].select = True
bpy.data.objects['Lamp'].select = True
bpy.ops.object.delete() 

#time delayed loop that adds geometry. I want to CHANGE, not add the geometry. 
for x in range(1,10):
    len = x
    #Define box
    verts = [(-len,.5,.3),
             (len,.5,.3),
             (len,-.5,.3),
             (-len,-.5,.3),
             (-len,.5,-.3),
             (len,.5,-.3),
             (len,-.5,-.3),
             (-len,-.5,-.3),
            ]
    faces = [(0, 1, 2, 3),(4,5,6,7),(0,4,7,3),(1,5,6,2),(0,1,5,4),(3,2,6,7)]
    edges = []

    my_mesh = bpy.data.meshes.new('Meshy')
    my_object = bpy.data.objects.new('Objey', my_mesh)
    bpy.context.scene.objects.link(my_object)
    my_mesh.update(calc_edges=True)
    time.sleep(1)

Right now it just waits 10 seconds to run through the loop, then opens blender with 9 separate boxes, as one would expect. As indicated above, this is not what I want to do.

$\endgroup$
0
$\begingroup$

Well, I still can't find a way to change an object, but I did find out how to delete the current object and create a slightly altered object for every frame.

The key is to use bpy.app.handlers:

import bpy, math

#remove all default objects
bpy.data.objects['Cube'].select = True
bpy.data.objects['Camera'].select = True
bpy.data.objects['Lamp'].select = True
bpy.ops.object.delete() 

#Define box
verts = [(0,0,0),
         (0,0,0),
         (0,0,0),
         (0,0,0),
         (0,0,0),
         (0,0,0),
         (0,0,0),
         (0,0,0),
         ]
faces = [(0, 1, 2, 3),(4,5,6,7),(0,4,7,3),(1,5,6,2),(0,1,5,4),(3,2,6,7)]
edges = []

my_mesh = bpy.data.meshes.new('Meshy')
my_object = bpy.data.objects.new('Objey', my_mesh)
bpy.context.scene.objects.link(my_object)

my_mesh.from_pydata(verts, edges, faces)
my_mesh.update(calc_edges=True)

def change_geom(scene):
    #assign frame number
    f = bpy.context.scene.frame_current
    #assign vertex values
    d = 5*math.sin(f/1000*180/3.141592)
    z = 1+math.sin(f/(250)*180/3.141592)

    #delete previous geometry
    bpy.data.objects['Objey'].select = True
    bpy.ops.object.delete() 

    #create new geometry
    verts = [(-d,d,z),
             (d,d,z),
             (d,-d,z),
             (-d,-d,z),
             (-d,d,-z),
             (d,d,-z),
             (d,-d,-z),
             (-d,-d,-z),
            ]
    faces = [(0, 1, 2, 3),(4,5,6,7),(0,4,7,3),(1,5,6,2),(0,1,5,4),(3,2,6,7)]
    edges = []

    my_mesh = bpy.data.meshes.new('Meshy')
    my_object = bpy.data.objects.new('Objey', my_mesh)
    bpy.context.scene.objects.link(my_object)

    my_mesh.from_pydata(verts, edges, faces)

#calls the function every time you change frames
bpy.app.handlers.frame_change_pre.append(change_geom)

Still looking to find a way to alter existing geometry instead of re-creating it (which is way less efficient)!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.