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$

1 Answer 1

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$
1
  • $\begingroup$ Your script works beautifully, thanks! $\endgroup$
    – Noob Cat
    Jul 4, 2019 at 18:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .