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.

50 Digital Joints in Featurescript

Aaron_HooverAaron_Hoover Member Posts: 35 EDU
Hi Folks, 

I'm embarking on a project to create FeatureScript versions of Jochen Gross' 50 Digital Joints (https://www.flickr.com/photos/satiredun/15868308421/sizes/o/). My goals are create a useful set of features for folks interested in CNC furniture manufacturing and to get more proficient in FeatureScript as I go. Caveat emptor: I'm a newbie to FeatureScript (but not to CAD programming and concepts), so bear with me if these features break spectacularly or behave in unexpected ways. 


So far, I've implemented: 
  1. A simple miter joint - https://cad.onshape.com/documents/9f4cce8606bea7e49e320254/w/b09b01b42cf427bd4a530258/e/32f3785f8f7f20d099d3a2ac (not one of the 50 digital joints, but it was a chance to get my feet wet with FeatureScript)
  2. The joint he calls "Halving with Elliptical Tenon" - https://cad.onshape.com/documents/adfedeff1e00a5990b0a77b7/w/aa9cf84b45740819a6fcca5e/e/c650a5eb2d645060e0907338
I have imported IGES models that I'm working from for all 50 joints, but since I can't share a folder by link, let me know if you're interested in seeing those. Also, let me know if you're interested in testing/improving my FeatureScripts. It's pretty tricky to create bulletproof features given the myriad ways a user can generate and manipulate geometry, but I'd like to understand how people might want to use these features. 

Finally, if you have any suggestions for which joints you might like to see first, just let me know. Otherwise, I am starting with the joints that seem the easiest to implement first and working toward the more complex ones as I build my FeatureScript skills.  


Comments

  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    edited October 2018
    Great stuff @Aaron_Hoover !

    Let us know if you need any help or have any questions :)
    Jake Rosenfeld - Modeling Team
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    One suggestion I have is to consider grouping some of the joints by mechanical function (e.g., corner joints or lengthening joints) into features that let you select the joint type.  That'll make it easier for users who don't have to manage 50 custom features and may want to switch between joint types.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • Aaron_HooverAaron_Hoover Member Posts: 35 EDU
    One suggestion I have is to consider grouping some of the joints by mechanical function (e.g., corner joints or lengthening joints) into features that let you select the joint type.  That'll make it easier for users who don't have to manage 50 custom features and may want to switch between joint types.
    This is a great suggestion. Let's consider an example, just so I'm certain I understand you. I might have a single frame corner joint feature, and then within that feature, there would be an option to select, say, "Halved Dovetail Corner Joint," "Halving with Elliptical Tenon," or "Jigsaw Miter." Then, the feature would conditionally expose parameters for creating the geometry based on what type of frame corner joint the user selected? This would be similar to the conditional logic for doing dovetails in the Box Joint feature, right?

    This would actually be very helpful to me as well from the standpoint of minimizing code duplication. On a related note, is there any way to reuse FeatureScript code across features (ie. a user-defined library)?

    Thanks for the feedback and suggestions! 
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    Hi Aaron,

    Yes, this is exactly what I meant.  You can certainly reuse code in FeatureScript -- a feature studio can define multiple features and utility functions that are not features.  Feature studios can also import other feature studios (from the same or other documents) to use their functions (as long as they are declared export).  The std is an example of a large code base with a lot of code reuse.

    Let us know if you need help with this stuff.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • lemon1324lemon1324 Member, Developers Posts: 223 EDU
    Cool project!

    Couple things I think may be issues as you get to more complex joints:

    When you're generating the vector for the miter joint split plane, I think you're implicitly assuming it's drawn on the top plane, and not at some arbitrary orientation (Lines 56-57).  In my laser joint feature I ended up using cross product to find perpendicular vectors, and adding two unit vectors to find a vector pointing between them (e.g. into/out of a corner).

    More generally, it takes the vast majority of the time making sure it works at weird orientations and corner cases; I found it helpful to make several part studios in the document, each with a specific different corner case, to treat them like unit-tests for making sure it works.  Every bug report I get adds a corner case.

    Also, one thing I found: sketching with FeatureScript is really slow.  I found significant improvements by using the primitives where possible, transforming them, and then boolean subtracting/adding.  This might be less important for usability in your case if each feature only ever makes a single joint; I wanted mine to be able to drag-select everything in the part studio and work pretty well.
    Arul Suresh
    PhD, Mechanical Engineering, Stanford University
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    @lemon1324

    When you say primitives, do you mean like fCuboid and fCylinder?  Those use sketches as well to be created.  But yes, in general it will be probably be faster if you create your first tool with a sketch -> extrude, and then any matching ones with pattern.
    Jake Rosenfeld - Modeling Team
  • lemon1324lemon1324 Member, Developers Posts: 223 EDU
    @Jake_Rosenfeld Yeah, the fcuboid. 

    Interesting, are they optimized under the hood? Because I'm pretty sure I got to those by testing alternatives and finding that they regenerated faster than me defining my own sketch.
    Arul Suresh
    PhD, Mechanical Engineering, Stanford University
  • Aaron_HooverAaron_Hoover Member Posts: 35 EDU
    @lemon1324

    Thanks for the helpful suggestions. Yes, my features are pretty dumb at this point because I'm really learning FeatureScript as I go. I'm trying to create minimum viable product features that "work" assuming the user is doing something sensible (the idea of anticipating all the crazy ways a user could try to join to bodies, is a little daunting!). 

    Also, thank you for the excellent Laser Joint feature, it's been my primary point of reference for learning FeatureScript (and I point all my first-year design students to it for any project that uses laser-cutting).

    PS - I see you're a PhD candidate in Mark Cutkosky's lab. I was a Stanford ME undergrad, and I did my PhD with Ron Fearing at Berkeley working on biomimetic multi-legged locomotion. Small world! 
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    @lemon1324

    They are pretty simple sketches, but they are not optimized under the hood.  You can see exactly what they are doing in the primitives.fs file of the standard library:

    https://cad.onshape.com/documents/12312312345abcabcabcdeff/w/a855e4161c814f2e9ab3698a/e/dc9e71d454d34142ae66df18

    Here is fCuboid:
    /**
    * Create a simple rectangular prism between two specified corners.
    * @param id : @autocomplete `id + "cuboid1"`
    * @param definition {{
    * @field corner1 {Vector} :
    * @eg `vector(0, 0, 0) * inch`
    * @field corner2 {Vector} :
    * @eg `vector(1, 1, 1) * inch`
    * }}
    */
    export const fCuboid = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {
    is3dLengthVector(definition.corner1);
    is3dLengthVector(definition.corner2);
    for (var dim in [0, 1, 2])
    !tolerantEquals(definition.corner1[dim], definition.corner2[dim]);
    }
    {
    const sketchId = id + "sketch";
    {
    var plane = XY_PLANE;
    plane.origin[2] = min(definition.corner1[2], definition.corner2[2]);
    const sketch = newSketchOnPlane(context, sketchId, { sketchPlane : plane });
    skRectangle(sketch, "rectangle",
    { "firstCorner" : vector(resize(definition.corner1, 2)),
    "secondCorner" : vector(resize(definition.corner2, 2))
    });

    skSolve(sketch);
    }
    {
    const query = makeQuery(sketchId + "imprint", "IMPRINT", EntityType.FACE, {});
    opExtrude(context, id + "extrude",
    { "entities" : query,
    "startBound" : BoundingType.BLIND,
    "endBound" : BoundingType.BLIND,
    "startDepth" : 0 * meter,
    "direction" : [0, 0, 1],
    "endDepth" : abs(definition.corner2[2] - definition.corner1[2])
    });
    }
    {
    const query = qCreatedBy(sketchId, EntityType.BODY);
    opDeleteBodies(context, id + "deleteSketch", { "entities" : query });
    }
    });
    So its a pretty simple operation, but not special compared to any other FS code.
    Jake Rosenfeld - Modeling Team
Sign In or Register to comment.