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
-
after you got the query of cylindrical faces by
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
0 -
Hello Konstantin,
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
0 -
something like this - define an empty list and append it with newly calculated values in the loop
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});
}
1 -
Got it!
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
0 -
yep, featurescript doesn't pamper us by too big amount of syntax sugar
so if you going to perform some standart operation to data structure you should likely search a function for this in its standart library
0 -
There are qLargest and qSmallest queries that you can use for this. To get the second largest face, you can do something like:
var largestQuery = qLargest(faces);
var secondLargest = qLargest(qSubtraction(faces, largestQuery));Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc1


