Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:

  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Performance Tips for Sweeps?

dave_cowdendave_cowden Member, Developers Posts: 447 ✭✭✭
Hey, all:

I'm working on a thread generator, which has pretty realistic threads, with a profile swept along a helix.

Yes, before you say it, I know that most people don't want real threads. But this generator is for people who do, for example, because they are 3d printing things, or making lens caps, etc.

Anyhow, i'm using the cool startTimer and printTimer function to look at execution time ( kudos @ilya_baran  for those functions).

I'm seeing ( not surprisingly ) that creating the thread geometry, and then subtracting/adding that to the base part are accounting for all of the time.

Does anyone have overall pointers/tips/tricks for how to speed things up?

Here is a picture of the geometry, nothing fancy:

By way of example, this code takes about 1.2 seconds (creating the thread forms by sweeping a profile over a helix):

    var sweepId = id + "_sweep1";    opSweep(context, sweepId, {                "profiles" : sweepItems,                "path" : qCreatedBy(helixOpId, EntityType.EDGE)    });    var qSweeps = qCreatedBy(sweepId, EntityType.BODY);        printTimer("Sweeps-1");

The helix and sketch is what you'd guess from the above picture...

And this takes about 1.2 seconds ( subtracting the threads from the parent body )

        startTimer("FuseSweepsToParent");        var fuse = id + "fuse";        opBoolean(context, fuse, {            "tools" : qUnion([parentBody, qSweeps ]),            "operationType" : BooleanOperationType.UNION        });        printTimer("FuseSweepsToParent");
My assumption is that this is just 'complex geometry' and that there is not much that can be done. But if there are any 'expert' tricks that can be used, please let me know!

Best Answers


  • dave_cowdendave_cowden Member, Developers Posts: 447 ✭✭✭
    Thanks! @elif
    Just wanted to make sure I wasnt missing anything.  One thing I can do is provide an option for the user to reduce the complexity of the profile. I'm not sure how much that will help, but i'll run a couple of tests to find out.  My anecdotal experience has been that the complexity of the profile doesnt impact performance as much as the pitch of the helix. 
  • dave_cowdendave_cowden Member, Developers Posts: 447 ✭✭✭
    Ok, so i found something interesting.  After doing a bunch of tests.

    Turns out, a tiny difference in geometry makes a 10x performance difference!

    This is a cross-section of a profile swept on a helix. Note the highlighted flat portion of the profile. This took 0.3ms to create:

    Now, here is the same profile, but with a 3 point arc there instead of the flat section:

    Shockingly, this small difference increases build time to a whopping 2.86 seconds!!! That's nearly 10x longer!

    As a third test, i added another point, connected by lines instead of an arc. The question is; was it the extra point or the arc and the resulting surface:

    Performance on this is 0.9s-- 3x slower than without the intermediate point, but still nearly 3x faster than the arc.

    @ilya_baran  @elif, is this something you would have expected? I certainly didnt!

    Anyway, these tests helped me understand how to give the user a speedier option. In this case, just letting them opt out of that little relieve radius saves 10x!  

  • elifelif Onshape Employees Posts: 49
    I'm curious - is it the sweep or the boolean that takes much longer? I would expect the boolean but not 100% sure really...

    Team Lead, Part Studios
  • dave_cowdendave_cowden Member, Developers Posts: 447 ✭✭✭
    very good question!

    Here are the performance timings for the 'fully complex' profile:

    Timer "Helix": 1 ms
    Timer "Sweeps-1": 1519 ms
    Timer "Runout-Sweeps": 0 ms
    Timer "Pattern": 0 ms
    Timer "TrimSweeps": 41 ms
    Timer "MakeTrimCylinders": 20 ms
    Timer "TrimSweeps": 205 ms
    Timer "FuseSweepsToParent": 1491 ms
    Timer "WholeThing": 3289 ms
      Result: Regeneration complete

    And here are the timings for the 'simplified' profile:

    Timer "Helix": 1 ms
    Timer "Sweeps-1": 31 ms
    Timer "Runout-Sweeps": 0 ms
    Timer "Pattern": 0 ms
    Timer "TrimSweeps": 31 ms
    Timer "MakeTrimCylinders": 16 ms
    Timer "TrimSweeps": 139 ms
    Timer "FuseSweepsToParent": 104 ms
    Timer "WholeThing": 335 ms
      Result: Regeneration complete

    we have about 3 seconds more time on the complex profile, and it is split roughly equally between creating the sweeps and fusing them to the parent, as shown in bold.

    The "TrimSweeps" item is very, very interesting too.  After i create the helix by sweeping the profile, i trim it on top and bottom with two cylinders, so that it is limited to just the threads I want to create.  That's a boolean subtraction-- starting with the sweeps and REMOVING the cylinders.

    What's really really interesting is that while it takes 1.5 seconds to fuse sweeps to the parent body, it takes only 0.2 seconds to subtract TWO cylinders from the sweeps.  Its really strange that subtracting is so much faster than the union.  This is repeatable too. Its such a huge difference that i considered re-organizing my code to try to subtract from some huge cuboid instead of unioning. 
  • dave_cowdendave_cowden Member, Developers Posts: 447 ✭✭✭
    Wow that's a great tip lana, thanks for that ! i will give this trick a try and see how much that helps!
  • dave_cowdendave_cowden Member, Developers Posts: 447 ✭✭✭
    Hi, Lana:

    For those coming after me-- I did some performance tests using the 'overshoot' idea Lana suggested, and I can confirm that it works.  

    In my tests, performance was 10-15% faster overshooting vs having booleans with a 'line on line' mate.  Its not a huge difference, but it is a repeatable difference that can add up if your feature has many booleans.
Sign In or Register to comment.