I went in a different direction and used a DialogOperator. While I can’t make it work from the object context menu (I’ve asked about that under the Python tag), I was trying to reduce pointer movement. (I use a 4K screen and sometimes it’s a long way from an object I’m working with to the Blender menu.)
I’m now using this script as an add-on. It appends the item to the end of the Object View Menu (and I added it to my Quick Menu). Using the DialogOperator saves me mouse movement, since the dialog pops up under my pointer. Since I use this with my quick menu, it’s very little mouse movement to do the scaling work.
I have 3 items I would still like to work out:
-
I used an unregister() function the way I’ve seen it done in examples, so it should work, but I get an error if I call it. (However, when I have it installed as an add-on, and uncheck the box so it’s removed, I don’t get an error.) I’ve posted about that in another thread (as yet unanswered).
-
As mentioned, if I use the Object Context Menu (VIEW3D_MT_object_context_menu
) and pick this from that menu, the dialog never opens up. I can’t find out why. I’ve asked about it here.
-
I want to add another button to the DialogOperator and have it trigger a cancel function. I know you can cancel with , but I’d like a button on the dialog box because often I tend to think more with the pointer than hitting a key on the keyboard. I’ve tried to find out how to add a button to the box, but I see very little that is both recent and useful for this.
Okay, so here’s the updated script, with comments:
#=============================================================================================
#Shrinkage Scaler (Add-on for Blender)
#
#Used for designing clay molds. Clays always shrink when fired. (Side note: For most pottery
#work, you make the piece, fire it to bisque it, so it's hard and moisture is removed, then put
#the glaze on, then fire again. Most clays will shrink from 8-12%, some shrink more.)
#If a mold is needed, then the size of the mold can depend on the shrinkage rate for the clay.
#
#For example, if Standard Clay's 182 will shrink 11% at cone 8. So the mold for something that
#will be fired at cone 8 needs to be made so when the clay it's used on shrinks 11%, it'll be
#the size needed. Note this means the mold has to be more than 11% bigger than the final size.
#The size can be figured out by 100 / (100 - shrink rate), or, for this, 100 / (100 - 11), or
#100/89, which comes out to 112.359550561798% of the intended size.
#
#This adds a function to the object menu "Shrinkage Scaler", that, when picked, brings up a
#dialog with one INT object in it. It defaults to 10. Select the shrinkage rate from there.
#The amount to scale up, so it will shrink to the right size, is calculated, and the selected
#object is scaled up as needed.
#
#TODO:
# * Make work from object context menu
# * Add Cancel button
#
#=============================================================================================
import bpy
bl_info = {
"name" : "Shrinkage Scaler",
"blender" : (4, 0, 2),
"category" : "Object"
}
class ShrinkageScalerDialog(bpy.types.Operator):
bl_idname = "object.dialog_operator"
bl_label = "Shrinkage Scaler"
shrink_rate: bpy.props.IntProperty(name="Clay Shrink Rate",
description="Shrinkage rate for clay body",
default=10, min=0, max=90, subtype='PERCENTAGE')
def execute(self, context):
expand = 100 / (100 - self.shrink_rate)
message = "Using shrinkage rate of %s and expansion rate of %s" % (self.shrink_rate, expand)
self.report({'INFO'}, message)
sel_objs = [obj for obj in bpy.context.selected_objects if obj.type == 'MESH']
# bpy.ops.object.select_all(action='DESELECT')
for obj in sel_objs:
s = obj.scale
obj.scale = (s[0] * expand, s[1] * expand, s[2] * expand)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
# Only needed if you want to add into a dynamic menu.
def menu_func(self, context):
self.layout.operator(ShrinkageScalerDialog.bl_idname, text=ShrinkageScalerDialog.bl_label)
def register():
bpy.utils.register_class(ShrinkageScalerDialog)
bpy.types.VIEW3D_MT_object.append(menu_func)
# bpy.types.VIEW3D_MT_object_context_menu.append(menu_func)
def unregister():
bpy.utils.unregister_class(ShrinkageScalerDialog)
bpy.types.VIEW3D_MT_object.remove(menu_func)
# bpy.types.VIEW3D_MT_object_context_menu.remove(menu_func)
if __name__ == "__main__":
register()
# unregister()