Hello
I want write very simple button. Who is opening window with filepatch, useris choosing a object,and after import, Blender is rename object. I wrote such a script:
class Import(bpy.types.Operator):
"""Import"""
bl_idname = "fp.import"
bl_label = "Import"
def execute(self,context):
for obj in bpy.data.objects:
obj.tag = True
if not bpy.data.filepath:
bpy.ops.import_mesh.stl('INVOKE_AREA')
else:
bpy.ops.import_mesh.stl('INVOKE_AREA')
self.report({'INFO'}, 'File saved.')
for obj in bpy.context.selected_objects:
obj.name = "Bacon"
obj.data.name = "Bacon"
return {'FINISHED'}
But is not working. Name is changing, when I press second time a button with this class.
Can any one can help me ?
The reason it does not work is an Asynchronous issue in your code.
You call the operator invoke function : bpy.ops.import_mesh.stl('INVOKE_AREA')
Basically, it means this line instantly returns {RUNNING_MODAL}
In that case, the import_mesh operator is running asynchronously.
So, this loop :
for obj in bpy.context.selected_objects:
obj.name = "Bacon"
obj.data.name = "Bacon"
Is already executed when you are browsing your files.
To make sure you can try to add these prints :
Which shows that your import is actually run after the âafterâ print
What you want is having the import_mesh blocking (i.e. synchronously) so that, when itâs finished, you can run some piece of code AFTER itâs finished.
The way to run import_mesh synchronously is to call explicit files parameters like so : bpy.ops.import_mesh.stl(filepath=some_path_to_file)
Finaly, to do so you will need the user to be able to choose a file. That is done by calling context.window_manager.fileselect_add in your Operator Invoke function.
To conclude :
import bpy
class Import_STL_Custom(bpy.types.Operator):
bl_idname = "object.import_stl_custom"
bl_label = "Import STL Custom"
# Choosen path will be stored here
filepath : bpy.props.StringProperty(subtype="FILE_PATH")
# Filter files to show only STL
filter_glob : bpy.props.StringProperty(
default="*.stl;",
options={'HIDDEN'},
)
def invoke(self, context, event):
# Call the "choose file" browser
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
def execute(self, context):
# Explicit import_mesh call with self.filepath saved with invoked fileselect_add
bpy.ops.import_mesh.stl(filepath=self.filepath)
# Piece of code to be run AFTER import
for obj in bpy.context.selected_objects:
obj.name = "Bacon"
obj.data.name = "Bacon"
return {"FINISHED"}
def register():
bpy.utils.register_class(Import_STL_Custom)
def unregister():
bpy.utils.unregister_class(Import_STL_Custom)
if __name__ == "__main__":
register()
bpy.ops.object.import_stl_custom("INVOKE_DEFAULT")
Wooow.
Thaqnk You for this example. I have problems with invoke
But I have one problem. When I run a script without any problems, window manager is opening. But when I put this code to button, window manager is not opening and script is taking object from filepath,
which I wrote.
Greets, and one more time thank You for help.