Invalid input edges when using createBRepEdgeProfile method

Invalid input edges when using createBRepEdgeProfile method

11713013
Contributor Contributor
552 Views
2 Replies
Message 1 of 3

Invalid input edges when using createBRepEdgeProfile method

11713013
Contributor
Contributor

Hello, there.

Debugging for Fusion 360 API seems too difficult for me and it always costs me a lot of time.

As I have mentioned in another post, I have solved the problem about can't get bRepBodies for imported STEP files with the help by @tykapl.breuil . Thanks a lot here.

But I got another problem now.

Here is my code:

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

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        # ui.messageBox('Hello script')

        importManager = app.importManager # get importManager

        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent # get the root component

        # Import the up joint step to the origin point
        stepFileName1 = os.path.join(os.path.abspath(os.path.dirname(__file__)), "./STEP/joint_part_up.STEP")
        stepImportOptions1 = importManager.createSTEPImportOptions(stepFileName1)
        importManager.importToTarget(stepImportOptions1, rootComp)

        # Import the down joint step to the setting point
        stepFileName2 = os.path.join(os.path.abspath(os.path.dirname(__file__)), "./STEP/joint_part_down.STEP")
        stepImportOptions2 = importManager.createSTEPImportOptions(stepFileName2)
        importManager.importToTarget(stepImportOptions2, rootComp) 

        occ1 = rootComp.occurrences.item(0) # refers to joint_part_up:1
        occ2 = rootComp.occurrences.item(1) # refers to joint_part_down:1

        ## Using transform to move the occurrence
        # rotate joint_part_down for 180 degrees along its y axis
        origin = adsk.core.Point3D.create() # to store the origine point of the occurrence's coordinate system
        xAxis = adsk.core.Vector3D.create() # to store the xAxis of the occurrence's coordinate system
        yAxis = adsk.core.Vector3D.create() # to store the yAxis of the occurrence's coordiante system
        zAxis = adsk.core.Vector3D.create() # to store the zAxis of the occurrence's coordiante system
        (origin, xAxis, yAxis, zAxis) = occ2.transform.getAsCoordinateSystem() # get the occurrence's coordinate system
        rotY = adsk.core.Matrix3D.create()
        rotY.setToRotation(math.pi, yAxis, origin)
        trans3 = occ2.transform
        trans3.transformBy(rotY)
        occ2.transform = trans3

        # translate along the world coordinate z axis
        length = 10.0 # the distance between two faces for loft, unit: cm
        transZ = adsk.core.Matrix3D.create()
        transZ.translation = adsk.core.Vector3D.create(0.0, 0.0, length+4) # the extral part of two joint is 40 mm
        trans = occ2.transform
        trans.transformBy(transZ)
        occ2.transform = trans

        # twist the down joint 
        theta = math.pi/6 # twist angle
        (origin, xAxis, yAxis, zAxis) = occ2.transform.getAsCoordinateSystem() # re-get the occurrence's coordinate system
        rotZ = adsk.core.Matrix3D.create()
        rotZ.setToRotation(theta, zAxis, origin)
        trans = occ2.transform
        trans.transformBy(rotZ)
        occ2.transform = trans

        # add assembly clearance
        (origin, xAxis, yAxis, zAxis) = occ2.transform.getAsCoordinateSystem() # re-get the occurrence's coordinate system
        # transY = yAxis.scaleBy(0.1) # translation alonge the y axis by 0.1 cm
        transY = adsk.core.Matrix3D.create()
        vecY = adsk.core.Vector3D.create(yAxis.x / 10, yAxis.y / 10, yAxis.z / 10)
        transY.translation = vecY
        trans = occ2.transform
        trans.transformBy(transY)
        occ2.transform = trans

        # get bRepFaces for loft feature
        point1 = adsk.core.Point3D.create(0.0, 0.0, 2.0) 
        face1 = rootComp.findBRepUsingPoint(point1, adsk.fusion.BRepEntityTypes.BRepFaceEntityType)
        # loops1 = face1.item(0).loops # bRepLoops
        # loop1 = loops1.item(0) # bRepLoop
        # edges1 = loop1.edges
        edges1 = face1.item(0).edges
        ui.messageBox(str(edges1.count))
        profile1 = rootComp.createBRepEdgeProfile(edges1)
        # path1 = adsk.fusion.Path.create(edges1, adsk.fusion.ChainedCurveOptions.tangentChainedCurves)

        point2 = adsk.core.Point3D.create(0.0, 0.0, length+2.0)
        face2 = rootComp.findBRepUsingPoint(point2, adsk.fusion.BRepEntityTypes.BRepFaceEntityType)
        # loops2 = face2.item(0).loops
        # loop2 = loops2.item(0)
        # edges2 = loop2.edges
        edges2 = face2.item(0).edges
        profile2 = rootComp.createBRepEdgeProfile(edges2, False)
        # path2 = adsk.fusion.Path.create(edges2, adsk.fusion.ChainedCurveOptions.tangentChainedCurves)

        # create loft feature input
        loftFeats = rootComp.features.loftFeatures
        loftInput = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        loftSectionsObj = loftInput.loftSections
        loftSectionsObj.add(profile1)
        loftSectionsObj.add(profile2)
        loftInput.isSolid = False
        loftInput.isClosed = False
        loftInput.isTangentEdgesMerged = True

        loftFeats.add(loftInput) # create loft feature


    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

