Add Lattice Magic
to Addons
#48
@ -35,7 +35,7 @@ def ensure_tweak_lattice_collection(scene: bpy.types.Scene) -> bpy.types.Collect
|
||||
|
||||
def ensure_falloff_vgroup(
|
||||
lattice_ob: bpy.types.Object,
|
||||
vg_name="Group", multiplier=1) -> bpy.types.VertexGroup:
|
||||
vg_name="Group", multiplier=1, expression="x") -> bpy.types.VertexGroup:
|
||||
lattice = lattice_ob.data
|
||||
res_x, res_y, res_z = lattice.points_u, lattice.points_v, lattice.points_w
|
||||
|
||||
@ -53,7 +53,11 @@ def ensure_falloff_vgroup(
|
||||
|
||||
coord = Vector((x+2, y+2, z+2))
|
||||
distance_from_center = (coord-center).length
|
||||
influence = 1 - distance_from_center / max_res * 2
|
||||
distance_factor = 1 - (distance_from_center / max_res * 2)
|
||||
try:
|
||||
influence = eval(expression.replace("x", "distance_factor"))
|
||||
except:
|
||||
return None
|
||||
|
||||
vg.add([index], influence * multiplier, 'REPLACE')
|
||||
return vg
|
||||
@ -171,6 +175,7 @@ class TWEAKLAT_OT_Create(bpy.types.Operator):
|
||||
# Create some custom properties
|
||||
hook['Lattice'] = lattice_ob
|
||||
hook['Multiplier'] = 1.0
|
||||
hook['Expression'] = 'x'
|
||||
|
||||
rna_idprop_ui_create(
|
||||
hook, "Tweak Lattice", default = 1.0,
|
||||
@ -242,15 +247,36 @@ class TWEAKLAT_OT_Falloff(bpy.types.Operator):
|
||||
bl_label = "Adjust Falloff"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
def update(self, context):
|
||||
def update_falloff(self, context):
|
||||
if self.doing_invoke: return
|
||||
hook = context.object
|
||||
lattice_ob = hook['Lattice']
|
||||
ensure_falloff_vgroup(lattice_ob, 'Hook', multiplier=self.multiplier)
|
||||
ret = ensure_falloff_vgroup(lattice_ob, 'Hook', multiplier=self.multiplier, expression=self.expression)
|
||||
self.is_expression_valid = ret != None
|
||||
if ret:
|
||||
hook['Expression'] = self.expression
|
||||
hook['Multiplier'] = self.multiplier
|
||||
|
||||
is_expression_valid: BoolProperty(
|
||||
name = "Error",
|
||||
description = "Used to notify user if their expression is invalid",
|
||||
default = True
|
||||
)
|
||||
# Actual parameters
|
||||
multiplier: FloatProperty(name="Multiplier", default=1, update=update, min=0, soft_max=2)
|
||||
multiplier: FloatProperty(
|
||||
name="Multiplier",
|
||||
description = "Multiplier on the weight values",
|
||||
default=1,
|
||||
update=update_falloff,
|
||||
min=0,
|
||||
soft_max=2
|
||||
)
|
||||
expression: StringProperty(
|
||||
name="Expression",
|
||||
default="x",
|
||||
description = "Expression to calculate the weight values where 'x' is a 0-1 value representing a point's closeness to the lattice center",
|
||||
update=update_falloff,
|
||||
)
|
||||
|
||||
# Storage to share info between Invoke and Update
|
||||
lattice_start_scale: FloatVectorProperty()
|
||||
@ -268,6 +294,10 @@ class TWEAKLAT_OT_Falloff(bpy.types.Operator):
|
||||
self.hook_start_scale = hook.scale.copy()
|
||||
lattice_ob = hook['Lattice']
|
||||
self.lattice_start_scale = lattice_ob.scale.copy()
|
||||
if 'Expression' not in hook:
|
||||
# Back-comp for Tweak Lattices created with older versions of the add-on.
|
||||
hook['Expression'] = 'x'
|
||||
self.expression = hook['Expression']
|
||||
|
||||
self.doing_invoke = False
|
||||
wm = context.window_manager
|
||||
@ -277,6 +307,12 @@ class TWEAKLAT_OT_Falloff(bpy.types.Operator):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
layout.prop(self, 'expression', text="Expression", slider=True)
|
||||
if not self.is_expression_valid:
|
||||
row = layout.row()
|
||||
row.alert = True
|
||||
row.label(text="Invalid expression.", icon='ERROR')
|
||||
|
||||
layout.prop(self, 'multiplier', text="Strength", slider=True)
|
||||
|
||||
def execute(self, context):
|
||||
|
Loading…
Reference in New Issue
Block a user