How to create an objectSet node?

How to create an objectSet node?

Anonymous
Not applicable
2,499 Views
12 Replies
Message 1 of 13

How to create an objectSet node?

Anonymous
Not applicable

Hello.

 

I want to create an objectSet in a node in maya 2016.

A possible node superclass seems to be MPxObjectSet, but i found absolutely no documentation how to initialize the dagSetMembers Attribute, which seems not to be initialized by the superclass (which doesn't have an own initialize method). I tried some possibilities, where most of them just crashed maya.

 

Then i just thought i can create a node, which has an output plug, which can be connected to objectSet.dagSetMembers (or the corresponding plug on a shape node, where the set node i connected to).

 

My current try looks like this:

 

objGroupComponentsListAttr = tAttr.create("objectGrpCompList", "gcl",
    MFnData::kComponentList, &status);
tAttr.setWritable(false);
MObject objGroupId = nAttr.create("objectGroupId", "gid", MFnNumericData::kLong, 0);
MObject objGroupColor = nAttr.create("objectGrpColor", "gco", MFnNumericData::kShort, -1);

dagSetMembersAttr = cAttr.create("dagSetMembers", "dsm", &status);
cAttr.setWritable(false);
cAttr.addChild(objGroupComponentsListAttr);
cAttr.addChild(objGroupId);
cAttr.addChild(objGroupColor);

the objGrpCompList output contains after the node computation edges like "e[0:11]" and looks just like the shape.instObjGroups[0].objectGroups[0].objGrpCompList plug in the outliner, which has a tooltip with "e[0:11]" as well, if i create a corresponding set via create->Sets->Set menu.

I cannot connect the objGripCompList directly (as it is not connectable on the Shape node), but i can connect the objectGroup plug.

 

Then i first connect a groupId node to the objGroupId plug in my generator node, then i try to connect either the generator node to the objectSet node or try to connect it to the shape node and connect the shape node to the objectSet node.

 

I did not find any connection, which made the edges appear in the set in the outliner. I am not 100% sure if i got all attributes right. I think especially the generic attribute in the objectSet probably accepts even wrong connections.

0 Likes
Accepted solutions (1)
2,500 Views
12 Replies
Replies (12)
Message 2 of 13

cheng_xi_li
Autodesk Support
Autodesk Support

Hi Alex,

 

I think it should be overriding MPxNode:postConstruct and using MFnSet

MFnSet setFn( thisMObject() );
setFn.addMembers( ... );

I haven't test it, but it should work.

 

Yours,

Li

0 Likes
Message 3 of 13

Anonymous
Not applicable

Thank you for the answer.My current problem is, that i want to create a node, which updates a set on changed input. I guess a postConstruct method will not help there on updates after the initial creation of the node.

 

Probably it should be a set connected to the node, as i want the user to be able to connect the components / removeComponents plug to edit the set.

 

What i want to achive is, that i have some input mesh, where the node extracts edges based on the shape of the mesh. Then the user should be able to see a preview (i.e. a set selection) and possibly to edit it (e.g. by connecting other sets to components/removeComponents)

0 Likes
Message 4 of 13

Anonymous
Not applicable

Attached is a screenshot how i would like the nodes to be connected to generate a edge set (seam) in my seamGen node, which is shown in the DAG as objectSet.

0 Likes
Message 5 of 13

Anonymous
Not applicable

And another possible structure, which doesn't work for me.

Something like this should be possible, shouldn't it?

0 Likes
Message 6 of 13

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

objectSets could be modified with MFnSet.

 

You can add callback to node when connection has been changed. I've written a blog about how to use node as input for your custom node, you can check it out here.

 

Yours,

Li

Message 7 of 13

Anonymous
Not applicable

Thank you. I guess using such a callback is the solution.

 

Possibly i can solve https://forums.autodesk.com/t5/maya-programming/how-to-use-assignuvs-with-an-uvsets-plug/td-p/713507... this way as well.

 

I am still a bit new and was told in other forums, you should never call code outside of the compute method, so i tried to solve both problems using input-plugs and MDataBlock only.

0 Likes
Message 8 of 13

Anonymous
Not applicable

I am still a bit unsure, how to deal with attributes in the node itself.

 

When i now want to have the seamGen node connected like this:

 

inMesh -> SeamGen

inSet -> seamGen

SeamGen.seams (unconnected)

 

Then i register a addNodeDirtyPlugCallback for inMesh (inSet doesn't change as in the camera example), i can use MFnSet on inSet and update the set members. But when i change a numeric attribute like seamGen.someNumber, i can dirty seamGen.seams but this won't run the inMesh callback, which updates the inSet.

Using a (unconnected) dummy Plug can trigger the compute function to recompute the dirty output, but I do not see how to get the callback to run again. And probably using a dummy plug or the someNumber plug is the same for this purpose anyway.

0 Likes
Message 9 of 13

Anonymous
Not applicable

What works for me:

- connectionMade and connectionBroken to determine if a set is connected

- addAttributeChangedCallback to detect if an attribute of the node was changed

 

But without a output connection, compute isn't called for changed input connections or attributes. This means i cannot detect if inMesh was changed, as long as there is no connection to seams (output plug), which shouldn't be neccessary, because the main purpose of the node is to change the objectSet (inSet plug).

 

I could not yet test MFnSet on the inSet plug, but i assume this will work as soon as i get the calculation of the output data calculated on changes of the input data.

 

0 Likes
Message 10 of 13

Anonymous
Not applicable

There are even more problems.

I can get the set, all needed callbacks and change events and by triggering a MPlug.getValue() i can get the attributeChanged callback to run the compute() method.

 

But when i then select edges from the inMesh, i cannot add them to the set, as this needs an additional dagPath(pointing to inMesh).

A mesh input to a node only provides geometry, but no dag object, so i cannot add the edge. Using DagPath::getAPathTo doesn't work, none of the MFn... objects have working .dagPath() methods and adding MObjects without a dagPath to the set doesn't work.

 

0 Likes
Message 11 of 13

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

Have you tried to get the source of inMesh plug?  You should be able to get the input mesh node with it(MPlug::node) and you should be able to get a vaild dag path with MDagPath::getAPathTo,

 

Yours,

Li

0 Likes
Message 12 of 13

Anonymous
Not applicable
I think i found yesterday a way. I can get the inMesh with a dagPath
like you said. I do not get a dagPath to the set, but I can construct a
working MFnSet and can add Elements to the set.
I will post a summary how I get it working later.
0 Likes
Message 13 of 13

Anonymous
Not applicable
Accepted solution

Its working. I got it that way:

 

Inputs:

- inputMesh

- inSet (optional)

 

Output:

- outEdges (optional)

 

Callbacks:

- In connectionMade I store the inMesh dagPath and the inSet node in a private variable, as well as a flag that it's connected. If the inSet is connected, i add the edges from the private MComponentListData variable to the set.

- In connectionBroken I reset the connected flags and clear the private MComponentListData variable.

- In attributeChanged:

-- If the attribute is outEdges, I update the set, by creating a MFnSet for the inSetNode and add the edges with addMember(inMeshDagPath, componentListData[i])

-- if inMesh is changed, I call findPlug("outEdges").getValue(obj) to trigger the compute method, even when nothing is connected to outEdges.

- In the compute method I calculate the list of edges, store them in a private MComponentListData  variable and output them to the outEdges plug in the MDataBlock.

 

So i get the following features:

- When connecting or changing the inMesh, this recalculates the outEdges plug and if a set is connected, the edges are put into the set.

- When connecting a inSet, the current edge list (may be empty) is put into the set.

- the outEdges plug always contains the current edge list (may be empty).

- When disconnecting the inMesh, the edge list is cleared.

 

The only strange thing with the node is, that the set is connected to an input plug instead of an output plug. But otherwise i would need assumptions about the input plugs on the set object.

0 Likes