It got problem with this information:

Failed:
Traceback (most recent call last):
  File "C:/Users/61648/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/LegGenerating/LegGenerating.py", line 81, in run
    profile1 = rootComp.createBRepEdgeProfile(edges1)
  File "C:/Users/61648/AppData/Local/Autodesk/webdeploy/production/50d1a2b00ac928c7781cbca6551e586a5384d498/Api/Python/packages\adsk\fusion.py", line 42403, in createBRepEdgeProfile
    return _fusion.Component_createBRepEdgeProfile(self, edges, chainEdges)
RuntimeError: 3 : invalid input edges

But I don't know why my edges are invalid. According to the manual of createBRepEdgeProfile method, the input of the edges can be: "A single BRepEdge object or an ObjectCollection containing multiple BRepEdge objects, or a BRepLoop object."

My code is attached with a zip file.

Also, hoping you can share your experience for debugging Fusion360 API script here.

Best wishes!

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

tykapl.breuil
Advocate
Advocate
Accepted solution

Hey there !

 

I don't know why createBRepEdgeProfile does not work but I admit I didn't spend much time trying to find out as the loft feature works by simply using the faces, it's easier in this case so I see no point in not using them.

 

Second, the transform of the occurence was not getting registered with the snapshot command which made the part revert to its initial position when trying to use it on the loft. I havenever encountered this problem before as I've never tried to transform components but using the design.snapshots.add() solves it, I do not know if it is the best way to solve this however.

 

Here is the code that works (at least on my machine) :

