Add Lattice Magic to Addons #48

Merged
Nick Alberelli merged 36 commits from feature/lattice_magic into main 2023-05-17 20:48:52 +02:00
2 changed files with 43 additions and 7 deletions
Showing only changes of commit d7b10433ae - Show all commits

View File

@ -71,7 +71,7 @@ def draw_lattice_reset(self, context):
self.layout.operator(LATTICE_OT_Reset.bl_idname, text="Reset Point Positions", icon='FILE_REFRESH')
classes = [
LATTICE_OT_Reset
LATTICE_OT_Reset
]
def register():

View File

@ -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):