Community
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.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Thin Extrude an open profile via API

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
AudacityMicro
352 Views, 3 Replies

Thin Extrude an open profile via API

Hey everyone!

 

First time poster, and I'm new to this API stuff, and I'm new to coding for that matter. So sorry if I'm missing something obvious, or use a word incorrectly. 

 

My end-goal with this script is to automate the production of generative artwork by creating 2D artwork in an existing sketch, extruding it onto an existing model, and then regenerating and posting GCODE from the manufacturing environment. But I haven't gotten that far yet. Right now I am just trying to extrude a collection of lines.

 

The problem I am running into is that I have only figured out how to extrude closed profiles, rather than open curves. I am able to do it manually in the normal Fusion modeling environment, but the Thin Extrude method doesn't seem to accept open curves. Is there a way to make it work with open lines like you can in the modeling environment? or does the API not allow that?

 

I've attached two pictures, one show the results of my script, and the other one shows the desired outcome, which I was able to manually extrude in the modeling environment. 

 

 

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

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface

        #Pattern Definitions
        PatternWidth = 10       #in cm
        PatternHeight = 10      #in cm
        Instances = 10          #unitless
        Weight = .7             #unitless
        ExtrudeThickness = "1"    #in cm UOS
        ExtrudeDepth = "1"        #in cm UOS

        
        #Prompt User to select a sketch
        Sketch=getSelectedSketchName()

        #Draw Lines in pattern
        for X in frange(-PatternWidth/2, PatternWidth/2, PatternWidth/Instances):
            for Y in frange(-PatternHeight/2, PatternHeight/2, PatternHeight/Instances):
                RandomLine(Sketch, X, Y,PatternWidth/Instances,Weight)

            
        #Extrude Sketch
        ThinExtrude(Sketch, ExtrudeThickness, ExtrudeDepth)




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


# Get the selected sketch name; otherwise an empty string
def getSelectedSketchName():

    #setup stuff
    app = adsk.core.Application.get()
    ui  = app.userInterface

    #Prompt to select sketch
    Selection = ui.selectEntity("Select Sketch", "Sketches")

    return Selection.entity


#Draws a line from a designated start point, to a designated end point in a given sketch
def DrawLine(mySketch,Start,End):
    #start and end should be in the form (x, y).

    LineStart = adsk.core.Point3D.create(Start[0],Start[1],Start[2])
    LineEnd = adsk.core.Point3D.create(End[0],End[1],End[2])

    # Get the SketchLines collection from an existing sketch.
    lines = mySketch.sketchCurves.sketchLines
    # Call an add method on the collection to create a new line.
    NewLine = lines.addByTwoPoints(LineStart,LineEnd)

    return NewLine

#Creates a diagnol line randomly between the specfied X and Y coordinated.
def RandomLine(Sketch,X,Y,Step,Weight):
    X=float(X)
    Y=float(Y)
    Step=float(Step)

    if (random.uniform(0,1))<Weight:
        DrawLine(Sketch,(X,Y,0),(X+Step,Y+Step,0))
    else:
        DrawLine(Sketch,(X+Step,Y,0),(X,Y+Step,0))


    return


#Creates a list of float numbers, just like the range comand, but flotats. Float range, Frange, get it?
def frange(A, L=None, D=None):
    #Use float number in range() function
    # if L and D argument is null set A=0.0 and D = 1.0
    if L == None:
        L = A + 0.0
        A = 0.0
    if D == None:
        D = 1.0
    while True:
        if D > 0 and A >= L:
            break
        elif D < 0 and A <= L:
            break
        yield ("%g" % A) # return float number
        A = A + D

#Do a thin extrude on everything in a sketch
def ThinExtrude(Sketch, Distance, Thickness):

    app = adsk.core.Application.get()
    product = app.activeProduct
    design = adsk.fusion.Design.cast(product)
    rootComp = design.rootComponent


    #set all inputs needed for extrude
    extrudeFeatures = rootComp.features.extrudeFeatures
    operation = adsk.fusion.FeatureOperations.NewBodyFeatureOperation
    wallLocation = adsk.fusion.ThinExtrudeWallLocation.Center
    wallThickness = adsk.core.ValueInput.createByString(Thickness)
    distance = adsk.core.ValueInput.createByString(Distance)
    isFullLength = True

    NumberOfProfiles = Sketch.sketchCurves.count
    #extrude all profiles in sketch
    for I in range(0,NumberOfProfiles,1):
        Profile = Sketch.profiles.item(I)
        input = extrudeFeatures.createInput(Profile, operation)
        input.setSymmetricExtent(distance, isFullLength)
        input.setThinExtrude(wallLocation, wallThickness)


        extrudeFeature = extrudeFeatures.add(input)



    return extrudeFeature

 

Labels (3)
3 REPLIES 3
Message 2 of 4
kandennti
in reply to: AudacityMicro

Hi @AudacityMicro .

 

I tried it.
Since the sketch lines cannot be used as-is for the profile, I used the Component.createOpenProfile method to create the profile.

 

Only the ThinExtrude function was changed.

