Jump to content

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!

Link to comment
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
Link to comment
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);

Link to comment
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()?

Link to comment
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.

Link to comment
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]

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...