objectCollection returned from .include is empty but draws point

objectCollection returned from .include is empty but draws point

tim.brodrick
Explorer Explorer
430 Views
2 Replies
Message 1 of 3

objectCollection returned from .include is empty but draws point

tim.brodrick
Explorer
Explorer

In my script I am making several planes and on each plane's sketch I have a point. I want to do a fitted spline that goes through all these points.

 

My understanding is that I need to get all these points onto the same sketch so that I can do a spline through them using the API.

 

I know that using the .include() method will copy a point to a new sketch, so my plan was to use it and then convert the output from that back into point3D so that I can add it to a growing collection of points3Ds and then do the fitted spline through them.

 

However the output from .include() is an empty object collection (count=0, isValid=false). It does correctly draw the point on the new sketch inside Fusion so I am not sure what is going on.

 

Below is a section of my code

pointsForSpline = adsk.core.ObjectCollection.create()    

originalPoint3D     = adsk.core.Point3D.create(100*x, 100*y, 0.0) 
originalSketchPoint = originalSketch.sketchPoints.add(originalPoint3D) #create sketchpoint from point3d on the sketchplane
newObjectCollection = newSketch.include(originalSketchPoint) #copy sketch point onto a different sketchplane, this should return an object coillection of  sketchpoints

#method 1 to get point3d from sketchpoint using .geomtry()      
#newSketchPoint = newObjectCollection.item(0) #get the sketchpoint from the object collection
#newSketchPoint.geometry #use the .geometry to get the point3D (with coordinates in local sketch plane) of the sketchpoint
   
#method 2 to get point3d from object collection using cast()     
for idx, pnt in enumerate(newObjectCollection):
    p = adsk.core.Point3D.cast(pnt)
    pointsForSpline.add(p) 

 

Any suggestions here?  

0 Likes
Accepted solutions (2)
431 Views
2 Replies
Replies (2)
Message 2 of 3

BrianEkins
Mentor
Mentor
Accepted solution

I wrote a quick test and cannot reproduce the problem you described. I went back and looked closer at your code and the problem isn't what you think it is. The problem is line 13. The include method returns an ObjectCollection that, in this case, returns a SketchPoint. In line 13, you're attempting to cast the SketchPoint to a Point3D object. That will fail, and the cast function will return None as a result. If you change line 13 to this, I believe it will work.

 

p = adsk.fusion.SketchPoint.cast(pnt)

 

And, since I already wrote it, here's the test case I created. I learned a couple of things. First is that if I used an ObjectCollection to do the include, the results weren't necessarily in the same order as the input. I don't think this is a bug, but is just the behavior you need to be aware of. As a result, I included them one at a time, which you were already doing. The other thing I learned is that the creation of the spline uses the input sketch points to get the coordinates, but does not associate the spline with the input points. I had to create a coincident point between the included points and the spline points. The code below does this.

 

def run(context):
    app = adsk.core.Application.get()
    ui = app.userInterface
    try:
        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        des: adsk.fusion.Design = doc.products.itemByProductType('DesignProductType')
        root = des.rootComponent

        # Create several construction planes with a sketch on each one.
        constPlanes = root.constructionPlanes
        planeInput = constPlanes.createInput()
        planeInput.setByOffset(root.xYConstructionPlane, adsk.core.ValueInput.createByReal(5))
        plane1 = constPlanes.add(planeInput)
        s1 = root.sketches.add(plane1)

        planeInput = constPlanes.createInput()
        planeInput.setByOffset(root.xYConstructionPlane, adsk.core.ValueInput.createByReal(10))
        plane2 = constPlanes.add(planeInput)
        s2 = root.sketches.add(plane2)

        planeInput = constPlanes.createInput()
        planeInput.setByOffset(root.xYConstructionPlane, adsk.core.ValueInput.createByReal(15))
        plane3 = constPlanes.add(planeInput)
        s3 = root.sketches.add(plane3)

        planeInput = constPlanes.createInput()
        planeInput.setByOffset(root.xYConstructionPlane, adsk.core.ValueInput.createByReal(20))
        plane4 = constPlanes.add(planeInput)
        s4 = root.sketches.add(plane4)

        # Create a point on each plane.
        pointsOnPlanes = []
        p1 = s1.sketchPoints.add(adsk.core.Point3D.create(5,0,1))
        pointsOnPlanes.append(p1)
        p2 = s2.sketchPoints.add(adsk.core.Point3D.create(5,6,1))
        pointsOnPlanes.append(p2)
        p3 = s3.sketchPoints.add(adsk.core.Point3D.create(10,8,1))
        pointsOnPlanes.append(p3)
        p4 = s4.sketchPoints.add(adsk.core.Point3D.create(12,15,1))
        pointsOnPlanes.append(p4)

        # Include the points into the result sketch. They are included
        # one at a time to be able to match the result to the input.
        resultSk: adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane)
        pointsInResult = []
        for point in pointsOnPlanes:
            result = resultSk.include(point)
            pointsInResult.append(result[0])

        # create the spline using the points.
        fitPoints = adsk.core.ObjectCollection.create()
        for point in pointsInResult:
            fitPoints.add(point)
        crv = resultSk.sketchCurves.sketchFittedSplines.add(fitPoints)

        # Add coincident constraints between the fit points and the sketch points.
        geomConsts = resultSk.geometricConstraints
        for i in range(4):
            geomConsts.addCoincident(pointsInResult[i], crv.fitPoints[i])
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 3 of 3

tim.brodrick
Explorer
Explorer
Accepted solution

Thanks for your code. After a few hours of comparing it to my own code I found my issue.

newSketch.isComputeDeferred = True

I had deferred the compute on the sketch and this caused the following line:

newObjectCollection = newSketch.include(originalSketchPoint)

to return an empty object collection (although it still seems to correctly plot the point).

0 Likes