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.
Using a for loop for multiple operations on multiple parts
Lee_Hesketh
Member, Developers Posts: 148 ✭✭✭
Hello, I have a script that makes a new sketch on a selected face, draw a rectangle, extrude and finally a Boolean subtraction. Currently it only works for one face at a time. How could I use a for loop to allow the operations to be done on all selected faces? This is for a mortise and tenon script I'm writing and when I tried to use a for loop an error was thrown concerning multiple operations with duplicate id names.
Any ideas?
Thanks
Lee Hesketh
Any ideas?
Thanks
Lee Hesketh
There are 10 types of people in the world. Those who know binary, those who don't and those who didn't expect base 3!
Tagged:
1
Best Answers
-
Hi, there's a good explanation in the help files somewhere for this. I'm sure someone will be along with a full explanation soon but the solution is to append i to the feature ID within the loop to make each iteration unique.
Owen S.
Business Systems and Configuration Controller
HWM-Water Ltd5 -
As @owen_sparks mentioned each feature/sketch needs to have a unique Id. An easy way to do this is to add "i" to you feature/sketch Id. Something similar to this...
<br>var sketchId = id + "sketch"; for (var i = 0; i < numberOfThings; i += 1) { sketchId = sketchId + i; var sketch = newSketchOnPlane(context, sketchId, { "sketchPlane" : sketchPlane }); //sketch some stuff here }Notice "i" is incremented with each pass of the for loop so the "i + 1" you mentioned is not needed.5 -
@Lee_Hesketh
Your skRectange is failing because the second argument is not supposed to be an id, its just a string that uniquely identifies this part of the sketch. This is true in general for all "sk" operations. Sketch code should look something like:const sketchId = id + "sketch"; var sketch = newSketchOnPlane(context, sketchId, {...}); skRectangle(sketch, "rectangle1", {...}); skRectangle(sketch, "rectangle2", {...}); skLineSegment(sketch, "lineSegment", {...}); skSolve(sketch);
Hope this helps,
JakeJake Rosenfeld - Modeling Team5
Answers
-
Hi, there's a good explanation in the help files somewhere for this. I'm sure someone will be along with a full explanation soon but the solution is to append i to the feature ID within the loop to make each iteration unique.
Owen S.
Business Systems and Configuration Controller
HWM-Water Ltd5 -
@owen_sparks How would I do this? Would it just be a case of say for an opExtrude be opExtrude(context, id + "extrude" + i)?
if I was using two extrudes, would the second one be opExtrude(context, id + "extrude" + i+1)?There are 10 types of people in the world. Those who know binary, those who don't and those who didn't expect base 3!0 -
Here is the file so you can have a look.
https://cad.onshape.com/documents/57aee7f1e4b083f3982e60a4/w/720337d038a4a9744878f874/e/2059dc0192a94404a962ca5c
There are 10 types of people in the world. Those who know binary, those who don't and those who didn't expect base 3!0 -
As @owen_sparks mentioned each feature/sketch needs to have a unique Id. An easy way to do this is to add "i" to you feature/sketch Id. Something similar to this...
<br>var sketchId = id + "sketch"; for (var i = 0; i < numberOfThings; i += 1) { sketchId = sketchId + i; var sketch = newSketchOnPlane(context, sketchId, { "sketchPlane" : sketchPlane }); //sketch some stuff here }Notice "i" is incremented with each pass of the for loop so the "i + 1" you mentioned is not needed.5 -
@cody_armstrong I tired that but when I was using skRectangle, it threw an error. Could you have a look at the whole script to see if you can see what's happening?
There are 10 types of people in the world. Those who know binary, those who don't and those who didn't expect base 3!0 -
@LeeH This is a different error than the duplicate Id error mentioned in the original post. The error states "Call skRectangle(Sketch,Id(array), map) does not match skRectangle(..." This error means it does not like something you have entered for the definition of your sketch rectangle.
I copied your Doc and was able to get "Mortise and Tenon Test" feature to work, so I cannot recreate the error. I would debug your inputs for the rectangle and make sure they are correct. My guess is one of your variables should be a string, but is instead an array. Or something similar.0 -
@cody_armstrong Did you edit it in any way because I can't get it to work. Also, I have rewritten the script but now the error is EXTRUDE_NO_SELECT_REGION. Could you have a look at feature studio1 and see if you can see what's going on?There are 10 types of people in the world. Those who know binary, those who don't and those who didn't expect base 3!0
-
What if there are nested loops, such as two FOR loops one inside the other with loop counters i and j? How to increment ID in a unique way?
P.S. I found that using hash functions(see e.g. https://math.stackexchange.com/questions/531906/calculate-unique-integer-representing-a-pair-of-integers ), such as Cantor pairing function: id + 0.5*(i+j)*(i+j+1)+j works for low values of i, j, but then it becomes non-monotonic and the error "Parent Id FWDxIioBKfXZcAh_3.6 used at two non-contiguous points in operation history (Cannot have FWDxIioBKfXZcAh_3.10.2 between FWDxIioBKfXZcAh_3.6.1 and FWDxIioBKfXZcAh_3.6.0)" is thrown.0 -
@ivan_skachko
a pair of i, j is unique inside the loop so the id should be something like id + ("sketch" ~ i ~ j). "~" is a string concatenation operator
1 -
@Lee_Hesketh
Your skRectange is failing because the second argument is not supposed to be an id, its just a string that uniquely identifies this part of the sketch. This is true in general for all "sk" operations. Sketch code should look something like:const sketchId = id + "sketch"; var sketch = newSketchOnPlane(context, sketchId, {...}); skRectangle(sketch, "rectangle1", {...}); skRectangle(sketch, "rectangle2", {...}); skLineSegment(sketch, "lineSegment", {...}); skSolve(sketch);
Hope this helps,
JakeJake Rosenfeld - Modeling Team5 -
Didn't realize the original post was from 2016 and there is a new question at hand.
@ivan_skachko @konstantin_shiriazdanov
Note that if there is a large loop with konstantin's solution, you could run into a bad situation where the ids are not unique. For example:
i = 1 j = 12
"sketch112"
i = 11 j = 2
"sketch112"
This can be mitigated with something like:var sketchId = id + ("sketch." ~ i ~ "." ~ j);"sketch.1.12"
"sketch.12.1"
or even:var sketchId = id + unstableIdComponent(i) + unstableComponentId(j) + "sketch"
Note that code like:for (increasing i) { newSketch(context, id + "sketch" + unstableIdComponent(i), {...}); opExtrude(context, id + "extrude" + unstableIdComponent(i), {...});<br> opDraft(context, id + "draft" + unstableIdComponent(i), {...});<br>}
will fail because of id hierarchy.
From the documentation (https://cad.onshape.com/FsDoc/library.html):
Jake Rosenfeld - Modeling Team2 -
thanks for pointing this, totally missed such situationJake_Rosenfeld said:Note that if there is a large loop with konstantin's solution, you could run into a bad situation where the ids are not unique.
1





