1
$\begingroup$

Does anyone know if it's possible to write a python code that enables you to manually set individual parameters for modifiers? For example:

Solidify-Modifier to set the wall thickness

bpy.ops.object.modifier_add(type='SOLIDIFY')
bpy.context.object.modifiers["Solidify"].thickness = 0.4 #[mm]
bpy.context.object.modifiers["Solidify"].use_even_offset = True
bpy.context.object.modifiers["Solidify"].use_quality_normals = True
bpy.context.object.modifiers["Solidify"].use_rim = True
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")

Is it possible to not set the value for the wall thickness in the code itself, but rather have the user type a value manually? This is only part of the code for a mesh-reparing Add-On I need for 3D Printing. And the wall thickness will depend on the structure. Any suggestions are appreciated!!

$\endgroup$
0
$\begingroup$

Invoke a popup dialog.

enter image description here

Test script to invoke a properties dialog to "manually" type in a thickness value, then add and apply a thickness modifier to a mesh object. I've called the operator "Add Thickness", hit F3 to bring up search.

Notice I've used the API method ob.modifiers.new(name, type) rather than the add modifier operator.

import bpy

class WM_OT_myop(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "wm.myop"
    bl_label = "Add thickness"
    # annotations in 2.8
    thickness : bpy.props.FloatProperty(name="Thickness", default=0.4)

    @classmethod
    def poll(cls, context):
        return (context.active_object is not None and context.object.type == 'MESH')

    def execute(self, context):
        ob = context.object
        m = ob.modifiers.new("Solidify", type='SOLIDIFY')
        m.thickness = self.thickness
        m.use_even_offset = True
        m.use_quality_normals = True
        m.use_rim = True
        bpy.ops.object.modifier_apply(apply_as='DATA', modifier=m.name)
        return {'FINISHED'}

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_dialog(self)


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

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

if __name__ == "__main__":
    register()

    # test call
    bpy.ops.wm.myop('INVOKE_DEFAULT')

Note this example is for 2.8. To make it for prior, change

thickness : bpy.props.FloatProperty(name="Thickness", default=0.4)

to

thickness = bpy.props.FloatProperty(name="Thickness", default=0.4)

and use the spacebar to bring up the operator search.

Note: I could have simply pasted your code into the execute method of the operator. This is why (on my soapbox) I strongly recommend using a context variable, eg a line context = bpy.context at the top of test code (not to paste if context is defined elsewhere). For example if the context is overridden in an operator the context passed to execute may not be bpy.context

| improve this answer | |
$\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.