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.

can I get an ELI5 on reconstructOp when joining surfaces?

Evan_ReeseEvan_Reese Member Posts: 510 PRO
I'm trying to add support for surfaces to my Multi-Mirror feature, and I'm looking at joinSurfaceBodiesWithAutoMatching as a function to achieve that. All of the inputs make sense except for reconstructOp, which is looking for a function of some kind, but I don't know what info it needs. I've already looked at std | boolean.fs and it doesn't make enough sense to me. Can I please get a plain-English rundown on the reason it's there and what data it needs?
Evan Reese / Principal and Industrial Designer with Fractal
Website: fractalmade.com
Instagram: @evan.reese.designs

Best Answer

Answers

  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 1,894 PRO
    Alternatively, you could use opBoolean with detectAdjacencyForSheets set to true and just pass your surfaces to it
    MB - I make FeatureScripts: View FeatureScripts
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    Alternatively, you could use opBoolean with detectAdjacencyForSheets set to true and just pass your surfaces to it
    this sounds better to me since I've already got opBoolean in there for solids. I'll play with it and see where it gets me. Thanks for the explanation.
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    @MBartlett21
    what you suggested worked, but how could I have found that out on my own? I don't see detectAdjacencyForSheets in the standard library documentation for opBoolean (maybe it's not updated yet). I also don't see it in the code for the opBoolean function declaration, but maybe I'm looking in the wrong place. I'm trying to become a bit more self-sufficient so I don't have to bug the forum as much.
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 3,269
    That’s because @MBartlett21 is a hacker! 😂

    it’s not an officially documented feature yet, but should be soon. It was added to enable the Boolean of surfaces in the Dec 3 release. 
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    edited January 4
    NeilCooke said:
    That’s because @MBartlett21 is a hacker! 😂

    it’s not an officially documented feature yet, but should be soon. It was added to enable the Boolean of surfaces in the Dec 3 release. 
    lol, I thought the reason was going to be something like that. So are you saying that I couldn't have found it even by looking at the most recent opBoolean code?

    While I'm at it, is there some secret way to make a solid from the surfaces with opBoolean, or do I follow it up with opEnclose. I'm working on the opEnclose version now
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    edited January 5
    I've got it working in a scenario in which the surfaces merge to form only 1 solid body, but it fails if the surfaces should form 2 solid bodies. See my gif below.


    1. When I press Top it booleans the surfaces and does opEnclose in a try statement, which fails and does an opDeleteBodies in the catch statement, which is what I want, in order to clean up a duplicate surface body.
    2. When I press Front, the try statement succeeds and I get the solid I'm looking for and delete the surface bodies.
    3. When I press Right, now the surfaces should form 2 separate solid bodies, but Onshape doesn't know which surfaces should form which bodies and the whole thing fails.

    can opBoolean work for me here? Is there some other function that won't require me to sort all of the bodies into sets that can merge and process them one-by-one in a for loop? if not, any pointers on how to identify which ones go together? qAdjacent, maybe?
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 1,894 PRO
    @Evan_Reese
    opBoolean has a makeSolid option that you can set to true to have it try to create a solid :)
    MB - I make FeatureScripts: View FeatureScripts
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 1,894 PRO
    @Evan_Reese
    Also, the surfaces seem to have correct normals, so detectAdjacencyForSheets shouldn't actually be needed. If you set allowSheets to true instead of detectAdjacencyForSheets, does it work then?
    MB - I make FeatureScripts: View FeatureScripts
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    @MBartlett21
    Appreciate it. This is much better than what I had since it's less code, and preserves the surface names when it makes a solid. Again, I'm unclear how I could find this out without pestering the forum. None of these options are in the standard documentation (yet) and I'm not sure how to find it otherwise. Any advice?

    It still fails if the resultant surfaces should form 2+ solid bodes. In practice, this is probably not important since this is an edge-case for my workflow, but I'm feeling stubborn and I'd still like to make it work as users expect it should.

    I don't presume it, but If you want to take a look at my specific case you can go here, and play with the feature called "Multi-Mirror To Edit" to see why it fails.
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 1,894 PRO
    @Evan_Reese

    I edited a copy of your feature to use a single opPattern for each part and boolean it all together rather than patterning and booleaning each direction individually. Due to changing it to a single boolean, it now works properly for multiple surfaces, etc.
    http://onsha.pe/documents/93f8968e453c6aaad6b66008

    I also made it use an unstableIdComponent with setExternalDisambiguation to make it work better when changing selection.
    MB - I make FeatureScripts: View FeatureScripts
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    @Evan_Reese

    I edited a copy of your feature to use a single opPattern for each part and boolean it all together rather than patterning and booleaning each direction individually. Due to changing it to a single boolean, it now works properly for multiple surfaces, etc.
    http://onsha.pe/documents/93f8968e453c6aaad6b66008

    I also made it use an unstableIdComponent with setExternalDisambiguation to make it work better when changing selection.
    Fantastic! I'll take a look when I have time so I can learn what I can, then I may copy/paste it back to my side (in case I want to add more to it) with a note of thanks to you at the top of the code.
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    edited January 11
    @MBartlett21
    your code is about half the length, and works much better, haha.

    Not sure I fully get the "disambiguation" part. Is it so the IDs stay sensible even if the selections change or something?

    I noticed that it works great, except in some situations with surfaces and a single direction. On my example cube thing, if I select both surfaces and do only X or only Z it fails. I added a try silent() to the opBoolean in the if(isSheet) area, and it seemed to fix it, but is that an ok way to solve it?

    Also, I saw that you ditched my custom enums in favor of a boolean, which is simpler, but seeing 4 checked boxes in a row seemed confusing so I changed it to "use mate connector" false by default to set it apart from the "true" xyz booleans.

    I wanted to add icons like in the "move" area of the Mate Connector UI, but it seems like you can only add parameter icons to enums and quantity parameters. I want to show the user which color line they should look at, but it doesn't seem possible. Any ideas?

    You can see my fiddling around with it here.
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,578
    @Evan_Reese

    Here is a description of external disambiguation and unstable components that I wrote for some internal programmers a little while ago:

    External disambiguation is a way of associating an operation or set of operations with a specific piece of geometry, to stabilize the reference. Imagine writing a feature that takes in 3 vertices, and makes solid cubes centered on each vertex. If you do it like this:
    for (var i = 0; i < 3; i++)
    {
        const cuboidId = id + ("cuboid" ~ i);
    fCuboid(context, cuboidId, { ... }); }
    You will successfully create the three cuboids, but they are unstable.  If you do a bunch of fillets on the “second” cuboid, and then change the order of the selected vertices, or pick a new set of vertices that includes that vertex, the downstream fillets may jump from one cube to another.  Specifically, the fillets will always appear on whatever the second created cuboid is (because the only information that the system has to disambiguate the cuboids is the id). Now imagine doing something like this:
    const centers = evaluateQuery(context, definition.centers);
    for (var i = 0; i < size(centers); i += 1)
    {
        const cuboidId = (id + "cuboid") + unstableIdComponent(i);
        setExternalDisambiguation(context, cuboidId, centers[i]);
        fCuboid(context, cuboidId, { ... });
    }
    the unstableIdComponent alerts the system that you are going to be doing something ambiguous, and the external disambiguation tells the system how to disambiguate. Now, if you do some fillets downstream, and then go and redo your selection to some different vertices, the fillet will map back onto the same cuboid that you expect. No matter how you reorder or change the selected vertices.

    For most operations, this is not needed since the operation's query inputs will be used as the disambiguation automatically (i.e. extruding many faces keeps the extruded geometry associated with the original face). But for operations without query inputs for each bit (things like fCuboid, fCylinder, opPattern, sketches) this is needed for good behavior.

    Jake Rosenfeld - Modeling Team
  • Evan_ReeseEvan_Reese Member Posts: 510 PRO
    @Jake_Rosenfeld
    ah, I see. Thanks for the explanation and simple example! That makes sense
    Evan Reese / Principal and Industrial Designer with Fractal
    Website: fractalmade.com
    Instagram: @evan.reese.designs
Sign In or Register to comment.