Hi I'm wanting to break a spline with multiple fit points into multiple individual splines.
I can import the spline points from a csv, create the spline, add lines at every fit point so I can break the sketch up manually but I was wondering if there is a function to break the sketch using the fusion api, i.e <Sketch>.break(<3D_Point_1, <3D_Point_2>)
Cheers,
Luke
Solved! Go to Solution.
Solved by Jorge_Jaramillo. Go to Solution.
Solved by kandennti. Go to Solution.
Hi @lukeQA94F -San.
I tried to find it, but there seems to be no break function.
I tried to make a sample using the text command, but I don't think it is useful for actual use.
# Fusion360API Python script
import traceback
import adsk.core as core
import adsk.fusion as fusion
def run(context):
ui: core.UserInterface = None
try:
app: core.Application = core.Application.get()
ui = app.userInterface
app.documents.add(core.DocumentTypes.FusionDesignDocumentType)
des: fusion.Design = app.activeProduct
root: fusion.Component = des.rootComponent
ary = [
[0, 0, 0],
[1, 3, 0],
[2, -1, 0],
[3, 0, 0],
[4, 2, 0],
[5, 0, 0],
]
points = [core.Point3D.create(*a) for a in ary]
skt: fusion.Sketch = root.sketches.add(
root.xYConstructionPlane
)
crv: fusion.SketchFittedSpline = create_spline(skt, points)
break_curve_by_points(crv, points[1:-1])
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def break_curve_by_points(
crv: fusion.SketchEntity,
points: list[core.Point3D],
):
app: core.Application = core.Application.get()
sels: core.Selections = app.userInterface.activeSelections
skt: fusion.Sketch = crv.parentSketch
target: fusion.SketchFittedSpline = crv
for pnt in points:
sels.clear()
sels.add(skt)
app.executeTextCommand(u"Commands.Start SketchActivate")
target = break_curve(target, pnt)
app.executeTextCommand(u"Commands.Start SketchStop")
def break_curve(
crv: fusion.SketchEntity,
point: core.Point3D,
):
app: core.Application = core.Application.get()
sels: core.Selections = app.userInterface.activeSelections
eva: core.CurveEvaluator3D = crv.geometry.evaluator
_, prm = eva.getParameterAtPoint(point)
_, vec, _ = eva.getCurvature(prm)
vec.scaleBy(0.01)
sPnt: core.Point3D = point.copy()
sPnt.translateBy(vec)
vec.scaleBy(-1)
ePnt: core.Point3D = point.copy()
ePnt.translateBy(vec)
skt: fusion.Sketch = crv.parentSketch
lines: fusion.SketchLines = skt.sketchCurves.sketchLines
tool: fusion.SketchLine = lines.addByTwoPoints(sPnt, ePnt)
sels.clear()
sels.add(crv)
app.executeTextCommand(u"Commands.Start BreakSketchCmd")
try:
tool.deleteMe()
except:
pass
sels.clear()
return skt.sketchCurves[-1]
def create_spline(
skt: fusion.Sketch,
points: list[core.Point3D],
) -> fusion.SketchFittedSpline:
splines: fusion.SketchFittedSplines = skt.sketchCurves.sketchFittedSplines
return splines.add(
core.ObjectCollection.createWithArray(points)
)
@lukeQA94F -San.
Another idea is to use parameters to create a new curve for each interval and delete the original curve.
# Fusion360API Python script
import traceback
import adsk.core as core
import adsk.fusion as fusion
def run(context):
ui: core.UserInterface = None
try:
app: core.Application = core.Application.get()
ui = app.userInterface
app.documents.add(core.DocumentTypes.FusionDesignDocumentType)
des: fusion.Design = app.activeProduct
root: fusion.Component = des.rootComponent
ary = [
[0, 0, 0],
[1, 3, 0],
[2, -1, 0],
[3, 0, 0],
[4, 2, 0],
[5, 0, 0],
]
points = [core.Point3D.create(*a) for a in ary]
skt: fusion.Sketch = root.sketches.add(
root.xYConstructionPlane
)
crv: fusion.SketchFittedSpline = create_spline(skt, points)
create_split_curve_by_points(crv, points)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def create_split_curve_by_points(
crv: fusion.SketchEntity,
points: list[core.Point3D],
removeOriginal: bool = True,
):
geo = crv.geometry
nurbs: core.NurbsCurve3D = None
if hasattr(geo, "asNurbsCurve"):
nurbs = geo.asNurbsCurve
else:
nurbs = geo
eva: core.CurveEvaluator3D = nurbs.evaluator
_, prms = eva.getParametersAtPoints(points)
crvs = [nurbs.extract(s, e) for s, e in zip(prms, prms[1:])]
skt: fusion.Sketch = crv.parentSketch
splines: fusion.SketchFixedSplines = skt.sketchCurves.sketchFixedSplines
[splines.addByNurbsCurve(c) for c in crvs]
if removeOriginal:
crv.deleteMe()
def create_spline(
skt: fusion.Sketch,
points: list[core.Point3D],
) -> fusion.SketchFittedSpline:
splines: fusion.SketchFittedSplines = skt.sketchCurves.sketchFittedSplines
return splines.add(
core.ObjectCollection.createWithArray(points)
)
@Jorge_Jaramillo - this post is being edited to remove PII.
Hi @lukeQA94F ,
I was able to split the curve with the spline's built-in function breakCurve().
Here is the code:
def break_spline():
points = [(0,0,0), (5,-1,0), (6,4,0), (2,5,0), (-1,2,0)]
oc = adsk.core.ObjectCollection.create()
for coords in points:
oc.add(adsk.core.Point3D.create(*coords))
# gets first sketch on root's current desing
skt = root.sketches[0]
# creates spline with the points provided
sfs = skt.sketchCurves.sketchFittedSplines.add(oc)
sfs.isClosed = True
# print lines on the sketch
app.log('Before splitting:')
for i in range(skt.sketchCurves.count):
app.log(f' {i} {skt.sketchCurves[i]}')
# make n-1 curve breaks
for i in range(len(points)-1):
# make a circle intersecting the curve in points i-th and (i+1)-th
sk_c = skt.sketchCurves.sketchCircles.addByTwoPoints(oc[i], oc[i+1])
# get a point before and near the (i+1)-th point
#
# it has to be different that the intersecting point, so that is why it is multiplied by 90%
#
(_, par) = sfs.geometry.evaluator.getParameterAtPoint(oc[i+1])
par *= 0.9
(_, po_break) = sfs.geometry.evaluator.getPointAtParameter(par)
# then break the curve using that point
ocr = sfs.breakCurve(po_break)
# delete the circle
sk_c.deleteMe()
# look for the original spline in the sketchFittedSplines collection
# I could NOT use the endSketchPoint attribute because it generates an exception
# (it is possible a BUG!! since every spline has to contain an endSketchPoint)
for sfs_i in range(skt.sketchCurves.sketchFittedSplines.count):
if skt.sketchCurves.sketchFittedSplines[sfs_i].fitPoints.count:
fitPoints = skt.sketchCurves.sketchFittedSplines[sfs_i].fitPoints.count
if skt.sketchCurves.sketchFittedSplines[sfs_i].fitPoints[fitPoints-1].geometry.isEqualTo(oc[0]):
sfs = skt.sketchCurves.sketchFittedSplines[sfs_i]
break
# print lines on the sketch
app.log('After splitting:')
for i in range(skt.sketchCurves.count):
app.log(f' {i} {skt.sketchCurves[i]}')
After breaking the spline I experienced some errors trying to access start and end points of the result splines, which could be a bug in the product. That is the reason to check for fitpoints (line #40 in the code above) count first instead of the endSketchPoint attribute.
I hope this could help.
Regards,
Jorge Jaramillo
Cheers @kandennti and @Jorge_Jaramillo , both your solutions worked! Thanks for your help
Can't find what you're looking for? Ask the community or share your knowledge.