Guest xionmark Posted March 26, 2011 Share Posted March 26, 2011 Hello, I need to store data between frames in a POP, it appears (please correct me if I'm wrong) the best way is to store it as "blind data" in the pop context using the POP_BlindData class. The only code fragment I could find was in the notes of the header file but it's not a working example: http://www.sidefx.com/docs/hdk11.0/_p_o_p___blind_data_8h_source.html I've modified the POP_CircleForce example and attached to this post, it contains these 2 code fragments: In the POP_CircleForce.h file: // "blind data" class class MyBlindData : public POP_BlindData { public: int anInt; float aFloat; //MyBlindData(MyBlindData theData); //~MyBlindData(); }; And in the POP_CircleForce.C file: // do something with the POP's blind data POP_BlindData *mydata; mydata = data->getBlindData(this); if (!mydata) { mydata = new MyBlindData(); data->addBlindData(mydata); } But when compiling, I get the following errors: In file included from POP_CircleForce.C:39: POP_CircleForce.h:46: error: invalid use of incomplete type ‘struct POP_BlindData’ /opt/hfs11.0.658/toolkit/include/POP/POP_ContextData.h:40: error: forward declaration of ‘struct POP_BlindData’ POP_CircleForce.C: In member function ‘virtual OP_ERROR HDK_Sample::POP_CircleForce::cookPop(OP_Context&)’: POP_CircleForce.C:189: error: cannot convert ‘HDK_Sample::MyBlindData*’ to ‘POP_BlindData*’ in assignment Compile failed Does anyone have a working example? Thanks! Mark Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 27, 2011 Share Posted March 27, 2011 Woops, uploaded wrong source code example. Correct one attached here. Quote Link to comment Share on other sites More sharing options...
mrice Posted March 27, 2011 Share Posted March 27, 2011 Hey Mark, It looks like there's only a forward declaration of POP_BlindData before your MyBlindData class, so I think its just a matter of including POP_BlindData.h before that point. Also, the use of goto statements in that example precludes you from initializing MyBlindData where you are trying to. I haven't tried actually using the class though, but I've done something similar by creating a singleton which can store persistent state information, although without the cache friendliness. HTH, Michael Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 29, 2011 Share Posted March 29, 2011 Hi Michael, Yea, I was actually getting it to compile in my plugin code but messed up building the example in POP_CircleForce. I have it compiling now, but it's complaining about a symbol lookup error: /opt/hfs11.0.658/bin/houdini-bin: symbol lookup error: /home/mstory/houdini11.0/dso/POP_CircleForce.so: undefined symbol: _ZN11MyBlindDataC1EP8POP_Node Runtime linking error perhaps? Not sure yet. I've attached the source code and example file. Mark Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 29, 2011 Share Posted March 29, 2011 Hi, So this compiles but crashes H11 when cooking the POP: class MyBlindData : public POP_BlindData { public: int anInt; float aFloat; float aFloatArray[5]; MyBlindData(POP_Node *node); ~MyBlindData(); MyBlindData *duplicate(const POP_ContextData *src); }; MyBlindData *myData; myData = (MyBlindData*)data->getBlindData(this); if (!myData) { myData = new MyBlindData(this); myData->anInt = 1; myData->aFloat = 1.23f; myData->aFloatArray[0] = 0.1; myData->aFloatArray[1] = 0.2; myData->aFloatArray[2] = 0.3; myData->aFloatArray[3] = 0.4; myData->aFloatArray[4] = 0.5; data->addBlindData(myData); cout << "added blind data " << endl; } else { cout << "blind data: anInt " << myData->anInt << endl; cout << "blind data: aFloat " << myData->aFloat << endl; for(int i =0; i < 5; ++i) cout << "blind data: " << myData->aFloatArray[i] << endl; } What's weird is that I was testing on an H9.5 machine (using the Local Force example instead) and I get this error when starting hscript (logging in remote so I can't run Houdini to see if it's only hscript that's complaining). It happens with the HDK supplied example code without my modifications: /POP_LocalForce.so: undefined symbol: _ZNK7OP_Node21pushAsPwdAndRunPythonER15PY_CompiledCodeN9PY_Result4TypeERS2_P20PY_EvaluationContext Very odd. Anyway, I can store data from frame to frame within the POP object but if I can get the BlindData to work I think I can share it easier with other POPs through the shared context data space. I can resort to other methods but this seems to be convenient. Mark Quote Link to comment Share on other sites More sharing options...
mrice Posted March 29, 2011 Share Posted March 29, 2011 I think the reason you're seeing crashing and/or link errors is because you haven't implemented your MyBlindData class. But after that's done, it looks to me like something in POP_BlindData::resetSimulation or POP_ContextData::resetBlindData is broken? A workaround could be to reimplement resetSimulation, handling any reset stuff yourself and returning 0. hth Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 30, 2011 Share Posted March 30, 2011 I think the reason you're seeing crashing and/or link errors is because you haven't implemented your MyBlindData class. But after that's done, it looks to me like something in POP_BlindData::resetSimulation or POP_ContextData::resetBlindData is broken? A workaround could be to reimplement resetSimulation, handling any reset stuff yourself and returning 0. hth Not sure I'm following, there is an implementation, albeit very simple with only member variables. I've attached a copy of the source that declares a "BlindData" class and can be instanced from the LocalForce POP and have it's variables modified between frames. The only difference between that class and a POP_BlindData would be the ability to have the member var(the "blind data" stored in the context memory space which is shared via other POPs. At least that what I've gleaned from the docs ... HDK examples would sure be nice but I've beat that dead horse too many times. So at a minimum I should be able to create a POP_BlindData object and store "something" there ... once I know that works, I can figure just exactly what resetSimulation and how the rest of POP_BlindData works ... So for this simple example: class MyBlindData //class MyBlindData : public POP_BlindData { public: int anInt; float aFloat; float aFloatArray[5]; // POP_ContextData myPopContext; MyBlindData(); // MyBlindData(POP_Node *node); ~MyBlindData(); // POP_BlindData *duplicate(const POP_ContextData *src); }; MyBlindData::MyBlindData() { cout << "MyBlindData constructor called" << endl; anInt = 0; aFloat = 0.0f; aFloatArray[0] = 0.0; aFloatArray[1] = 0.0; aFloatArray[2] = 0.0; aFloatArray[3] = 0.0; aFloatArray[4] = 0.0; }; In the LocalForce POP interface: MyBlindData *myData; In the LocalForce POP's constructor: myData = new MyBlindData(); And then in cookPop(): myData->anInt += 1; myData->aFloat += 0.01f; cout << "blind data: anInt " << myData->anInt << endl; cout << "blind data: aFloat " << myData->aFloat << endl; for(int i =0; i < 5; ++i) { myData->aFloatArray[i] += t; cout << "blind data: aFloatArray[" << i << "] = " << myData->aFloatArray[i] << endl; } Quote Link to comment Share on other sites More sharing options...
mrice Posted March 30, 2011 Share Posted March 30, 2011 (edited) So for this simple example: class MyBlindData //class MyBlindData : public POP_BlindData { public: int anInt; float aFloat; float aFloatArray[5]; // POP_ContextData myPopContext; MyBlindData(); // MyBlindData(POP_Node *node); ~MyBlindData(); // POP_BlindData *duplicate(const POP_ContextData *src); }; I don't see how this compiles, for one thing POP_BlindData::duplicate is pure-virtual, and I dont see it implemented in the version posted above (post #4) MyBlindData::MyBlindData() { cout << "MyBlindData constructor called" << endl; anInt = 0; aFloat = 0.0f; aFloatArray[0] = 0.0; aFloatArray[1] = 0.0; aFloatArray[2] = 0.0; aFloatArray[3] = 0.0; aFloatArray[4] = 0.0; }; I don't see this definition in the code above, or the destructor, and as you've defined it the compiler shouldn't be synthesizing one. And I don't see a POP_BlindData::POP_BlindData() constructor, (I'm looking at the H11 interface), so I would think you need to explicitly call POP_BlindData::POP_BlindData(POP_Node* node) Edited March 30, 2011 by mrice Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 30, 2011 Share Posted March 30, 2011 I don't see how this compiles, for one thing POP_BlindData::duplicate is pure-virtual, and I dont see it implemented in the version posted above (post #4) I don't see this definition in the code above, or the destructor, and as you've defined it the compiler shouldn't be synthesizing one. And I don't see a POP_BlindData::POP_BlindData() constructor, (I'm looking at the H11 interface), so I would think you need to explicitly call POP_BlindData::POP_BlindData(POP_Node* node) Yea, it compiles, that recent example has duplicate() removed, it was only an example of an arbitrary class being instanced as a member var of the POP node, which can in fact keep state info, but the problem (from the description of POP_BlindData) is when there are multiple POP contexts to deal with. I've never had to worry about that before but the POP I'm working on will share a number of structures with other POPS. I do have it compiling with the POP_BlindData derived class (MyBindData) but it still crashes: /opt/hfs11.0.658/bin/houdini-bin: symbol lookup error: /home/mstory/houdini11.0/dso/POP_LocalForce.so: undefined symbol: _ZN11MyBlindDataC1EP8POP_Node I've attached the source code that does compile, but generates the error above. Puzzled. Mark Quote Link to comment Share on other sites More sharing options...
mrice Posted March 31, 2011 Share Posted March 31, 2011 (edited) I do have it compiling with the POP_BlindData derived class (MyBindData) but it still crashes: /opt/hfs11.0.658/bin/houdini-bin: symbol lookup error: /home/mstory/houdini11.0/dso/POP_LocalForce.so: undefined symbol: _ZN11MyBlindDataC1EP8POP_Node The demangled symbol _ZN11MyBlindDataC1EP8POP_Node is MyBlindData::MyBlindData(POP_Node*). Its not implemented in the code you last posted, nor is the destructor. Try: class MyBlindData : public POP_BlindData { public: MyBlindData(POP_Node *node) : POP_BlindData(node) {} virtual ~MyBlindData() {} ... }; The duplicate method should probably be returning a pointer to a new object.. Edited March 31, 2011 by mrice Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 31, 2011 Share Posted March 31, 2011 Nope, that doesn't fix it ... Won't compile at all ... Would you mind posting the source with your edit? Quote Link to comment Share on other sites More sharing options...
mrice Posted March 31, 2011 Share Posted March 31, 2011 Nope, that doesn't fix it ... Won't compile at all ... Would you mind posting the source with your edit? No problem. It doesn't compile after the class is implemented because the compiler then sees that there's no POP_ContextData::POP_ContextData() constructor, so you would need to initialize myPopContext properly. I commented that out, and this works for me POP_LocalForce_blindData_v4_MR.tar.gz Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 31, 2011 Share Posted March 31, 2011 No problem. It doesn't compile after the class is implemented because the compiler then sees that there's no POP_ContextData::POP_ContextData() constructor, so you would need to initialize myPopContext properly. I commented that out, and this works for me OK. Got it. I messed up in 2-3 different places while trying different things (and juggling to many other tasks at the same time!), it makes sense why the loader was missing that symbol. I figured I wasn't properly deriving my class. Thanks for casting a second pair of eyes on the problem!!!!! Take care, Mark Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 31, 2011 Share Posted March 31, 2011 Ha! Wouldn't you know it! <SNIP> UT_Signal::processSignal(int, siginfo*, void*) (??:0) POP_ContextData::resetBlindData(int) (??:0) POP_ContextData::resetBlindData(int) (??:0) POP_ContextData::offsetReset() (??:0) POP_ContextData::reset(POP_Node*, GU_Detail*, char const*, bool, unsigned int, bool) (??:0) SOP_Popnet::cookMySop(OP_Context&) (??:0) SOP_Node::cookMe(OP_Context&) (??:0) OP_Node::cook(OP_Context&) (??:0) SOP_Node::getCookedGeoHandle(OP_Context&, int) (??:0) SOP_Popnet::getCookedPopnetGeoHandleForSceneViewer(OP_Context&, int) (??:0) </SNIP> The hunt continues ... Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 31, 2011 Share Posted March 31, 2011 Hi Mike, Having some trouble getting the debugger to trap on the resetSimulation() call, but this is what I'm working with at the moment. In POP_LocalForce.h (the call to addBlindData() crashes Houdini, it's commented out): class MyBlindData : public POP_BlindData { public: int anInt; float aFloat; float aFloatArray[5]; MyBlindData(POP_Node *node) : POP_BlindData(node) { cout << "MyBlindData constructor called" << endl; anInt = 0; aFloat = 0.0f; aFloatArray[0] = 0.0; aFloatArray[1] = 0.0; aFloatArray[2] = 0.0; aFloatArray[3] = 0.0; aFloatArray[4] = 0.0; } virtual ~MyBlindData() {} POP_BlindData *duplicate(const POP_ContextData *src); }; POP_BlindData * MyBlindData::duplicate(const POP_ContextData *src) { MyBlindData *myData; myData = (MyBlindData*)src->getBlindData(this->getOwner()); if (myData->resetSimulation()) cout << "MyBlindData::duplicate() - simulation was reset " << endl; if (myData->resetSimulation() || !myData) { myData = new MyBlindData(this->getOwner()); myData->anInt = 1; myData->aFloat = 1.23f; myData->aFloatArray[0] = 0.1; myData->aFloatArray[1] = 0.2; myData->aFloatArray[2] = 0.3; myData->aFloatArray[3] = 0.4; myData->aFloatArray[4] = 0.5; // src->addBlindData((POP_BlindData *)myData); cout << "MyBlindData::duplicate() - added blind data ************" << endl; } return (POP_BlindData *)this; }; And in POP_LocalForce.C (the call to resetSimulation() crashes Houdini, when commented out, it crashes when the sim resets itself): myData->anInt += 1; myData->aFloat += 0.01f; cout << "foo blind data: anInt " << myData->anInt << endl; cout << "foo blind data: aFloat " << myData->aFloat << endl; for(int i =0; i < 5; ++i) { myData->aFloatArray[i] += t; cout << "foo blind data: aFloatArray[" << i << "] = " << myData->aFloatArray[i] << endl; } cout << endl; MyBlindData *myData; myData = (MyBlindData*)data->getBlindData(this); if (myData->resetSimulation()) cout << "bar simulation was reset " << endl; // if (myData->resetSimulation() || !myData) { if (!myData) { myData = new MyBlindData(this); myData->anInt = 1; myData->aFloat = 1.23f; myData->aFloatArray[0] = 0.1; myData->aFloatArray[1] = 0.2; myData->aFloatArray[2] = 0.3; myData->aFloatArray[3] = 0.4; myData->aFloatArray[4] = 0.5; data->addBlindData((POP_BlindData *)myData); cout << "bar added blind data " << endl; } else { myData->anInt += 1; myData->aFloat += 0.01f; cout << "bar blind data: anInt " << myData->anInt << endl; cout << "bar blind data: aFloat " << myData->aFloat << endl; for(int i =0; i < 5; ++i){ myData->aFloatArray[i] += t; cout << "bar blind data: aFloatArray[" << i << "] = " << myData->aFloatArray[i] << endl; } } Quote Link to comment Share on other sites More sharing options...
mrice Posted April 1, 2011 Share Posted April 1, 2011 Hey Mark, see post 6 above. You might need to provide your own implementation of resetSimulation. To begin with, just try returning 0 and see if that gets rid of any crashing when the particle sim resets. Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted April 1, 2011 Share Posted April 1, 2011 Hey Mark, see post 6 above. You might need to provide your own implementation of resetSimulation. To begin with, just try returning 0 and see if that gets rid of any crashing when the particle sim resets. It doesn't seem to get called. From the header file: // When the simulation get's reset, the following method is called. If the // method returns 1, then the blind data will be deleted and reset inside // the context. This can be used to detect a reset without having to // reconstruct expensive data structures on the next cook. // The default behaviour is to return 1 (i.e. delete itself on reset of // the simulation). virtual int resetSimulation(); From the crash log ContextData is resting the sim, but not calling resetSimulation(): UT_Signal::processSignal(int, siginfo*, void*) (??:0) POP_ContextData::resetBlindData(int) (??:0) POP_ContextData::resetBlindData(int) (??:0) POP_ContextData::offsetReset() (??:0) POP_ContextData::reset(POP_Node*, GU_Detail*, char const*, bool, unsigned int, bool) (??:0) SOP_Popnet::cookMySop(OP_Context&) (??:0) SOP_Node::cookMe(OP_Context&) (??:0) Have you been able to call addBlindData() successfully? Mark Quote Link to comment Share on other sites More sharing options...
mrice Posted April 1, 2011 Share Posted April 1, 2011 Have you been able to call addBlindData() successfully? Yes, as far I could tell in a few minutes. Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted April 1, 2011 Share Posted April 1, 2011 Yes, as far I could tell in a few minutes. And it was successfully retrieved after the sim was reset? I've got something else working (using standard C++ methods) that does what I need for this POP but I'd like see if I can get this blind data feature working properly, I'm curious. Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted April 1, 2011 Share Posted April 1, 2011 Attached is a "working" version, the duplicate method isn't playing nice yet. One thing I was doing wrong was some naming confusion of the POP's member var and the temp var in the cook method. Doh! (human multi-tasking is a myth). Will try to see if it holds up with multi pop networks now. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.