PDA

View Full Version : Deleting a Mesh


ypuech
04-13-2007, 08:50 AM
Hi,

In a Maya plugin, we delete a mesh and all the shading groups and shaders associated to like this:

while (fnTransform.childCount())
{
MObject child = fnTransform.child(0);
if (child.apiType() == MFn::kMesh)
{
//--- Destroy associated shading groups & shaders

fnMesh.setObject(child);

fnMesh.getConnectedShaders(0, Shaders, ShaderIndices);
for (i=0; i<Shaders.length(); ++i)
{
if (fnSet.setObject(Shaders[i]))
{
Plug = fnSet.findPlug("surfaceShader");
Plug.connectedTo(ConnectedPlugs, true, false);

if (ConnectedPlugs.length())
{
//--- Disconnect previous shader

fnDependencyNode.setObject(ConnectedPlugs[0].node());

Cmd = "delete ";
Cmd += fnDependencyNode.name();
MGlobal::executeCommand(Cmd, false, false);
}

Cmd = "delete ";
Cmd += fnSet.name();
MGlobal::executeCommand(Cmd, false, false);
}
}
}

Cmd = "delete ";
fnDagNode.setObject(child);
Cmd += fnDagNode.name();
MGlobal::executeCommand(Cmd, false, false);
}

But this code is an infinite loop...

I've modified the loop:

unsigned int childCount = fnTransform.childCount();
for(unsigned int i = 0; i < childCount; i++)
{
MObject child = fnTransform.child(i)
// etc...
}

But I'm getting an error message saying : "More than one object matching name: object name".

I think it must exists a better method to do that but I can't find it because I'm new to Maya programming. So any help appreciated :).

Robert Bateman
04-13-2007, 09:13 AM
I'm guessing that

a) use a different integer variable other than i, since that's now used for both the shader and child indices.

b) You may have either a mesh instance, or two nodes with the same name in the scene. This will require that you use the dag path names rather than the simple names, ie "|joint1|joint2|joint3" rather than "joint3". So you could do :


Cmd = "delete ";
MDagPath path;
fnDagNode.setObject(child);
fnDagNode.getPath(path);
Cmd += path.fullPathName();


or better yet, use an MDgModifier to perform the deleting.


MDgModifier dgMod;
for (unsigned j=0;j!=fnTransform.childCount();++j)
{
MObject child = fnTransform.child(j);
if (child.apiType() == MFn::kMesh)
{
//--- Destroy associated shading groups & shaders

fnMesh.setObject(child);

fnMesh.getConnectedShaders(0, Shaders, ShaderIndices);
for (i=0; i<Shaders.length(); ++i)
{
if (fnSet.setObject(Shaders[i]))
{
Plug = fnSet.findPlug("surfaceShader");
Plug.connectedTo(ConnectedPlugs, true, false);

if (ConnectedPlugs.length())
{
//--- Disconnect previous shader

dgMod.deleteNode(ConnectedPlugs[0].node());
}
dgMod.deleteNode(Shaders[i]);
}
}
}
dgMod.deleteNode(child);
}
// perform all node deletions...
dgMod.doIt();

ypuech
04-13-2007, 10:42 AM
Hi Rob,

Thanks for the reply.

Using the path solution I'm still having an infinite loop.
The MDGModifier solution makes a memory error...

Robert Bateman
04-13-2007, 10:53 AM
yes. Things such as :


while(fn.childCount())
{
if(fn.child(0)==MFn::kMesh)
{
}
else
{
// child 0 is NOT a mesh, in which case we hit an infinite loop. and will get
// here every single time.
// chances of this happening are extremely high.
// Don't do it!
}
}


whilch is what you are currently doing.... Use a for loop!


for(unsigned j=0;j!=fn.childCount();++j)
{
if(fn.child(j)==MFn::kMesh)
{
}
}


The MDGModifier solution cannot make a memory error..... You can have a bug in your code that can make a memory error (out of bounds array access maybe?), which is most likely. Use a debugger to find out where this problem is occuring, and then post back with more info. "I've got an error occuring somewhere in my code base" is not something too many of us will be able to help with i'm afraid.

ypuech
04-13-2007, 11:56 AM
With the for loop and the path name, there's still an infinite loop. Here is the code:

unsigned int childCount = fnTransform.childCount();
for(unsigned int j = 0; j < childCount; j++)
{
MObject child = fnTransform.child(j);
if (child.apiType() == MFn::kMesh)
{
//--- Destroy associated shading groups & shaders

fnMesh.setObject(child);

fnMesh.getConnectedShaders(0, Shaders, ShaderIndices);
for (i=0; i<Shaders.length(); ++i)
{
if (fnSet.setObject(Shaders[i]))
{
Plug = fnSet.findPlug("surfaceShader");
Plug.connectedTo(ConnectedPlugs, true, false);

if (ConnectedPlugs.length())
{
//--- Disconnect previous shader

fnDependencyNode.setObject(ConnectedPlugs[0].node());

Cmd = "delete ";
Cmd += fnDependencyNode.name();
MGlobal::executeCommand(Cmd, false, false);
}

Cmd = "delete ";
Cmd += fnSet.name();
MGlobal::executeCommand(Cmd, false, false);
}
}
}

Cmd = "delete ";
MDagPath path;
fnDagNode.setObject(child);
fnDagNode.getPath(path);
Cmd += path.fullPathName();
MGlobal::executeCommand(Cmd, false, false);
}

With the MDGModifier, the error happens in assembly code (dll or maya exe maybe) after the function where the mesh is deleted.

Robert Bateman
04-13-2007, 01:26 PM
Have you used a debugger to find out *why* there is an infinite loop?

ypuech
04-13-2007, 02:00 PM
Have you used a debugger to find out *why* there is an infinite loop?

Well, I found the bug...
In fact the problem comes from the use of a MProgressWindow. When I break all the code with debugger I jump into user32.dll assembly code (maybe because our plugin uses also MFC, mfc71.dll is also in the call stack...).
On the PC running Windows XP x32, the code works fine but my PC is a x64 (Maya 8.0). I've commented the use of the MProgressWindow and now it works fine. Strange....

Thanks for the help.

CGTalk Moderation
04-13-2007, 02:00 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.