Fusion API and Scripts

Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.

- Forums Home
- >
- Fusion Community
- >
- API and Scripts forum
- >
- the intersection of a sketch curve and a sphere surface

Fusion API and Scripts

Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.

Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

This page has been translated for your convenience with an automatic translation service. This is not an official translation and may contain errors and inaccurate translations. Autodesk does not warrant, either expressly or implied, the accuracy, reliability or completeness of the information translated by the machine translation service and will not be liable for damages or losses caused by the trust placed in the translation service.
Translate

25 REPLIES 25

SOLVED
Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

Message 1 of 26

05-07-2023
10:12 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-07-2023
10:12 PM

I wanted to get the intersection of a sketch curve and a sphere surface, but could not find an api to do so.

Using the basic features of fusion360 I was able to get the intersection I wanted to get.

The specific steps are as follows.

step1:Create a sketch curve and a sphere (or sphere surface) [sample1.png]

step2:Project a sketch curve on a spherical surface with a 3d sketch by Intersection Curve.

(sketch > CREATE > Project/Include > Intersection Curve)[sample2.png]

step3:Place a point at the intersection of the sketch curve and the projection curve. [sample3.png]

I would like to achieve this procedure with api. Please give me your advice.

Solved! Go to Solution.

Solved by Jorge_Jaramillo. Go to Solution.

Solved by Jorge_Jaramillo. Go to Solution.

Solved by kandennti. Go to Solution.

Solved by MichaelT_123. Go to Solution.

25 REPLIES 25

Message 2 of 26

05-08-2023
01:24 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-08-2023
01:24 AM

Hi @S.T0116 .

Perhaps there is no direct way to find the intersection of a surface and a curve.

I am trying a little, but this is quite difficult and takes time to find a method.

Message 3 of 26

05-08-2023
03:59 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-08-2023
03:59 AM

**Hi Mr. S.T0116**

I am using mobile to draft this simple * curve/sphere intersecting algorithm* ... in the mathematical sense. Mind you ... this is a

If you are familiar a little bit with numerical analysis, do the following:

- Parametrize curve; you can use
facilities**F360** - Take virtual point
**P(t)** - Find its distance to the center of a sphere
**D(P(T),Sc(r))** - Assemble&Solve the nonlinear equation
using perhaps the standard numerical solver**Eq(D-r=0)****scipy.solve (t, Eq, r, Sc, ...)**

Scan the full range of the parameter * t,* as there might be multiple solutions.

**Regards**

**MichaelT**

MichaelT

Message 4 of 26

05-08-2023
04:41 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-08-2023
04:41 AM

@MichaelT_123 @kandennti

Thank you for the useful information.

The content of the two indicates that critical api does not exist at this time.

As for MichaelT's suggestion, I interpreted it as determining the interior and exterior of the sphere by comparing the distance to the point and the radius, as shown in the figure.

It may be possible to implement it this way.

I will take MichaelT's reply as a solution this time, but if kandennti has a better method or code, I would like to know.

Message 5 of 26

05-08-2023
06:50 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-08-2023
06:50 AM

Hi @S.T0116 ,

I was able to solved it with this script:

```
def curves_intersections():
c1 = root.sketches.item(0).sketchCurves.item(0)
c2 = root.sketches.item(0).sketchCurves.item(1)
oc = adsk.core.ObjectCollection.create()
oc.add(c2)
(rv, ic, ip) = c1.intersections(oc)
app.log(f'{rv=} {ic.count=} {ip.count=}')
for p in ip:
app.log(f' {adsk.core.Point3D.cast(p).asArray()}')
root.sketches.item(0).sketchPoints.add(p)
```

I created an sphere, then a sketch on XZ plane, drew a spline line (c1) and the projects the sphere on the plane (c2).

The resulting intersection points where create on the same sketch and its coordinates printed in the text command output window. This is the result:

I hope this could help.

Regards,

Jorge Jaramillo

Message 7 of 26

05-08-2023
08:12 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-08-2023
08:12 AM

@Jorge_Jaramillo

Thank you for the specific script.

Sketch curves are preferred to 3d sketches. For your script, this works for curves in the 2d plane.

My explanation was insufficient.

You are right.

I think that the idea proposed by MichaelT can be implemented in 3d space.

Message 8 of 26

05-08-2023
11:47 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

Message 9 of 26

05-09-2023
02:33 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
02:33 AM

@S.T0116 .

After much consideration, we created a large number of points on the curve and used the points within a tolerance distance from the center as the intersection points.

However, the accuracy is not good, and in some cases, multiple points that are very close to each other are obtained in areas where there should be only one point of intersection.

