How to Copy a Part with featurescript

Best Answer
-
There are a few options to do that, but if you want to repeat the sketch inside of a loop you can use something like this:
for (var i = 0; i < count; i += 1) { newSketch(context, id ~ i, { "sketchPlane" : qCreatedBy(makeId("Top"), EntityType.FACE) }); ... }Notice the id ~ i as the Sketch Id.
You can see other FS examples like rib.fsUn saludo,
Eduardo Magdalena C2i Change 2 improve ☑ ¿Por qué no organizamos una reunión online?
Partner de PTC - Onshape Averigua a quién conocemos en común6
Answers
-
There are a few options to do that, but if you want to repeat the sketch inside of a loop you can use something like this:
for (var i = 0; i < count; i += 1) { newSketch(context, id ~ i, { "sketchPlane" : qCreatedBy(makeId("Top"), EntityType.FACE) }); ... }Notice the id ~ i as the Sketch Id.
You can see other FS examples like rib.fsUn saludo,
Eduardo Magdalena C2i Change 2 improve ☑ ¿Por qué no organizamos una reunión online?
Partner de PTC - Onshape Averigua a quién conocemos en común6 -
-
Eduardo is correct -- that will fix the immediate issue, but I would second Morgan's recommendation for opPattern -- it will work faster.
Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc0 -
hi ilya,ilya_baran said:Eduardo is correct -- that will fix the immediate issue, but I would second Morgan's recommendation for opPattern -- it will work faster.
i need to scale a part and keep the original one, (so i need to copy before scaling isnt it?)
for the scaling i was using opTransform, but i can not finish understanding how to,at the same time, be able to copy it, i say that if I put two transforms
transform1*transform2 it does in order, but i can not find how to do the first transform to copy it, is it possible? as i didnt find it in the list of transform types (https://cad.onshape.com/FsDoc/library.html#Transform) but i found that there is makeCopy in transform (https://cad.onshape.com/FsDoc/library.html#module-transformCopy.fs)
i can not get the difference between each other, one is a parameter inside optransform and the other one is a function itself? i dont get it at all....
(i am having a headache with the op..... :'( )
could you please help me to understand the difference between them? and how i could solve my problem? best regards
to be exactly, i want to take a part, scale it, see if a point is contained in the scaled version, insert a second object in that point if it is the case, and then intersect that second object to the original one....0 -
@Otaola_Franco if you use opPattern (which essentially takes the same inputs as opTransform) it will copy for you.
Senior Director, Technical Services, EMEA0 -
thanks neil,NeilCooke said:@Otaola_Franco if you use opPattern (which essentially takes the same inputs as opTransform) it will copy for you.
is there any part to read a little bit about the op operations? i am looking at the https://cad.onshape.com/FsDoc/library.html#opPattern-Context-Id-map
but i dont finish to get how the work exactly, for example the opPattern/transform, or right now i am having issues about calling a created bodie from a opBoolean... i know that i can post it in the forum and someone will help but i feel a little bit guilty about... i am reading the info in the link before and i saw your video (https://www.onshape.com/videos/the-beginners-guide-to-building-custom-cad-features-in-featurescript-010819) but i would love to learn a little bit more... (actually the video was super helpfull...thanks for that!)0 -
Sometimes the docs are not easy to follow because there are no examples.
First, don't call the result of the opBoolean, call the first feature used in the opBoolean, for exampleqCreatedBy(id+"extrude1", EntityType.BODY);
so something like:opPattern(context, id+"pattern", {entities: qCreatedBy(id+"extrude1", EntityType.BODY),transforms: [scaleUniformly(2)], // note this is an arrayinstanceNames: ["1"]}^ I typed this from memory, so hopefully I made no typos.Senior Director, Technical Services, EMEA1 -
perfect! thanks
have a few last questions (with an answer already for some, so maybe
is going to be more of a confirmation of what i am understanding
) when i was doing the opBoolean i created several cylinders that i used a qUnion to put them all together for the Boolean for example:
Q1/2_
var cyls=qUnion([qCreatedBy(id+"cylinder1", EntityType.BODY),qCreatedBy(id+"cylinder2", EntityType.BODY),qCreatedBy(id+"cylinder3", EntityType.BODY),qCreatedBy(id+"cylinder4", EntityType.BODY),qCreatedBy(id+"cylinder5", EntityType.BODY),qCreatedBy(id+"cylinder6", EntityType.BODY),qCreatedBy(id+"cylinder7", EntityType.BODY),qCreatedBy(id+"cylinder8", EntityType.BODY),qCreatedBy(id+"cylinder9", EntityType.BODY),qCreatedBy(id+"cylinder10", EntityType.BODY),qCreatedBy(id+"cylinder11", EntityType.BODY),qCreatedBy(id+"cylinder12", EntityType.BODY)]);
opBoolean(context, id + "cell", { "tools" : cyls, "operationType" : BooleanOperationType.UNION });
after that when i do the opPattern as you said, it worked perfectly:
opPattern(context, id + "pattern", {
"entities" : qCreatedBy(id+"cylinder1", EntityType.BODY),
"transforms" : transforms,
"instanceNames" : instanceNames });
first, i dont get why it patterns everything if in entities is selected only first one. is it because the id of the "cylinder1" is inherit to the body that is created by opBoolean (so basically: Q1) "cylinder1" becomes the howl thing and not only the cylinder made by the first fcylinder?) as after doing the opPattern (Q2) why i cant use qCreatedBy(id+"cell",EntityType.BODY) (from the opBoolean)? )
Q3_
, i do a opDeleteBodies to delate the original body, so this time i use:opDeleteBodies(context, id + "deleteBodies", {
"entities" : qCreatedBy(id+"cylinder1", EntityType.BODY)
});
i re use qCreatedBy(id+"cylinder1", EntityType.BODY) because opPatterns doesnt modify the body, it creates another one so, it has another id,is that so?So now if i want to work with the results bodies created from the opPatterns, i should use
qCreatedBy(id+”pattern”,Entity.BODY) no?
Q4_
I re scaled and copy a body (with your help in another post…),
opPattern(context, id + "scaled_body", {
"entities" : definition.entities,
"transforms" : [scaleNonuniformly(scaleX,scaleY,scaleZ)],
"instanceNames" : ["scaled_body"]
});
So to call the orginal one would be,
definition.entities (it is a query from the UI)
and for the scaled one:
qCreatedBy(id+” scaled_body”,Entity.BODY)
I am correct?
Q5_ how can i understand if a operation creates a new id for the body or keeps the same one? (as simple as if it creates a new bodie?)
Q6_(and last! Sorry for the long post!)
how can i divide a query in equal parts? I am having the issue that i create voxelyse an object and as the voxel goes down in size (creating more and more voxels…) if in the FS i do a opBoolean directly from the pattern (all the objects in one time Boolean) the document gives error (variating and i had needed to go down in the version to solve it… or contact the support (thanks guys ^^), but i realized that if i don’t do the Boolean at all with the FS, the FS doesn’t give any error and it only takes a lot of time, (normal….) and after that i do small Booleans in sections of the parts created…. That way it works, but it tedious post treatment of the FS. I thought about a loop, but I don’t know how to “cut” the query from the pattern in small parts…
thanks and sorry for bothering so much,
0 -
OK, here goes. Before I get into your questions, the qUnion should not be hardcoded. Here are some options:
You can either loop through cylinder creation and add it to a query as you go, or loop the query afterwards:var cyls = qNothing(); // sets variable to be of type query for(var i = 1; i < 13; i += 1) { fCylinder(context, id + ("cylinder" ~ i), { ... } cyls = qUnion([cyls, qCreatedBy(id + ("cylinder" ~ i), EntityType.BODY)]); }Senior Director, Technical Services, EMEA1 -
Another option is to add an extra level to your id. However, id's can only be created contiguously, so no other operation can be carried out on the cylinders until all cylinders have been created. You can try to follow along here: https://cad.onshape.com/FsDoc/library.html#Id
for(var i = 1; i < 13; i +=1) { fCylinder(context, id + "cylinder" + i, { ... } // no other operations that create a new id can be added here } var cyls = qCreatedBy(id + "cylinder", EntityType.BODY); // this will get cylinder plus all its children
Senior Director, Technical Services, EMEA1 -
Q1: An id is a unique identifier for the operation, not the solid body. opBoolean uses the first body in the list as the parent - this keeps body internal id's (not the same as operation id's) consistent so that part names and other references don't change.
Q2: Same as Q1?
Q3: Correct & Correct
Q4: Correct & Correct
Q5: If a body has only been modified (boolean / transform) you query the original body.
Q6: Loop is a bad idea for opBoolean - the script would be very slow. Do the voxels overlap? We talked about this here: https://forum.onshape.com/discussion/comment/56573#Comment_56573Senior Director, Technical Services, EMEA0 -
Q6.yes they overlap, well I am trying to finish the project of that original post.... what i have donne to solve the not precise method at the end of the post is to scale the body only to be sure that it contains another line of voxels, and then intersect the voxels created with the original body(not scaled) (that i am intersecting.... Q7)NeilCooke said:Q1: An id is a unique identifier for the operation, not the solid body. opBoolean uses the first body in the list as the parent - this keeps body internal id's (not the same as operation id's) consistent so that part names and other references don't change.
Q2: Same as Q1?
Q3: Correct & Correct
Q4: Correct & Correct
Q5: If a body has only been modified (boolean / transform) you query the original body.
Q6: Loop is a bad idea for opBoolean - the script would be very slow. Do the voxels overlap? We talked about this here: https://forum.onshape.com/discussion/comment/56573#Comment_56573
in the post you recommend me or at least kept it like that from the other user sugestion,
to useopBoolean(context, id + "boolean", { "tools" : qCreatedBy(id + "pattern", EntityType.BODY), "operationType" : BooleanOperationType.UNION });my issue is that when i was working even if the bodies were intersecting, when they were too many, the FS was not working, without editing anything else, and erasing the opboolean, the FS worked.... so after that i was boolean them manually after the FS in the part studio.
Q7 i found the issue for this one
when i intersect the bodies with opBoolean i get all the bodies that a part of them is inside but it keeps the exterior part of it. for example if i intersect A with B and A is the tool, and part of it is inside B after the boolean op i get A and B not the small part of A inside BopBoolean(context, id + "boolean12", {"tools" : qUnion([qCreatedBy(id+"cylinder1", EntityType.BODY),definition.entities]),"operationType" : BooleanOperationType.INTERSECTION,"keepTools" : true,});0 -
If you add the extra level before the "cylinder", likeNeilCooke said:Another option is to add an extra level to your id. However, id's can only be created contiguously, so no other operation can be carried out on the cylinders until all cylinders have been created. You can try to follow along here: https://cad.onshape.com/FsDoc/library.html#Idfor(var i = 1; i < 13; i +=1) { fCylinder(context, id + "cylinder" + i, { ... } // no other operations that create a new id can be added here } var cyls = qCreatedBy(id + "cylinder", EntityType.BODY); // this will get cylinder plus all its childrenid + i + "cylinder", you then can do other operations on the cylinder, using other ids in the same format: e.g.id + i + "doStuff"You can then query for all the cylinders by queryingqCreatedBy(id + ANY_ID + "cylinder", EntityType.BODY);1