#Author-Nuofan
#Description-Generate a leg

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

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        # ui.messageBox('Hello script')

        importManager = app.importManager # get importManager

        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent # get the root component

        # Import the up joint step to the origin point
        stepFileName1 = os.path.join(os.path.abspath(os.path.dirname(__file__)), "./STEP/joint_part_up.STEP")
        stepImportOptions1 = importManager.createSTEPImportOptions(stepFileName1)
        importManager.importToTarget(stepImportOptions1, rootComp)

        # Import the down joint step to the setting point
        stepFileName2 = os.path.join(os.path.abspath(os.path.dirname(__file__)), "./STEP/joint_part_down.STEP")
        stepImportOptions2 = importManager.createSTEPImportOptions(stepFileName2)
        importManager.importToTarget(stepImportOptions2, rootComp) 

        occ1 = rootComp.occurrences.item(0) # refers to joint_part_up:1
        occ2 = rootComp.occurrences.item(1) # refers to joint_part_down:1

        ## Using transform to move the occurrence
        # rotate joint_part_down for 180 degrees along its y axis
        origin = adsk.core.Point3D.create() # to store the origine point of the occurrence's coordinate system
        xAxis = adsk.core.Vector3D.create() # to store the xAxis of the occurrence's coordinate system
        yAxis = adsk.core.Vector3D.create() # to store the yAxis of the occurrence's coordiante system
        zAxis = adsk.core.Vector3D.create() # to store the zAxis of the occurrence's coordiante system
        (origin, xAxis, yAxis, zAxis) = occ2.transform.getAsCoordinateSystem() # get the occurrence's coordinate system
        rotY = adsk.core.Matrix3D.create()
        rotY.setToRotation(math.pi, yAxis, origin)
        trans3 = occ2.transform
        trans3.transformBy(rotY)
        occ2.transform = trans3

        # translate along the world coordinate z axis
        length = 10.0 # the distance between two faces for loft, unit: cm
        transZ = adsk.core.Matrix3D.create()
        transZ.translation = adsk.core.Vector3D.create(0.0, 0.0, length+4) # the extral part of two joint is 40 mm
        trans = occ2.transform
        trans.transformBy(transZ)
        occ2.transform = trans

        # twist the down joint 
        theta = math.pi/6 # twist angle
        (origin, xAxis, yAxis, zAxis) = occ2.transform.getAsCoordinateSystem() # re-get the occurrence's coordinate system
        rotZ = adsk.core.Matrix3D.create()
        rotZ.setToRotation(theta, zAxis, origin)
        trans = occ2.transform
        trans.transformBy(rotZ)
        occ2.transform = trans

        snapshot = design.snapshots.add()

        # add assembly clearance
        (origin, xAxis, yAxis, zAxis) = occ2.transform.getAsCoordinateSystem() # re-get the occurrence's coordinate system
        # transY = yAxis.scaleBy(0.1) # translation alonge the y axis by 0.1 cm
        transY = adsk.core.Matrix3D.create()
        vecY = adsk.core.Vector3D.create(yAxis.x / 10, yAxis.y / 10, yAxis.z / 10)
        transY.translation = vecY
        trans = occ2.transform
        trans.transformBy(transY)
        occ2.transform = trans

        # get bRepFaces for loft feature
        point1 = adsk.core.Point3D.create(0.0, 0.0, 2.0) 
        face1 = rootComp.findBRepUsingPoint(point1, adsk.fusion.BRepEntityTypes.BRepFaceEntityType).item(0)

        point2 = adsk.core.Point3D.create(0.0, 0.0, length+2.0)
        face2 = rootComp.findBRepUsingPoint(point2, adsk.fusion.BRepEntityTypes.BRepFaceEntityType).item(0)

        # create loft feature input
        loftFeats = rootComp.features.loftFeatures
        loftInput = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        loftSectionsObj = loftInput.loftSections
        loftSectionsObj.add(face1)
        loftSectionsObj.add(face2)
        loftInput.isSolid = False
        loftInput.isClosed = False
        loftInput.isTangentEdgesMerged = True

        loftFeats.add(loftInput) # create loft feature


    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

The result I get is that:

tykaplbreuil_0-1648541534646.png

For debugging Fusion scripts, here are I think some good tips:

- The app.log method can allow for more quick dumping of what is going on without interrupting the program with a message box

- The vscode integration is really well done, allowing for step by step debugging, breakpoints and looking at the status of the current variables, I highly recommend that you use it on more complex problems.

- Finally, and this is not really linked to debugging but in the context of the Fusion API, it is interesting to use and abuse python type hints and in general to treat API objects as strongly typed. By that I mean that vscode should always know the type of the object you are working with, it generally knows through inference but when it doesn't, using typehints can be very powerful !

Message 3 of 3

11713013
Contributor
Contributor

I don't realize that bRepBody can be used for loftSection because I just followed the loft feature example and think I should got the Profile for loftSection.

Thank you so much for your reply and thank again for your advise for debugging!

0 Likes