1
$\begingroup$

In reference to my other question, i try to display my properties operator directly in the UI Panel, but when i "click" on the created buttons and field, nothing happens.

For my tow parameters "axis" and "newdim" :

The action takes place here: bpy.context.object.axis = y

The action takes place here: bpy.context.object.newdim = 2.5

where i need it takes place like this:

bpy.data.window_managers["WinMan"].(null) = 2.5
bpy.data.window_managers["WinMan"].(null) = 'y'
bpy.ops.object.resize_proportional(axis='y', newdim=2.5)

So, change value have no effect. How can i have this panel presentation in UI (like the script bellow), with direcly choice between X, Y and Z, and directly de width value adjustable, and above all this to take effect ?

from bpy import *
import bpy
from bpy.props import FloatProperty, EnumProperty

#————————————————————————————————————————————————————————————————————————————————#
    # The Resize Operator
#————————————————————————————————————————————————————————————————————————————————#
class ResizeProportional(bpy.types.Operator):
    bl_idname = "object.resize_proportional"
    bl_label = "Choose_the_Right_Axis"
    bl_description = "This is to choose the axis"
    bl_options = {'REGISTER', 'UNDO'}

    axis = EnumProperty(
            name="Axis",
            description="Axis selection",
            items= [('x', "X", ""),('y', "Y", ""),('z', "Z","")],
            default='x'
            )

    newdim = FloatProperty(
            name="Width",
            description="Scale",
            min=0.01, max=100.0,
            default=1,
            )

    # The Resize function
    #———————————————————————————————————#
    def scale(self, axis, new_dim):
        ob = bpy.context.active_object
        d = ob.dimensions

        x = d[0]
        y = d[1]
        z = d[2]

        scale =  axis

        if( scale == "x"):
            indice = 0
        elif( scale == "y"):
            indice = 1
        else:
            indice = 2

        old_dim = d[indice] 
        factor = new_dim / old_dim

        scale_x = ob.scale[0]
        scale_y = ob.scale[1]
        scale_z = ob.scale[2]

        ob.scale[0] = scale_x * factor
        ob.scale[1] = scale_y * factor
        ob.scale[2] = scale_z * factor

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

    def execute(self, context):
        self.scale(self.axis,self.newdim)
        return {'FINISHED'}

#————————————————————————————————————————————————————————————————————————————————#
    # The Proportional Dimensions Panel
#————————————————————————————————————————————————————————————————————————————————#
class ProportionalDimensions(bpy.types.Panel):
    """Creates a Panel in the Object UI window"""
    bl_label = "Proportional Dimensions"
    bl_idname = "prop_dim"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    #bl_context = "object"

    def draw(self, context):
        layout = self.layout
        obj = context.object

        layout.prop(obj, "my_global_axis", expand=True)
        layout.prop(obj, "my_global_newdim")

        #props = layout.operator(ResizeProportional.bl_idname)
        #props.axis = obj.my_global_axis

        #layout = self.layout
        #layout.operator(ResizeProportional.bl_idname, text ="Resize active object: "+ obj.name)

#————————————————————————————————————————————————————————————————————————————————#

def register():
    bpy.utils.register_class(ProportionalDimensions)
    bpy.utils.register_class(ResizeProportional)

    bpy.utils.register_module(__name__)

    bpy.types.Object.my_global_axis = EnumProperty(
        name="Axis",
        description="Axis selection",
        items= [('x', "X", ""),('y', "Y", ""),('z', "Z","")],
        default='x'
    )

    bpy.types.Object.my_global_newdim = FloatProperty(
        name="Width",
        description="Scale",
        min=0.01, max=100.0,
        default=1,
    )


def unregister():
    bpy.utils.unregister_class(ProportionalDimensions)
    bpy.utils.unregister_class(ResizeProportional)

    bpy.utils.unregister_module(__name__)

    del bpy.types.Object.axis
    del bpy.types.Object.newdim

if __name__ == "__main__":
    register()
$\endgroup$
  • $\begingroup$ Is this question primarily about how to resize proportionally? I don't see a reason why you would want to implement that, there are already multiple built-in ways to do that - S to scale (with optional keyboard input) and multi-number editing. To do something alike with Python, I would probably use a property with callback, but it's a bit tricky to not create infinite loops. $\endgroup$ – CodeManX Feb 4 '15 at 11:08
  • $\begingroup$ There is no tools, and no ways to do this. Exemple : you make a bottle to a exact size like 1 unit = 1 cm (for exemple). You bottle messure x: 6,8 cm, and y: 3,2 cm. Your client want to change this after to x: 4,36 (again for exemple), but you must keep exactly the proportions of the bottle created. So, how could you do that ? you can't, in blender you juste can't. the scale is approximative and you can't specify an exact measure. With this tool, you can. $\endgroup$ – Fabrice Feb 4 '15 at 14:16
  • $\begingroup$ 4.36cm / 6.8cm = ~0.6412, select the bottle, hit S and type 0.6412 to rescale to exact dimensions while keeping proportions. If you want to make this a tool that automatically uses e.g. the bounding box dimensions of either of the 3 axes, I would use a props dialog. Also see blender.stackexchange.com/questions/4890/… (but note that proportions are not kept if you edit a single scale property). $\endgroup$ – CodeManX Feb 4 '15 at 15:21
1
$\begingroup$

There is a simple workflow to resize an object, without the need to code any new tools.

Going from your comments I will be resizing a bottle. First open the Properties panel with N.
In object mode simply type the new dimension for any of the three axes in to the proper Dimensions field in the properties panel.
The Next step is to copy the new scale value to the other two axes. Simply hover over the changed scale field and press CtrlC, then hover over the two unscaled axis and press CtrlV.
Last (if you want the object's scale set to one) apply the new scale with A > *Scale*, or in the 3D view header *Object > Apply > Scale*.

You now have a resized object with the exact same portions as the original.

bottle to resize with properties panel open bottle after changing a dimension for one of the axes

| improve this answer | |
$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.