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.
how to copy bodies in each vector of a query?
otaolafr
Member Posts: 113 EDU
I want to repeat a body in each value of a query I am creating, and then boolean all together, any easy way to do it?
I know there is opPattern but I dont get how to use it. I read the description from here https://cad.onshape.com/FsDoc/library.html#opPattern-Context-Id-map even then I don't get how to use it.
also to create the query I am using points= append(points, pt) and the function is inside a loop with a conditional (if true) stock pt in points, (if false) don't stock it. and when I add the append the FS becomes suuuper slow (not something that is impossible to use) I was asking myself if there is another way to do it.
I know there is opPattern but I dont get how to use it. I read the description from here https://cad.onshape.com/FsDoc/library.html#opPattern-Context-Id-map even then I don't get how to use it.
also to create the query I am using points= append(points, pt) and the function is inside a loop with a conditional (if true) stock pt in points, (if false) don't stock it. and when I add the append the FS becomes suuuper slow (not something that is impossible to use) I was asking myself if there is another way to do it.
for (var ix = -round(boxSize[0] / blockSize[0], 1)-blockSize[0]/millimeter; ix < (round(boxSize[0] / blockSize[0], 1)+blockSize[0]/millimeter); ix += 1) {
const x = 0 *millimeter+ (ix + 0.5) * blockSize[0];
for (var iy = -round(boxSize[1] / blockSize[1],1)-blockSize[1]/millimeter; iy < (round(boxSize[1] / blockSize[1],1)+blockSize[1]/millimeter); iy += 1) {
const y = 0*millimeter + (iy + 0.5) * blockSize[1];
for (var iz = -round(boxSize[2] / blockSize[2],1)-blockSize[2]/millimeter; iz < (round(boxSize[2] / blockSize[2],1)+blockSize[2]/millimeter); iz += 1) {
const z = 0*millimeter + (iz + 0.5) * blockSize[2];
const pt = vector(x, y, z);
if (size(evaluateQuery(context, qContainsPoint(definition.bodies, pt))) > 0)
{points= append(points, pt);
}
}
}
}
Tagged:
0
Comments
See if that is any faster. At the end you could resize the array based on "count".
the idea is to be able to put the X',Y',Z' directions of the cubes not necessarily in the same x,y,z of the original body, what I am doing is:
turning original body for the new XYZ'.
creating a minimum box that contains the turned body
doing 3 loops to make the grid of points, and keep only the ones that are inside of the body ( if (size(evaluateQuery(context, qContainsPoint(definition.bodies, pt))) > 0))
then I stock the points inside a query
copy the "block" in each point of the query
intersect the bodies with the original one
re turning the final body to original XYZ.
thats my goal, from my goal to achive it is another thing ahahaha. but I have at least for the moment with the debug successfully show the box that contains the turned body, and the inside points.
Here is an example feature that does what you want.
IR for AS/NZS 1100
If you add
opOffsetFace(context, id + "offsetIn", { "faces" : qCreatedBy(id, EntityType.FACE), "offset" : -voxelSize * 0.005 })
at the end, it will fix the extra size of the voxelsIR for AS/NZS 1100
first of all, thanks for the GREAT help.
I have some questions about the scripts:
1. if the body is slightly bigger than half of the cell size, the voxelized body would not contain all the original body, how could I do to add an extra line in each direction so the howl original body can be contained inside? to show what I meant in the next fig I colored (in red) the parts that stay out of the voxelized body (original a cylinder) (voxelized in transparent blue and in green the body that is inside the voxelized created body)
2.if I understand correctly instancename (line 45,56) is necessary for opPattern(line 71), (but what is inside it is not important as it is the name of each produced body for the oppattern). wouldnt be more efficient to create it ( and also transforms inline 44 and 55) after the loop and the resize of points? so it would be faster?
3. I don't get how transforms works, I see that inside has transform so I assume that is to each time move the object patterned to the right position, i am correct? so it is an array composed of functions? (each time transform)
4. I saw that inline 23 to be sure that is going to boolean you add a little bit of extra in the sizes I am planning to use another body that is contained inside the cube and modify the FS to be capable of select it and use it in the pattern, should I add some extra in the body to assure this too? (I don't get exactly why as the points were created using the block size... I thought that maybe it was easier for onshape to boolean bodies in union that had intersected volume more than intersecting surfaces, is that the case?)
5.from the comment of mbartlett opOffsetFace(context, id + "offsetIn", { "faces" : qCreatedBy(id, EntityType.FACE), "offset" : -voxelSize * 0.005 }) would eliminate the extra 0.01 of the voxel size that was created for the situation in question 4? is that?
6.when I finish doing the FS I would like to publish as an EDU FS but I couldn't find how to publish something with an EDU status, how can I do this?
also, thanks for all the help guys .
HWM-Water Ltd
calculate the remainder of each size of the boundingBox and the size of the cube (remainder x, remainder y, remainder z)
if the remainder i < size i of the cube (so there is a smaller part than half of the cube size, in the positive and in the negative direction)
then scale the original body in that direction i by the ((cube size+boundingBox size i) /boundingBox size i)
change the bounds with a new boundingBox of the scaled body
use the new scaled body in (evaluateQuery(context, qContainsPoint(bodies, point)) != [])
that way the voxelize would be sligly bigger than the orignal body.
what you think ? is the only way i can thing to extend the list of points by one block in each direction if it is not completely contained.
2. okey, going to give a try, but yeah, i can see that would be marginally but as the howl process is machine consuming I am going to try to optimize it the better i can.
3.excalty what I was understanding, god FS language is powerful.
4. but they don't touch by edges or vertices only, they touch by surfaces, no?
5. okis
6. an educational document I was trying to s
thanks
Imagine a scenario where this is the solution:
A boolean will fail on that because if that thing was one solid body, it would have an edge that bounds 4 faces.
You can imagine a slightly more complex similar scenario for a shared non-manifold vertex.
Making the cubes slightly larger solves this.
For #1, for something that is a little more robust but still not technically correct for all cases, try the following: Imagine the grid of cubes you have already set up. Instead of testing at the center of each cube, test at the center of each cube face. If there is material at the center of the cube face, then the two cubes sharing this face should both be constructed. If you are careful, this algorithm will not need to be for (each cube) { for (each face center) {} } because each face center actually belongs to two cubes. What I would do is something along the lines of the top, right, and back face of each cube, and then add then add both cubes when you get a hit.
If you use this solution, you should also optimize by not adding a transform to the transforms array if it is already in there. If you do that, you'll get lots of extra geometry that will just slow the system down.
Some psuedocode:
thanks for the clarification with educational vr, I thought that in a public accound you could also public educational. i am going to look in the edu plan, thanks.
for your fist comment, ups i didnt though of a geometry like that ahahahaha, but you are right, thanks
for your second message, i am sorry it is super late and a little bit tired (and preeety sure that i am wrong....) but, is it always true? i though of an example like this: (depending on the size of the cell it would or not be true...)
also another question, as i mentioned before, the final idea is to have a contructed cell that i am going to be able to choose for the moment,as a second body in the part studio, for this i modified the code and add an entry for a body
annotation { "Name" : "cell", "Filter" : EntityType.BODY }
In the picture you provided, the block to the left of the yellow dot may or may not be built. It won't be built off the cube to the right, as you have shown. But it might be built from the top depending on where that midpoint is:
like I said though, this method won't be perfect either, it will just be better than using the centers.
If you want it perfect, you could use `evDistance` to find the closest point to the center, and see if that point is inside the cube, but that will be super slow. Maybe some kind of `evDistance` approach combined with spatial division using an oct-tree? https://en.wikipedia.org/wiki/Octree
Depending on how much work you want to do you can go down a major rabbit hole here.
For you second question, you want
not
well, I find myself with an issue, when I use another "seed" instead of the cube, now the document gives me the error (ab0f9fef133a4db30ed79d2a), I know that is because it is too complex as when I resized the same seed but bigger it worked correctly, is there any way around this? I mean by an API or aaany way that I can export the result in a.STEP or other file types where I can have the final part?
thanks for all the help guys, the onshape team is always surprising me.
maybe you would like the link of the document:https://cad.onshape.com/documents/868b98813dc2470facff8624/w/7aaae9fc38becda0507096c6/e/5fc5e3ce45f6741d0263f932