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 I evaluate a query and store one of the resulting entities?
tim268
Member, Developers Posts: 3 PRO
Hello,
I am hoping you can help me.
I would like to find the 2 largest Cylindrical surfaces on a part by surface area.
I can do this, but I think there must be a better method? I am used to object oriented programming in java where I could store this sort of thing using an object.
I havn't put the full code (as it long and may confuse things) but the basic method I am using at the moment:
// Query the all cylindrical faces
var cyls = qGeometry(qOwnedByBody(part, EntityType.FACE), GeometryType.CYLINDER);
var counter = 0;
var cylOneIndex = 0;
var cylTwoIndex = 0;
// Loop through the cylindrical faces
for (var cyl in evaluateQuery(context, cyls))
{
var cylArea = evArea(context, {
"entities" : cyl
});
// If the surface is largest by area - store it's array position/index
cylOneIndex = counter;
// If the surface is second largest by area - store it's array position/index
cylTwoIndex = counter;
counter += 1;
}
Then, if I want to use either of the 2 largest surfaces later on, I use Query Nth element (because I now know the position/index):
qNthElement(cyls, cylOneIndex);
or
qNthElement(cyls, cylTwoIndex);
Is there a better way of doing this? Is it possible to evaluate a query and store one of the resulting entities? For example:
// Query the all cylindrical faces
var cyls = qGeometry(qOwnedByBody(part, EntityType.FACE), GeometryType.CYLINDER);
// Initialise the Cylinders as undefined??
var cylOne is Cylinder = undefined;
var cylTwo is Cylinder = undefined;
// Loop through the cylindrical faces
for (var cyl in evaluateQuery(context, cyls))
{
var cylArea = evArea(context, {
"entities" : cyl
});
// If the surface is largest by area - store the Cylinder
cylOne = cyl;
// If the surface is second largest by area - store the Cylinder
cylTwo = cyl;
}
Then, if I want to use either of the 2 largest surfaces later on, I just used the cylOne or cylTwo variables? For example:
cylOne.radius;
or
cylTwo.radius;
My concerns with my current method are:
Any help would be appreciated! Thank you
Tim
I am hoping you can help me.
I would like to find the 2 largest Cylindrical surfaces on a part by surface area.
I can do this, but I think there must be a better method? I am used to object oriented programming in java where I could store this sort of thing using an object.
I havn't put the full code (as it long and may confuse things) but the basic method I am using at the moment:
// Query the all cylindrical faces
var cyls = qGeometry(qOwnedByBody(part, EntityType.FACE), GeometryType.CYLINDER);
var counter = 0;
var cylOneIndex = 0;
var cylTwoIndex = 0;
// Loop through the cylindrical faces
for (var cyl in evaluateQuery(context, cyls))
{
var cylArea = evArea(context, {
"entities" : cyl
});
// If the surface is largest by area - store it's array position/index
cylOneIndex = counter;
// If the surface is second largest by area - store it's array position/index
cylTwoIndex = counter;
counter += 1;
}
Then, if I want to use either of the 2 largest surfaces later on, I use Query Nth element (because I now know the position/index):
qNthElement(cyls, cylOneIndex);
or
qNthElement(cyls, cylTwoIndex);
Is there a better way of doing this? Is it possible to evaluate a query and store one of the resulting entities? For example:
// Query the all cylindrical faces
var cyls = qGeometry(qOwnedByBody(part, EntityType.FACE), GeometryType.CYLINDER);
// Initialise the Cylinders as undefined??
var cylOne is Cylinder = undefined;
var cylTwo is Cylinder = undefined;
// Loop through the cylindrical faces
for (var cyl in evaluateQuery(context, cyls))
{
var cylArea = evArea(context, {
"entities" : cyl
});
// If the surface is largest by area - store the Cylinder
cylOne = cyl;
// If the surface is second largest by area - store the Cylinder
cylTwo = cyl;
}
Then, if I want to use either of the 2 largest surfaces later on, I just used the cylOne or cylTwo variables? For example:
cylOne.radius;
or
cylTwo.radius;
My concerns with my current method are:
- I am evaluating the query twice. I assume this is poor on performance?
- What if the index/position of the entities changes in the array?
- There must be a better way of doing this?
Any help would be appreciated! Thank you
Tim
0
Comments
var cyls = qGeometry(qOwnedByBody(part, EntityType.FACE), GeometryType.CYLINDER);
i would reccomend to make a list of map structures for each face like {"query": cylFaceQuery,"area":cylFaceArea}
and sort that list with sort() function. the compare function should be: function(cyl1, cyl2) {return cyl2.area-cyl1.area}
the two first elements of resulting list will contain the query and the area of two largest by area cylinders
Thank you for your quick response.
Would you be able to explain how I make a list of map structures?
Do I define an empty var? Loop through and add the maps to the var?
// Query the all cylindrical faces
var cyls = qGeometry(qOwnedByBody(part, EntityType.FACE), GeometryType.CYLINDER);
//Define Empty var?
var cylList;
// Loop through the cylindrical faces
for (var cyl in evaluateQuery(context, cyls))
{
var cylArea = evArea(context, {
"entities" : cyl
});
// Add a map to the array??
cylList + {"query": cyl,"area":cylArea};
}
sort(cylList ,function(cyl1, cyl2) {return cyl2.area-cyl1.area;});
I will try and work this out. But again any help would be appreciated. Thank you!
Tim
var cylList=[];
// Loop through the cylindrical faces
for (var cyl in evaluateQuery(context, cyls))
{
var cylArea = evArea(context, { "entities" : cyl });
cylList = append(cylList, {"query": cyl,"area":cylArea});
}
Thank you so much. I couldn't work out how to init an empty array and then append to it!
I've been trying:
var cylList = null;
var cylList = undefined;
var cylList[5];
etc. etc.
And:
cylList[counter] = {"query": cyl,"area":cylArea};
cylList += {"query": cyl,"area":cylArea};
cylList.set(counter) = {"query": cyl,"area":cylArea};
etc. etc.
Seems stupid when you know how!
Thank you very much.
Tim
var largestQuery = qLargest(faces);
var secondLargest = qLargest(qSubtraction(faces, largestQuery));