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: 

Is there a less expensive (faster) way to draw lines in a sketch?

17 REPLIES 17
SOLVED
Reply
Message 1 of 18
owendelong
863 Views, 17 Replies

Is there a less expensive (faster) way to draw lines in a sketch?

Currently, I'm using this:

 

 

tickLine = sketchLines.addByTwoPoints(adsk.core.Point3D.create(Top, xpos, 0), adsk.core.Point3D.create(Bottom, xpos, 0))

 

to draw a series of lines in a sketch.
On average, this call seems to take approximately 200ms to complete, which isn't that long if you're only drawing a few lines, but in this case, I'm generating a several hundred lines, so it leads to a significant wait for the end user overall.
 
I don't need 3d lines (as you can see, Z is fixed at 0 in both coordinates). If there's an alternative mechanism (whether another method in the sketchLines class or otherwise that is faster, I think that's very desirable in this instance.
 
Thanks in advance for any pointers.
 
17 REPLIES 17
Message 2 of 18
kandennti
in reply to: owendelong

Hi @owendelong -San.

 

Sketch processing is slow.
The only thing that might work is the Sketch.isComputeDeferred property, but it will still be slow if there is a lot of it.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-a174973f-79ac-4330-8dd7-3d3ded63e63e 

 

Other options are,
・Create your own logic to create the DXF and load the DXF.
・Abandon the sketch and create the 3D model directly.

Message 3 of 18
owendelong
in reply to: kandennti

Since the point here is to produce a DXF that can be used for Laser Cutting, direct 3D object creation isn't really a useful solution.

 

I suppose creating the DXF without involving Fusion is an option, but that seems like it would involve a significant amount of recoding. I guess for now, I'll just live with the slow.

 

Interestingly, it seems to get slower the more lines you have in the sketch.

 

I will look into the deferred Compute option.

 

Message 4 of 18
owendelong
in reply to: owendelong

Deferred Compute isn't a panacea, as you stated, but it definitely helped quite a bit. Script now seems to build the sketch in about half the previous time.

 

Message 5 of 18
owendelong
in reply to: owendelong

FWIW, I gained a LOT more speed by switching from storing the variables in a python dictionary to storing them as Fusion User Parameters and significantly reducing progress reporting. Not sure how much each of these contributed, but since line drawing itself accelerated greatly (single API call time in/time out difference greatly reduced) I have to assume a significant amount came from the change to User Parameters.

I find this surprising, but YMMV and I figured I'd share it here.
Message 6 of 18
kandennti
in reply to: owendelong

@owendelong -San.

 

Very interesting. Could you be more specific? Many people must have the same problem.

Message 7 of 18
owendelong
in reply to: owendelong

Well.. I'm not sure how much more specific I can be, but basically, I turned this (times 7 python dictionary entries):

myParameters = { 'Type' : False }

 

into this:

if (myParameters.itemByName("Type"))
  myParameters.itemByName("Type").value = False
else:
  myParameters.add("Type",adsk.core.ValueInput.createByBoolean(False),"",
                   "False for Linear, True for Grid")

 

I also removed several calls to this function:

def debug(ui, *args, **kwargs):
    buf = io.StringIO()
    print(*args, **kwargs, file=buf)
    ui.palettes.itemById('TextCommands').writeText(buf.getvalue())

 

However, where most of the performance improvement happened, wasn't where most of the removed calls were located, so I have to think that the former had more to do with the speed gain than the latter.

 

Unfortunately, it's a fairly hairy script (with some embarrassingly quick and dirty code elements) that I think would have limited value to the community.

Message 8 of 18
OceanHydroAU
in reply to: owendelong

This sounds promising:-

sketch.isComputeDeferred = True / sketch.isComputeDeferred = False

but does not work for me.

 

But the reason it is slow is because every new line you're drawing "touches" in some way some other thing already, and those 200ms is Fusion working it's hardest to prevent inserting duplicated things.  If you can add lines in an order to minimize how they coincide with anything else, that will drastically speed things up.

 

I was able to improve some really bad issues by inserting things in a deliberately wrong place, then moving them to where they should be.

 

A better bet would be to investigate how to turn off that optimising thing that's de-duping your inserts.

 

 

Message 9 of 18
OceanHydroAU
in reply to: owendelong

you know that python can directly create DXF files (ezdxf I think?), and that fusion360 can read them - right ?

Message 10 of 18
kandennti
in reply to: owendelong

@owendelong -San.

 

I didn't understand it even though you went out of your way to explain it to me. I am sorry.

 

I know this is a different topic, but can you create a user parameter without units here? I get an error.

1.png

Message 11 of 18
owendelong
in reply to: kandennti

Are you sure that the error you are getting is from the "" and not from the type of value you are passing?

Note that there is a difference between:
parameterobject.add("name",value,"","description")
and:
parameterobject.add("name",adsk.core.ValueInput.createByBoolean(value),"","description")

Namely that the second argument (which is usually reported in the error as argument 3 to a deeper function because that deeper function is called with a prepend of '''self,''' to the argument list (gotta love objects).


The former will cause a type error because the value you are passing is merely a value and not a valueInput object (which is the type required by the function).

I struggled with that one for quite a while myself.
Message 12 of 18
owendelong
in reply to: OceanHydroAU

Yes, but this exercise is as much about learning the Fusion API as it was about generating DXF files to laser cut rulers. I keep hoping that some day, someone will build a CAM interface with post processor for LightBurn or other Laser cutters, but so far, I have to manually post-process DXF files.
Message 13 of 18
owendelong
in reply to: OceanHydroAU

That actually makes some sense as to why making it into userParameters instead of an internal python Dictionary in my script would accelerate things, then. Since the values are being pulled from Fusion's userParameters, it has probably cached/pre-computed a number of things related to de-dup.

 

Message 14 of 18
kandennti
in reply to: owendelong

@owendelong -San.

 

Thanks for explaining the parameters. I was indeed able to create a unitless user parameter with the CreateByReal method.

Can I create parameters with Boolean type?

1.png


I have tested with the following code, but they all give an error.

# adsk.fusion360API Python script

import traceback
import adsk.core
import adsk.fusion

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface
        des: adsk.fusion.Design = app.activeProduct

        myParameters: adsk.fusion.UserParameters = des.userParameters

        myParameters.add(
            "Test",
            adsk.core.ValueInput.createByBoolean(False),
            "",
            ""
        )

        myParameters.add(
            "Test",
            False,
            "",
            ""
        )

        myParameters.add(
            "Test",
            adsk.core.ValueInput.createByString("False"),
            "",
            ""
        )

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


The CreateByString method does not generate an error, but it does on the GUI.

Message 15 of 18
owendelong
in reply to: kandennti

I could have sworn I had createByBoolean working previously, but I certainly haven't been able to get it working since it stopped. Because the script is under very active development, there were a lot of changes at the same time, so it's possible that the switch from createByReal to createByBoolean happened after the last test run and before the other changes that prompted the next test run where things were broken.

 

Interestingly, as I also mentioned in the other thread, assignment of a boolean value to an existing parameter seems to work (e.g. userParameter_var.value=True), so I'll probably create a Real and then set the boolean value as a workaround for now.

 

Message 16 of 18
OceanHydroAU
in reply to: owendelong

I'm almost finished an add-in which comes very close to what you're talking about. Sounds almost trivial to re-purpose it to output stuff for cutters. Your phrase "laser cut rulers." puzzles me slightly (I'm guessing these are long rectangular things with units etched on them?). What exactly would your dream "CAM interface" be doing for you here (my guess: generating a DXF file with cut lines and etch markings, right? Anything else?)
Message 17 of 18
owendelong
in reply to: OceanHydroAU

Etch/Cut DXF layers would be good. Native LightBurn support or similar would be even better, one where I could identify the different power/speed/pulse(where applicable) settings as part of the CAM process (similar to the way you select different end mills for a milling process) and output a file that can be directly loaded into the LASER control software would be unimaginably wonderful.

 

(LASER equivalent of the ShopBot post processor, for example)

 

Yes, the current project is transparent acrylic rulers. The script I'm writing is capable of producing sketches suitable for cutting thin wood or acrylic on the laser with etched unit lines. It can do either linear (one or two long sides with same or different units (imperial/metric)) or grid (frequently used in graphic layout and/or textiles) rulers with the same units on all 4 sides, frequently wider (think 7-15cm wide and upwards of 40cm long) and unit grids with sub-unit ticks on all the grid lines.

 

Message 18 of 18
BrianEkins
in reply to: owendelong

You can set two things on a sketch that should speed up the creation.

  1. Sketch.isComputeDeferred - This has already been mentioned and disables the standard solving done as you draw sketch geometry.
  2. Sketch.areProfilesShown - This is also available in the UI and stops the display of profiles in the sketch. It also stops the computation of profiles, which will be the most beneficial when creating sketch geometry with the API.

Any operation in Fusion has a few costs. First is the internal cost of calculating the result for whatever you're creating. This is trivial for a sketch line but expensive for a complex loft. Second, the result may also involve other calculations to update related geometry. When drawing sketch geometry, this includes the things we're trying to skip with the properties listed above. When editing a feature or changing a parameter, there is the cost of updating all of the features in the timeline after the feature that is modified. Finally, there is some cost of transacting all of that work so it can be undone.  

 

Regarding the Boolean parameter, Fusion only supports numeric parameters and as a result, that's all the API supports.

---------------------------------------------------------------
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  

Autodesk Design & Make Report