PDA

View Full Version : what wrong with my boolean operation plugin? (with source)


gohkgohk
08-30-2009, 01:19 PM
I have created the following plugin, which create a sphere with each selected object vertex, and then union it with the object.
But some bad thing happened.
When i select only one vertex and run my plugin, it works fine.
but when i create one big sphere, and then use mouse to select more vertex, the boolean operations go wrong, and all thing disappear....
am i touching the bug in maya?
do anyone have any idea to fix it?
please help me! thx
here is the source. (my command called "my")
and the attachment is just the zip of code.


#include <maya/MIOStream.h>
#include <maya/MFnPlugin.h>
#include <maya/MPointArray.h>
#include <maya/MPoint.h>
#include <maya/MSelectionList.h>
#include <maya/MItSelectionList.h>
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MString.h>
#include <maya/MPxCommand.h>
#include <maya/MArgList.h>
#include <maya/MItMeshVertex.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MFnTransform.h>



#include <math.h>
#include <vector>

class ConDeform : public MPxCommand
{

public:
ConDeform();
virtual ~ConDeform();

MStatus doIt( const MArgList& );
MStatus redoIt();
MStatus undoIt();
bool isUndoable() const;
std::vector<MStringArray> FTree;
static void* creator();

public:
MStatus CreateSphere(MPoint SourcePt);
MStatus BoolOperation(MString Poly1,MString Poly2,int Mode,MStringArray& ResultArray);
MString Duplicate(MString Poly1);

};

MStatus ConDeform::doIt( const MArgList& args )
{
MStatus status;
MSelectionList activeList;
MGlobal::getActiveSelectionList(activeList);
MItSelectionList iter(activeList);
MDagPath node;
MObject component2;
MSelectionList list;
MFnDagNode nodeFn;
MString bodyname;

for ( MItSelectionList listIter( activeList ); !listIter.isDone(); listIter.next() )
{
listIter.getDagPath( node, component2 );
nodeFn.setObject( node );
MObject hisp= nodeFn.parent(0,0);
MFnDependencyNode TN(hisp);
bodyname= TN.name().asChar();
}
cout << "bodyname = " << bodyname << endl;

MPointArray ArrayPoint;
for ( ; !iter.isDone(); iter.next())
{
MObject component;
MDagPath item;
iter.getDagPath(item, component);
MStatus status;
MItMeshVertex pIter(item, component, &status);
for ( pIter.reset() ; !pIter.isDone() ; pIter.next() )
{
ArrayPoint.append(pIter.position(MSpace::kWorld,&status));
}
}
std::vector<MString> CTree;
for (int i=0;i<(int)ArrayPoint.length();++i)
{
CreateSphere(ArrayPoint[i]);
MString based =(FTree.back())[0];
MString TempBody;
TempBody=Duplicate(bodyname);
MStringArray ResultArray;
BoolOperation((FTree.back())[0],TempBody,2,ResultArray);
CTree.push_back(ResultArray[0]);
}

for (int i=0;i<(int)CTree.size();++i)
{
cout << i+1 << "/" << CTree.size() << endl;
MStringArray ResultArray;
MStatus St1=BoolOperation(bodyname,CTree[i],1,ResultArray);
bodyname=ResultArray[0];
if (St1!=MS::kSuccess)
break;
}
return MS::kSuccess;
}

MStatus ConDeform::redoIt()
{

return MS::kSuccess;
}

MStatus ConDeform::undoIt()
{
return MS::kSuccess;
}

void* ConDeform::creator()
{
return new ConDeform();
}

ConDeform::ConDeform()
{}

ConDeform::~ConDeform()
{

}

bool ConDeform::isUndoable() const
{
return false;
}

MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");

status = plugin.registerCommand( "my", ConDeform::creator );
if (!status) {
status.perror("registerCommand");
return status;
}

return status;
}

MStatus uninitializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj );

status = plugin.deregisterCommand( "my" );
if (!status) {
status.perror("deregisterCommand");
return status;
}

return status;
}

MStatus ConDeform::CreateSphere(MPoint SourcePt)
{

double max_length;
max_length=5;
MStatus status;
MStringArray result;
MString command("polySphere -ch on -o on -r 2 ;");
status = MGlobal::executeCommand(command, result, true, true);
FTree.push_back(result);

MGlobal::selectByName(result[0],MGlobal::kReplaceList);
MSelectionList activeList;
MGlobal::getActiveSelectionList(activeList);
MItSelectionList iter(activeList,MFn::kTransform);

for ( ; !iter.isDone(); iter.next())
{
MObject component;
MDagPath item;
iter.getDagPath(item, component);
MFnTransform abc(item,0);
MVector vt1;
vt1.x=SourcePt.x;
vt1.y=SourcePt.y;
vt1.z=SourcePt.z;
abc.setTranslation(vt1,MSpace::kWorld);
}

return status;
}

MStatus ConDeform::BoolOperation(MString Poly1,MString Poly2,int Mode,MStringArray& ResultArray)
{
MStatus status;
MString command("polyBoolOp -op ");
command+=Mode;
command+=" -ch 1 -useThresholds 1 -preserveColor 1 ";
command+=Poly1;
command+=" ";
command+=Poly2;
command+=";";
status = MGlobal::executeCommand(command, ResultArray, true, true);
return status;
}

MString ConDeform::Duplicate(MString Poly1)
{
MStatus status;
MStringArray result;
MString command("duplicate -rr -renameChildren -ic ");
command+=Poly1;
command+=";";
status = MGlobal::executeCommand(command, result, true, true);
return result[0];
}

davegreenwood
09-03-2009, 02:06 PM
Hi there, I've recently been looking at the boolean functions... the api version is the same as the interface version, and unfortunately there is not much chance of it working with multiple iterations. I'm currently looking out for a good boolean library. Have a look at CGAL (http://www.cgal.org/), which is a gpl licence (free to use), the booleans are robust as they deal with floating point errors. This is probably why the maya booleans fail so quickly.
The problem with a 3rd party library is you'll have to deal with getting into and out of their poly data structure... which is quite easy, and also, with much greater difficulty, you will have to figure the interpolation of your normals and UVs at the intersections. I don't know if that's built in to CGAL. If there are other libraries out there they are not very prominent... I'd love to hear if you find anything.
Dave.

CGTalk Moderation
09-03-2009, 02:06 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.