```
# Fusion360API Python script
import traceback
import adsk
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
# select face
msg: str = 'Select SphericalFace'
selFilter: str = 'SphericalFaces'
sel: core.Selection = selectEnt(msg, selFilter)
if not sel: return
face: fusion.BRepFace = sel.entity
# select curve
msg: str = 'Select SketchCurve'
selFilter: str = 'SketchCurves'
sel: core.Selection = selectEnt(msg, selFilter)
if not sel: return
crv: fusion.SketchCurve = sel.entity
# find intersect points
intersectPoints = get_intersect_points(
face,
crv
)
if len(intersectPoints) < 1: return
# dump points
des: fusion.Design = app.activeProduct
root: fusion.Component = des.rootComponent
skt: fusion.Sketch = root.sketches.add(
root.xYConstructionPlane
)
skt.name = 'Intersect Points'
[skt.sketchPoints.add(p) for p in intersectPoints]
ui.messageBox('Done')
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def get_intersect_points(
face: fusion.BRepFace,
crv: fusion.SketchCurve,
tolerance: float = 0.00009,
) -> list[core.Point3D]:
if face.geometry.objectType != core.Sphere.classType():
return []
crvGeo: core.Curve3D = crv.worldGeometry
crvEva: core.CurveEvaluator3D = crvGeo.evaluator
_, stPrm = crvEva.getParameterAtPoint(
crv.startSketchPoint.worldGeometry
)
_, endPrm = crvEva.getParameterAtLength(
stPrm,
crv.length
)
_, crvPnts = crvEva.getStrokes(
stPrm,
endPrm,
0.000000001
)
sphere: core.Sphere = face.geometry
origin: core.Point3D = sphere.origin
radius: float = sphere.radius
intersectPoints = [p for p in crvPnts
if abs(origin.distanceTo(p) - radius) < tolerance]
return intersectPoints
def selectEnt(
msg: str,
filterStr: str
) -> core.Selection:
try:
app: core.Application = core.Application.get()
ui: core.UserInterface = app.userInterface
sel = ui.selectEntity(msg, filterStr)
return sel
except:
return None
```

Message 10 of 26

05-09-2023
02:58 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
02:58 AM

I don't think I can express myself well in English when I can't even express myself well in Japanese....

The SurfaceEvaluator object and the CurveEvaluator3D object both have getParameterAtPoint and getPointAtParameter methods.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-31dad9b2-ee1d-4216-8100-09ea44f9967a

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-dc7ae251-e060-4d87-b6b8-e7f78abc0777

I think it is possible to get some candidate close points using the getStrokes method of the CurveEvaluator3D object.

This method uses two methods to increase the accuracy based on the candidate points.

The getParameterAtPoint method always returns a parameter at a close position, even if there is no point on the surface or curve.

If the distance between two points converges to a certain distance, it may be possible to obtain a point with high accuracy, but there may be no guarantee of convergence.

The image is like this. (The green points are the candidate points obtained by the getStrokes method.)

Message 11 of 26

05-09-2023
03:45 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
03:45 AM

* Hi Kandennti-San*,

* Your idea is quite tricky* ... and might lead to a solution method that doesn't require the

I am still on my mobile, so it would be challenging to write the code ... but I will try to give some hints.

- First ... forget about the sphere, breps, surfaces ...
- Only the distance between the intersection point and the center of the sphere matters
- Now imagine the intersection point and the small tangential segment at it.
- If my imagination is correct, one end of the segment will be closer to the center point than the other
- You don't need to find tangents directly; I use this concept only for visualization.
- For simplicity, I ignore the case here when the curve is tangential to the sphere
- Now find the solution through the iteration
- Take two points (P1, P2) on the curve (endpoints in the first iteration)
- Check their distances (D1, D2) from the center
- If D1 < R and D2 > R, we have at least one intersection point between P1 and P2.
- Divide this curve segment
- Check the condition as in step 9 for both subsegments
- Continue divisions until the required precision is met.
- Implement the above as a recursive function and always check both fork branches (the curve division sub-segments)
- Collect intersection points on the way

**Regards**

**MichaelT**

MichaelT

Message 12 of 26

05-09-2023
06:11 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
06:11 AM

Hi All,

I get it done with getStrokes() and a recursion function to increase accuracy on each new iteration.

