first step spline animation
This commit is contained in:
parent
7de8fcc5d1
commit
58e0df3427
2 changed files with 152 additions and 4 deletions
14
__init__.py
14
__init__.py
|
@ -2040,13 +2040,27 @@ def on_depsgraph_update(scene, depsgraph):
|
|||
elif butils.is_text_object_legit(u.id.original):
|
||||
# must be duplicate
|
||||
link_text_object_with_new_text_properties(u.id.original, scene)
|
||||
# butils.prepare_text(
|
||||
# text_properties.font_name,
|
||||
# text_properties.face_name,
|
||||
# text_properties.text,
|
||||
# )
|
||||
elif (
|
||||
butils.is_text_object_legit(u.id.original)
|
||||
and len(u.id.original.users_collection) > 0
|
||||
):
|
||||
# must be a new thing, maybe manually created or so
|
||||
link_text_object_with_new_text_properties(u.id.original, scene)
|
||||
# butils.prepare_text(
|
||||
# text_properties.font_name,
|
||||
# text_properties.face_name,
|
||||
# text_properties.text,
|
||||
# )
|
||||
butils.clean_text_properties()
|
||||
try:
|
||||
butils.set_text_on_curve(text_properties)
|
||||
except:
|
||||
pass
|
||||
update_active_text_index()
|
||||
unlock_depsgraph_updates()
|
||||
|
||||
|
|
142
butils.py
142
butils.py
|
@ -217,6 +217,118 @@ def calc_bezier_length(bezier_point_1, bezier_point_2, resolution=20):
|
|||
return length
|
||||
|
||||
|
||||
def get_hook_modifiers(blender_object: bpy.types.Object):
|
||||
return [m for m in blender_object.modifiers if m.type == "HOOK"]
|
||||
|
||||
|
||||
class BezierSplinePoint:
|
||||
def __init__(
|
||||
self,
|
||||
co: mathutils.Vector,
|
||||
handle_left: mathutils.Vector,
|
||||
handle_right: mathutils.Vector,
|
||||
):
|
||||
self.co: mathutils.Vector = co
|
||||
self.handle_left: mathutils.Vector = handle_left
|
||||
self.handle_right: mathutils.Vector = handle_right
|
||||
|
||||
|
||||
class BezierSpline:
|
||||
def __init__(
|
||||
self,
|
||||
n: int,
|
||||
use_cyclic_u: bool,
|
||||
resolution_u: int,
|
||||
):
|
||||
self.bezier_points = [BezierSplinePoint] * n
|
||||
self.use_cyclic_u: int = use_cyclic_u
|
||||
self.resolution_u: int = resolution_u
|
||||
self.beziers: []
|
||||
self.lengths: [float]
|
||||
self.total_length: float
|
||||
|
||||
def calc_length(self, resolution) -> float:
|
||||
# ignore resolution when accessing length to imitate blender function
|
||||
print(f"{self.total_length=}")
|
||||
return self.total_length
|
||||
|
||||
|
||||
class BezierData:
|
||||
def __init__(self, n):
|
||||
self.splines = [BezierSpline] * n
|
||||
|
||||
|
||||
class BezierCurve:
|
||||
def __init__(self, blender_curve: bpy.types.Object, resolution_factor=1.0):
|
||||
self.data = BezierData(len(blender_curve.data.splines))
|
||||
i = 0
|
||||
hooks = get_hook_modifiers(blender_curve)
|
||||
print(f"{blender_curve.name=} =============================================")
|
||||
for si, blender_spline in enumerate(blender_curve.data.splines):
|
||||
self.data.splines[si] = BezierSpline(
|
||||
len(blender_spline.bezier_points),
|
||||
blender_spline.use_cyclic_u,
|
||||
blender_spline.resolution_u,
|
||||
)
|
||||
for pi, blender_bezier_point in enumerate(blender_spline.bezier_points):
|
||||
self.data.splines[si].bezier_points[pi] = BezierSplinePoint(
|
||||
blender_bezier_point.co,
|
||||
blender_bezier_point.handle_left,
|
||||
blender_bezier_point.handle_right,
|
||||
)
|
||||
print(pi)
|
||||
for hook in hooks:
|
||||
hook_co = False
|
||||
hook_handle_left = False
|
||||
hook_handle_right = False
|
||||
for vi in hook.vertex_indices:
|
||||
if vi == i * 3:
|
||||
hook_handle_left = True
|
||||
elif vi == i * 3 + 1:
|
||||
hook_co = True
|
||||
elif vi == i * 3 + 2:
|
||||
hook_handle_right = True
|
||||
if hook_co:
|
||||
location = (
|
||||
blender_curve.matrix_world.inverted()
|
||||
@ hook.object.matrix_world.translation
|
||||
)
|
||||
print(f"co {location=}")
|
||||
self.data.splines[si].bezier_points[pi].co = (
|
||||
self.data.splines[si]
|
||||
.bezier_points[pi]
|
||||
.co.lerp(location, hook.strength)
|
||||
)
|
||||
# if hook_handle_left:
|
||||
# location = (
|
||||
# hook.object.matrix_world.translation
|
||||
# - blender_curve.matrix_world.translation
|
||||
# ) + mathutils.Vector((-1, 0, 0))
|
||||
# print(f"handle_left {location=}")
|
||||
# self.data.splines[si].bezier_points[pi].handle_left = (
|
||||
# self.data.splines[si]
|
||||
# .bezier_points[pi]
|
||||
# .handle_left.lerp(location, hook.strength)
|
||||
# )
|
||||
# if hook_handle_right:
|
||||
# location = (
|
||||
# hook.object.matrix_world.translation
|
||||
# - blender_curve.matrix_world.translation
|
||||
# )
|
||||
# self.data.splines[si].bezier_points[pi].handle_right = (
|
||||
# self.data.splines[si]
|
||||
# .bezier_points[pi]
|
||||
# .handle_right.lerp(location, hook.strength)
|
||||
# )
|
||||
i += 1
|
||||
(
|
||||
self.data.splines[si].beziers,
|
||||
self.data.splines[si].lengths,
|
||||
self.data.splines[si].total_length,
|
||||
) = get_real_beziers_and_lengths(self.data.splines[si], resolution_factor)
|
||||
print(f"total length {self.data.splines[si].total_length}")
|
||||
|
||||
|
||||
def get_real_beziers_and_lengths(bezier_spline_obj, resolution_factor):
|
||||
beziers = []
|
||||
lengths = []
|
||||
|
@ -277,8 +389,14 @@ def calc_point_on_bezier_spline(
|
|||
# if the bezier points sit on each other we have same issue
|
||||
# but that is then to be fixed in the bezier
|
||||
if p.handle_left == p.co and len(bezier_spline_obj.bezier_points) > 1:
|
||||
beziers, lengths, total_length = get_real_beziers_and_lengths(
|
||||
bezier_spline_obj, resolution_factor
|
||||
beziers, lengths, total_length = (
|
||||
get_real_beziers_and_lengths(bezier_spline_obj, resolution_factor)
|
||||
if not isinstance(bezier_spline_obj, BezierSpline)
|
||||
else (
|
||||
bezier_spline_obj.beziers,
|
||||
bezier_spline_obj.lengths,
|
||||
bezier_spline_obj.total_length,
|
||||
)
|
||||
)
|
||||
travel_point = calc_point_on_bezier(beziers[0][1], beziers[0][0], 0.001)
|
||||
travel = travel_point.normalized() * distance
|
||||
|
@ -291,8 +409,14 @@ def calc_point_on_bezier_spline(
|
|||
else:
|
||||
return location
|
||||
|
||||
beziers, lengths, total_length = get_real_beziers_and_lengths(
|
||||
bezier_spline_obj, resolution_factor
|
||||
beziers, lengths, total_length = (
|
||||
get_real_beziers_and_lengths(bezier_spline_obj, resolution_factor)
|
||||
if not isinstance(bezier_spline_obj, BezierSpline)
|
||||
else (
|
||||
bezier_spline_obj.beziers,
|
||||
bezier_spline_obj.lengths,
|
||||
bezier_spline_obj.total_length,
|
||||
)
|
||||
)
|
||||
|
||||
iterated_distance = 0
|
||||
|
@ -336,6 +460,8 @@ def calc_point_on_bezier_curve(
|
|||
output_spline_index=False,
|
||||
resolution_factor=1.0,
|
||||
):
|
||||
# bezier_curve = BezierCurve(bezier_curve_obj)
|
||||
# curve = bezier_curve.data
|
||||
curve = bezier_curve_obj.data
|
||||
|
||||
# Loop through all splines in the curve
|
||||
|
@ -343,6 +469,7 @@ def calc_point_on_bezier_curve(
|
|||
for i, spline in enumerate(curve.splines):
|
||||
resolution = int(spline.resolution_u * resolution_factor)
|
||||
length = spline.calc_length(resolution=resolution)
|
||||
print(f"{utils.LINE()} {length=}")
|
||||
if total_length + length > distance or i == len(curve.splines) - 1:
|
||||
if output_spline_index and output_tangent:
|
||||
# return value from c_p_o_b_s is a tuple
|
||||
|
@ -1704,7 +1831,11 @@ def set_text_on_curve(
|
|||
# global lock_depsgraph_update_n_times
|
||||
|
||||
# starttime = time.perf_counter_ns()
|
||||
if text_properties is None:
|
||||
return False
|
||||
mom = text_properties.text_object
|
||||
if mom is None:
|
||||
return False
|
||||
if mom.type != "CURVE":
|
||||
return False
|
||||
if len(mom.users_collection) < 1:
|
||||
|
@ -1812,6 +1943,9 @@ def set_text_on_curve(
|
|||
location, tangent, spline_index = calc_point_on_bezier_curve(
|
||||
mom, applied_advance, True, True
|
||||
)
|
||||
# location, tangent, spline_index = calc_point_on_bezier_curve(
|
||||
# mom_hooked, applied_advance, True, True
|
||||
# )
|
||||
|
||||
# check if we are on a new line
|
||||
if spline_index != previous_spline_index:
|
||||
|
|
Loading…
Add table
Reference in a new issue