0
$\begingroup$

THe classic method of scale 2d object is like to

###some script to configure ob data bmesh etc.
pivot = Vector(0.5,0.5)
scale_factor = 0.9 decrease scale example

for v in bm.verts:
    v.co -= pivot
    v.co.x *= scale_factor
    v.co.y *= scale_factor
    v.co += pivot

but i whant controll the scale with floatproperty in ui panel like to

pivot = Vector(0.5,0.5)
scale_factor = my_float_property

for v in bm.verts:
    v.co -= pivot
    v.co.x *= scale_factor
    v.co.y *= scale_factor
    v.co += pivot

Clearly this cannot work, I tried to declare a previous value in another floatproperty, so I tried:

def myfunction(self,context):
    custom = bpy.context.object.mycustomclass

    pivot = Vector(0.5,0.5)
    scale_factor = 1- (custom.my_float_property-custom.last_float)

    for v in bm.verts:
        v.co -= pivot
        v.co.x *= scale_factor
        v.co.y *= scale_factor
        v.co += pivot

    custom.last_float = custom.my_float_property

but have some problem,it is not accurate.

Any idea how to control the scale with a slider, in fact (my_float_property)?

$\endgroup$
2
$\begingroup$

Use a setter getter on the property

enter image description here

Can keep the previous value of a property using the custom property ob["scale_factor"] to store the previous value.

Warning will cause an issue if you hit exactly 0.0, which may need to be handled in some way.

import bpy

def draw(self, context):
    layout = self.layout
    ob = context.object
    layout.prop(ob, "scale_factor")

def set_float(self, value):
    prev_sf = self.get("scale_factor", 1)
    sf = value / prev_sf
    self.scale.xy *= sf
    self["scale_factor"] = value


def get_float(self):
    return self.get("scale_factor", 1)        

def register():
    bpy.types.Object.scale_factor = bpy.props.FloatProperty(get=get_float, set=set_float)
    bpy.types.TEXT_HT_footer.append(draw)

def unregister():
    pass
    # TODO

if __name__ == "__main__":
    register()

I have done the scaling on an object level here. For a mesh could use bmesh and

bmesh.ops.scale(bm, 
        vec=(sf, sf, 1),
        space=Matrix.Translation(-pp), # pivot point (x, y, 0)
        verts=bm.verts)

or simply make the scale and translation matrices and

import bpy
from mathutils import Matrix, Vector
pp = Vector((1, 1, 0))
sf = 2
me = bpy.context.object.data

Sxy = Matrix.Scale(sf, 4, (1, 0, 0)) @ Matrix.Scale(sf, 4, (0, 1, 0))

me.transform(Matrix.Translation(-pp))
me.transform(Sxy)
me.transform(Matrix.Translation(pp))
$\endgroup$
  • $\begingroup$ Your script works beautifully, thanks! $\endgroup$ – Pastrokkio Jul 4 at 18:51

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.