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.

opSplit with evFaceTangentPlane... or anything, really

adamohernadamohern Member, OS Professional Posts: 216 PRO
I'm having trouble getting opSplit to work. My ultimate goal is to create something similar to the "cut with surface" tool in SolidWorks, where I can lop off a chunk of material in one operation using a face, plane, or sketch as input.

My assumption was that if I query a face, I could just feed that face into the opSplit operation. No such luck, as it doesn't seem to work even in easy cases. I thought maybe it needed to be a sheet body first, so I tried doing an opOffsetFaces first and then feeding the result into the opSplit. No dice. So I gave up and decided to use a plane instead, just to keep messing with it. I used evFaceTangentPlane to create a plane from an input face, and then tried to use it in the opSplit... but apparently opSplit only allows queries, not explicit planes. Sigh.

Sorry for the long story, just wanted to provide some context in case someone might be so kind as to explain where my thinking's gone wrong here. I'm trying to learn to fish.


  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 521
    I'd guess you're probably passing a face instead of a body as the tool for opSplitPart. Calling debug on the query will let you know what entity type (or types) you have in the notices flyout. If the surface body you need doesn't exist you can create it with opPlane:
            opPlane(context, id + "plane", {
                    "plane" : myPlane
            opSplitPart(context, id + "splitPart1", {
                    "targets" : definition.targets,
                    "tool" : qCreatedBy(id + "plane", EntityType.BODY)
    opOffsetFaces() didn't help you since it doesn't create any new bodies. It's designed to move a single face on a part (check out the Offset option in the Move face feature).

    One piece of fishing advice... Why not start by copying Onshape's split feature? It's got a pre-made GUI and a functional implementation to boot (Here, the call to qOwnerBody in there is what tipped me off about what you might be missing). For a case like this I imagine it's easier to iterate on working code than to start blind and trying to get something to work.

  • adamohernadamohern Member, OS Professional Posts: 216 PRO
    edited April 2016
    Thanks a ton for all your help today, Kevin!

    If the surface body you need doesn't exist you can create it with opPlane.
    I was trying to avoid that, since I don't ultimately want to keep the plane. It seemed cleaner to use a regular 'plane' than creating an opPlane, since I wouldn't have to delete it afterwards. Oh, well.

    opOffsetFaces() didn't help you since it doesn't create any new bodies.
    Ah, of course. So does Onshape not have a sheet offset tool? If not, I'm assuming it's impossible to create one? That's a pretty huge limitation. Is there any way to duplicate a face such that it becomes a sheet?

    One piece of fishing advice... Why not start by copying Onshape's split feature?

    Because if you remove the face-splitting capabilities of the split feature, all you end up with is:

    annotation { "Feature Type Name" : "Cut", "Filter Selector" : "allparts" }
    export const cut = defineFeature(function(context is Context, id is Id, definition is map)
            annotation { "Name" : "Targets", "Filter" : EntityType.BODY && (BodyType.SOLID || BodyType.SHEET) }
            definition.targets is Query;
            annotation { "Name" : "Tool",
                "Filter" : (EntityType.BODY && BodyType.SHEET) || (GeometryType.PLANE && ConstructionObject.YES),
                "MaxNumberOfPicks" : 1 }
            definition.tool is Query;
            definition.tool = qOwnerBody(definition.tool);
            opSplitPart(context, id, definition);
        }, { keepTools : false, splitType : SplitType.PART });

    Helpful as that is, it's really not all that informative. Basically the feature just lets the user fill in the arguments for the built-in opSplitPart command--I could have figured that out on my own. What I'm trying to do is improve on opSplitPart, so my approach is going to have to be different.

  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,026
    I agree that splitting with a Plane should be possible without creating a construction plane (and deleting it afterwards).  Our focus so far has been primarily on infrastructure and providing capabilities that our bultin features use.  Following the public release, our plan is to go from a "shortest path to builtin feature that doesn't hurt our ability to later generalize" approach to an "if it makes sense to do it, it should be possible unless there's a good reason" approach to the FS library development.  Splitting with a Plane and offsetting a sheet (you can work around that with a opThicken) are examples of this type of thing.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • adamohernadamohern Member, OS Professional Posts: 216 PRO
    Cool, thanks Ilya. The system is amazingly thorough for a beta pre-release.
Sign In or Register to comment.