let’s imagine I have the following operator, and a simple panel to invoke it
import bpy
class Foo( bpy.types.Operator ):
bl_idname = "screen.foo"
bl_label = "Foo"
def execute( self, context ):
# A
objects = bpy.data.objects
for curr in objects:
print(curr.location)
return {'FINISHED'}
def register():
bpy.utils.register_class( Foo )
def unregister():
bpy.utils.register_class( Foo )
if __name__ == '__main__':
register()
I then invoke it like this :
bpy.ops.screen.foo()
Now check the spot I marked with comment “A” in the operator; let’s imagine that instead of working on all objects, I want to operate on a subset of the objects, i.e. something like
def returnAllObjectNames ():
# NOTE: This returns all object names in Blender, not scene specific.
result = []
for ob in bpy.data.objects:
result.append(ob.name)
return result
def returnObjectNamesLike(passedName):
# Return objects named like our passedName.
result = []
isLike = passedName
l = len(isLike)
all_obs = returnAllObjectNames()
for name in all_obs:
candidate = name[0:l]
if isLike == candidate:
result.append(name)
return result
This way I can fetch a list of objects that are named similar and operate upon them.
numby, I think you misunderstood me I know how to gather the list, what I don’t know is how to pass it as an operator parameter. There are types bpy.props.BoolProperty , bpy.props.StringProperty, bpy.props.FloatProperty, bpy.props.IntProperty, bpy.props.EnumProperty… but none that seems to let me pass lists of objects (or parameters of arbitrary type). And the operator can’t build the list itself, this just doesn’t fit into what I’m trying to do (to make a long story short, it’s an exporter, and we need a way to tell it which objects to export)
Atom: so you are suggesting to convert the objects into a string that would contain their names? This would indeed work, thanks for the advice; though it feels a bit hackish IMO, so if anyone knows a cleaner way to achieve this please let the world know
If it is an exporter, why not just look at the select tag of each object in the scene? If it is selected, it gets exported…less hackish, more integrated into the work-flow of the system.
Here is a way to pass a couple of variables to an operator.
import bpy
class cls_myClass(bpy.types.PropertyGroup):
item = bpy.props.StringProperty(name="Item", description="Type the name of the object that will inherit this objects motion here.")
bpy.utils.register_class(cls_myClass)
class SimpleOperator(bpy.types.Operator):
'''Tooltip'''
bl_idname = "object.simple_operator"
bl_label = "Simple Object Operator"
the_list = bpy.props.CollectionProperty(type=cls_myClass)
add = bpy.props.BoolProperty(default = True)
item = bpy.props.StringProperty(default = "NA")
def invoke(self, context, event):
print("
Simple Operator.")
print("Item=" + self.item)
collection = self.the_list
l =len(collection)
for n in range(l):
print(":" + collection[n].item)
return {'FINISHED'}
class OBJECT_PT_hello(bpy.types.Panel):
bl_label = "Hello World Panel"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
collection = []
my_class = cls_myClass
my_class.item = "Item #1"
collection.append(my_class)
my_class = cls_myClass
my_class.item = "Item #2"
collection.append(my_class)
def draw(self, context):
ob = context.object
if ob != None:
layout = self.layout
layout.operator("object.simple_operator", icon = "ZOOMIN").add = True
layout.operator("object.simple_operator", icon="ZOOMOUT", text="").item="My String"
def register():
bpy.utils.register_class(SimpleOperator)
bpy.utils.register_class(OBJECT_PT_hello)
def unregister():
bpy.utils.unregister_class(SimpleOperator)
bpy.utils.unregister_class(OBJECT_PT_hello)
if __name__ == "__main__":
register()
One button passes a string (you could pass you list here if it was hackishly delimited).
The other button passes a Boolean.
I also left in an attempt at creating a collection of classes to pass to the operator, but that always end in some kind of read-only error (you may have encountered as well)
Atom, thanks for your answer and code snippet, this is interesting.
We can’t use the select flag because this is an exporter for a game, in two parts. The upper level part decides what needs to be exported, does quite a bit of logic to determine which objects are exporter together, which objects are exported alone, which are not exported at all, etc. And when it determined everything we invoke the model exporter, giving it a list of objects to export. So our current design has two different operators, and the main export operator needs to be able to communicate with the model exporter when it’s invoked. We could merge the two into a single operator but I think this would be ugly and break encapsulation and good design principles
So I think I’ll just go for a collection of object names, thanks
EDIT: oops, I’d missed the part about read-only error -.- I’ll see what I can do
If the selection field is reserved, for some reason, you can always add another custom property to all objects in Blender and use that as your detection method.