Exemplo n.º 1
0
MStatus intersectCmd::doIt(const MArgList& args)

// Description:
// 		Determine if the ray from the spotlight intersects the mesh.
//		If it does, display the intersection points.

{
	MStatus stat = MStatus::kSuccess;

	if (args.length() != 2) 
	{
		MGlobal::displayError("Need 2 items!");
		return MStatus::kFailure;
	}

	MSelectionList activeList;
	int i;
	
	for ( i = 0; i < 2; i++)
	{
		MString strCurrSelection;
		stat = args.get(i, strCurrSelection);
		if (MStatus::kSuccess == stat) activeList.add(strCurrSelection);
	}

	MItSelectionList iter(activeList);
	MFnSpotLight fnLight;  
	MFnMesh fnMesh;
	MFnDagNode dagNod;
	MFnDependencyNode fnDN;

	float fX = 0;
	float fY = 0;
	float fZ = 0;

	for ( ; !iter.isDone(); iter.next() )
	{
		MObject tempObjectParent, tempObjectChild;
		iter.getDependNode(tempObjectParent);

		if (tempObjectParent.apiType() == MFn::kTransform)
		{
			dagNod.setObject(tempObjectParent);
			tempObjectChild = dagNod.child(0, &stat);
		}

		// check what type of object is selected
		if (tempObjectChild.apiType() == MFn::kSpotLight)
		{
			MDagPath pathToLight;
			MERR_CHK(MDagPath::getAPathTo(tempObjectParent, pathToLight), "Couldn't get a path to the spotlight");
			MERR_CHK(fnLight.setObject(pathToLight), "Failure on assigning light");
			
			stat = fnDN.setObject(tempObjectParent);

			MPlug pTempPlug = fnDN.findPlug("translateX", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fX);
			}

			pTempPlug = fnDN.findPlug("translateY", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fY);
			}

			pTempPlug = fnDN.findPlug("translateZ", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fZ);
			}	
		}
		else if (tempObjectChild.apiType() == MFn::kMesh)
		{
			MDagPath pathToMesh;
			MERR_CHK(MDagPath::getAPathTo(tempObjectChild, pathToMesh), "Couldn't get a path to the spotlight");
			MERR_CHK(fnMesh.setObject(pathToMesh), "Failure on assigning light");	
		}
		else
		{
			MGlobal::displayError("Need a spotlight and a mesh");
			return MStatus::kFailure;
		}
	}

	MFloatPoint fpSource(fX, fY, fZ);
	MFloatVector fvRayDir = fnLight.lightDirection(0, MSpace::kWorld, &stat);
	MFloatPoint hitPoint;
	
	MMeshIsectAccelParams mmAccelParams = fnMesh.autoUniformGridParams();
	
	float fHitRayParam, fHitBary1, fHitBary2;
	int nHitFace, nHitTriangle;

	// a large positive number is used here for the maxParam parameter
	bool bAnyIntersection = fnMesh.anyIntersection(fpSource, fvRayDir, NULL, NULL, false,				MSpace::kWorld, (float)9999, false, &mmAccelParams, hitPoint, &fHitRayParam, &nHitFace, &nHitTriangle, 		&fHitBary1, &fHitBary2, (float)1e-6, &stat);
	
	if (! bAnyIntersection) 
	{
		MGlobal::displayInfo("There were no intersection points detected");
		return stat;
	}

	MFloatPointArray hitPoints;
	MFloatArray faHitRayParams;
	MIntArray iaHitFaces;
	MIntArray iaHitTriangles;
	MFloatArray faHitBary1;
	MFloatArray faHitBary2;

	bool bAllIntersections = fnMesh.allIntersections(fpSource, fvRayDir, NULL, NULL, false, MSpace::kWorld, 9999, false, NULL, false, hitPoints, &faHitRayParams, &iaHitFaces, &iaHitTriangles, &faHitBary1, &faHitBary2, 0.000001f, &stat);
	
	if (! bAllIntersections)
	{
		MGlobal::displayInfo("Error getting all intersections");
		return stat;
	}
	
	// check how many intersections are found
	unsigned int nNumberHitPoints = hitPoints.length();

	if (! nNumberHitPoints)
	{
		MGlobal::displayInfo("No hit points detected");
		return MStatus::kSuccess;
	}

	// Intersection exists; display intersections as spheres
	MString strCommandString = "string $strBall[] = `polySphere -r 0.5`;";
	strCommandString += "$strBallName = $strBall[0];";

	float x = 0;
	float y = 0;
	float z = 0;

	for (i = 0; i < (int)nNumberHitPoints; i++)
	{
		// get the points
		x = hitPoints[i][0];
		y = hitPoints[i][1];
		z = hitPoints[i][2];

		// execute some MEL to create a small sphere
		strCommandString += "setAttr ($strBallName + \".tx\") ";
		strCommandString += x;
		strCommandString += ";";

		strCommandString += "setAttr ($strBallName + \".ty\") ";
		strCommandString += y;
		strCommandString += ";";

		strCommandString += "setAttr ($strBallName + \".tz\") ";
		strCommandString += z;
		strCommandString += ";";

		MGlobal::executeCommand(strCommandString);
	}

	return stat;
}
Exemplo n.º 2
0
	// ==========================================================================================================
	// ==========================================================================================================
	virtual MStatus compute(const MPlug& plug, MDataBlock& dataBlock)
	{

		// enable this node or not
		if ( dataBlock.inputValue(aEnable).asBool() == false )
		{
			return MS::kSuccess;
		}

		// check if the inpute attribute is connected
		// in Not, stop compute()
		// in order to avoid crash when disconnect input attributes on the fly 
		
		//cout << "isPlugConnect: " << isPlugConnect(aVolumeObj) << endl;
		
		if ( isPlugConnect(aSourceObj) == false || isPlugConnect(aVolumeObj) == false )
		{
			return MS::kSuccess;
		}

		// execution when output attr needs to be updated
		if ( plug == aOutValue || plug == aOutMesh || plug == aOutCompList )
		{
			// test if input source object is a valid type
			if ( dataBlock.inputValue(aSourceObj).type() != MFnData::kMesh )
			{
				MGlobal::displayInfo( MString("No Object Input!") ); 
				return MS::kSuccess;
			}

			MObject sourceObj = dataBlock.inputValue(aSourceObj).asMeshTransformed();

			MArrayDataHandle arrayHandle = dataBlock.inputValue(aVolumeObj);
			arrayHandle.jumpToArrayElement(0);

			MSelectionList sList;		// add the vertice every ligal loop 
			for ( int idx=0; idx < arrayHandle.elementCount(); idx++, arrayHandle.next() )
			{

				// first, check if the sub-plug is un-connected
				if ( isPlugConnect( aVolumeObj, idx ) == false  )
				{
					cout << "No Data " << idx << endl;
					continue;
				}

				// second, check if the input object is mesh
				if ( arrayHandle.inputValue().type() != MFnData::kMesh )
				{
					return MS::kSuccess;
					MGlobal::displayError( "input voulme objects is not mesh" );
				}

				// input volume object as Wrold mesh
				MObject volumeObj = arrayHandle.inputValue().asMeshTransformed();

				MFnMesh sourceMeshFn;
				MFnMesh volumeMeshFn;

				// third, test if the input obj is compatible with meshFn
				if ( volumeMeshFn.hasObj(sourceObj) && volumeMeshFn.hasObj(volumeObj) )
				{
					volumeMeshFn.setObject(volumeObj);

					// check if object is closed
					if ( isClosedMesh(volumeObj) == false )
					{
						if ( dataBlock.inputValue(aClosedObj).asBool() == true )
						{
							//MGlobal::displayInfo( MString("The volume object is not closed!") );
							continue;
						}
					}

					sourceMeshFn.setObject( sourceObj );
					int numVtx = sourceMeshFn.numVertices();

					vector<int> tmpCompArray;	// an temporary int array to store component index

					// do hit test
					// to check if each source's component is inside
					//
					for ( int i=0; i < numVtx; i++ )
					{
						// get each vertex of source object
						MPoint srcVtx;
						sourceMeshFn.getPoint( i, srcVtx, MSpace::kWorld );

						// Test how much hit is for each vertex 
						// declare parameters for allIntersection()
						MFloatPoint raySource;
						raySource.setCast(srcVtx);

						MFloatVector rayDirection(0, 0, 1);
						MFloatPointArray hitPoints;
						MIntArray hitFaces;

						bool hit = volumeMeshFn.allIntersections( raySource,
																	rayDirection,
																	NULL,
																	NULL,
																	false,
																	MSpace::kWorld,
																	99999,
																	false,
																	NULL,
																	true,
																	hitPoints,
																	NULL,
																	&hitFaces,
																	NULL,
																	NULL,
																	NULL,
																	1e-6 );

						if (hit)
						{
							int isInside = hitFaces.length() % 2;
							// cout << "isInside: " << isInside << endl;

							// if the mod is odd, it's inside
							if ( isInside > 0 )
							{
								tmpCompArray.push_back(i);
							}
						}
					}

					// declare a dynamic array to recieve All elements from tmpCompArray
					int* compArray = new int[tmpCompArray.size()];

					// copy array data from tmpCompArray --> compArray
					memcpy( &compArray[0], &tmpCompArray[0], sizeof( int ) * tmpCompArray.size() );


					// the below processes are to collect component data, and then select them in viewport
					//
					// first, get dagPath from the source object 
					MDagPath dPathSrcObj = getConnectNodeDagPath(aSourceObj);


					// second, get the selection list storing components by feeding comopnet array  
					MSelectionList vtxSelList = getVtxSelList( dPathSrcObj, compArray, tmpCompArray.size() );
					sList.merge(vtxSelList);

					delete [] compArray;
				}
			}
			// end of loop


			// if so, actively select these component
			int compType = dataBlock.inputValue(aComponentType).asInt();
			MSelectionList currCompSelList;

			if( dataBlock.inputValue(aKeepSel).asBool() == true )
			{
				// clear if last-time is not keep selection
				if (flag==0)
				{
					addSelComponentList.clear();
					flag = 1; 
				}
				else
				{
					addSelComponentList.merge(sList);	// merge the accumulative components
					currCompSelList = convertVtxSListToCompSList( addSelComponentList, compType );
					MGlobal::setActiveSelectionList( currCompSelList, MGlobal::kReplaceList );
					flag = 1;
				}
			}
			else
			{
				addSelComponentList.clear();	// celar all components
				addSelComponentList.merge(sList);
				currCompSelList = convertVtxSListToCompSList( addSelComponentList, compType );
				MGlobal::setActiveSelectionList( currCompSelList, MGlobal::kReplaceList );
				flag = 0;
			}

			// keep this node selecting 
			if ( dataBlock.inputValue(aFixPanel).asBool() == true )
				MGlobal::select( thisMObject(), MGlobal::kAddToList );


			// **** OUTPUT ATTRIBUTE ****
			MObject currCompList = getCompListFromSList( currCompSelList );
			
			MFnComponentListData compListDataFn;
			MObject currCompListData = compListDataFn.create();		// pointer to the component data
			compListDataFn.add( currCompList );

			dataBlock.outputValue(aOutCompList).set( currCompListData );
			
			// 
			MFnMeshData outMeshDataFn;
			MObject outObj = outMeshDataFn.create();
			MFnMesh outMeshFn( outObj );
			outMeshFn.copy( sourceObj, outObj );

			dataBlock.outputValue(aOutMesh).set( outObj );
		}		
		// end of if ( plug == aOutValue || plug == aOutMesh )

		return MS::kSuccess;
	}