# How to use Python to set the tilt of a curve towards a target object?

How to use Python to set the tilt of a curve towards a target object?

I wrote some code, but I encountered difficulties in setting the tilt and couldn't solve them. Please help me.

import bpy
import math

def find_closest_vertex(obj, target_vertex):
vertices = obj.data.vertices

min_distance = float("inf")
closest_vertex = None

for vertex in vertices:
distance = math.sqrt((vertex.co[0] - target_vertex[0]) ** 2 + (vertex.co[1] - target_vertex[1]) ** 2 + (vertex.co[2] - target_vertex[2]) ** 2)
if distance < min_distance:
min_distance = distance
closest_vertex = vertex

return closest_vertex

obj = bpy.data.objects["obj"]
splines = bpy.data.objects["curve"].data.splines

for spline in splines:
for point in spline.points:
# Get the location of the nearest point
target_loc = find_closest_vertex(obj, point.co[0:3]).co[0:3]

vector_to_target = (target_loc[0] - point.co[0], target_loc[1] - point.co[1], target_loc[2] - point.co[2])

# tilt
tilt = math.atan2(vector_to_target[1], vector_to_target[0])
tilt = tilt if tilt > -math.pi else tilt + 2 * math.pi

print(tilt)
point.tilt = tilt


That won't be a totally perfect result, but you can use the following:

See closest_point_on_mesh for more information.

Once you have the closest face normal, get its angle from the Z axis and use it as a tilt.

obj = bpy.data.objects["obj"]
splines = bpy.data.objects["curve"].data.splines

for spline in splines:
for point in spline.points:
# Get the location of the nearest point
point_co = point.co.xyz
(hit, loc, norm, face_index) = obj.closest_point_on_mesh(point_co)

tilt = Vector((0,0,1)).angle(norm)

print(tilt)
point.tilt = tilt


After upgrading to Blender 4.0, I have found a new solution that combines Geometry Nodes and Python, enabling me to achieve this functionality.

Just select the curve object, and then execute the Python code.

The approximate workflow is as follows: initially, calculate the correct tilt value using Geometry Nodes, and subsequently execute actions through Python to:

1. Duplicate the object;
2. Convert it into a mesh (since curves are not compatible with direct application of Geometry Node modifiers);
3. Transfer the Tilt property.

However, this method suffers from a performance issue due to my limited proficiency in mathematics. Consequently, I have had to resort to an iterative process within Geometry Nodes, which involves extending the normal direction of each point and comparing the distance between that point and the surface of the mesh to incrementally adjust the Tilt value.

I suspect there might be a more direct mathematical approach to calculate the precise Tilt value without requiring iterations. I am hoping someone can assist me with finding such a solution.