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.

Part Draft

fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
edited April 2016 in FeatureScript
So, my first stab at FS is going to be a "Part Draft" feature. I just want to query for a neutral plane, and a body - and I want the feature to split the body with the plane, then draft both sides.

I figured I'd start with the draft, then incorporate the split. I could get the draft working when I queried for the faces, but I'm having trouble getting FS to automatically find the faces. Here's the code



If I just query for draftFaces, I can get the draft to work, so I think there's something wrong with my intersect/filter?

Thanks for the help!

Comments

  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    BTW, this is what it looks like today, using standard features:



    In order to get the pull direction correct on both sides, the body needs to be split, and the second draft needs the direction flipped, then a union to put it back together. I'm going to do it all in one feature!
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    With the code above, you should be getting an error on the qIntersectsPlane line -- the second argument is expected to be a Plane, while definition.neutralPlane is a Query.  To get a Plane from a Query for a planar face, you can use evPlane:

    var intersect = qIntersectsPlane(definition.draftBody, evPlane(context, { "face" : definition.neutralPlane }));

    See this paragraph in the docs for a slightly longer explanation.

    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    One more issue I just noticed

    qIntersectsPlane filters out entities from whatever is passed in as the first argument.  The query I wrote asks "which of the bodies returned by draftBody intersect the neutral plane?"  whereas what you want is "which of the faces owned by draftBody intersect the neutral plane".  To do that, use 
    qOwnedByBody(definition.draftBody, EntityType.FACE) instead of definition.draftBody.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    Thanks, let me digest this a bit., For the record, the original code had zero errors.
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    I believe the error in the original code would not have been detected in the Feature Studio, but rather as soon as you tried to use your feature in a Part Studio.  It would have been reported as a warning.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    HAHA YES!!! I got it!!!!! (No I didn't spend all day on it, I promise)

    Here's the code, I just used the qSplitBy to get the faces for the draft, and then I used a qUnion to get them both for the boolean. Is this a good/clean/smart way to do it?



  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    Yes -- that looks good -- basically, how I'd do it.  You could probably pass in definition.draftBody for the "tools" parameter (instead of the qUnion of qSplitBy's) and it'll do the right thing.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    Got it. I didn't even try that, because I guess I assumed that draftBody wouldn't work because new bodies were created after the split feature, and therefore the draftBody was then outdated... Is that not how it works?

  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    Also, quick question: I copied "targets" : qUnion([]), from the "real" draft feature. Is this the preferred approach for an empty value? Could I just omit that line of code to keep things neat and tidy?
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    When entities split and merge, we try to preserve their identities.  So a qCreatedBy query that resolves to a body before a split should resolve to the bodies that resulted from splitting the original body.  If the query had been evaluated (converted to "transient" queries) then they would be outdated.

    You can omit the "targets" : qUnion([]) line -- it's not required in this case as per the opBoolean documentation.

    One more suggestion: for putting code into the forum, you can use the "code" option in the paragraph menu instead of pasting an image -- that way people can copy/paste your code e.g. to try it out or to reuse pieces.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    Awesome, thanks! Here's the final code, with separate angles for top/bottom and the "reapply fillets" option available:

    annotation { "Feature Type Name" : "Part Draft" }
    export const partdraft = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "Neutral Plane", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 1 }
            definition.neutralPlane is Query;
    
            annotation { "Name" : "Top Draft Angle" }
            isAngle(definition.draftAngleTop, ANGLE_360_BOUNDS);
    
            annotation { "Name" : "Bottom Draft Angle" }
            isAngle(definition.draftAngleBot, ANGLE_360_BOUNDS);
    
            annotation { "Name" : "Part to Draft", "Filter" : EntityType.BODY && BodyType.SOLID }
            definition.draftBody is Query;
    
            annotation { "Name" : "Reapply Fillet" }
            definition.reFillet is boolean;
        }
        {
            //Split the part through the neutral plane
            splitPart(context, id + "splitPart1", {
                        "targets" : definition.draftBody,
                        "tool" : definition.neutralPlane
                    });
            //Select the faces on the front side of the split to draft
            var draftFacesFr;
            draftFacesFr = qSplitBy(id + "splitPart1", EntityType.FACE, false);
    
            //Draft the front body
            draft(context, id + "draft1", {
                        "neutralPlane" : definition.neutralPlane,
                        "draftFaces" : draftFacesFr,
                        "angle" : definition.draftAngleTop,
                        "pullDirection" : false,
                        "reFillet" : definition.reFillet
                    });
            //Select the faces on the back side of the split to draft
            var draftFacesBa;
            draftFacesBa = qSplitBy(id + "splitPart1", EntityType.FACE, true);
    
            //Draft the back body
            draft(context, id + "draft2", {
                        "neutralPlane" : definition.neutralPlane,
                        "draftFaces" : draftFacesBa,
                        "angle" : definition.draftAngleBot,
                        "pullDirection" : true,
                        "reFillet" : definition.reFillet
                    });
            //Union the bodies back together
            booleanBodies(context, id + "boolean1", {
                        "tools" : definition.draftBody,
                        "operationType" : BooleanOperationType.UNION
                    });
        }, { /* default parameters */ });


    Enjoy!
  • fastwayjimfastwayjim Member, OS Professional, Mentor Posts: 220 PRO
    This is the resulting geometry. Each part was drafted with a single feature!


  • traveler_hauptmantraveler_hauptman Member, OS Professional, Mentor, Developers Posts: 419 PRO
    nice!
Sign In or Register to comment.