Jump to content
resonanz

sorting array - again

Recommended Posts

I am still struggling to sort arrays in the HDK and hence I have a couple of questions.

For example, if I have added a float attribute to my primitives how can I sort the primitives according to these values? I know how to access and read the attribute into the HDK but have no idea what I should do next.

And the other question is: How do I sort a UT_ValArray of vectors by the length of the vector?

Here is what I have so far:


GA_ROAttributeRef myattrib;
myattrib = gdp->findPrimitiveAttribute("area");
GA_ROHandleF myhandle(myattrib.getAttribute());
for(GA_Iterator it(gdp->getPrimitiveRange()); !it.atEnd(); it.advance()){
cout << myhandle(it.getOffset()) << endl;
}
[/CODE]

Any help would be appreciated!

Share this post


Link to post
Share on other sites

For example, if I have added a float attribute to my primitives how can I sort the primitives according to these values? I know how to access and read the attribute into the HDK but have no idea what I should do next.

Here is what I have so far:


GA_ROAttributeRef myattrib;
myattrib = gdp->findPrimitiveAttribute("area");
GA_ROHandleF myhandle(myattrib.getAttribute());
for(GA_Iterator it(gdp->getPrimitiveRange()); !it.atEnd(); it.advance()){
cout << myhandle(it.getOffset()) << endl;
}
[/CODE]

to sort prims you'll need to reorder the corresponding GA_IndexMap which basically is responsible for the prim-numbering you see in the viewport.

[CODE]
// get index map
GA_IndexMap &indexMap = gdp->getIndexMap(GA_ATTRIB_PRIMITIVE);
// set comparator
GA_IndexMap::AttributeCompare compare(myattrib.getAttribute(), 0);
// instead of using your myattrib it´s possible to access the attribute direcly
// GA_IndexMap::AttributeCompare compare(indexMap, "area", 0);

// sort indexMap
indexMap.sortIndices(compare);


// NOTE:
// you could change
GA_ROAttribRef areaAttribRef = gdp->findPrimitiveAttribute("area");
GA_ROHandleF areaHandle(areaAttribRef.getAttribute());
// to
GA_ROHandleF areaHandle(gdp, GA_ATTRIB_PRIMITIVE, "area");[/CODE]

And the other question is: How do I sort a UT_ValArray of vectors by the length of the vector?

for this you´ll need a comparison function

[CODE]
// comparator
int compare(const UT_Vector3 *vec1, const UT_Vector3 *vec2)
{
if(vec1->length() < vec2->length())
return -1;
if(vec1->length() > vec2->length())
return 1;
return 0;
}


UT_ValArray<UT_Vector3> vecArray;
// sort array
vecArray.sort(compare);[/CODE]

hth.

petz

Edited by petz
  • Like 1

Share this post


Link to post
Share on other sites

GU_Detail provides a variety of methods (essentially all the methods available on the Sort SOP) for sorting points and primitives.

Share this post


Link to post
Share on other sites

@Petz

Thanks, works like a charm!!

@Graham

Thanks Graham! I have allready found sortPrimitiveList() in GU_Detail but I am not sure how to use it correctly.

Thanks again!!

Share this post


Link to post
Share on other sites

You can use the sortPrimitiveList() with the float * signature to essentially sort by attribute value/expression using some supplied list of values.

The following 2 lines mimics 4 primitives (0,1,2,3) with respective attribute values (1,3,2,0). After sorting, they will be sorted in increasing order of the corresponding values.

float order[4] = {1, 3, 2, 0};
gdp-&gt;sortPrimitiveList(order);

Share this post


Link to post
Share on other sites

You can use the sortPrimitiveList() with the float * signature to essentially sort by attribute value/expression using some supplied list of values.

The following 2 lines mimics 4 primitives (0,1,2,3) with respective attribute values (1,3,2,0). After sorting, they will be sorted in increasing order of the corresponding values.

float order[4] = {1, 3, 2, 0};
gdp-&gt;sortPrimitiveList(order);

Thanks Graham, it´s starting to make sense now. But still one question remains. If I want to sort the primitives by an attribute, for example the area, do I have to create the list of floats first? Or, to rephrase the question, what would be the preferred way to have "area" accessible to sortPrimitiveList()?

Share this post


Link to post
Share on other sites

Yeah, you would basically need to create the list of values from the attribute values. I believe there is a function for point attributes that will return all the values in a flattened array, but I don't believe such a function exists for primitive attributes.

Share this post


Link to post
Share on other sites

If it is pointFloatAttribValues, there is also primFloatAttribValues. Not sure if that's the one you guys are talking about.

EDIT: Didn't realize this was HDK :)

Edited by magneto

Share this post


Link to post
Share on other sites

Yeah, you would basically need to create the list of values from the attribute values. I believe there is a function for point attributes that will return all the values in a flattened array, but I don't believe such a function exists for primitive attributes.

to get an array from the primitive attribute values you may want to use GA_AIFTuple. that way you´ll get floats which could be directly used by sortPrimitiveList() in GU_Detail.

but even so, if you´ll have to sort primitives by existing attribute values i would use the method i´ve posted before. it´s cleaner and considerably faster.

hth.

petz

just for completion....


// get attribute
GA_ROAttributeRef areaAttribRef = gdp->findFloatTuple(GA_ATTRIB_PRIMITIVE, "area", 0);
// get GA_AIFTuple
const GA_AIFTuple *areaTuple = areaAttribRef.getAIFTuple();
// allocate array
float *areaArray = new float[gdp->getNumPrimitives()];
// get array of values
areaTuple->getRange(areaAttribRef.getAttribute(), gdp->getPrimitiveRange(), areaArray);
// sort prims
gdp->sortPrimitiveList(areaArray);
// cleaning
delete [] areaArray;
[/CODE]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×