Kostra
Kostra
About Me
Connect
LOCATION
Not Specified
WEBSITE
Houdini Skills
Availability
Not Specified
Recent Forum Posts
Increase resolution of a field in DOP Aug. 2, 2020, 2:18 p.m.
Is there an easy way to increase resolution of a field in DOP? Example: I have `surface` field with resolution and I would like to increase it to while keeping field's size and position.
I expected that `Gas Resize Field` would be able to do this, but I have not figured how.
I expected that `Gas Resize Field` would be able to do this, but I have not figured how.
Day 9 | Motion: Growth July 9, 2020, 5:57 p.m.
My crystal growth solver.
HDK: How to use GA_BlobData? Aug. 23, 2019, 10:07 a.m.
I do not know what I was doing wrong. It works for me now.
For the future lost souls I'm including a working node with a simple test scene. Download & extract the attached archive somewhere and run the following commands
The result should be:
Not sure about the lifetime of attachments here, but I'm frustrated when they disappear. Thus the code in plain text
BlobDataTest.h
BlobDataTest.cpp
CMakeLists.txt
For the future lost souls I'm including a working node with a simple test scene. Download & extract the attached archive somewhere and run the following commands
export CC=gcc-6
export CXX=g++-6
mkdir build
pushd build
cmake .. -DHOUDINI_ROOT=/opt/hfs17.5/
make -j
popd
./test.py
Stored a string to a blob: "Hello World!"
Finished cooking!
Retrieved a string form a blob: "Hello World!"
Finished cooking!
Not sure about the lifetime of attachments here, but I'm frustrated when they disappear. Thus the code in plain text
BlobDataTest.h
#pragma once #include <SOP/SOP_Node.h> #include <UT/UT_MemoryCounter.h> ///////////////// String Blob ////////////////////////////// class StringBlob : public GA_BlobData { public: StringBlob(); StringBlob(const char *str); virtual ~StringBlob(); virtual uint hash() const; virtual bool isEqual(const GA_BlobData &blob) const; virtual int64 getMemoryUsage(bool inclusive) const; virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const; public: UT_String myString; }; ///////////////// String Blob Test Node ////////////////////////////// class SOP_BlobDataTest : public SOP_Node { public: SOP_BlobDataTest(OP_Network *net, const char *name, OP_Operator *op); virtual ~SOP_BlobDataTest(); static PRM_Template myTemplateList[]; static OP_Node * myConstructor(OP_Network *, const char *, OP_Operator *); protected: /// Method to cook geometry for the SOP virtual OP_ERROR cookMySop(OP_Context &context); private: };
BlobDataTest.cpp
#include <iostream> #include <string> #include <GA/GA_AIFBlob.h> #include <GU/GU_Detail.h> #include <OP/OP_AutoLockInputs.h> #include <OP/OP_Director.h> #include <OP/OP_Operator.h> #include <OP/OP_OperatorTable.h> #include <PRM/PRM_Include.h> #include <UT/UT_DSOVersion.h> #include "BlobDataTest.h" ///////////////// String Blob ////////////////////////////// StringBlob::StringBlob() : myString() {} StringBlob::StringBlob(const char *str) : myString(UT_String::ALWAYS_DEEP, str) {} StringBlob::~StringBlob() {} // Implementation of methods on GA_Blob uint StringBlob::hash() const { return myString.hash(); } bool StringBlob::isEqual(const GA_BlobData &blob) const { const StringBlob *s; s = dynamic_cast<const StringBlob *>(&blob); return s && (s->myString == myString); } int64 StringBlob::getMemoryUsage(bool inclusive) const { int64 mem = inclusive ? sizeof(*this) : 0; mem += myString.getMemoryUsage(); return mem; } void StringBlob::countMemory(UT_MemoryCounter &counter, bool inclusive) const { if (counter.mustCountUnshared()) { counter.countUnshared(getMemoryUsage(inclusive)); } } ///////////////// String Blob Test Node //////////////////////// void newSopOperator(OP_OperatorTable *table) { table->addOperator(new OP_Operator( "blob_data_test_node", "Blob Data Test Node", SOP_BlobDataTest::myConstructor, SOP_BlobDataTest::myTemplateList, 0)); } PRM_Template SOP_BlobDataTest::myTemplateList[] = { PRM_Template(), }; OP_Node *SOP_BlobDataTest::myConstructor(OP_Network *net, const char *name, OP_Operator *op) { return new SOP_BlobDataTest(net, name, op); } SOP_BlobDataTest::SOP_BlobDataTest(OP_Network *net, const char *name, OP_Operator *op) : SOP_Node(net, name, op) { // Right now I'm assuming that anything can change // In fugure, I might bump data IDs base on which attribute handles were // created with `getattrib` function // mySopFlags.setManagesDataIDs(true); } SOP_BlobDataTest::~SOP_BlobDataTest() {} OP_ERROR SOP_BlobDataTest::cookMySop(OP_Context &context) { // We must lock our inputs before we try to access their geometry. // OP_AutoLockInputs will automatically unlock our inputs when we return. // NOTE: Don't call unlockInputs yourself when using this! OP_AutoLockInputs input_lock_guard(this); if (input_lock_guard.lock(context) >= UT_ERROR_ABORT) return error(); // Duplicate incoming geometry duplicateSource(0, context); flags().setTimeDep(true); auto owner = GA_ATTRIB_DETAIL; auto scope = GA_SCOPE_PUBLIC; auto attribute_name = "blob_test"; GA_RWAttributeRef blob_gah = gdp->findAttribute(owner, scope, attribute_name); // Set the blob if does not exists // Should be executed in the `test.hipnc/obj/geo1/set_blob` node if (!blob_gah) { // create attribute GA_RWAttributeRef blob_gah = gdp->createAttribute( owner, scope, attribute_name, nullptr, nullptr, "blob"); // create blob GA_Attribute * attr = blob_gah.getAttribute(); const GA_AIFBlob *aif = attr->getAIFBlob(); StringBlob * blob_ptr = new StringBlob{"Hello World!"}; // save blob aif->setBlob(attr, blob_ptr, 0); std::cout << "Stored a string to a blob: " << blob_ptr->myString << std::endl; } else { // Get the blob if it exists // Should be executed in the `test.hipnc/obj/geo1/get_blob` node // Retrieve the blob GA_Attribute * attr = blob_gah.getAttribute(); const GA_AIFBlob *aif = attr->getAIFBlob(); GA_BlobRef blob = aif->getBlob(attr, 0); auto strblob = dynamic_cast<const StringBlob *>(blob.get()); std::cout << "Retrieved a string form a blob: " << strblob->myString << std::endl; } if (error() >= UT_ERROR_ABORT) return error(); std::cout << "Finished cooking!" << std::endl; return error(); }
CMakeLists.txt
# Specify the minimum required version of CMake to build the project. cmake_minimum_required( VERSION 3.6 ) set(CMAKE_PREFIX_PATH "${HOUDINI_ROOT}/toolkit") ### LIBRARIES ### find_package(Houdini REQUIRED) find_package(Eigen3 REQUIRED) ### EXECUTOR ### # SOP add_library(BlobDataTest SHARED BlobDataTest.cpp) target_link_libraries(BlobDataTest Houdini) houdini_configure_target( BlobDataTest )