Hello everyone,
I am looking for some assistance with creating a custom plugin through the HDK that stores data in the Houdini scene that is able to be modified and is persistent to the file.
The data will be brought into the node as a byte-stream (std::byte*) and then held in a buffer of a known size which I will want to read and modify if needed.
Methods I have tried so far:
1. Following the SOP_BlindData.C example:
I was not able to get this example to build in H19.5.605 and get a few errors:
/src/houdini/plugin/SOP_BlindData.h:17:25: error: expected ‘;’ at end of member declaration
17 | const char *inputLabel(OP_InputIdx idx) const override;
| ^~~~~~~~~~
| ;
/src/houdini/plugin/SOP_BlindData.h:17:47: error: expected ‘)’ before ‘idx’
17 | const char *inputLabel(OP_InputIdx idx) const override;
| ~ ^~~~
| )
/src/houdini/plugin/SOP_BlindData.h:19:25: error: ‘OP_ERROR HDK_Sample::SOP_BlindData::save(std::ostream&, const OP_SaveFlags&, const char*, const UT_StringHolder&)’ marked ‘override’, but does not override
19 | OP_ERROR save(std::ostream &os,
| ^~~~
/src/houdini/plugin/SOP_BlindData.C:57:1: error: ‘const char* HDK_Sample::SOP_BlindData::inputLabel’ is not a static data member of ‘class HDK_Sample::SOP_BlindData’
57 | SOP_BlindData::inputLabel(OP_InputIdx) const
| ^~~~~~~~~~~~~
/src/houdini/plugin/SOP_BlindData.C:57:27: error: ‘OP_InputIdx’ was not declared in this scope; did you mean ‘OP_Input’?
57 | SOP_BlindData::inputLabel(OP_InputIdx) const
| ^~~~~~~~~~~
| OP_Input
/src/houdini/plugin/SOP_BlindData.C: In member function ‘OP_ERROR HDK_Sample::SOP_BlindData::save(std::ostream&, const OP_SaveFlags&, const char*, const UT_StringHolder&)’:
/src/houdini/plugin/SOP_BlindData.C:69:61: error: ‘UT_String::UT_String(const UT_StringRef&)’ is private within this context
69 | if (SOP_Node::save(os, flags, path_prefix, name_override) >= UT_ERROR_ABORT)
| ^
In file included from
.../src/houdini/plugin/SOP_BlindData.C:1:
/dd/tools/stores/commercial/houdini/19.5.605/cent7_64/toolkit/include/UT/UT_String.h:129:5: note: declared private here
129 | UT_String(const UT_StringRef &);
| ^~~~~~~~~
gmake: *** Error 1
gmake: *** Error 2
gmake: *** Error 2
error: failed with status 2
I remember reading some UT_String related changes in the HDK changelog so I'm not sure if it's an issue with the example not being updated for the latest version of the HDK.
2. Saving as a Node Variable:
UsingOPgetDirector()->getCommandManager()->setVariable(varName, varValue, 0); to save to the base Houdini node / and OPgetDirector()->getCommandManager()->getVariable(varName, buffer); to load from it, works as long as the value is a const char* but does not work for bytes and casting the bytes to const char* causes issues because a value {0} byte seems to be interpreted as a string terminator.
3. Saving as to the UserDataDict:
Similarly I tried using the UserData with:
OPgetDirector()->setUserData(key, value, 0);
bool error = OPgetDirector()->getUserData(key, buffer);
but again, it only works with UT_StringHolder values, and when the bytes are used directly in the constructor, we run into a byte 0 issue which causes the string to be empty. To get around this, I tried to do a memcpy to the location of the UT_StringHolder in memory, but this would cause either the string to get terminated early or it would cause larger issues where the string would contain other information that was nearby in memory.
If the byte array did not contain a {0} everything would work as expected but the implementation needs to be able to handle all possible values.
4. Serializing the data into integers:
This was more of a last ditch effort as the byte could be quite large (30-300MB) and so converting the bytes to their integer representation and then saving this as a string "works" in that it doesn't immediately break, but it requires 3x the storage footprint and takes minutes to convert between the data types and so is not a reasonable solution.
5. Modify the input to be a JSON string instead of a byte-stream:
This is a solution we are open to exploring, since getting the data as JSON may be a feature in the future, but initial investigation has not lead anywhere as it seems that the HDK mostly assumes that you are receiving JSON data from a file through an IStream instead of allowing the input to be a JSON formatted string.
In the end, a solution that does not make use of an external file is required for our purposes as well as one that allows for a simple way to store an arbitrarily sized byte buffer to a node in the scene that can be read and written to, with resizing and reallocs if necessary.
This has already been accomplished in Maya with a plugin and custom node (MPxNode https://help.autodesk.com/view/MAYADEV/2025/ENU/?guid=MAYA_API_REF_cpp_ref_class_m_px_node_html) utilizing a custom attribute (MPxData https://help.autodesk.com/view/MAYADEV/2025/ENU/?guid=MAYA_API_REF_cpp_ref_class_m_px_data_html) by implementing both the readBinary and writeBinary attributes along with storing the data to a simple std::byte*, and so hopefully something can be accomplished in Houdini that is similar.
Thank you for any help or insight you can provide.
Help with Custom Plugin to Store Arbitrary Data in Bytes
259 0 0-
- CarterDD
- Member
- 1 posts
- Joined: 11月 2025
- オフライン
-
- Quick Links
