Jump to content

POP_BlindData proper useage


Guest xionmark

Recommended Posts

Guest xionmark

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

Link to comment
Share on other sites

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 :ph34r: 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

Link to comment
Share on other sites

Guest xionmark

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

Link to comment
Share on other sites

Guest xionmark

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

Guest xionmark

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;
    }

Link to comment
Share on other sites

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 by mrice
Link to comment
Share on other sites

Guest xionmark

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. :unsure:

Mark

Link to comment
Share on other sites

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 by mrice
Link to comment
Share on other sites

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

Link to comment
Share on other sites

Guest xionmark

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

Link to comment
Share on other sites

Guest xionmark

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 ...

Link to comment
Share on other sites

Guest xionmark

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;
        }
    }

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Guest xionmark

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

Link to comment
Share on other sites

Guest xionmark

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.

Link to comment
Share on other sites

Guest xionmark

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...