Just lower MIN_TOLERANCE to increase precision and set skt_n (sketch #), cur_n (SketchFittedSpline curve # in the sketch) and body (the sphere).

It will create points in the sketch and display their coordinates and distance to sphere center in text command output window.

```
def curves_intersections():
# design: 20230508 esphere - spline intersection
#--3D--
INI_TOLERANCE = 0.001
MIN_TOLERANCE = 1e-20
def refine_search(minP: float,
maxP:float,
ev: adsk.core.CurveEvaluator3D,
sk: adsk.fusion.Sketch,
body: adsk.fusion.BRepBody,
tolerance: float
):
POINT_CONTAINMENT_INSIDE = [adsk.fusion.PointContainment.PointInsidePointContainment, adsk.fusion.PointContainment.PointOnPointContainment]
(rv, points) = ev.getStrokes(minP, maxP, tolerance)
# app.log(f' {minP=} {maxP=} {tolerance=} {len(points)=}')
p1_is_inside: boolean
mat = sk.transform
p2: adsk.core.Point3D = points[0].copy()
p2.transformBy(mat)
p2_is_inside: boolean = body.pointContainment(p2) in POINT_CONTAINMENT_INSIDE
for i in range(1, len(points)):
p1 = p2
p2 = points[i].copy()
p2.transformBy(mat)
p1_is_inside = p2_is_inside
p2_is_inside = body.pointContainment(p2) in POINT_CONTAINMENT_INSIDE
if p2_is_inside ^ p1_is_inside:
#one point inside and the following outside, or the opposite
if p2_is_inside:
if tolerance <= MIN_TOLERANCE:
sk.sketchPoints.add(points[i])
dist = p2.distanceTo(body.physicalProperties.centerOfMass)
app.log(f'====> {p2.asArray()} dist to center={dist=}')
else:
if tolerance <= MIN_TOLERANCE:
sk.sketchPoints.add(points[i-1])
dist = p1.distanceTo(body.physicalProperties.centerOfMass)
app.log(f'====> {p1.asArray()} dist to center={dist=}')
if tolerance > MIN_TOLERANCE:
(rv, params) = ev.getParametersAtPoints([points[i-1], points[i]])
refine_search(params[0], params[1], ev, sk, body, tolerance/10)
skt_n = 0 # sketch_number, inside the root component
cur_n = 0 # curve_number, inside the sketch
c1 = root.sketches.item(skt_n).sketchCurves.item(cur_n)
app.log(f'Curve: {c1}')
body = root.bRepBodies.item(0)
app.log(f'Body: {body.name}')
sfs = adsk.fusion.SketchFittedSpline.cast(c1)
ev = sfs.geometry.evaluator
refine_search(0.0, 1.0, ev, root.sketches.item(skt_n), body, INI_TOLERANCE)
```

Hope this help.

Best regards,

Jorge Jaramillo

Message 13 of 26

05-09-2023
07:43 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
07:43 AM

Message 14 of 26

05-09-2023
08:02 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
08:02 AM

Thank you, everyone.

I appreciate the sample, but it's taking me some time to understand it because I'm using C++ and have limited knowledge of APIs.

I understand your script. I also tried it and got multiple points at the same crossing point. There are many useful API usage examples, and these could be used to implement @MichaelT_123 's idea. It's one simple and effective solution.

More time is needed to understand the script. Also, being new to python, I am not sure how to run this function to select curves and spheres. It would be helpful if you could provide the entire script.

I may ask you questions about this script later.

Message 15 of 26

05-09-2023
08:07 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
08:07 AM

Yes, it is @MichaelT_123 idea, but except for item #1 since it was the requirement: "(...) I wanted to get the intersection of a sketch curve and a sphere surface (...)", so the sphere and the curve were used.

The idea of this algorithm is to find consecutive points over the line where one in inside the sphere and the other is not (or vice-verse), and then refine the search between them the same way until the precision is met.

Regards,

Jorge Jaramillo

Message 16 of 26

05-09-2023
08:43 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
08:43 AM

Hi @S.T0116 ,

Please find attached the python script. Just create a new python script on fusion360, and replace the main .py file content with this one.

Look for INPUT PARAMETERS section in the script and set them accordingly. A added some explanations on them.

Feel free to ask me any question you might have.

Best regards,

Jorge Jaramillo

Message 17 of 26

05-09-2023
03:17 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
03:17 PM

**Hi Mr. Jorge Jarammilo,**

**Well**** done!**

... * but it could be better* 😉.

* getStrokes()* is an expensive function, as the number of points generated in each iteration increases, so the number of necessary calculations grows in arithmetic or even geometric series.

The good news is that the script can be modified to moderate the processor/memory load.

**Regards**

**MichaelT**

MichaelT

Message 18 of 26

05-09-2023
06:04 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
06:04 PM

Hi @MichaelT_123 ,

What kind of improvement do you suggest?

I can tell you that last night when I was testing the algorithm, the first version I wrote was with a single iteration which used a specific tolerance (I believed I tested until 1e-8), it was processing about 2 million points and was taking about 3 minutes to complete.

It was the reason I choose to make it recursive with iterations that allows it to reduce tolerance every time by 1/10th.

With the last version I wrote, it is analyzing 400 points at most for a minimum tolerance of 1e-20, and taking about 1 or 2 seconds to complete.

Regards,

Jorge Jaramillo

Message 19 of 26

05-09-2023
07:25 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
07:25 PM

I thought the getStrokes method could be replaced by a function like this.

```
def getStrokesLike(
self: adsk.core.CurveEvaluator3D,
fromParameter: float,
toParameter: float,
count: int = 100,
) -> tuple[bool, list[adsk.core.Point3D]]:
step = (toParameter - fromParameter) / count
prms = [fromParameter + step * i for i in range(count)]
prms.append(toParameter)
return self.getPointsAtParameters(prms)
```

However, I am not sure of the appropriate count value, and some oversight has occurred.

I think the getStrokes method is fast enough for me.

Message 20 of 26

05-09-2023
07:44 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

05-09-2023
07:44 PM

**Hi ****IntersectingFellow**,

In each iterations only four points are essential:

**Sc****P1****P2**- new division**P3**

Thus for each branch of the fork only the last * (P3)* must be re-computed. Previous

**Regards**

**MichaelT**

MichaelT

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page