Might be related to https://forums.autodesk.com/t5/api-and-scripts/addfillet-in-sketchmode-between-a-line-and-arc/m-p/65...
I'm iterating through sketch to find all sketch points where an arc joins another arc or line, and trying to add a fillet between the two.
When it tries to add fillet between two Arcs it fails (I'm using sketchPoint.connectedEntities, but checking to make sure the connection is due to start/end rather than arc center). If I modify the code to only try fillets at points where a sketchArc meets a sketchLine it works.
points_to_fillet = [] for p in sketch.sketchPoints: if p.connectedEntities and p.connectedEntities.count == 2: if p.connectedEntities[0].classType()=="adsk::fusion::SketchArc" or p.connectedEntities[1].classType()=="adsk::fusion::SketchArc": if p.connectedEntities[0].startSketchPoint == p or p.connectedEntities[0].endSketchPoint == p: if p.connectedEntities[1].startSketchPoint == p or p.connectedEntities[1].endSketchPoint == p: points_to_fillet.append(p) for p in points_to_fillet: e1, e2 = p.connectedEntities fillet_point = p.geometry sketch.sketchCurves.sketchArcs.addFillet(e1, fillet_point, e2, fillet_point, radius)
I used a bunch of debugging print statements to get coordinates of p as well as e1 and e2 start/end sketch points and it looks like it should work:
---------- point p ---------- <adsk.fusion.SketchPoint; proxy of <Swig Object of type 'adsk::core::Ptr< adsk::fusion::SketchPoint > *' at 0x1497228a0> > x=1.139926523123076, y=9.246681703470033, z=0.0 ---------- entity e1 ---------- <adsk.fusion.SketchArc; proxy of <Swig Object of type 'adsk::core::Ptr< adsk::fusion::SketchArc > *' at 0x149722ba0> > start: x=8.027898386072238, y=-2.683635524262752, z=0.0 end: x=1.139926523123076, y=9.246681703470033, z=0.0 ---------- entity e2 ---------- <adsk.fusion.SketchArc; proxy of <Swig Object of type 'adsk::core::Ptr< adsk::fusion::SketchArc > *' at 0x149722c60> > start: x=0.31749999999999995, y=7.457127787579157, z=0.0 end: x=1.139926523123076, y=9.246681703470033, z=0.0 ---------- radius ---------- r=0.127
The arcs in question started out as sketchCircles that intersected and were trimmed - the problematic points are the unfilleted ones in the pic below, and they all fail with "RuntimeError: 3 : Failed to create fillet." (a more descriptive error message would be helpful!)
Best regards,
Michael
Solved! Go to Solution.
Solved by ekinsb. Go to Solution.
The reason for the failure is because of the points you're using in the addFillet method. You can't use the end point in your case because it's also the intersection point of the two curves. The picture below shows two lines on the left and two lines on the right. In both cases there are four different possible fillets between the two curves are shown.
Giving the intersection point as the fillet point doesn't identify which of the four fillets to create. Instead you need a point close to the intersection, but on the portion of the curve that will be kept. In the picture below, if you provide a point anywhere along the red portion as the fillet point on the two curves, you'll end up with the highlighted fillet.
Here's a variation of your program that finds points very close to the intersection but off just a little bit in the direction of the other end of the curve. My algorithm assumes the curves are end point connected and not overlapping, which will always be the case in your problem because you're first finding the connected curves.
def run(context): try: global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface des = adsk.fusion.Design.cast(_app.activeProduct) root = des.rootComponent sketch = root.sketches.item(0) points_to_fillet = [] for p in sketch.sketchPoints: if p.connectedEntities and p.connectedEntities.count == 2: if p.connectedEntities[0].classType()=="adsk::fusion::SketchArc" or p.connectedEntities[1].classType()=="adsk::fusion::SketchArc": if p.connectedEntities[0].startSketchPoint == p or p.connectedEntities[0].endSketchPoint == p: if p.connectedEntities[1].startSketchPoint == p or p.connectedEntities[1].endSketchPoint == p: points_to_fillet.append(p) p = adsk.fusion.SketchPoint.cast(None) for p in points_to_fillet: e1, e2 = p.connectedEntities filletPoint1 = closePoint(p, e1) filletPoint2 = closePoint(p, e2) sketch.sketchCurves.sketchArcs.addFillet(e1, filletPoint1, e2, filletPoint2, 1.0) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def closePoint(skPoint, skCurve): isStart = False if skPoint == skCurve.startSketchPoint: isStart = True curveEval = adsk.core.CurveEvaluator3D.cast(skCurve.geometry.evaluator) (retVal, startParam, endParam) = curveEval.getParameterExtents() if isStart: paramEval = (endParam + startParam) * .05 else: paramEval = (endParam + startParam) * .95 (retVal, pnt) = curveEval.getPointAtParameter(paramEval) return(pnt)
Hmm, I don't understand the difference between the line+curve case vs curve+curve case - in both, the intersection point is the endpoint.
My code works on this point:
but fails on this point:
The lines/curves end at the intersection point, I don't understand how Fusion 360 would see 4 possible fillets here. (and if so, why only in the 2nd case).
I will use the code modification to work around but it still seems like a bug to me!
Best regards,
Michael
Good question about why lines would work and fillets don't. I don't understand that either and apparently it's just a side-effect of how some things are computed internally. I understand in your case there is only one obvious fillet, but the API needs to take care of the general case where you have two entities that aren't connected but cross over each other. In that case there are four possible fillets and specifying the intersection point is ambiguous and doesn't identify which of the possible four results to create. I agree that it would be best if it was smart enough to see that the curves are end connected and just create the single result but that's not the current behavior and by specifying a point along the curve instead of at the intersection you can get the desired result.
Thanks, I used your code for grabbing a nearby point on the line and I've got all the desired fillets!
Best regards,
Michael
I have used the modified code by Brian and it works until I drastically changed some parameters. I am wondering if the conditional statement,
if isStart: paramEval = (endParam + startParam) * .05 else: paramEval = (endParam + startParam) * .95
should not have been,
if isStart: paramEval = startParam + (endParam - startParam) * .05 else: paramEval = startParam + (endParam - startParam) * .95
@ekinsb , I do not know if there is an arc whose start parameter is non-zero. I was not able to create such an arc, and the results of modifications that I tried such as breaking and trimming were always arcs with a start parameter of 0.
But assuming there is such an arc, the results of the following code can be outside the range of start and end parameters.
if isStart:
paramEval = (endParam + startParam) * .05
else:
paramEval = (endParam + startParam) * .95
For example, for the start parameter 0.6 and the end parameter 1.0, the results will be 0.08 and 1.52 which both are outside [0.6, 1.0] range. So I think it will be better to change the code to:
if isStart:
paramEval = startParam + (endParam - startParam) * .05
else:
paramEval = startParam + (endParam - startParam) * .95
or:
if isStart:
paramEval = .95 * startParam + .05 * endParam
else:
paramEval = .05 * startParam + .95 * endParam
Can't find what you're looking for? Ask the community or share your knowledge.