I am writing a script that loops through a list of objects in the scene and while it’s looping it imports .mdd caches to each of the objects of list.
I notice that my script doesn’t work because I am unable to activate/highlight the object in the outliner while I am looping.
I am using bpy.ops.object.select_all(action=‘DESELECT’) and bpy.ops.object.select_pattern(pattern=obj) to deselect all objects and select the object I want to import the caches to, but if they are not highlighted in the outliner, my script doesn’t import the cache to the right object.
Sounds a bit odd that I need to highlight the object in the outliner. The way I figured this out was importing the cache to only one object in the scene with the object highlighted. Also when the script loops, only one object stays highlighted in the outline and that’s why I believe the script isn’t importing the cache to the right object.
This is my script:
def import_caches_to_objs(objs_name, selected_path):
‘’’
Loops through list of objects provided and import mdd caches to them.
‘’’
for obj in objs_name:
print(‘Importing Cache’)
filepath=selected_path + ‘/’ + obj + ‘.mdd’ # Making the filepath for the .mdd cache
print(filepath)
bpy.ops.object.select_all(action=‘DESELECT’) # Deselecting object
bpy.ops.object.select_pattern(pattern=obj) # Selecting object from list
bpy.ops.import_shape.mdd(filepath=filepath, frame_start=1) # Importing cache to selected object
print(‘Cache Imported’)
return objs_name
The scripts imports every cache, but it doesn’t import the caches to the right objects in the loop. It imports the cache to the highlighted object.
Am I doing the right way? Or is there a proper way to select the object using python overriding the highlighted object in the outliner?
Thank you for your attention in advance
Rodrigo Guimaraes
pS: Sorry for the code without indent, I don’t know how to quote the code lines.
And you can have a selected object and no active object. Most operators work (primarily) on the active object.
Change the body of your method to something like
def import_caches_to_objs(scene, obj_names, selected_path):
bpy.ops.object.select_all(action='DESELECT') # Deselecting all
for name in obj_names:
print('Importing Cache')
# get out of the habit of string concat.
filepath = "%s/%s.mdd" % (selected_path, name)
# filepath=selected_path + '/' + name + '.mdd' # Making the filepath for the .mdd cache
print(filepath)
obj = scene.objects.get(name) # the object or None
scene.objects.active = obj
bpy.ops.import_shape.mdd(filepath=filepath, frame_start=1) # Importing cache to selected object
print("Cache Imported for %s" % name)
return obj_names # ???
Thank you very much for your help. You’re always around to help me out here.
My script is working fine now.
Just one question about your code lines.
When I tested the line below in the console, it worked but not in my script:
C.scene.objects.active = None
So I had to type in my script:
bpy.context.scene.objects.active = None
Also for:
scene = context.scene
I had to type:
bpy.context.scene
Was that a typo error? Or Am I missing something?
I am asking these questions because I am new to Blender’s python scripting and I really would like to understand it better.
I was pointing out that the active object could be unset, ie set to None while you still had selected objects, in which case a lot of operators will not work.
C is the convenience variable for bpy.context, D for bpy.data in the console. As pointed out when the console is first opened.
Yep in most (if not all) cases the context is bpy.context. My suggestion tho is to avoid using the full bpy.context… in code as most class methods pass the context as a parameter, for example, operator poll, invoke, execute and cancel as well as panel poll and draw methods.
class MyOp(Operator):
@classmethod
def poll(cls, context):
obj = bpy.context.scene.objects.active # IMO this is bad as opposed to
scene = context.scene
obj = scene.objects.active
return (obj is not None)
Putting in the simple line
context = bpy.context
in test code, makes copy and paste later when you are making operators / panels etc a lot easier, which sooner or later needs to be done to make the code “operational” to use in the blender interface rather than via text or console.