Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

BUGs splitting a SketchFittedSpline with breakCurve() function

Jorge_Jaramillo
Collaborator

BUGs splitting a SketchFittedSpline with breakCurve() function

Jorge_Jaramillo
Collaborator
Collaborator

@Jorge_Jaramillo - this post is being edited to remove PII.

 

Hi All,

 

I believe two bugs are generated when a closed SketchFittedSpline is broken with breakCurve() function:

1. One of the splines is generated without fit points and accessing startSketchPoint and endSketchPoint attributes generates "error: 2 : InternalValidationError : pt" error.

2. The model report having 3 profiles, when the circle used to make the profiles 2 and 3 was deleted.

The number profiles is consistent with what is displayed, but only 1 should be displayed.  See image below.

The circle I mentioned here is used to break the spline, so in the script it is created and then deleted.

 

Attached is the script I used.  To reproduce the error just run it over a design with a empty sketch (could be a XY).

The attached F3D file contains the status of the design after running the script.

Below is the information displayed in the Text Command window once the script is run:

 

 -------------------------------------------- app.version='2.0.16490' Python=3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)]
 Before splitting:
       0   <adsk.fusion.SketchFittedSpline; proxy of <Swig Object of type 'adsk::core::Ptr< adsk::fusion::SketchFittedSpline > *' at 0x00000248E6603D80> >  #5-True
  skt.profiles.count=1
 0 ===================
 After splitting:
  sketch curve #0:
       type             = <class 'adsk.fusion.SketchFittedSpline'>
       isClose          = False
       fitPoints.count  = 5
       startSketchPoint = (5.0, -1.0, 0.0)
       endSketchPoint   = (0.0, 0.0, 0.0)
  sketch curve #1:
       type             = <class 'adsk.fusion.SketchFittedSpline'>
       isClose          = True
       fitPoints.count  = 0
       startSketchPoint (error: 2 : InternalValidationError : pt)
       endSketchPoint   (error: 2 : InternalValidationError : pt)
  skt.profiles.count=3

 

 

wtallerdemadera_0-1690169337100.png

 

For BUG #1:

I'm assuming every spline has start and end fit points.

After breaking the original spline, one of them generates errors when trying to access startSketchPoint and endSketchPoint attributes from the data model, has attribute isClose set to True when it isn't and doesn't have fitPoints defined:

 

  sketch curve #1:
       type             = <class 'adsk.fusion.SketchFittedSpline'>
       isClose          = True
       fitPoints.count  = 0
       startSketchPoint (error: 2 : InternalValidationError : pt)
       endSketchPoint   (error: 2 : InternalValidationError : pt)

 

Also check that its curve is displayed in black color, meaning it is completely constrained when it is not.

 

For BUG #2:

The number of profiles in sketch are extracted from skt.profiles.count:

 

    app.log(f' {skt.profiles.count=}')

 

It displayed 3 as if the circle already exist in the model.

 

Now, selecting profile #3 I choose to extrude it from the UI, but once I hit OK in the extrude dialog a new body is creating out of the 2 splines, not with the profile originally profile selected:

wtallerdemadera_1-1690169926703.png 

wtallerdemadera_2-1690169943686.png

 

After making this extrude the number of profiles became 1 and the sketch is displayed without the deleted circle (as it should be before the extrude feature was made).

 

 

I hope I could provide the full information and detailed step by step to reproduce the bugs, and that Fusion 360 team will further investigate these bugs.

 

Script source code:

 

#Author-
#Description-

import sys
import adsk, adsk.core, adsk.fusion, adsk.cam, traceback

try:
    app = adsk.core.Application.get()
    des: adsk.fusion.Design = adsk.fusion.Design.cast(app.activeProduct)
    root = des.rootComponent
    ui = app.userInterface
except:
    pass


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]}  #{skt.sketchCurves[i].fitPoints.count}-{skt.sketchCurves[i].isClosed}')
    app.log(f' {skt.profiles.count=}')

    # make n-1 curve breaks
    for i in range(1):
        app.log(f'{i} ===================')

        # 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' sketch curve #{i}:')
        app.log(f'      type             = {type(skt.sketchCurves[i])}')
        app.log(f'      isClose          = {skt.sketchCurves[i].isClosed}')
        app.log(f'      fitPoints.count  = {skt.sketchCurves[i].fitPoints.count}')
        try:
            app.log(f'      startSketchPoint = {skt.sketchCurves[i].startSketchPoint.geometry.asArray()}')
        except Exception as exc:
            app.log(f'      startSketchPoint (error: {exc})')
        try:
            app.log(f'      endSketchPoint   = {skt.sketchCurves[i].endSketchPoint.geometry.asArray()}')
        except Exception as exc:
            app.log(f'      endSketchPoint   (error: {exc})')
    app.log(f' {skt.profiles.count=}')



def run(context):
    try:
        app.log(f'-------------------------------------------- {app.version=} Python={sys.version}')
        break_spline()

        adsk.terminate()
    except:
        app.log('Failed:\n{}'.format(traceback.format_exc()))

 

 

Regards,

Jorge Jaramillo

 

3 Likes
Reply
357 Views
2 Replies
Replies (2)

BrianEkins
Mentor
Mentor

I played with this a bit today and found a couple of problems.

 

The first and biggest, problem is not specific to the API but can be reproduced interactively. It's the bad spline that's created by the break operation. If you draw a spline starting and stopping at the origin, then draw a circle by two points from the origin to another location along the spline and then break the spline, you'll get a bad result. A bug has been logged for this.

 

The other problem with the profiles after deleting the circle is API specific. The problem is that the profiles aren't being recomputed after the circle is deleted. This is also a bug, and I'll see it gets logged. However, there's a simple solution for now. Turn off the display of the profiles, delete the circle, and then turn the display back on. This forces the profiles to be recomputed.

sk.areProfilesShown = False
skCircle.deleteMe()
sk.areProfilesShown = True

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
1 Like

Jorge_Jaramillo
Collaborator
Collaborator

@Jorge_Jaramillo - this post is being edited to remove PII.

 

Thank you @BrianEkins for your feedback and for taking care the bugs are logged.

 

Regarding the first one: I still have the same issue if the spline start point is moved out from the sketch origin; and if the pairs of points are 1-2, 2-3, ... , like in the following image when I used points with index 2 and 3.

wtallerdemadera_1-1690424277867.png

 

The only way it generates a valid spline after the break is if I use points 1-3, 2-4, ...  to constraint the circle:

wtallerdemadera_0-1690424144562.png

Somehow the Fusion 360 team could investigate deeply based on the findings provided.

 

For the second bug, it is working properly with the instructions you provided.  I wasn't aware it exists. Thank you.

 

Best regards,

Jorge Jaramillo

 

1 Like