For documentation on working with PDG through HAPI, see PDG.
PDG Cooking With Events
Below is a code snippet that queries the TOP nodes in a Houdini digital asset, executes a non-blocking PDG cook of a particular TOP node, receives the emitted PDG events in real-time, and acquires the work item results.
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <cassert>
#define ENSURE_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastError() << std::endl; \
exit( 1 ); \
}
#define ENSURE_COOK_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastCookError() << std::endl; \
exit( 1 ); \
}
static std::string getLastError();
static std::string getLastCookError();
int
main(int argc, char **argv)
{
const char * hda_file = argc == 2 ? argv[1] : "examples/top_sphere_mountain.hda";
&cook_options,
true,
-1,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr));
int asset_count;
std::string asset_name = getString(assetsh);
ENSURE_SUCCESS(
HAPI_CreateNode(&session, -1, asset_name.c_str(),
nullptr,
true, &asset_node_id));
ENSURE_SUCCESS(
HAPI_CookNode(&session, asset_node_id, &cook_options));
int cook_status;
do
{
ENSURE_SUCCESS(cook_result);
ENSURE_COOK_SUCCESS(cook_status);
int network_count = 0;
assert(network_count == 1);
std::vector<HAPI_NodeId> network_ids(network_count);
&session, asset_node_id, network_ids.data(), network_count));
std::string name = getString(node_info.
nameSH);
assert(name == "topnet1");
int child_count = 0;
true, &child_count));
assert(child_count == 2);
std::vector<HAPI_NodeId> child_node_ids(child_count);
&session, top_network_id, child_node_ids.data(), child_count));
std::string geoimport_name = "geometryimport1";
{
std::string child_name = getString(child_node_info.
nameSH);
std::cout << "TOP node name: " << child_name << std::endl;
if (child_name.compare(geoimport_name) == 0)
{
geoimport_id = child_id;
}
}
assert(geoimport_id != -1);
int num_contexts = 0;
std::vector<HAPI_PDG_EventInfo> pdg_events;
bool finished = false;
do
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::vector<HAPI_StringHandle> context_names(num_contexts);
std::vector<int> context_ids(num_contexts);
context_names.data(), context_ids.data(), 0, num_contexts));
for (int c = 0; c < num_contexts; c++)
{
int cook_context = context_ids[c];
std::vector<HAPI_PDG_EventInfo> event_infos(32);
int drained = 0, leftOver = 0;
event_infos.data(), 32, &drained,
&leftOver));
for (int i = 0; i < drained; i++)
{
switch (event_infos[i].eventType)
{
{
break;
}
{
break;
}
{
break;
}
{
finished = true;
break;
}
{
{
ENSURE_SUCCESS(
HAPI_GetWorkitemInfo(&session, cook_context, event_infos[i].workitemId, &workitem_info));
if (workitem_info.numResults > 0)
{
event_infos[i].workitemId, result_infos, workitem_info.numResults));
std::cout << "Result: Tag=" << getString(result_infos[0].resultTagSH) << "; Path="
<< getString(result_infos[0].resultSH) << std::endl;
delete[] result_infos;
}
}
break;
}
default:
break;
}
}
}
} while (!finished);
return 0;
}
static std::string
getLastError()
{
int bufferLength;
&bufferLength);
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
static std::string
getLastCookError()
{
int bufferLength;
&bufferLength);
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
static std::string
{
if (stringHandle == 0)
{
return "";
}
int bufferLength;
stringHandle,
&bufferLength));
if (bufferLength > 0)
{
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
else
{
return "";
}
}
PDG Cooking With Results
Below is a code snippet that queries the TOP nodes in a Houdini digital asset, executes a blocking PDG cook of a particular TOP node, then acquires the work item results.
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#define ENSURE_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastError() << std::endl; \
exit( 1 ); \
}
#define ENSURE_COOK_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastCookError() << std::endl; \
exit( 1 ); \
}
static std::string getLastError();
static std::string getLastCookError();
int
main(int argc, char **argv)
{
const char * hda_file = argc == 2 ? argv[1] : "examples/top_sphere_mountain.hda";
&cook_options,
true,
-1,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr));
int asset_count;
std::string asset_name = getString(assetsh);
ENSURE_SUCCESS(
HAPI_CreateNode(&session, -1, asset_name.c_str(),
nullptr,
true, &asset_node_id));
ENSURE_SUCCESS(
HAPI_CookNode(&session, asset_node_id, &cook_options));
int cook_status;
do
{
ENSURE_SUCCESS(cook_result);
ENSURE_COOK_SUCCESS(cook_status);
int network_count = 0;
assert(network_count == 1);
std::vector<HAPI_NodeId> network_ids(network_count);
&session, asset_node_id, network_ids.data(), network_count));
std::string name = getString(node_info.
nameSH);
assert(name == "topnet1");
int child_count = 0;
true, &child_count));
assert(child_count == 2);
std::vector<HAPI_NodeId> child_node_ids(child_count);
&session, top_network_id, child_node_ids.data(), child_count));
std::string geoimport_name = "geometryimport1";
{
std::string child_name = getString(child_node_info.
nameSH);
std::cout << "TOP node name: " << child_name << std::endl;
if (child_name.compare(geoimport_name) == 0)
{
geoimport_id = child_id;
}
}
assert(geoimport_id != -1);
int num_items = 0;
assert(num_items == 5);
for (int i = 0; i < num_items; i++)
{
std::cout << "Result: Tag=" << getString(result_infos[0].resultTagSH) << "; Path="
<< getString(result_infos[0].resultSH) << std::endl;
delete[] result_infos;
}
delete[] workitem_ids;
return 0;
}
static std::string
getLastError()
{
int bufferLength;
&bufferLength);
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
static std::string
getLastCookError()
{
int bufferLength;
&bufferLength);
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
static std::string
{
if (stringHandle == 0)
{
return "";
}
int bufferLength;
stringHandle,
&bufferLength));
if (bufferLength > 0)
{
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
else
{
return "";
}
}
Creating TOP Graph
Below is a code snippet that dynamically creates a TOP graph in a Houdini Engine session, creates work items, then sets and gets data from work items.
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#define ENSURE_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastError() << std::endl; \
exit( 1 ); \
}
#define ENSURE_COOK_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastCookError() << std::endl; \
exit( 1 ); \
}
static std::string getLastError();
static std::string getLastCookError();
int
main(int argc, char **argv)
{
&cook_options,
true,
-1,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr));
ENSURE_SUCCESS(
HAPI_CreateNode(&session, -1,
"Object/topnet",
nullptr,
true, &topnet_id));
ENSURE_SUCCESS(
HAPI_CookNode(&session, topnet_id, &cook_options));
int cook_status;
do
{
ENSURE_SUCCESS(cook_result);
ENSURE_COOK_SUCCESS(cook_status);
ENSURE_SUCCESS(
HAPI_CreateNode(&session, topnet_id,
"genericgenerator",
nullptr,
false, &generator_id));
ENSURE_SUCCESS(
HAPI_CreateNode(&session, topnet_id,
"textoutput",
nullptr,
false, &textoutput_id));
ENSURE_SUCCESS(
HAPI_CookNode(&session, topnet_id, &cook_options));
do
{
ENSURE_SUCCESS(cook_result);
ENSURE_COOK_SUCCESS(cook_status);
ENSURE_SUCCESS(
HAPI_CookPDG(&session, textoutput_id, 0, 1));
int num_items = 0;
assert(num_items == 1);
ENSURE_SUCCESS(
HAPI_CookPDG(&session, textoutput_id, 0, 1));
assert(num_items == 3);
ENSURE_SUCCESS(
HAPI_CreateWorkitem(&session, generator_id, &work_item_id,
"testwork1", num_items));
int val = 99;
float fvals[2] = { 2.f, 3.f };
const char *test_string = "This is a test string!";
assert(num_items == 4);
int datalen = 0;
val = 0;
fvals[0] = fvals[1] = 0;
assert(datalen == 1);
assert(val == 99);
assert(fvals[0] == 2.f && fvals[1] == 3.f);
assert(datalen == 1);
assert(datalen == strlen(test_string) + 1);
std::vector<char> stringData(datalen + 1);
ENSURE_SUCCESS(
HAPI_GetString(&session, str_handle, stringData.data(), datalen));
assert(strcmp(stringData.data(), test_string) == 0);
return 0;
}
static std::string
getLastError()
{
int bufferLength;
&bufferLength);
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
static std::string
getLastCookError()
{
int bufferLength;
&bufferLength);
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
static std::string
{
if (stringHandle == 0)
{
return "";
}
int bufferLength;
stringHandle,
&bufferLength));
if (bufferLength > 0)
{
char * buffer = new char[bufferLength];
std::string result(buffer);
delete[] buffer;
return result;
}
else
{
return "";
}
}