Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- 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.
New to FeatureScript
sebastian_sombra
Member Posts: 16 ✭
Hi,
When creating parts for 3d printing sometimes I add a sacrificial layer to avoid using supports. In the image below for instance, I would extrude upwards 0.2mm from the selected edge. The way I normally do it is creating a sketch, projecting the circle to the sketch and extruding it. It could be a circle, a rectangle or any other shape.
I thought that a featurescript would be useful for that, and that it would be a nice exercise to learn about featurescripts. However, after reading a lot of forum entries and watching some tutorials I just can't find my way to do it. In my mind, the idea was to ask the user to select an edge (in this example the selected circle) and extrude it 0.2mm (or any length). In order to do that I used a query parameter. However, If I use a query parameter with EDGE as Entity type, The result from the extrusion is a surface:
but If I use FACE as Entity Type, the Extrusion is the ring and not the inner circle:
I also tried to do it in a similar way I use to do it (create a sketch in the face of the part, project the shape and extrude it), but I was not able to find a way to "project" the circle to the sketch in a featurescript. I realize that my knowledge is very limited but I do like to learn, so if someone can point me to an example or where to look at, it would be great.
When creating parts for 3d printing sometimes I add a sacrificial layer to avoid using supports. In the image below for instance, I would extrude upwards 0.2mm from the selected edge. The way I normally do it is creating a sketch, projecting the circle to the sketch and extruding it. It could be a circle, a rectangle or any other shape.
I thought that a featurescript would be useful for that, and that it would be a nice exercise to learn about featurescripts. However, after reading a lot of forum entries and watching some tutorials I just can't find my way to do it. In my mind, the idea was to ask the user to select an edge (in this example the selected circle) and extrude it 0.2mm (or any length). In order to do that I used a query parameter. However, If I use a query parameter with EDGE as Entity type, The result from the extrusion is a surface:
annotation { "Name" : "Figura", "Filter" : EntityType.EDGE, "MaxNumberOfPicks" : 1 }
definition.myFig is Query;
opExtrude(context, id + "extrude1", {
"entities" : definition.myFig,
"direction" : face.normal,
"endBound" : BoundingType.BLIND,
"endDepth" : definition.myCapa
});
but If I use FACE as Entity Type, the Extrusion is the ring and not the inner circle:
annotation { "Name" : "Figura", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 1 }
definition.myFig is Query;
I also tried to do it in a similar way I use to do it (create a sketch in the face of the part, project the shape and extrude it), but I was not able to find a way to "project" the circle to the sketch in a featurescript. I realize that my knowledge is very limited but I do like to learn, so if someone can point me to an example or where to look at, it would be great.
0
Comments
However, there is a potential work around using surfaces; if we first create a group of surfaces which enclose the desired region, we can then use enclose to get the actual desired body. It's fairly complex, but I thought this was a good opportunity to make an example feature for the community, which is something I've been wanting to do more and more lately. So, here's an example of a feature that does what you're trying to do:
https://cad.onshape.com/documents/4c21d0c3c89c0a81aadfdac6/w/a7ccf556a74ce09cd04151e0/e/9e183a644bcc124310d7dfe3
I tried my best to explain the rationale behind everything in the code. Hopefully it makes sense, and serves as a springboard for improving your own understanding of FeatureScript. I would encourage you to try adapting it to fit your own needs as you see fit. Good luck!
https://cad.onshape.com/documents/4c21d0c3c89c0a81aadfdac6/w/a7ccf556a74ce09cd04151e0/e/9e183a644bcc124310d7dfe3
One last question:
The code does work as expected, BUT the extrude operation creates a second part. Ideally, I would like the extrude operation to ADD to the existing part instead to create a new part (assuming that the 2 parts intersect, of course). I mean, I can always go and add the parts together with the boolean feature, but why not incorporating that to the script. So I got into the forums and found this little example using the opBoolean:
which did the job. Is that the best solution?
To go one step further, lots of features, such as the Onshape extrude feature, offer a merge scope and a merge with all option when performing opBoolean operations. This is a good way to prevent, for example, a single feature accidentally joining a couple different parts together into a single part, and to give the user greater control over the feature's performance. You can also use editing logic to automatically select the merge scope when a user first makes their edge selections. Features can get quite advanced, depending on the level of adaptability and utility you want to get out of them - that's what makes writing FeatureScripts so interesting and rewarding. Fortunately, a lot of this stuff is also optional. After all, custom features only have to be as functional as their users desire - the way you choose to do it is ultimately up to you.
Thanks, I will try with this one.
The only thing I changed was the name of the opExtrude result to extrudePart, following the code.
I'm glad to hear you're working on this feature! A Bridge Layers feature like this been on my backlog to write myself. I figure I'll go ahead and share some ideas around the approach since I've already been considering it a bit. Feel free to use what you like and ignore the rest:
- Automatically find all holes and fill them - Specify a body and a printer Z direction in the UI, then find every parallel planar face, and search it for internal geometry to fill. I'd make this option the default since I probably don't want to leave any holes open, but there could be an enum to pick each face or edge instead.
- Face to exclude - if it's going to automatically find the faces, you could add a query field for faces to exclude instead of which ones to include.
- Base Plane- if the thing you pick for the Z direction is a plane, you could check a box to say that it's on the print bed, so it will ignore all co-planar openings.
I'd be glad to make an icon for you too if you're planning on making the feature public and aren't feeling up to doing it yourself.Great ideas, in my particular case, I would prefer to select the holes I want to fill. Unfortunately these improvements are way beyond my capabilities . I started using OnShape to be able to design things for 3D printing RC parts. While my design skills are very limited (I am an economist), my programming skills are even worst , as you can see by the questions I ask here in the forums. Having said that, I really like to learn new things and I am sure that I will keep trying Featurescripts as new ideas come.
Regarding this particular need, the script works so far and I will be more than happy to share it (I don´t know how by the way ), although most of the code was actually made by others. It is designed to fill one hole at a time, the user selects the hole and a layer is created and added to the main body (0.2mm is the depth default, but it could be changed by the user). I am sure that there are much more things to improve in tjhe code and I hope to have the skills and the time to continue doing it as I learn more.
If you care to make it publicly available, click the blue "Share" button at the top right, and go to the "Public" tab like this, then post a link here.
For instance in this example:
However, the way it is designed now makes it difficult as the user has to select all edges of a hole with one query parameter, putting all edges in the same query, making difficult to build paths for more than one hole. So I thought that the solution would be to select faces instead of edges, then looping the query to take one face at a time and getting the edges for that particular face. However, I didn't find a way to take only the inner edges of a face. I read a lot of forum entries without finding a solution.
Currently, my workaround is to do a query for all the edges in a face and then use qSmallest to filter the small ones. This workaround only works when all edges of a hole are the same length (i.e. a circle, a square, etc...), which is OKish as I mostly use it for circular holes when designing parts (usually for recessed screws), but I would like it to be more universal.
Could someone suggest me a solution to get the inner edges of a face? actually the outer edges will work as well.
Granted, this doesn't filter for only the internal hole, so the whole thing will be extruded, but I can't think of a scenario where I care since the bridge layers are so small. There might be a way to query just the hole if that turns out to be a problem. Here's a link to the start of some code. I used forEachEntity which can process more than one face selection. Since the query parameter is filtered for planar faces on geometry (not construction planes) you can just box select them and it won't pick the cylindrical hole faces inside.
Thanks for this example, I will change my script with your approach. Just a quick note, while I can use a box select with most faces, there are some instances where the box select picks edges and the script then throws an error. This one works:
But this one doesn't, and both holes are on the same part:
I, however, can select that irregular part by clicking directly on the face.
I feel ambivalent about posting this here since this feature is your project-based-learning project, and I don't want to ruin it by posting a solution, but, on the other hand, I've also been wanting to make a Bridge Layer feature for a year or two, and you might find it really useful for learning and actual modeling.
Here's the most distilled logic I could get to:
- If you're using this feature, that means you don't plan to print with support, which means there's a face you plan to print directly on the build platform.
- The face on the platform can (1) identify the body you're printing, and (2) define the Z direction of the print.
- Once I have a body to work on and a Z direction I can find faces whose normals point in the -Z direction, and select only those.
- From there I do what I've shown above, which is create an "empty" sketch on those faces which will contain the face itself (sketch regions are "faces"), but also faces for the holes.
- Next, I count the sketch faces. If it's >2 I know there's no hole and I skip it.
- Last, I extrude it, and boolean it to the body.
The great thing about this logic is that it's just one click.One case this logic doesn't handle right is something like this, where the hole isn't totally enclosed inside the sketch face. I don't think I've ever had this case in my life, so I think I'm okay with it. Let me know if you run into this one.
I hope this is helpful!
I have a question, which is the correct way to add a Custom Feature created by another user to our collection? should I search in the add custom features and add it from there (if I find it...)? make a copy of the document?
Thanks again for taking the time to write and share this code.