def ThinExtrude(Sketch: adsk.fusion.Sketch, Distance, Thickness):

    app = adsk.core.Application.get()
    product = app.activeProduct
    design = adsk.fusion.Design.cast(product)
    rootComp = design.rootComponent

    #set all inputs needed for extrude
    extrudeFeatures = rootComp.features.extrudeFeatures
    operation = adsk.fusion.FeatureOperations.NewBodyFeatureOperation
    wallLocation = adsk.fusion.ThinExtrudeWallLocation.Center
    wallThickness = adsk.core.ValueInput.createByString(Thickness)
    distance = adsk.core.ValueInput.createByString(Distance)
    isFullLength = True

    comp: adsk.fusion.Component = Sketch.parentComponent
    pros = []
    objs: adsk.core.ObjectCollection = adsk.core.ObjectCollection.create()
    for crv in Sketch.sketchCurves:
        objs.clear()
        objs.add(crv)
        pros.append(comp.createOpenProfile(objs, False))

    for profile in pros:
        extIpt: adsk.fusion.ExtrudeFeatureInput = extrudeFeatures.createInput(profile, operation)
        extIpt.setSymmetricExtent(distance, isFullLength)
        extIpt.setThinExtrude(wallLocation, wallThickness)
        extrudeFeature = extrudeFeatures.add(extIpt)

    return extrudeFeature

 

However, the state after execution is not so beautiful.

1.png

 

I have not examined it in detail, but it may be necessary to change the way the sketch line is written.

Message 3 of 4
AudacityMicro
in reply to: kandennti

I just checked it on my end, and I think I can make that work! Thank you so much!

 

It'll take a little tinkering to get the corners to match up right, but that should be a solvable problem.

Message 4 of 4
BrianEkins
in reply to: AudacityMicro

Here's some code that is able to get everything connected together. Here you can see the sketch and the resulting extrude.

ThinExtrude.png

There are a couple of quirks with how this works that it took me some experimenting to understand. You can see the same behavior in the command, but when using the API, you need to take care to create the same input. 

 

The main issue is defining the profiles to use as input for the command. The input for this specific case should be an ObjectCollection that contains two open profiles. One profile consists of two connected lines and the other is a profile of one line. I use the createOpenProfile method to create the profiles. If you draw the two connected lines you'll usually end up with a coincident constraint tieing the two ends together. If there is a coincident point and you have the "chaining" option selected in the dialog, it will automatically select the second when you pick the first. If there isn't a coincident constraint between them but their ends happen to end at the same coordinate, it won't automatically chain them but when you pick the second line, the command sees they are geometrically connected and still creates a single profile. You can see this in the selection input because even after selecting the second line it will still say there is one item selected. When you select the third line there will be two items selected because it's not connected.

In the API, if the two lines have a coincident point and you set the second argument of createOpenProfile to True, it will automatically find the second line and include both lines in the profile. If there isn't a coincident point, you can still create a single profile by creating an ObjectCollection containing both of the lines. When you create sketch geometry and provide a sketch point as input, a coincident constraint is automatically created. These are both demonstrated in the code below.

 

def thinExtrude():
    app = adsk.core.Application.get()
    ui = app.userInterface   
    try:
        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType, True)
        des: adsk.fusion.Design = app.activeProduct
        root = des.rootComponent

        sk: adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane)
        linesColl = sk.sketchCurves.sketchLines

        autoChain = True
        if autoChain:
            line1 = linesColl.addByTwoPoints(adsk.core.Point3D.create(0,5,0),
                                            adsk.core.Point3D.create(0,0,0))
            line2 = linesColl.addByTwoPoints(line1.endSketchPoint,
                                            adsk.core.Point3D.create(7,0,0))

            line3 = linesColl.addByTwoPoints(adsk.core.Point3D.create(0,3,0),
                                            adsk.core.Point3D.create(5,3,0))

            prof1 = root.createOpenProfile(line1, True)
            prof2 = root.createOpenProfile(line3, True)
        else:
            line1 = linesColl.addByTwoPoints(adsk.core.Point3D.create(0,5,0),
                                            adsk.core.Point3D.create(0,0,0))
            line2 = linesColl.addByTwoPoints(adsk.core.Point3D.create(0,0,0),
                                            adsk.core.Point3D.create(7,0,0))

            line3 = linesColl.addByTwoPoints(adsk.core.Point3D.create(0,3,0),
                                            adsk.core.Point3D.create(5,3,0))

            lines = adsk.core.ObjectCollection.create()
            lines.add(line1)
            lines.add(line2)
            prof1 = root.createOpenProfile(lines, False)
            prof2 = root.createOpenProfile(line3, True)

        profs = adsk.core.ObjectCollection.create()
        profs.add(prof1)
        profs.add(prof2)

        exts = root.features.extrudeFeatures
        extInput = exts.createInput(profs, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        extInput.setThinExtrude(adsk.fusion.ThinExtrudeWallLocation.Center,
                                adsk.core.ValueInput.createByReal(1))

        distanceExtent = adsk.fusion.DistanceExtentDefinition.create(adsk.core.ValueInput.createByReal(5))
        extInput.setOneSideExtent(distanceExtent, adsk.fusion.ExtentDirections.PositiveExtentDirection)

        ext = exts.add(extInput)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
            app.log('Failed:\n{}'.format(traceback.format_exc()))

 

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report