Maybe removing "cast" isn't so simple. When I tried to access the Sketchpoint of the tangent line directly, the system throws an error suggesting a bug in the proxy scheme, so I left it and documented the issue inline. Below is the make_spline function. This works as much as I've tested it.
def get_z_vec(xform):
return xform.getAsCoordinateSystem()[3]
def get_3Dsketch(sketch_name, comp): # lie, makes it if doesn't exist
# also get the xy plane because that matches the 3D axis set
logger.info("found {} existing sketches".format(comp.sketches.count))
the_sketch = comp.sketches.itemByName(sketch_name)
if the_sketch is None:
the_sketch = comp.sketches.add(comp.xYConstructionPlane)
the_sketch.name = sketch_name
logger.info("creating sketch {}".format(sketch_name))
else:
logger.info("found sketch {}".format(sketch_name))
return the_sketch
def to_point3d(point):
"""Returns a copy of a Point3D, Sketchpoint, or proxied Sketchpoint
as Point3D"""
if isinstance(point, Point3D):
return point.copy()
if isinstance(point, SketchPoint):
#cast is required because some bug in the proxy system
#won't allow direct access to the sketchpoint properties
#using a tangent line
return adsk.fusion.SketchPoint.cast(point).geometry.copy()
def move_sketch_point(skpoint, dest_point):
"""move point1 to the location of point2 (without destroying stuff)"""
p1 = to_point3d(skpoint)
p2 = to_point3d(dest_point)
skpoint.move(p1.vectorTo(p2))
def get_end_tangent_handles(the_spline):
"""Get tangent handle line of sketchpoint, activating if necessary"""
start_tan = the_spline.getTangentHandle(the_spline.startSketchPoint)
if not start_tan:
start_tan = the_spline.activateTangentHandle(the_spline.startSketchPoint)
end_tan = the_spline.getTangentHandle(the_spline.endSketchPoint)
if not end_tan:
end_tan = the_spline.activateTangentHandle(the_spline.endSketchPoint)
return start_tan, end_tan
def make_spline(comp, target_name):
""" makes a spline in component comp
Search the occurances in comp for a name and draw a spline between
their origins on a dedicated sketch.
Create sketch if doesn't exist.
Adjust existing spline if it already exists.
"""
STRETCH = 1
# Get list of connectors
conns = [o for o in comp.allOccurrences if o.component.name == target_name]
if len(conns) != 2:
logger.error("expected 2 {}, got {}".format(CONN_NAME, len(conns)))
return None
#find start and end vectors
start_frame = conns[0].transform
end_frame = conns[1].transform
# beginning and end are the origins of the connectors
# exit vector is along the z axis of the connector * STRETCH
start0 = start_frame.translation.asPoint()
start1 = start0.copy()
start_vec = get_z_vec(start_frame)
start_vec.scaleBy(STRETCH) # really need a better parameter concept than "stretch"
start1.translateBy(start_vec)
end0 = end_frame.translation.asPoint()
end1 = end0.copy()
end_vec = get_z_vec(end_frame)
end_vec.scaleBy(STRETCH)
end1.translateBy(end_vec)
points = adsk.core.ObjectCollection.create() # todo try to use simple list see what happens
points.add(start0) # start of spline
points.add(end0) # end of spline
#create/find sketch in comp0
spline_sketch = get_3Dsketch(SPLINE_SKETCH_NAME, comp)
#find existing spline and adjust if exists, else make new
spline_count = spline_sketch.sketchCurves.sketchFittedSplines.count
logger.info("found {} splines".format(spline_count))
if spline_count > 1:
return
if spline_count == 0:
logger.info("creating new spline")
the_spline = spline_sketch.sketchCurves.sketchFittedSplines.add(points)
else: # spline count == 1
logger.info("adjusting old spline")
the_spline = spline_sketch.sketchCurves.sketchFittedSplines.item(0)
move_sketch_point(the_spline.startSketchPoint, start0)
move_sketch_point(the_spline.endSketchPoint, end0)
#get the end tangent handles of the spline to adjust it to
#take off on the z axis
start_tan, end_tan = get_end_tangent_handles(the_spline)
# at start point, the end tangent handle is toward spline and viceversa
move_sketch_point(start_tan.endSketchPoint, start1)
move_sketch_point(end_tan.startSketchPoint, end1)
return the_spline