Hi Mathieu,
Glad you solved the
first problem!
For the second you can investigate in 2 different areas,
both involving saving data in the XSI scene graph, which is the only way of
ensuring data persistence between XSI sessions.
The first one is called
UserDataBlob, and the second is UserDataMap, the doc provides good exemples
for both to use them.
Then you have to know if the data you're using needs
to be updated everytime the operator is updated.
If not (it's just
initialization data) you can compute the values and store them in either
storage solution BEFORE applying the operator with a custom command: you'll
save yourself a lot of headache by doing so. And you can put your CPP custom
command in the same DLL than the operator (and thus share some code).
If
yes, you'll have to do the same as what you're doing now (store the data in
your class), and connect your storage to an output port of your operator. The
tricky part is that you'll have to ensure that XSI request the evalution of
your operator's storage port before deleting the operator. I can write a
little more about that if you need it.
Hope this
helps,
Aloys
On 01/02/06, Mathieu Leclaire <mleclair(at)hybride.com>
wrote:
-----Original
Message-----
From: owner-xsi(at)Softimage.COM [mailto:owner-xsi(at)Softimage.COM]On Behalf Of Mathieu Leclaire
Sent: Tuesday, January 31,
2006 12:04 PM
To: XSI(at)Softimage.COM
Subject: PutUserData in custom
operator
Hi, I'm creating a custom operator and I
need to initialize and save data for each vertex of a polymesh. Since I have
different kind of data to save in the _init call of the operator and reload at
each _update call, I figured I'd create a class and put all my data in it then
store that object using the PutUserData() function of the UpdateContext. But
since I allocate memory in the constructor and delete that memory in the
destructor, I think once I pull back my data in the _update function using
GetUserData(), it returns me random data since it looks like the memory has
already been released. Here is an example of what I'm
doing:
#ifndef
_myVertexInfo_h
#define
_myVertexInfo_h
class myVertexInfo
{
private:
int
_nbPts;
float*
_targetPositions;
int*
_idxPts;
public:
myVertexInfo
(int nbPts) {
_nbPts = nbPts;
_targetPositions = new float[nbPts*3];
_idxPts = new int[nbPts*3];
}
virtual
~myVertexInfo (){
delete [] _targetPositions;
delete [] _idxPts;
}
int
GetNbPts() {
return _nbPts;
}
…
};
#endif
Then in my operator's
_Init function I do something like this:
…
//put local
positions in obj2PtsPosArray.
obj2PtsPosArray =
inGeom.GetPoints().GetPositionArray();
int nb =
obj2PtsPosArray.GetCount();
myVertexInfo
* posData = new myVertexInfo (nb);
…
ctx.PutUserData(
(CValue::siPtrType)posData );
Then pull it back in
the _update function doing something like this:
CValue::siPtrType
pUserData = ctx.GetUserData();
myVertexInfo *
posData = (myVertexInfo *)pUserData;
Application
app;
app.LogMessage(
CValue((float)posData->GetNbPts()).GetAsText());
But I lose all
information saved from the _init call. So what am I doing wrong? How do I
allocate memory only in the _init function and release it only in the _term
function?
I also have a second
question: How can I store this information so that when I load a model
containing instances of that operator, it won't recalculate all that
information from the _init call but load the data calculated when the operator
was first applied. See, I only need to calculate the necessary information
when it's first applied, then use the calculated information at every _update
call of the operator. But if I export a model containing instances of this
operator, when I re-import it (usually by switching the low resolution
reference model by a higher resolution one that contains this operator) then
it recalls the _init of the operator and recalculates all the values instead
of reusing the values that where calculated when first applied. I had the same
problem with a previous operator I created but I overcame the issue by adding
a "FirstLoad" Boolean parameter to the SPDL so that when it first got applied,
it would change that parameter value to false and save the desired data in the
rest of the parameters and so when it loaded again in a model, and the
"FirstLoad" parameter value was set to false, it would only read the
parameters instead of recalculating them. That worked well in that case
because I only had a couple floats and a couple integers that had to be saved
per operator so I saved them as parameters. Now I have whole arrays of data to
save and it's length is dependant on the number of vertices. How should I
solve this issue? The only solution I have in mind would be to save it to a
file but then we'd have files to manage with the model and paths to check… I'm
looking for a way to save that data directly into the operator or somewhere in
the exported model so that I can reload it when imported. Any
suggestions?
Thanks for any help
you can provide and sorry for the lengthy post, I just figure I'd better give
too much information then not enough.
Mathieu
Leclaire
R&D
Programmer
Hybride