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.

Advent of Code

jason_1jason_1 Member Posts: 24 PRO
So has anyone here ever done Advent of Code before using Onshape FeatureScript? I didn't see any mention on this forum and I'm wondering, if anyone's used FS for it before. I just did Day 1 this year and it worked great and I was also able to plot out a fun graphical representation of the data (with a regen time of 1.2s). I'd be interested in seeing how other people would approach the problem though, especially how to best "read" the input


Comments

  • jnewth_onshapejnewth_onshape Member, Onshape Employees Posts: 42
    I was just going to try advent of code myself! I spend all day writing FeatureScript, so I am going to do them in lua. I applaud you for your efforts with FS. Keep us posted!
  • jason_1jason_1 Member Posts: 24 PRO

    sketching all the vertical and horizontal sketch segments in day 5 was pretty simple, but is there a simple way to find the number or places where the line segments intersect? All of the queries or evaluate functions that might sound relevant at first aren't made to work with sketches as far as I know. Are there ways to query using sketch parts in a sketch?
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    We've got some super smart software guys at Ovyl that pointed me to it, but I expect it to get over my head before the end. I'm not formally trained and FS is all I know, so I'm using that. I'm mostly just printing numbers to the notices panel for the answers. I love seeing the graph! I'm not getting any extra credit like that. It looks like you're using spheres for that. I'd have reached for opPoint first probably, which I'd guess to be a bit more performant, but definitely check that for yourself. I'd love to see some updates as you progress. I'm only through day 3.1 so I'm already getting a bit behind, but having fun.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • jason_1jason_1 Member Posts: 24 PRO
    Thanks @Evan_Reese! I'm a subscriber to your(/Ovyl's) youtube channel and I've specifically made the "How to Branch and Merge in Onshape" video required viewing for onboarding mechEs to Onshape, so thank you for that A+ content 🙏

    You're right that using points will probably be faster, but spheres worked surprisingly fast and what's the point of using Onshape if you're not going to make unnecessary 3D geometry ;) plus if you zoom in you can see that my points are actually festive baubles each colored in one of Formlabs' 16 named color kit resin colors. All "bonus points" here are just making up for the fact that I really don't know what I'm doing (I'd love to see other's code though!) and skipped two full days. But day 6 was pretty fun... 
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    ooh ok that Christmas Spirit is definitely worth the performance hit  :D 

    I'm pumped that you're watching the videos! I know my release pace is pretty low right now, but I try to make up for it in quality. I've got another one about 75% done, but not sure when I'll have time to finish it.

    As for your question about how to "read" the input, I assume you mean how to process and format the inputs. If so, have you tried using the built-in regex capability in the find/replace tool. Here's an example from Day3. I am only just getting started in learning some regex, but there are tons of tutorials.


    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • jason_1jason_1 Member Posts: 24 PRO
    Whoa that's awesome! I knew FS had regex capabilities (and read a handful of tutorials before giving up on using it) but I thought it was only for "REGEX_NUMBER(_CAPTURE)" and "match/replace". I had no idea you could use regex directly within find/replace. I was basically doing the same thing you're showing (great animation 👍) just copying and pasting from google sheets and using one or more hacky string concatenate commands. 

    The other direction I looked into was directly importing the data into the onshape doc and learning how to use imports directly (I've only done it with 3D geometry) but it appears that I'd have to convert it to JSON or CSV or something first since the AoC inputs are all .txt files. 
  • jason_1jason_1 Member Posts: 24 PRO
    I decided to continue plotting the data in 3D for day 9 which made a pretty cool height map (and I might actually 3D print a subset of it!). Surprisingly, Onshape was able to display all 10k cylinders, but doing a boolean union on all of them fails for some number around 2500 bodies. Does anyone know what the actual limit is here? And if it's not number of unique bodies what is the limit I'm hitting? I was able to solve 9.2 for only a 50x50 grid (image 1), but displaying all 10k unique bodies (image 2) works fine. 


  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    Looks cool! I haven't made much more progress on mine (I'm still on bingo) and haven't looked ahead at the new ones either. Why do you want to boolean them? You shouldn't have to in order to print it. If it's just to make it more wieldy in your parts list, consider a closed composite part instead.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • jason_1jason_1 Member Posts: 24 PRO
    @Evan_Reese good point. I use closed composites all the time for actual work stuff (and rarely use the boolean ops), but for Day 9 I'm specifically trying to solve the challenge using the 3D geometry. This is definitely a "bad" approach and at this point it would probably be a more valuable FS learning opportunity to figure out an optimized searching algo that drops the answer in the notices pane without ever modeling anything in the part studio.

    Have you looked at day 9 yet? I personally skipped Bingo in favor of focusing on ones that were more interesting visually in 3D (also it was a weekend day). The second pic is 9.1 visualized which is pretty neat, but the first pic is actually solving 9.2 -- basically it's plotting cylinders at every non-9 point such that they overlap with non-diagonal neighbors. All these cylinders are also 1 cubic mm so that when all bodies get boolean unioned you are left with the "basins" only and the volume of those remaining bodies is their "size" value (i.e. number of cylinders that were merged to create them). This works fine for ~one quadrant of the input but fails for the whole thing.

    I then tried a version where I modeled the points as cuboids and plotted *only* the 9s so that there were much fewer points and that each body had far fewer tris to render. This was able to produce a similar output (see "pixel art" ver below) but also fails for the full input data set


  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    I like your idea of focusing on the ones that you can actually leverage the 3D-ness of Onshape. I haven't made any more time to work on it. I might get to it, but I kinda doubt it. I have been working on a bit of other Featurescript on the side though.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • jason_1jason_1 Member Posts: 24 PRO
    Here’s the day 22 input visualized as a festively colored (3D printable!) orb with the 329 "on" cuboids in green and the 91 "off" ones in red. I didn't really have any interest in solving this one, but I really like modeling every day that has inputs with x, y, and z coords. 


  • jason_1jason_1 Member Posts: 24 PRO
    The question I have with this one is something I've also run into before; structuring feature ids correctly so that I can leverage their hierarchal nature while also avoiding the non-unique colliding ids or discontinuous ids errors. I think I understand how ids work, but when it comes to actually writing them I don't understand how to best have 2 different operations happening within a single loop. In this case I just loop through the input twice; once for the ONs and once for the OFFs, which isn't "correct" but it allows me to just have a single query/set appearance for each color (and it appears that the extra loops don't really add much time since the total number of fcubioid calls is constant). Is there some better way to have done this?




  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    In your loop, you can have i as the middle part of the id, and then use ANY_ID when querying the parts:

    for (var bounds, isOn in input)
    {
        i += 1;
        if (isOn)
            fCuboid(context, id + i + "posCuboid", { ... });
        else
            fCuboid(context, id + i + "negCuboid", { ... });
    }
    
    var posCuboids is Query = qCreatedBy(id + ANY_ID + "posCuboid", EntityType.BODY);
    var negCuboids is Query = qCreatedBy(id + ANY_ID + "negCuboid", EntityType.BODY);

    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • jason_1jason_1 Member Posts: 24 PRO
    Yes! Thank you. I knew there must be a way to do this simply, but wasn't aware of "ANY_ID" 
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    woah me either. I'd have appended them to an array in the loop and used qUnion after, but this way is better.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • jason_1jason_1 Member Posts: 24 PRO
    Alright I'm back trying to model the interesting 3D input for AoC 2022 in Onshape. I've got some cool looking forests for Day 8 (here is the example, because I hit a 10 minute time out trying to show the full thing at once), but I've gotten stuck trying to parse the Day 12 input "the right way" -- I was attempting to make a map that has all the letters and numbers as key value pairs e.g. {"a" : 1, "b" : 2 ... "z" : 26}. Can I then use "maparray" to turn my array of strings (each single letter) into an array of numbers? I got the input into an array or arrays where each row is it's own array, but I'm stuck on converting all the letters into numbers. How would you approach?

  • jason_1jason_1 Member Posts: 24 PRO
    Day 18 has a bunch of of coordinates for 1x1x1 voxels. Using the test input, it's trivial to model all the cubioids, boolean union them together, and get the area of all the remaining faces. If you don't do the boolean union you'll end up double counting adjacent faces when they shouldn't be counted at all.

    This is the code for that: 

            var voxelnum = 0;
            for (var voxel in testinput)
            {
                voxelnum += 1;
                println(voxelnum);
                var corner1 = vector(voxel[0], voxel[1], voxel[2]) * millimeter;
                var corner2 = corner1 + vector(1, 1, 1) * millimeter;
                fCuboid(context, id + "voxel" + voxelnum, {
                            "corner1" : corner1,
                            "corner2" : corner2
                        });
            }
            opBoolean(context, id + "boolean1", {
                        "tools" : qAllModifiableSolidBodiesNoMesh(),
                        "operationType" : BooleanOperationType.UNION
                    });
    
            var answer = round(evArea(context, {
                            "entities" : qAllModifiableSolidBodiesNoMesh()
                        }) / millimeter ^ 2);
            println("answer: " ~ answer);
    
        });
    
  • jason_1jason_1 Member Posts: 24 PRO
    However, the full input results in 2866 bodies, which is too big to handle in a single boolean union. Is this correct? I repeatedly get a time out issue, but I know know if or what the limit of solid bodies is. I tried to solve this problem by doing the opBoolean within the for loop and only call it every N voxels but I've tried a whole bunch of different groupings and there is something in the actual input ~1000 cubes in that gives a BOOLEAN INVALID error. What's going on?
    1. Is there a way to smartly union the cubes together and avoid these errors?
    2. OR if there is some smart way to detect adjacent faces can I skip the boolean completely and just evaluate that query to get the answer? What's the right query to select all faces that aren't touching another face?


  • thierry_maletthierry_malet Member Posts: 52 ✭✭
    you are ready for Minecraft party :smiley:
  • S1monS1mon Member Posts: 2,320 PRO
    You have some cubes that only share an edge, not a face. The Parasolid kernel doesn't support that for a Boolean add. 
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    yikes! that's a tough one. Like Simon said, it won't boolean because of the zero thickness geometry where cubes share and edge but not faces. My first thought was to make them all a little bit oversized, so they all overlap but that would mess up the calc. Boolean is computationally expensive anyway.

    I favor the analytical approach you suggested. Maybe you could find a point at parameter [0.5,0.5] on each face. Next, take your giant array of all points, and iterate over each one, subtracting it from the main array and using isin() to see if there's a match. If true, do nothing. If false, add the corresponding faces to their own big array to analyze later. I've not tested this, but something like that could work.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • jason_1jason_1 Member Posts: 24 PRO
    @S1mon I thought that might be the case but I was pretty sure that the test input has this case and it works well. Here the 13 cubes end up getting unioned into 6 parts and there is a void in the middle of the top which you can see in this x-section view. So what's happening where this simple test input is fine but the giant ball of cubes fails? When I manually try to union the results of this test I also get a descriptive error "Boolean resulted in no geometry change. The parts either do not intersect or are totally contained." which made me think that this was some other related error case, but I'd love to try to understand this more. Or alternately, get some help on a query to select all the non overlapping faces without having to boolean anything!
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,305
    I did a voxel script some time ago and I just enlarged each cube by a very small amount so that they would intersect. 
    Senior Director, Technical Services, EMEAI
  • jason_1jason_1 Member Posts: 24 PRO
    NeilCooke said:
    I did a voxel script some time ago and I just enlarged each cube by a very small amount so that they would intersect. 
    oooh thanks @NeilCooke. I love this hack. I ended up doing something similar for this last year
Sign In or Register to comment.