0
$\begingroup$

I'm trying to import a stl file manually via python. My code below is pretty straight forward, but I'm struggling with the following line. I'm not sure about the syntax and format of the arguments:

bpy.ops.import_mesh.stl(filepath=???, files=???)

The current state of my operator:

import bpy

class FILE_OT_import_stl(bpy.types.Operator):

    bl_idname = "file.import_model_stl"
    bl_label = "Import Model STL"
    bl_options = {'REGISTER', 'UNDO'} # Must have REGISTER!   

    def execute(self, context):
        #my_filepath = 'K:/PQJ/Mold Generator/Blender test/'
        #filepath = '//898L-OutputModel-SLA[]_09'
        #print(filepath)
        all_files=[bpy.types.Scene.import_path]
        #print(file[0])
        bpy.ops.import_mesh.stl(filepath=my_filepath, files=all_files)
        return {'FINISHED'}

class FILE_PANEL_PT_import_export(bpy.types.Panel):
    bl_label = "Import/Export"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    # bl_context = "object" # object vs edit mode

    def draw(self, context):
        layout = self.layout
        layout.label(text="Import")
               
        layout.prop(context.scene, "import_path")
        row = layout.row()                
        row.operator("file.import_model_stl")

classes = (
    FILE_OT_import_stl,
    FILE_PANEL_PT_import_export
)

def register():
    for cls in classes:
        bpy.types.Scene.import_path = bpy.props.StringProperty(name='Import path', subtype='FILE_PATH')
        bpy.utils.register_class(cls)

def unregister():
    del bpy.types.Scene.import_path
    for cls in classes:
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()

Q: How to import a certain STL file using the file browser (and add a custom material)?

$\endgroup$
5
  • $\begingroup$ Do bpy.ops.import_mesh.stl(filepath="your/path/here.stl"). $\endgroup$ – scurest Nov 13 '20 at 9:59
  • $\begingroup$ I tried that but it didn't work. Also I am trying not to hard code the path but get it from my custom prop. $\endgroup$ – DrDress Nov 13 '20 at 10:09
  • 1
    $\begingroup$ Depending on the situation you can just call bpy.ops.import_mesh.stl('INVOKE_DEFAULT') or use layout.operator("import_mesh.stl", text="Import STL", icon='FILE_NEW') in your draw method if you want to import 1 file. Have a look into the Operator File Import template (magic is done by its ImportHelper class). Related: How to use the File Browser's (with ImportHelper) execute function?, batch import example: How to batch import Wavefront OBJ files?. Do you'd like to import 1 or a few files? $\endgroup$ – brockmann Nov 13 '20 at 12:06
  • $\begingroup$ It's just 1 file and it needs to be selected by mouse click. After import I need to do a few things to the object - otherwise I could just use the import in the menu $\endgroup$ – DrDress Nov 13 '20 at 12:07
  • $\begingroup$ It is selected anyway... $\endgroup$ – brockmann Nov 13 '20 at 12:07
2
$\begingroup$

You can just add the built-in operator import_mesh.stl to your draw method of your panel which will open up the File Browser as usual and allows the user to select one .stl file:

enter image description here

import bpy

class OBJECT_PT_CustomPanel(bpy.types.Panel):
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"

    def draw(self, context):
        layout = self.layout
        #layout.operator_context = 'INVOKE_DEFAULT' #'INVOKE_AREA'
        layout.operator("import_mesh.stl", text="New", icon='FILE_NEW')

def register():
    bpy.utils.register_class(OBJECT_PT_CustomPanel)

def unregister():
    bpy.utils.unregister_class(OBJECT_PT_CustomPanel)

if __name__ == "__main__":
    register()

Related: How to call a confirmation dialog box?


In case you want to import and modify the .stl object for whatever reason, have a look into the Operator File Import template (operator_file_import.py) that comes with Blender.

enter image description here

Demo operator based on the template, allows to import the file, print the object reference and assigns a new material to the incoming object in one go:

# ImportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator

class ImportSomeData(Operator, ImportHelper):
    """This appears in the tooltip of the operator and in the generated docs"""
    bl_idname = "import_test.some_data"
    bl_label = "Import Some Stl File"
    bl_options = {'REGISTER', 'UNDO'}
    
    # ImportHelper mixin class uses this
    filename_ext = ".stl"
    filter_glob: bpy.props.StringProperty(
                default="*.stl",
                options={'HIDDEN'})
                
    def execute(self, context):
        if self.filepath:
            bpy.ops.import_mesh.stl(filepath=self.filepath)
            # Print the imported object reference
            print ("Imported object:", context.object)
            # Create a material
            mat = bpy.data.materials.new(name="STLMaterial")
            # Append the material to the last slot
            context.object.data.materials.append(mat)

        return {'FINISHED'}

Further reading:

$\endgroup$
3
  • $\begingroup$ Yeah. The 'INVOKE_DEFAULT' works like a charm. But I need to change the name of the object right after import (and maybe a few other things). This only imports (like in the menu) $\endgroup$ – DrDress Nov 13 '20 at 12:42
  • $\begingroup$ I have seen the template and it just says: "bpy.ops.import_mesh.stl(filepath=self.filepath)". I can't find where "self.filepath" is set. $\endgroup$ – DrDress Nov 13 '20 at 12:47
  • $\begingroup$ Comes from the ImportHelper class, see my demo code. $\endgroup$ – brockmann Feb 22 at 10:06

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.