HDK: a few questions

   2631   7   5
User Avatar
Member
4 posts
Joined: March 2017
Offline
Hi guys,

my first post ever on the Houdini forum, exciting to be here : )

The past couple of weeks I have been diving into the HDK and porting some of my (older) plugins to Houdini, you know, as a kind of “warm up”.
Making very good progress and feeling quite comfy with the HDK I must say.
I do have a couple of little questions, perhaps somebody knows the answer or can point me to an example.

1. How can one determine whether Houdini is running in interactive mode (i.e. with the UI) or in batch mode?

2. When editing the parameter interface within Houdini's UI one has several options on how ‘Folders“ are to be displayed: ”Collapsible“, ”Simple“, Tabs”, etc. Is there a way in the HDK to set the folder type? By default it is set to “Tabs”, but I would like to set it to “Simple” instead.

3. Is there an example for callback functions that are invoked when a parameter changes its value? What I would like to achieve is to have parameters be enabled/disabled depending on another parameter’s value.

4. Setting per point (“shared vertex”) attribute data works fine ( using GU_Detail::addFloatTuple(GA_ATTRIB_POINT, …) ), but when trying to set per vertex (“unique vertex”) data things don't seem to work, I even get crashes. I found several examples for “per point” data, but couldn't find anything for “per vertex”. Is there a HDK sample that sets “per unique vertex” data somewhere?

Thanks!

Cheers,
Eric
User Avatar
Member
1743 posts
Joined: March 2012
Offline
I can only easily answer #4, so hopefully someone else can answer the rest. (#2 will be easier once we have the new HDK SOP workflow working, but I don't know how to do it with PRM_Template, apart from guessing and checking various types in PRM_Type.h for the first argument to the constructor of PRM_Template.)

However, to answer #4, I need to ask: How are you iterating over the vertices? How are you writing to them?

For example, one could do:

GA_RWHandleV3 vector_attrib(detail.addFloatTuple(GA_ATTRIB_VERTEX, "attribname", 3));
if (!vector_attrib.isValid()) {
    return;
}
for (GA_Iterator primit(detail.getPrimitiveRange()); !primit.atEnd(); ++primit) {
    // getPrimitiveVertexList is new in 16.0; most people probably use getPrimitive,
    // then call getVertexCount and getVertexOffset on it.
    const GA_OffsetListRef vertices = detail.getPrimitiveVertexList(*primit);
    for (GA_Size i = 0, n = vertices.size(); i < n; ++i) {
        UT_Vector3 some_value(0,1,0);
        vector_attrib.set(vertices(i), some_value);
    }
}
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
402 posts
Joined: June 2014
Offline
Hi Eric,

The code in the docs is fairly clear here [www.sidefx.com] if you haven't managed to find it.

It's all wrapped up in the override of the updateParmsFlags() method, where you evaluate whatever parm you want to switch the others, perform your truth test against that value and then call enableParm(“target_parm”, result_of_truth_test).
Henry Dean
User Avatar
Member
4 posts
Joined: March 2017
Offline
Hello ndickson,

Thanks for the quick reply and the code snippet!
Here is how I set the "per shared vertex' data (in this case some normals):

// GU_Detail *gdp = ... ;

GA_RWHandleV3 rwh(gdp->addFloatTuple(GA_ATTRIB_POINT, "N", 3));
rwh->setTypeInfo(GA_TYPE_NORMAL);
for (LONG i = 0; i<numPoints; i++)
  rwh.set(i, some3DVector);

A while back, when attempting to set unique vertex data, I tried pretty much the same (as my above code), however I didn't use getPrimitiveVertexList which explains the problems I was seeing.
I will give it a try using your approach and will post here how it went!

Cheers,
Eric
User Avatar
Member
1743 posts
Joined: March 2012
Offline
mootzoid
for (LONG i = 0; i<numPoints; i++)
    rwh.set(i, some3DVector);

Alas, that isn't correct if there are holes in the point index map. It's okay if you've created the points with gdp->appendPointBlock(numPoints) and the detail was freshly cleared, (though in that case, I'd still use GA_Offset, instead of LONG, and probably start from the offset returned by appendPointBlock), but otherwise, it'd probably be best to do:

GA_Offset start; GA_Offset end;
for (GA_Iterator ptit(detail.getPointRange()); ptit.blockAdvance(start, end); ) {
    for (GA_Offset ptoff = start; ptoff < end; ++ptoff) {
        rwh.set(ptoff, some3DVector);
    }
}

It's probably also worth checking if the handle is valid before using it, just in case, since it's crash if you try to use it and it's not valid.
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
1390 posts
Joined: July 2005
Offline
mootzoid
1. How can one determine whether Houdini is running in interactive mode (i.e. with the UI) or in batch mode?

#include<HOM/HOM_Module.h>
...
HOM_Module &hou = HOM();
if (hou.isUIAvailable()) ...
User Avatar
Member
4 posts
Joined: March 2017
Offline
@ndickson : with the help of your code snippets and explanations I got everything working just fine and I am now also checking the validity of the handles before setting any data. Thanks so much for the help!

@symek: marvelous, thank you!
User Avatar
Member
4 posts
Joined: March 2017
Offline
friedasparagus
The code in the docs is fairly clear here if you haven't managed to find it.

Hello Henry,

ha, that is exactly what I was looking for! Beats me how I missed that when going through the HDK doc
I just gave it a quick try and it works like a charm, thank you!

Cheers,
Eric
  • Quick Links