If anyone is interested, here is a ChatGPT workaround. After the user snaps the transform node to the CV of a curve (unwanted behavior originally described) the script calculates the distance to the closest EP on the same curve and moves the transform node to that location. It's an extra step, but it can be used on a hotkey, so not too bad.
import maya.cmds as cmds
import maya.OpenMaya as om
def snap_transform_to_closest_curve_point():
# Get selected objects
selection = cmds.ls(selection=True, type='transform')
if len(selection) < 2:
cmds.error("Please select a transform node and a curve.")
return
transform_name = selection[0]
curve_name = selection[1]
# Check if the second selection is a curve
curve_shapes = cmds.listRelatives(curve_name, children=True, shapes=True)
if not curve_shapes or not cmds.objectType(curve_shapes[0], isType='nurbsCurve'):
cmds.error("Second selection must be a curve.")
return
# Get Edit Points of the curve
edit_points = cmds.ls(curve_name + '.ep[*]', fl=True)
if not edit_points: # Fallback to control vertices if no edit points
edit_points = cmds.ls(curve_name + '.cv[*]', fl=True)
# Get Transform Position
transform_position = cmds.xform(transform_name, q=True, ws=True, t=True)
if len(transform_position) == 3:
transform_pos = om.MVector(transform_position[0], transform_position[1], transform_position[2])
else:
cmds.error("Could not determine transform position.")
return
# Find Closest Curve Point
min_distance = float('inf')
closest_point = None
for point in edit_points:
point_pos = om.MVector(*cmds.pointPosition(point))
distance = (point_pos - transform_pos).length()
if distance < min_distance:
min_distance = distance
closest_point = point_pos
# Move Transform to Closest Curve Point
if closest_point:
cmds.move(closest_point.x, closest_point.y, closest_point.z, transform_name)
# Run the function
snap_transform_to_closest_curve_point()