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: 

python script pipe creation

15 REPLIES 15
SOLVED
Reply
Message 1 of 16
esean
1954 Views, 15 Replies

python script pipe creation

Hi,

 

I have been using this command to draw splines between 3 points, but I now would like to add pipes along those lines. 

 

sketch.sketchCurves.sketchFittedSplines.add(points)

 

I have not been able to find any examples for drawing pipes]. Can you point me to any documentation for this?

 

Thanks,

 

Sean

 

15 REPLIES 15
Message 2 of 16
liujac
in reply to: esean

Hi,

 

You can use the spline to create a Path (Path.create), and create a sweep feature along the path. Take the SweepFeature API sample for example: http://fusion360.autodesk.com/learning/learning.html?guid=GUID-8261B011-EAAA-49F9-A5A4-48DC0BFC1548. Also you can take the "Pipe" script sample on "Scripts and Add-ins" dialog for example.

 

Regards,

Jack

Message 3 of 16
esean
in reply to: liujac

Hi Jack,

 

I have already marked this topic as resolved, but I have another more detailed question now that I've had a chance to make some sweeps from scripts. Let me know if you think I should create a new thread.

 

1st problem)

 

I have attached an example python script which illustrates the issue I'm having with sweeps.

 

Overall my goal is to create a closed-path sweep consisting of multiple merged splines, then dragging a profile over that single closed-path spline to create a pipe.

 

I also tried a method of creating a sweep for each spline, but ran into the same issue as I recall. I suspected merging all splines into one path might simplify sweep computations.

 

The attached script contains two "face" datasets and two methods of merging the splines. For one set of face and method, I am able to generate the desired model, but it takes forever to compute and as I said, doesn't work for the other dataset.

 

Overall my goal is a pipe like this,

good_one_face.png

 

 

using this 'one face' dataset of (4) splines,

splines_one_face.png

 

 

'2nd face' dataset: (5) splines

splines_2nd_face.png

 

 

 

showing single spline and profile, but this fails to compute given the following error.

one_face_closed_path1_sketch.pngone_face_closed_path1.png

 

 

 

 

2nd problem)

 

Another related problem concerns the profile orientation to the spline. I would like to make the profile normal to the spline at all locations, but it seems I can only select one of the 3 F360 sketch planes for orienting that profile. 

 

I've attached a screen cast showing a profile that is very far from normal to the spline path.

 

Is this something I should be concerned with? And if so, how I do make the profile always normal to the path?

 

Thanks,

 

Sean

 

 

 

Message 4 of 16
esean
in reply to: esean

 

Message 5 of 16
liujac
in reply to: esean

Hi Sean,

 

The problem was that the profile you made was not perpendicular to the close path. To make the profile perpendicular to the close path, create a construction plane along the path, create the sketch on the construction plane, then create sketch circle on the sketch. I updated your script as below. It works.

 

#Author-seanharre@gmail.com
#Description-sweep pipe

import adsk.core, adsk.fusion, traceback

def newpt(x,y,z):
    global points
    point = adsk.core.Point3D.create(x,y,z)
    points.add(point)
    return point

def add_splines_to_plot(points):
    global sketchxy
    if points:
        spline = sketchxy.sketchCurves.sketchFittedSplines.add(points)
        all_spline.append(spline)

def main():
    ui = None
    try:
        global app,ui,sketchxy,rootComp,points,all_spline
        app = adsk.core.Application.get()
        ui  = app.userInterface
        #design = app.activeProduct
        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)

        # Get the root component of the active design.
        rootComp = design.rootComponent
        
        # Create a new sketch on the xy plane.
        sketchxy = rootComp.sketches.add(rootComp.xYConstructionPlane)
        
        # Create an object collection for the points.
        points = adsk.core.ObjectCollection.create()
        all_spline = []
        
        # "one face"
        # fails 'CLOSED_PATH #1', works with 'CLOSED_PATH #2'
        newpt(-3.0 , -2.00116 , 0.516875)
        newpt(-2.9010937500000002 , -2.0006500000000003 , 0.12921875)
        newpt(-2.604375 , -1.99912 , 0.0)
        add_splines_to_plot(points)
        points.clear()
        newpt(-2.604375 , -1.99912 , 0.0)
        newpt(-2.3076125000000003 , -1.99759 , 0.090481375)
        newpt(-2.208575 , -1.99708 , 0.3619255)
        add_splines_to_plot(points)
        points.clear()
        newpt(-2.208575 , -1.99708 , 0.3619255)
        newpt(-2.30739375 , -1.99759 , 0.672107)
        newpt(-2.6042 , -1.99912 , 0.8788005)
        add_splines_to_plot(points)
        points.clear()
        newpt(-2.6042 , -1.99912 , 0.8788005)
        newpt(-2.90105 , -2.0006500000000003 , 0.8657938749999999)
        newpt(-3.0 , -2.00116 , 0.516875)
        add_splines_to_plot(points)
        points.clear()


        # "2nd face"
        # fails even with 'CLOSED_PATH #2', giving distorted splines
#        newpt( -3.0 , -2.19475 , 1.1643249999999998 )
#        newpt( -3.0 , -2.4164 , 1.26222 )
#        newpt( -3.0 , -2.6941699999999997 , 1.2947549999999999 )
#        add_splines_to_plot(points)
#        points.clear()
#        newpt( -3.0 , -2.6941699999999997 , 1.2947549999999999 )
#        newpt( -3.0 , -2.9235425 , 1.13282 )
#        newpt( -3.0 , -3.0 , 0.647305 )
#        add_splines_to_plot(points)
#        points.clear()
#        newpt( -3.0 , -3.0 , 0.647305 )
#        newpt( -3.0 , -2.875145 , 0.16182625 )
#        newpt( -3.0 , -2.5005800000000002 , 0.0 )
#        add_splines_to_plot(points)
#        points.clear()
#        newpt( -3.0 , -2.5005800000000002 , 0.0 )
#        newpt( -3.0 , -2.1260149999999998 , 0.12921875 )
#        newpt( -3.0 , -2.00116 , 0.516875 )
#        add_splines_to_plot(points)
#        points.clear()
#        newpt( -3.0 , -2.00116 , 0.516875 )
#        newpt( -3.0 , -2.0495574999999997 , 0.9371749999999999 )
#        newpt( -3.0 , -2.19475 , 1.1643249999999998 )
#        add_splines_to_plot(points)
#        points.clear()

        
        do_pipe = 1
        if do_pipe == 1:
            splines = adsk.core.ObjectCollection.create()
            spline_prev = None
            first_spline = None
            for spline in all_spline:
                splines.add(spline)
                if not first_spline:
                    first_spline = spline
                if spline_prev:
                    spline_prev.endSketchPoint.merge(spline.startSketchPoint)
                    pass
                spline_prev = spline
        
            if not splines:
                all_spline.clear()
                return
            
            #
            # CHANGING THIS COMMENT = WORKS
            #
            #  -> CLOSED_PATH #1:
            #       does not work, F360 gives error
            spline_prev.endSketchPoint.merge(first_spline.startSketchPoint)
            #  -> CLOSED_PATH #2:
            #       works for some reason, but takes a long time and spins CPU fan
            #spline_prev.startSketchPoint.merge(first_spline.endSketchPoint)


            # Create a path for the sweep path and guide rail
            path = rootComp.features.createPath(splines)
            #guide = rootComp.features.createPath(line)

            
            # Create sketch for the profile to sweep
            planes = rootComp.constructionPlanes
            planeInput = planes.createInput()
            planeInput.setByDistanceOnPath(first_spline, adsk.core.ValueInput.createByReal(0))
            plane = planes.add(planeInput)
            
            sketches = rootComp.sketches
            sketch = sketches.add(plane)
            
            center = plane.geometry.origin
            center = sketch.modelToSketchSpace(center)
            sketch.sketchCurves.sketchCircles.addByCenterRadius(center, 0.1)
            prof = sketch.profiles[0]
            
            # Create a sweep input
            sweeps = rootComp.features.sweepFeatures
            sweepInput = sweeps.createInput(prof, path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
            #sweepInput.guideRail = guide
            #sweepInput.profileScaling = adsk.fusion.SweepProfileScalingOptions.SweepProfileScaleOption
            
            # Create the sweep.
            sweep = sweeps.add(sweepInput)
    
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
main()

Regards,

Jack

Message 6 of 16
esean
in reply to: liujac

Hi Jack,

 

Thanks for your help! I am now drawing pipes on many splines, and can now start generating a voronoi mesh!

 

But as I'm starting to add more splines I'm noticing the time it takes to create each spline is increasing. Even a simple mesh of 187 splines, the time to generate the last spline is approaching 90seconds.

 

increasing_spline_creation_time.png

 

 

I understand as I add more splines and pipes, F360 has to keep checking a larger space for collisions, etc. But this seems like a possible bug.

 

And I want to generate meshes with maybe thousands of spline/pipe combos, so it could take weeks to generate...

 

I've attached an example script and the output logfile it generated showing delta creation time seconds. If I run this script and set 'do_pipe=0' (so it  generates only the splines and no pipes), it completes in a few seconds.

 

Can you confirm my findings? And is there any optimization to speed this up?

 

Thanks again,

 

Sean

 

 

 

Message 7 of 16
ekinsb
in reply to: esean

I added the highlighted line below to your code and now the construction of your entire model takes about 2 minutes.

 

        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        design.designType = adsk.fusion.DesignTypes.DirectDesignType

 

This changes the model so it's no longer capturing the parametric history. It does seem strange to me that there's such a big difference and we should do some investigation into this.  But in your case I don't think you would care about having a parametric model in the end so this should solve your problem.


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 8 of 16
esean
in reply to: ekinsb

Thanks Brian, that was it! And yes, I don't care about the history, I just want the final STL.

 

 

btw, this forum has been extremely helpful, and the responses are very prompt. Thanks Autodesk for a great product!

 

Sean

 

 

Message 9 of 16
esean
in reply to: esean

Hi Brian,

 

I have found one problem case in my script where I would like to have history enabled. I may create a sweep that fails, so removing that sweep so I can try another is what I want.

 

Can you tell me how I can re-enable the history in a script, ie, so I can programmatically toggle state and revert errors?

 

 

Thanks,

 

Sean

 

Message 10 of 16
esean
in reply to: esean

Ok, I found my answer on this page,

 

def toogleCaptureHistory(isEnabled):
     app = adsk.core.Application.get()
     des = adsk.fusion.Design.cast(app.activeProduct)
     
     if isEnabled:
         des.designType = adsk.fusion.DesignTypes.ParametricDesignType 
     else:
         des.designType = adsk.fusion.DesignTypes.DirectDesignType
    
Message 11 of 16
ekinsb
in reply to: esean

As you found, there is API access to the setting to toggle whether the design history is captured or not.  Actually it's a toggle and also a conversion because if you have a design with the full design history and then change this setting, all of the existing design history is lost.

 

Anyway, I'm not sure you need this for the case you described.  Whether you're capturing the design history or not, when the feature fails and nothing is created so there's nothing to remove to re-try it.


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 12 of 16
esean
in reply to: ekinsb

Hi Brian,

 

I just wanted to describe the issue I'm trying to resolve using history and deleteMe() a little more. Mainly for the benefit of others.

 

In my script, I first create a spline, then make a sketchCircle to sweep along that spline. The issue I'm now seeing is the sweep may fail if the spline circumference is too small for the sketchCircle diameter I have set - if the sweep will intersect with itself because of the large diameter that was set for that circle.

 

So I have put the sweep in a try/except block, so if it fails then I can remove the first circle, and add a smaller one and try to sweep again.

 

Here's a picture showing the problem. The larger sketch circle caused the sweep inside the try/except to fail, so the script sets the circle size smaller and tries again. So you can see both larger and smaller circles because I haven't yet deleted the first larger one.

 

need_to_remove_sketch_curve.png

 

 

 

So for speed issues as we discovered before, I keep parametric history off, and toggle it back on when I go to draw the circle and attempt to sweep. If that's successful, the history is turned off again.

 

If it's not successful, then I have the history available to remove the circle and try again.

 

At least that what I'm striving for. It's my next todo.

 

Thanks again!

 

Sean

 

 

 

Message 13 of 16
ekinsb
in reply to: esean

I understand what you're trying to do.  I was just saying that you don't need the history turned on to be able to do that.  If the sweep fails you can still change the size of the circle and try the sweep again and you're in direct modeling mode.


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 14 of 16
esean
in reply to: ekinsb

Hi Brian,

 

That would be easier if I don't need history. But I'm not seeing how to modify the circle geometry.

 

I see a radius property on the SketchCircle object, so tried this but it's not correct...

 

Can you tell me how do I modify the diameter of existing SketchCircle?

 

Thanks,

 

Sean

 

        center = plane.geometry.origin
        center = sketch.modelToSketchSpace(center)
        circle1 = sketch.sketchCurves.sketchCircles.addByCenterRadius(center, pipe_thickness)
        prof = sketch.profiles[0]
        
        # Create a sweep input
        sweeps = rootComp.features.sweepFeatures
        sweepInput = sweeps.createInput(prof, path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        
        try:
            # Create the sweep.
            sweep = sweeps.add(sweepInput)
        except:
            circle1.radius(pipe_thickness/2)
            sweepInput = sweeps.createInput(prof, path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
Message 15 of 16
ekinsb
in reply to: esean

radius is a property of the SketchCircle object so you set the value using this syntax:

 

circle1.radius = pipe_thickness/2

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 16 of 16
esean
in reply to: ekinsb

Thank you! much appreciated! All working for me now

 

Sean

 

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report