Register Latest Topics
 
 
 


Reply
  Author   Comment  
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #1 

Hi,
I am creating custom suite of Node which used custom MPxData.
When i load the plugin in maya and check the plug-in information, i get the correct dependency Nodes: "customNode" and the correct dependency graph data types: "customData".
This data are correctly register in the maya plugin and also in the initialize custom node.

1- In the pluginMain.cpp:
initializePlugin()

Code:

status = plugin.registerData("customData", customData::id, customData::creator);
if (!status) {status.perror("Failed to register 'customData'");return status;}
status = plugin.registerNode("customNode", customNode::id, customNode::creator, customNode::initialize);
if (!status) {status.perror("customNode");return status;}

uninitializePlugin():

Code:

status = plugin.deregisterNode(customNode::id);if (!status) {status.perror("customNode");return status;}
status = plugin.deregisterData(customData::id);
if (!status) {status.perror("Failed to deregister 'customData'");return status;}

2- In the customNode.cpp:
initialize():

Code:

MFnTypedAttribute tAttr;

floatValue = nAttr.create("floatValue", "floatValue", MFnNumericData::kFloat, 1.0f);
nAttr.setMin(0.0f);
nAttr.setSoftMax(10.0f);
nAttr.setStorable(true);
nAttr.setKeyable(true);
addAttribute(floatValue);

p_outData = tAttr.create("outData", "outData", customData::id, MObject::kNullObj, &status);
tAttr.setStorable(false);
tAttr.setKeyable(false);
tAttr.setReadable(true);
tAttr.setWritable(false);
addAttribute(p_outData);

attributeAffects(floatValue, p_outData);

At this point everything seem to working fine, except in the compute() of the customNode.

compute():

Code:

MStatus customNode::compute(const MPlug& plug, MDataBlock& data){
if (plug == p_outData )
{
.....

The line "if (plug == p_outData )", don't return the correct value, it's always false. The p_outData (is connected to an other node)
"plug == p_outData" retrun correct value only when i unplug the p_outData....
I don't understand why, if i replace p_outData in the initialize by an other maya built-in DG data types it's working fine.
I try with MPxData and MPxGeometryData but i have the same issue.
If somehone have an idea it will be very helpfull, it's hard to find some example on internet about the MPxData.

Thanks

0
pshipkov

SOuP Jedi
Registered:
Posts: 4,641
Reply with quote  #2 
The info you provide is not enough for me to understand good enough what is happening and try give you and answer.

I used MPxData a long time ago only once and never again. Too much for too little.

If i need to load/save data i do it through Python or MPxCommand accessing data on the node or public members of the class instance storing it.

If i have to stream data in/out i implement it myself. It is more or less the same amount of work.

It sounds to me that you are streaming, correct ?
0
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #3 

Hi,
Thanks for the reply.

Yes i am trying to add new dependency graph data, for streamming data between node.

Below a capture of the custom plugin info:
plugInfo.png 

Below an example on the nodeEditor:
nodeAandB.PNG 

Like you can see on the picture :
customNodeA->out_customData is connected to in_customData<-customNodeB.
customNodeB->out_floatData is connected to in_floatData<-customNodeB.

The issue is in the compute() of customNodeA.

When i try to detect if the out_customData output is connected it fail.
But when i try to detect  if the out_floatData output is connected it works.

Below it's what i do in the compute of the customNodeA:

Code:

MStatus status;
if (plug == p_customData )
{
MGlobal::displayInfo(MString(" customNodeA -------> data "));
data.setClean(plug);
}else if (plug == p_floatData ){
MGlobal::displayInfo(MString(" customNodeA -------> float "));
data.setClean(plug);
}else{
return MS::kUnknownParameter;
}
return MS::kSuccess;


Below what i do i nthe initialize() of the computeA:
Code:

  //input  param
  p_inFloat = nAttr.create("in_float", "in_float", MFnNumericData::kFloat, 1.0f);
  nAttr.setMin(0.0f);
  nAttr.setSoftMax(10.0f);
  nAttr.setStorable(true);
  nAttr.setKeyable(true);
  addAttribute(p_inFloat);
  //output customData
    p_customData = tAttr.create("out_customData", "out_customData", customData::id, MObject::kNullObj, &status);
  tAttr.setWritable(false);
  tAttr.setStorable(false);
    status = addAttribute(p_customData);
  // output floatData
  p_floatData = nAttr.create( "out_floatData", "out_floatData", MFnNumericData::kFloat, 0.0 );
  nAttr.setWritable(false);
  nAttr.setStorable(false);
  status = addAttribute(p_floatData);

  attributeAffects(p_inFloat, p_customData);
  attributeAffects(p_inFloat, p_floatData);


I attach to this topic the sourceCode and the compiled mll(maya2016 win) of this example project.

Thanks

 

 
Attached Files
zip customExemple.zip (109.77 KB, 3 views)

0
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #4 
I just tested like this :
Code:

MObject thisNode = thisMObject();
MPlug testPlug (thisNode,p_customData);
if ( testPlug.isConnected() )
{
.....


And it seems to work, only if the out_float is also connected to customNodeB ...
0
pshipkov

SOuP Jedi
Registered:
Posts: 4,641
Reply with quote  #5 
MPxData is used rarely and i won't be surprised if it has bugs.

Usually what i do is create a compound attribute like this:
customData
   someDoubleArray
   someVectorArray
   someDouble
   someString
   etc. etc.

On the nodeA i have outCustomData attribute, on nodeB i have inCustomData attribute.
When i connect only the top compound attributes Maya takes care of moving the child attribute data. So it can be accessed from the target node in an explicit and easy way.
0
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #6 
yes it will work like this, but i would like to store specific things for simplifying the workflow and add custom std<<vector, random etc

0
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #7 
ok so i try different way with a compoundAttribute.

First i try a compoundAttribute with one child (customData), it's not working. The same issue as before. Also when trying to check the connection of the compoundAttribute

Second i try a compoundAttribute with two child: the customData and a dummy attribute, and it's working fine :)

So i keep the second try with  the one flow connection because of the compoundAttribute and i can continue to evaluate the connection with plug == customData for checking if the customAttribute is connected in the compute(). And i don't need to check if the dummy attribute is connected. I can now transfert all what i want in my customAttribute which is very cool for what i need.

Thanks you pshipkov  for the compoundAttribute idea :)

I think it's not the cleanest way but it work fine :)

If anybody have an other idea?



0
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #8 
ok so i try different way with a compoundAttribute.

First i try a compoundAttribute with one child (customData), it's not working. The same issue as before. Also when trying to check the connection of the compoundAttribute

Second i try a compoundAttribute with two child: the customData and a dummy attribute, and it's working fine :)

So i keep the second try with  the one flow connection because of the compoundAttribute and i can continue to evaluate the connection with plug == compoundData for checking if the customAttribute is connected in the compute(). And i don't need to check if the dummy attribute is connected. I can now transfert all what i want in my customAttribute which is very cool for what i need.

Thanks you pshipkov  for the compoundAttribute idea :)

I think it's not the cleanest way but it work fine :)

If anybody have an other idea?

0
jujut

Asking for seconds
Registered:
Posts: 33
Reply with quote  #9 
I finally get something working correctly without the compoundAttribute:
Capture.PNG 

On this exemple the custom data drive in one attribute 5 kind of data:
float
MColor
MPointArray
std::vector of MPointArray
std::mt19937

Below the compute of customNodeA:
Code:

  if ( plug==p_customData )
  {
    //create customData
    MFnPluginData fnCustomData;
    fnCustomData.create(customData::id, &status);
    MDataHandle customDataHandle;
    customDataHandle = data.outputValue(p_customData);
    customData* myData = NULL;
    myData = (customData*)fnCustomData.data(&status);

    //edit customData
    float floatValue = data.inputValue( p_inFloat ).asFloat();
    myData->floatData=floatValue;
    MColor colorValue (1,0,0);
    myData->colorData=colorValue;
    MPointArray pointArraValue;
    pointArraValue.setLength(25);
    myData->pointArrayData=pointArraValue;
    std::vector < MPointArray > pointArrayVectorValue;
    pointArrayVectorValue.resize(13);
    pointArrayVectorValue[5].setLength(3);
    pointArrayVectorValue[12].setLength(100);
    myData->pointArrayVectorData=pointArrayVectorValue;
    std::mt19937 randomValue;
    randomValue.seed(1234);
    myData->randomData=randomValue;
    //out data
    customDataHandle.set(myData);
    
    data.setClean(plug);
  }else{
    return MS::kUnknownParameter;
  }


Below the comput of the customNodeB
Code:

  if ( plug == p_outFloat )
  {
    //get customData
    MDataHandle customDataHandle = data.inputValue( p_inData, &status );
    customData* myData = (customData*) customDataHandle.asPluginData();
    float out=0.0f;
    MColor outColor(0,0,0);
    MPointArray outPointArray;
    std::vector < MPointArray > outPointArrayVector;
    std::mt19937 outRandomValue;
    MGlobal::displayInfo(MString("  check customNodeB -------> "));
    if (myData != NULL) 
    {
      out = myData->floatData;
      outColor = myData->colorData;
      outPointArray = myData->pointArrayData;
      outPointArrayVector = myData->pointArrayVectorData;
      outRandomValue = myData->randomData;
      std::uniform_real_distribution<> dis(0, 1);
  
      //check customData Value
      MGlobal::displayInfo(MString("  floatData -------> ")+out);
      MGlobal::displayInfo(MString("  outColor R -------> ")+outColor.r);
      MGlobal::displayInfo(MString("  outColor G -------> ")+outColor.g);
      MGlobal::displayInfo(MString("  outColor B -------> ")+outColor.b);
      MGlobal::displayInfo(MString("  outPointArray length -------> ")+outPointArray.length());
      MGlobal::displayInfo(MString("  outPointArrayVector length -------> ")+outPointArrayVector.size());
      MGlobal::displayInfo(MString("  outPointArrayVector[5] length -------> ")+outPointArrayVector[5].length());
      MGlobal::displayInfo(MString("  outPointArrayVector[12] length -------> ")+outPointArrayVector[12].length());
      MGlobal::displayInfo(MString("  random -------> ")+dis(outRandomValue));
      
    }else{
      MGlobal::displayInfo(MString("  nothing plug in p_inData "));
    }
    //test output
    data.outputValue(p_outFloat).set(out);
    data.setClean(plug);
  }else{
    return MS::kUnknownParameter;
  }


I attach  to this message the source code of the test plug.

 
Attached Files
zip customData.zip (11.19 KB, 5 views)

0
pshipkov

SOuP Jedi
Registered:
Posts: 4,641
Reply with quote  #10 
I didn't have the time to take a look at your problem, but glad to see you figured it out and posted the solution.
0
pshipkov

SOuP Jedi
Registered:
Posts: 4,641
Reply with quote  #11 
Btw, there is another class in the Maya API that is similar to MPxData, but does not rely on hardcoded data structure, so you can add/remove data on the fly. But it works on few predefined data types only. Which is ok in like 90% of the cases i found.
0
pshipkov

SOuP Jedi
Registered:
Posts: 4,641
Reply with quote  #12 
Maybe i should provide the name of the class, but not just talk about it. :)
MFnArrayAttrsData
0
Previous Topic | Next Topic
Print
Reply

Quick Navigation: