MObject from 'objectId ' ? 2003-11-27 - By deane@(protected)
Back On Mon, Nov 24, 2003 at 01:56:26PM -0300, Martin Leguizamon wrote: > > Has anyone successfully got the shape object from > the 'objectId' attribute ?
Well, yes and no. Read on.
> Seems that 'objectId' provides a pointer address > to the object, so I tried this in my shader with > no luck: > > ****** > > MStatus myShader::compute( const MPlug& plug, MDataBlock& block ) > { > > //... > > MStatus status; > > int objId = block.inputValue( aObjectId ).asLong(); > MFnDependencyNode dNode( *( MObject* ) objId, &status );
This won't work because 'objId' is a pointer to the internal node, not to an MObject.
If you look at the definition of MObject in MObject.h, you'll see that it has two private member variables: 'ptr' and 'tp'.
'objId' is equivalent to the 'ptr' value.
So to get an MObject which points to this, you want to do something like:
MObject myObj;
myObj.ptr = (MPtrBase*)objId;
Unfortunately, you cannot do it that easily because 'ptr' is private. However, assuming that the memory layout of a C++ class consists of its non-static members, you can do something like this:
MObject myObj;
memcpy((void*)&myObj, (void*)objId, sizeof(MPtrBase*));
A slightly more elegant approach, which is a bit less reliant on the in-memory ordering of the class members, is to create your own MObject class with all of its member variables public, e.g:
#undef _MObject #define MObject MyMObject #define private public #include <maya/MObject.h> #undef MObject #undef private
then use that to modify the contents of the MObject:
MyMObject* objPtr = (MyMobject*)&obj;
objPtr->ptr = (MPtrBase*)objId; objPtr->tp = MFn::kDependencyNode;
Unfortunately, this still doesn't work. As soon as you try to attach a functionset to the MObject, Maya crashes in MFnBase::setObject(). So there must be some internal state info (e.g. reference counting) which is not being properly initialized.
In my case I was able to work around the problem by creating, at the start of the render, a lookup table containing the MObjects for all of the objects using my shader. I would also create a 'singleShadingSwitch' node and connect all of the objects in the lookup table to it, using their indices within the table as their 'inSingle' value. The switch's 'output' value would then connect to an attr on my shader.
In the compute() I grab the value from the switch's 'output' and use that to index into the lookup table to find my MObject. (In theory, I really don't need the lookup table since I could follow the 'output' plug back to the singleShadingSwitch node, then index into its 'input' array to find the plug leading back to the shape. But I didn't think of that until later, and besides, in my case the lookup table was small enough that it was faster.)
If you don't like using a singleShadingSwitch node, then you can leave it out and in your compute() method step through each MObject in the lookup table and compare its 'ptr' value to your 'objId'.
=========================================================================== - deane Gooroos Software: Plugging you into Maya
Visit http://www.gooroos.com for more information
-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- --- List-help: <mailto:listar@(protected)?Subject=help> List-archive: <http://www.highend3d.com/maya/devarchive/>
|
|