Beispiel #1
0
bool
MayaPrimWriter::writePrimAttrs(const MDagPath &dagT, const UsdTimeCode &usdTime, UsdGeomImageable &primSchema) 
{
    MStatus status;
    MFnDependencyNode depFn(getDagPath().node());
    MFnDependencyNode depFn2(dagT.node()); // optionally also scan a shape's transform if merging transforms

    if (getArgs().exportVisibility) {
        bool isVisible  = true;   // if BOTH shape or xform is animated, then visible
        bool isAnimated = false;  // if either shape or xform is animated, then animated

        PxrUsdMayaUtil::getPlugValue(depFn, "visibility", &isVisible, &isAnimated);

        if ( dagT.isValid() ) {
            bool isVis, isAnim;
            if (PxrUsdMayaUtil::getPlugValue(depFn2, "visibility", &isVis, &isAnim)){
                isVisible = isVisible and isVis;
                isAnimated = isAnimated or isAnim;
            }
        }

        TfToken const &visibilityTok = (isVisible ? UsdGeomTokens->inherited : 
                                        UsdGeomTokens->invisible);
        if (usdTime.IsDefault() != isAnimated ) {
            if (usdTime.IsDefault())
                primSchema.CreateVisibilityAttr(VtValue(visibilityTok), true);
            else
                primSchema.CreateVisibilityAttr().Set(visibilityTok, usdTime);
        }
    }

    UsdPrim usdPrim = primSchema.GetPrim();

    // There is no Gprim abstraction in this module, so process the few
    // gprim attrs here.
    UsdGeomGprim gprim = UsdGeomGprim(usdPrim);
    if (gprim and usdTime.IsDefault()){

        PxrUsdMayaPrimWriterContext* unused = NULL;
        PxrUsdMayaTranslatorGprim::Write(
                getDagPath().node(),
                gprim,
                unused);

    }

    _writeUsdInfo(dagT, usdTime, usdPrim);
    
    // Write user-tagged export attributes. Write attributes on the transform
    // first, and then attributes on the shape node. This means that attribute
    // name collisions will always be handled by taking the shape node's value
    // if we're merging transforms and shapes.
    if (dagT.isValid() and !(dagT == getDagPath())) {
        PxrUsdMayaWriteUtil::WriteUserExportedAttributes(dagT, usdPrim, usdTime);
    }
    PxrUsdMayaWriteUtil::WriteUserExportedAttributes(getDagPath(), usdPrim, usdTime);

    return true;
}
void geometryReplicatorGeometryOverride::updateDG()
{
	if (!fPath.isValid()) {
		MFnDependencyNode fnThisNode(fThisNode);

		MObject messageAttr = fnThisNode.attribute("message");
		MPlug messagePlug(fThisNode, messageAttr);

		MPlugArray connections;
		if (messagePlug.connectedTo(connections, false, true)) {
			for (unsigned int i = 0; i < connections.length(); ++i) {
				MObject node = connections[i].node();
				if (node.hasFn(MFn::kMesh) ||
					node.hasFn(MFn::kNurbsSurface) ||
					node.hasFn(MFn::kNurbsCurve) ||
					node.hasFn(MFn::kBezierCurve))
				{
					MDagPath path;
					MDagPath::getAPathTo(node, path);

					fPath = path;
					fType = path.apiType();

					break;
				}
			}
		}
	}
}
bool					
DX11ResourceManager::translateCamera( const MDagPath &cameraPath )
//
// Description:
//		Translate Maya's camera 
//
{
	bool translatedCamera = false;
	if (cameraPath.isValid())
	{
		MStatus status;
		MFnCamera camera (cameraPath, &status);
		if ( !status ) {
			status.perror("MFnCamera constructor");
		}
		else
		{
			translatedCamera = true;

			MPoint eyePoint = camera.eyePoint( MSpace::kWorld );
			MPoint lookAtPt	= camera.centerOfInterestPoint( MSpace::kWorld );
			MVector	upDirection = camera.upDirection ( MSpace::kWorld );
			MFloatMatrix projMatrix = camera.projectionMatrix();

			double horizontalFieldOfView = MAngle( /* camera.verticalFieldOfView() / */ camera.horizontalFieldOfView()
				).asDegrees();
			double nearClippingPlane = camera.nearClippingPlane();
			double farClippingPlane = camera.farClippingPlane();

			// Convert API values to internal native storage.
			//
			m_camera.m_vEyePt = XMFLOAT3((float)eyePoint.x, (float)eyePoint.y, (float)eyePoint.z);
			m_camera.m_vLookatPt = XMFLOAT3((float)lookAtPt.x, (float)lookAtPt.y, (float)lookAtPt.z);
			m_camera.m_vUpVec = XMFLOAT3((float)upDirection.x, (float)upDirection.y, (float)upDirection.z);
			m_camera.m_FieldOfView = (float)horizontalFieldOfView;
			m_camera.m_nearClip = (float)nearClippingPlane;
			m_camera.m_farClip = (float)farClippingPlane;
			m_camera.m_isOrtho = camera.isOrtho();
		}
	}
	else
	{
		initializeDefaultCamera();
	}
	return translatedCamera;
}
MStatus InstanceCallbackCmd::doIt( const MArgList& args )
{
	
	MStatus status = MS::kSuccess;

	// Draw a circle and get its dagPath
	// using an iterator
	MGlobal::executeCommand("circle");
	MFnNurbsCurve circle;
		
	
	MDagPath dagPath;
	MItDependencyNodes iter( MFn::kNurbsCurve , &status);

	for(iter.reset(); !iter.isDone() ; iter.next())
	{
		MObject item = iter.item();
		if(item.hasFn(MFn::kNurbsCurve))
		{
			circle.setObject(item);
			circle.getPath(dagPath);
			MGlobal::displayInfo("DAG_PATH is " + dagPath.fullPathName());
			
			if(dagPath.isValid())
			{
				// register callback for instance add AND remove
				//
				MDagMessage::addInstanceAddedCallback   ( dagPath,addCallbackFunc,	NULL, &status);
				MDagMessage::addInstanceRemovedCallback ( dagPath,remCallbackFunc,	NULL, &status);

				MGlobal::displayInfo("CALLBACK ADDED FOR INSTANCE ADD/REMOVE");
				
			}
			
		}
	}

	
	if (status != MS::kSuccess)
	{
		MGlobal::displayInfo("STATUS RETURNED IS NOT SUCCESS");
	}
	
	return status;
}
void geometryReplicatorGeometryOverride::populateGeometry(
	const MGeometryRequirements& requirements,
	const MRenderItemList& renderItems,
	MGeometry& data)
{
	if (!fPath.isValid())
		return;

	// MGeometryExtractor::MGeometryExtractor.
	// here, fPath is the path of the linked object instead of the plugin node; it
	// is used to determine the right type of the geometry shape, e.g., polygon
	// or NURBS surface.
	// The sharing flag (true here) is just for the polygon shape.
	MStatus status;
	MPolyGeomOptions options = kPolyGeom_Normal;
	if( isBaseMesh() ) options = options|kPolyGeom_BaseMesh;
	MGeometryExtractor extractor(requirements, fPath, options, &status);
	if (MS::kFailure == status)
		return;

	// fill vertex buffer
	const MVertexBufferDescriptorList& descList = requirements.vertexRequirements();
	for (int reqNum = 0; reqNum < descList.length(); ++reqNum)
	{
		MVertexBufferDescriptor desc;
		if (!descList.getDescriptor(reqNum, desc))
		{
			continue;
		}

		switch (desc.semantic())
		{
		case MGeometry::kPosition:
		case MGeometry::kNormal:
		case MGeometry::kTexture:
		case MGeometry::kTangent:
		case MGeometry::kBitangent:
		case MGeometry::kColor:
			{
				MVertexBuffer* vertexBuffer = data.createVertexBuffer(desc);
				if (vertexBuffer) {
					// MGeometryExtractor::vertexCount and MGeometryExtractor::populateVertexBuffer.
					// since the plugin node has the same vertex data as its linked scene object,
					// call vertexCount to allocate vertex buffer of the same size, and then call
					// populateVertexBuffer to copy the data.
					unsigned int vertexCount = extractor.vertexCount();
					float* data = (float*)vertexBuffer->acquire(vertexCount, true /*writeOnly - we don't need the current buffer values*/);
					if (data) {
						status = extractor.populateVertexBuffer(data, vertexCount, desc);
						if (MS::kFailure == status)
							return;
						vertexBuffer->commit(data);
					}
				}
			}
			break;

		default:
			// do nothing for stuff we don't understand
			break;
		}
	}

	// fill index buffer
	for (int i = 0; i < renderItems.length(); ++i)
	{
		const MRenderItem* item = renderItems.itemAt(i);
		if (!item) continue;

		MIndexBuffer* indexBuffer = data.createIndexBuffer(MGeometry::kUnsignedInt32);
		if (!indexBuffer) continue;

		// MGeometryExtractor::primitiveCount and MGeometryExtractor::populateIndexBuffer.
		// since the plugin node has the same index data as its linked scene object,
		// call primitiveCount to allocate index buffer of the same size, and then call
		// populateIndexBuffer to copy the data.
		if (item->primitive() == MGeometry::kTriangles)
		{
			MIndexBufferDescriptor triangleDesc(MIndexBufferDescriptor::kTriangle, MString(), MGeometry::kTriangles, 3);
			unsigned int numTriangles = extractor.primitiveCount(triangleDesc);

			unsigned int* indices = (unsigned int*)indexBuffer->acquire(3 * numTriangles, true /*writeOnly - we don't need the current buffer values*/);
			status = extractor.populateIndexBuffer(indices, numTriangles, triangleDesc);
			if (MS::kFailure == status)
				return;
			indexBuffer->commit(indices);
		}
		else if (item->primitive() == MGeometry::kLines)
		{
			MIndexBufferDescriptor edgeDesc(MIndexBufferDescriptor::kEdgeLine, MString(), MGeometry::kLines, 2);
			unsigned int numEdges = extractor.primitiveCount(edgeDesc);

			unsigned int* indices = (unsigned int*)indexBuffer->acquire(2 * numEdges, true /*writeOnly - we don't need the current buffer values*/);
			status = extractor.populateIndexBuffer(indices, numEdges, edgeDesc);
			if (MS::kFailure == status)
				return;
			indexBuffer->commit(indices);
		}

		item->associateWithIndexBuffer(indexBuffer);
	}
}
void geometryReplicatorGeometryOverride::updateRenderItems(
	const MDagPath& path,
	MRenderItemList& list)
{
	if (!fPath.isValid())
		return;
	MRenderer* renderer = MRenderer::theRenderer();
	if (!renderer)
		return;
	const MShaderManager* shaderManager = renderer->getShaderManager();
	if (!shaderManager)
		return;

	if (fType == MFn::kNurbsCurve || fType == MFn::kBezierCurve)
	{
		// add render items for drawing curve
		MRenderItem* curveItem = NULL;
		int index = list.indexOf("geometryReplicatorCurve");
		if (index < 0)
		{
			curveItem = MRenderItem::Create("geometryReplicatorCurve", MRenderItem::NonMaterialSceneItem, MGeometry::kLines);
			curveItem->setDrawMode(MGeometry::kAll);
			list.append(curveItem);

			MShaderInstance* shader = shaderManager->getStockShader(MShaderManager::k3dSolidShader);
			if (shader) {
				static const float theColor[] = {1.0f, 0.0f, 0.0f, 1.0f};
				shader->setParameter("solidColor", theColor);

				curveItem->setShader(shader);
				shaderManager->releaseShader(shader);
			}
		}
		else {
			curveItem = list.itemAt(index);
		}
		if (curveItem) {
			curveItem->enable(true);
		}
	}
	else if (fType == MFn::kMesh)
	{
		// add render item for drawing wireframe on the mesh
		MRenderItem* wireframeItem = NULL;
		int index = list.indexOf("geometryReplicatorWireframe");
		if (index < 0)
		{
			wireframeItem = MRenderItem::Create("geometryReplicatorWireframe", MRenderItem::DecorationItem, MGeometry::kLines);
			wireframeItem->setDrawMode(MGeometry::kWireframe);
			wireframeItem->depthPriority(MRenderItem::sActiveWireDepthPriority);
			list.append(wireframeItem);

			MShaderInstance* shader = shaderManager->getStockShader(MShaderManager::k3dSolidShader);
			if (shader) {
				static const float theColor[] = {1.0f, 0.0f, 0.0f, 1.0f};
				shader->setParameter("solidColor", theColor);

				wireframeItem->setShader(shader);
				shaderManager->releaseShader(shader);
			}
		}
		else {
			wireframeItem = list.itemAt(index);
		}
		if (wireframeItem) {
			wireframeItem->enable(true);
		}

		// disable StandardShadedItem if CPV is shown.
		bool showCPV = isCPVShown();
		index = list.indexOf("StandardShadedItem", MGeometry::kTriangles, MGeometry::kShaded);
		if (index >= 0) {
			MRenderItem* shadedItem = list.itemAt(index);
			if (shadedItem) {
				shadedItem->enable(!showCPV);
			}
		}
		index = list.indexOf("StandardShadedItem", MGeometry::kTriangles, MGeometry::kTextured);
		if (index >= 0) {
			MRenderItem* shadedItem = list.itemAt(index);
			if (shadedItem) {
				shadedItem->enable(!showCPV);
			}
		}

		// add item for CPV.
		index = list.indexOf("geometryReplicatorCPV");
		if (index >= 0) {
			MRenderItem* cpvItem = list.itemAt(index);
			if (cpvItem) {
				cpvItem->enable(showCPV);
			}
		}
		else {
			// if no cpv item and showCPV is true, created the cpv item.
			if (showCPV) {
				MRenderItem* cpvItem = MRenderItem::Create("geometryReplicatorCPV", MRenderItem::MaterialSceneItem, MGeometry::kTriangles);
				cpvItem->setDrawMode((MGeometry::DrawMode)(MGeometry::kShaded|MGeometry::kTextured));
				list.append(cpvItem);

				MShaderInstance* shader = shaderManager->getStockShader(MShaderManager::k3dCPVSolidShader);
				if (shader) {
					cpvItem->setShader(shader);
					if (cpvItem) {
						cpvItem->enable(true);
					}
					shaderManager->releaseShader(shader);
				}
			}
		}
	}
}
Beispiel #7
0
ConstObjectPtr LiveScene::readAttribute( const Name &name, double time ) const
{
	if ( !m_isRoot && m_dagPath.length() == 0 )
	{
		throw Exception( "IECoreMaya::LiveScene::readAttribute: Dag path no longer exists!" );
	}
	
	tbb::mutex::scoped_lock l( s_mutex );
	if ( !m_isRoot )
	{

		if( name == SceneInterface::visibilityName )
		{
			bool visible = true;

			MStatus st;
			MFnDagNode dagFn( m_dagPath );
			MPlug visibilityPlug = dagFn.findPlug( MPxTransform::visibility, &st );
			if( st )
			{
				visible = visibilityPlug.asBool();
			}

			if( visible )
			{
				MDagPath childDag;

				// find an object that's either a SceneShape, or has a cortex converter and check its visibility:
				unsigned int childCount = 0;
				m_dagPath.numberOfShapesDirectlyBelow(childCount);

				for ( unsigned int c = 0; c < childCount; c++ )
				{
					MDagPath d = m_dagPath;
					if( d.extendToShapeDirectlyBelow( c ) )
					{
						MFnDagNode fnChildDag(d);
						if( fnChildDag.typeId() == SceneShape::id )
						{
							childDag = d;
							break;
						}

						if ( fnChildDag.isIntermediateObject() )
						{
							continue;
						}

						FromMayaShapeConverterPtr shapeConverter = FromMayaShapeConverter::create( d );
						if( shapeConverter )
						{
							childDag = d;
							break;
						}

						FromMayaDagNodeConverterPtr dagConverter = FromMayaDagNodeConverter::create( d );
						if( dagConverter )
						{
							childDag = d;
							break;
						}
					}
				}

				if( childDag.isValid() )
				{
					MFnDagNode dagFn( childDag );
					MPlug visibilityPlug = dagFn.findPlug( MPxSurfaceShape::visibility, &st );
					if( st )
					{
						visible = visibilityPlug.asBool();
					}
				}

			}

			return new BoolData( visible );
		}

	}
	else if( name == SceneInterface::visibilityName )
	{
		return new BoolData( true );
	}

	std::vector< CustomAttributeReader > &attributeReaders = customAttributeReaders();
	for ( std::vector< CustomAttributeReader >::const_reverse_iterator it = attributeReaders.rbegin(); it != attributeReaders.rend(); ++it )
	{
		ConstObjectPtr attr = it->m_read( m_dagPath, name );
		if( !attr )
		{
			continue;
		}
		return attr;
	}

	if( strstr( name.c_str(), "user:"******"ieAttr_" + name.string().substr(5) ).c_str(), false, &st );
		if( st )
		{
			FromMayaConverterPtr plugConverter = FromMayaPlugConverter::create( attrPlug );
			if( !plugConverter )
			{
				return IECore::NullObject::defaultNullObject();
			}
			return plugConverter->convert();
		}
	}

	return IECore::NullObject::defaultNullObject();
}
bool DX11ViewportRenderer::drawScene(const MRenderingInfo &renderInfo)
//
// Description:
//		Draw the Maya scene, using a custom traverser.
//
{
	bool useDrawTraversal = true;
	float groundPlaneColor[3] = { 0.8f, 0.8f, 0.8f };

	if (useDrawTraversal)
	{
		const MDagPath &cameraPath = renderInfo.cameraPath();
		if (cameraPath.isValid())
		{
			// You can actually keep the traverser classes around
			// if desired. Here we just create temporary traversers
			// on the fly.
			//
			MDrawTraversal *trav = new MDrawTraversal;
			if (!trav)
			{
				MGlobal::displayWarning("DX11 renderer : failed to create a traversal class !\n");
				return true;
			}

			trav->enableFiltering( false );

			const MRenderTarget &renderTarget = renderInfo.renderTarget();
			trav->setFrustum( cameraPath, renderTarget.width(), 
							  renderTarget.height() );

			if (!trav->frustumValid())
			{
				MGlobal::displayWarning("DX11 renderer : Frustum is invalid !\n");
				return true;
			}

			trav->traverse();

			unsigned int numItems = trav->numberOfItems();
			unsigned int i;
			for (i=0; i<numItems; i++)
			{
				MDagPath path;
				trav->itemPath(i, path);

				if (path.isValid())
				{
					bool drawIt = false;

					// Default traverer may have view manips showing up.
					// This is currently a known Maya bug.
					if ( path.hasFn( MFn::kViewManip ))
						continue;

					//
					// Draw surfaces (polys, nurbs, subdivs)
					//
					bool active = false;
					bool templated = false;
					if ( path.hasFn( MFn::kMesh) || 
						 path.hasFn( MFn::kNurbsSurface) || 
						 path.hasFn( MFn::kSubdiv) )
					{
						drawIt = true;
						if (trav->itemHasStatus( i, MDrawTraversal::kActiveItem ))
						{
							active = true;
						}
						if (trav->itemHasStatus( i, MDrawTraversal::kTemplateItem ))
						{
							templated = true;
						}
					}

					//
					// Draw the ground plane
					//
					else if (path.hasFn( MFn::kSketchPlane ) ||
							 path.hasFn( MFn::kGroundPlane ))
					{
						MMatrix  matrix = path.inclusiveMatrix();
						MFnDagNode dagNode(path);
						MBoundingBox box = dagNode.boundingBox();
						drawBounds( matrix, box, groundPlaneColor );
					}

					if (drawIt)
					{
						drawSurface( path, active, templated );
					}
				}
			}

			if (trav)
				delete trav;

			// Cleanup any unused resource items
			bool onlyInvalidItems = true;
			clearResources( onlyInvalidItems, false );
		}
	}
	else
	{
		// Draw some poly bounding boxes 
		//
		MItDag::TraversalType traversalType = MItDag::kDepthFirst;
		MFn::Type filter = MFn::kMesh;
		MStatus status;

		MItDag dagIterator( traversalType, filter, &status);

		for ( ; !dagIterator.isDone(); dagIterator.next() ) 
		{

			MDagPath dagPath;

			status = dagIterator.getPath(dagPath);
			if ( !status ) {
				status.perror("MItDag::getPath");
				continue;
			}

			MFnDagNode dagNode(dagPath, &status);
			if ( !status ) {
				status.perror("MFnDagNode constructor");
				continue;
			}

			MMatrix  matrix = dagPath.inclusiveMatrix();
			MBoundingBox box = dagNode.boundingBox();
			drawBounds( matrix, box, groundPlaneColor );
		}
	}
	return true;
}
Beispiel #9
0
MStatus dagMessageCmd::doIt( const MArgList& args)
//
// Takes the  nodes that are on the active selection list and adds an
// attriubte changed callback to each one.
//
{
	MStatus 		status;
	MSelectionList 	list;
    MArgDatabase argData(syntax(), args);

	status = argData.getObjects(list);
	if (MS::kSuccess != status) {
		MGlobal::displayError("Error getting objects");
		return status;
	}

	//	Get the flags
	//
	bool allDagUsed = argData.isFlagSet(kAllDagFlag);
	bool parentAddedUsed = argData.isFlagSet(kParentAddedFlag);
	bool parentRemovedUsed = argData.isFlagSet(kParentRemovedFlag);
	bool childAddedUsed = argData.isFlagSet(kChildAddedFlag);
	bool childRemovedUsed = argData.isFlagSet(kChildRemovedFlag);
	bool childReorderedUsed = argData.isFlagSet(kChildReorderedFlag);
	bool helpUsed = argData.isFlagSet(kHelpFlag);

	bool nothingSet = (	!allDagUsed && !parentAddedUsed && 
						!parentRemovedUsed && !childAddedUsed && 
						!childRemovedUsed && !childReorderedUsed && 
						!helpUsed);

	if (nothingSet) {
		MGlobal::displayError("A flag must be used. dagMessage -help for availible flags.");
		return MS::kFailure;
	}

	if (argData.isFlagSet(kHelpFlag)) {
		MGlobal::displayInfo("dagMessage -help");
		MGlobal::displayInfo("\tdagMessage adds a callback to the selected nodes,");
		MGlobal::displayInfo("\tor if no nodes are selected, to all nodes. The callback");
		MGlobal::displayInfo("\tprints a message when called. When the plug-in is unloaded");
		MGlobal::displayInfo("\tthe callbacks are removed.");
		MGlobal::displayInfo("");
		MGlobal::displayInfo("\t-h -help : This message is printed");
		MGlobal::displayInfo("\t-ad -allDag : parent changes and child reorders");
		MGlobal::displayInfo("\t-pa -parentAdded : A parent is added");
		MGlobal::displayInfo("\t-pr -parentRemoved : A parent is removed");
		MGlobal::displayInfo("\t-ca -childAdded : A child is added (only for individual nodes)");
		MGlobal::displayInfo("\t-cr -childRemoved : A child is removed (only for individual nodes)");
		MGlobal::displayInfo("\t-cro -childReordered : A child is reordered");
		MGlobal::displayInfo("");
	}

	unsigned nObjs = list.length();
	if (nObjs == 0) {
		//	Add the callback for all changes of the specified type.
		//
		if (allDagUsed) {
			MCallbackId id = MDagMessage::addAllDagChangesCallback(userDAGGenericCB, NULL, &status);
			if (status) {
				callbackIds.append( id );
				MGlobal::displayInfo("Added a callback for all Dag changes on all nodes.\n");
			} else {
				MGlobal::displayError("Could not add a -allDag callback");
				return status;
			}
		}

		if (parentAddedUsed) {
			status = addGenericCallback(NULL, 
										MDagMessage::kParentAdded,
										MString(" parent added "));
			if (MS::kSuccess != status) {
				return status;
			}
		}

		if (parentRemovedUsed) {
			status = addGenericCallback(NULL, 
										MDagMessage::kParentRemoved,
										MString(" parent removed "));
			if (MS::kSuccess != status) {
				return status;
			}
		}		

		if (childAddedUsed) {
			MGlobal::displayError("-childAdded can only be used when a node is selected");
			status = MS::kFailure;
			return status;
		}

		if (childRemovedUsed) {
			MGlobal::displayError("-childRemoved can only be used when a node is selected");
			status = MS::kFailure;
			return status;
		}	

		if (childReorderedUsed) {
			status = addGenericCallback(NULL, 
										MDagMessage::kChildReordered,
										MString(" child reordered "));
			if (MS::kSuccess != status) {
				return status;
			}
		}	
	} else {
		for (unsigned int i=0; i< nObjs; i++) {
			MDagPath dagPath;
			list.getDagPath(i, dagPath);

			if (!dagPath.isValid()) {
				continue;
			}

			//	Add the callback for all changes of the specified type.
			//
			if (allDagUsed) {
				MCallbackId id = MDagMessage::addAllDagChangesCallback(dagPath, userDAGGenericCB, NULL, &status);
				if (status) {
					callbackIds.append( id );
					MString infoStr("Added a callback for all Dag changes on ");
					infoStr += dagPath.fullPathName();
					MGlobal::displayInfo(infoStr);
				} else {
					MGlobal::displayError("Could not add a -allDag callback");
					return status;
				}
			}

			if (parentAddedUsed) {
				status = addGenericCallback(&dagPath, 
											MDagMessage::kParentAdded,
											MString(" parent added "));
				if (MS::kSuccess != status) {
					return status;
				}
			}

			if (parentRemovedUsed) {
				status = addGenericCallback(&dagPath, 
											MDagMessage::kParentRemoved,
											MString(" parent removed "));
				if (MS::kSuccess != status) {
					return status;
				}
			}		

			if (childAddedUsed) {
				status = addGenericCallback(&dagPath, 
											MDagMessage::kChildAdded,
											MString(" child added "));
				if (MS::kSuccess != status) {
					return status;
				}
			}

			if (childRemovedUsed) {
				status = addGenericCallback(&dagPath, 
											MDagMessage::kChildRemoved,
											MString(" child removed "));
				if (MS::kSuccess != status) {
					return status;
				}
			}	

			if (childReorderedUsed) {
				status = addGenericCallback(&dagPath, 
											MDagMessage::kChildReordered,
											MString(" child reordered "));
				if (MS::kSuccess != status) {
					return status;
				}
			}	
		}
	}
	
	return status;
}
/*
	From the draw context, get the list of lights and queue the ones we are interested in
	into the "desired list"
*/
MStatus shadowPrepass::execute( const MHWRender::MDrawContext & context )
{
	MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
	if (!theRenderer)
		return MStatus::kSuccess;

	// Skip lighting modes where there are no lights which can
	// cast shadows
	MHWRender::MDrawContext::LightingMode lightingMode = context.getLightingMode();
	if (lightingMode != MHWRender::MDrawContext::kSelectedLights &&
		lightingMode != MHWRender::MDrawContext::kSceneLights)
	{
		return MStatus::kSuccess;
	}

	MHWRender::MDrawContext::LightFilter lightFilter = 
		MHWRender::MDrawContext::kFilteredIgnoreLightLimit;
	unsigned int nbSceneLights = context.numberOfActiveLights(lightFilter);

	for (unsigned int i=0; i<nbSceneLights; i++)
	{
		MHWRender::MLightParameterInformation* lightInfo = 
			context.getLightParameterInformation( i, lightFilter );
		if (!lightInfo)
			continue;

		// Get the actually Maya light node
		MStatus status = MStatus::kFailure;
		MDagPath lightPath = lightInfo->lightPath(&status);
		if (status != MStatus::kSuccess || !lightPath.isValid())
			continue;

		// Would be good to have an API method here to indicate if it
		// casts shadows
		MIntArray intVals;

		// Check if light is enabled, and emits any lighting
		MHWRender::MLightParameterInformation::StockParameterSemantic semantic =
			MHWRender::MLightParameterInformation::kLightEnabled;
		if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals ))
		{
			if (intVals.length())
			{
				if (intVals[0] == 0)
					continue;
			}
		}

		semantic = MHWRender::MLightParameterInformation::kEmitsDiffuse;
		if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals ))
		{
			if (intVals.length())
			{
				if (intVals[0] == 0)
					continue;
			}
		}

		semantic = MHWRender::MLightParameterInformation::kEmitsSpecular;
		if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals ))
		{
			if (intVals.length())
			{
				if (intVals[0] == 0)
					continue;
			}
		}

		// Check if local shadows are enabled.
		semantic = MHWRender::MLightParameterInformation::kShadowOn;
		if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals ))
		{
			if (intVals.length())
			{
				if (intVals[0] == 0)
					continue;
			}
		}

		// Check if the shadow is "dirty"
		bool shadowIsDirty = false;
		semantic = MHWRender::MLightParameterInformation::kShadowDirty;
		if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals ))
		{
			if (intVals.length())
			{
				if (intVals[0] == 0)
				//	continue;

				shadowIsDirty = intVals[0] != 0 ? true : false ;
			}
		}

		// Check the light list to prune, if not already pruned
		bool prune = false;
		if (lightingMode != MHWRender::MDrawContext::kSelectedLights)
		{
			if (mLightList && mLightList->length())
			{
				prune = !mLightList->hasItem(lightInfo->lightPath());
			}
		}

		static bool debugShadowRequests = false;
		// Set that we require shadows for this light
		if (!prune)
		{
			if (debugShadowRequests)
				fprintf(stderr, "QUEUE light shadows for %s, shadowDirty = %d\n", 
					lightPath.fullPathName().asChar(), shadowIsDirty);

			theRenderer->setLightRequiresShadows( lightPath.node(), true );
		}
		
		// Set that we DON'T require shadows for this light
		else
		{
			if (debugShadowRequests)
				fprintf(stderr, "DEQUEUE light shadows for %s, shadowDirty = %d\n", 
					lightPath.fullPathName().asChar(), shadowIsDirty);
			theRenderer->setLightRequiresShadows( lightPath.node(), false );
		}
	}

	return MStatus::kSuccess;
}
MStatus AlembicExportCommand::doIt(const MArgList &args)
{
  ESS_PROFILE_SCOPE("AlembicExportCommand::doIt");

  MStatus status = MS::kFailure;

  MTime currentAnimStartTime = MAnimControl::animationStartTime(),
        currentAnimEndTime = MAnimControl::animationEndTime(),
        oldCurTime = MAnimControl::currentTime(),
        curMinTime = MAnimControl::minTime(),
        curMaxTime = MAnimControl::maxTime();
  MArgParser argData(syntax(), args, &status);

  if (argData.isFlagSet("help")) {
    // TODO: implement help for this command
    // MGlobal::displayInfo(util::getHelpText());
    return MS::kSuccess;
  }

  unsigned int jobCount = argData.numberOfFlagUses("jobArg");
  MStringArray jobStrings;
  if (jobCount == 0) {
    // TODO: display dialog
    MGlobal::displayError("[ExocortexAlembic] No jobs specified.");
    MPxCommand::setResult(
        "Error caught in AlembicExportCommand::doIt: no job specified");
    return status;
  }
  else {
    // get all of the jobstrings
    for (unsigned int i = 0; i < jobCount; i++) {
      MArgList jobArgList;
      argData.getFlagArgumentList("jobArg", i, jobArgList);
      jobStrings.append(jobArgList.asString(0));
    }
  }

  // create a vector to store the jobs
  std::vector<AlembicWriteJob *> jobPtrs;
  double minFrame = 1000000.0;
  double maxFrame = -1000000.0;
  double maxSteps = 1;
  double maxSubsteps = 1;

  // init the curve accumulators
  AlembicCurveAccumulator::Initialize();

  try {
    // for each job, check the arguments
    bool failure = false;
    for (unsigned int i = 0; i < jobStrings.length(); ++i) {
      double frameIn = 1.0;
      double frameOut = 1.0;
      double frameSteps = 1.0;
      double frameSubSteps = 1.0;
      MString filename;
      bool purepointcache = false;
      bool normals = true;
      bool uvs = true;
      bool facesets = true;
      bool bindpose = true;
      bool dynamictopology = false;
      bool globalspace = false;
      bool withouthierarchy = false;
      bool transformcache = false;
      bool useInitShadGrp = false;
      bool useOgawa = false;  // Later, will need to be changed!

      MStringArray objectStrings;
      std::vector<std::string> prefixFilters;
      std::set<std::string> attributes;
      std::vector<std::string> userPrefixFilters;
      std::set<std::string> userAttributes;
      MObjectArray objects;
      std::string search_str, replace_str;

      // process all tokens of the job
      MStringArray tokens;
      jobStrings[i].split(';', tokens);
      for (unsigned int j = 0; j < tokens.length(); j++) {
        MStringArray valuePair;
        tokens[j].split('=', valuePair);
        if (valuePair.length() != 2) {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }

        const MString &lowerValue = valuePair[0].toLowerCase();
        if (lowerValue == "in") {
          frameIn = valuePair[1].asDouble();
        }
        else if (lowerValue == "out") {
          frameOut = valuePair[1].asDouble();
        }
        else if (lowerValue == "step") {
          frameSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "substep") {
          frameSubSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "normals") {
          normals = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "uvs") {
          uvs = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "facesets") {
          facesets = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "bindpose") {
          bindpose = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "purepointcache") {
          purepointcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "dynamictopology") {
          dynamictopology = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "globalspace") {
          globalspace = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "withouthierarchy") {
          withouthierarchy = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "transformcache") {
          transformcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "filename") {
          filename = valuePair[1];
        }
        else if (lowerValue == "objects") {
          // try to find each object
          valuePair[1].split(',', objectStrings);
        }
        else if (lowerValue == "useinitshadgrp") {
          useInitShadGrp = valuePair[1].asInt() != 0;
        }

        // search/replace
        else if (lowerValue == "search") {
          search_str = valuePair[1].asChar();
        }
        else if (lowerValue == "replace") {
          replace_str = valuePair[1].asChar();
        }
        else if (lowerValue == "ogawa") {
          useOgawa = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "attrprefixes") {
          splitListArg(valuePair[1], prefixFilters);
        }
        else if (lowerValue == "attrs") {
          splitListArg(valuePair[1], attributes);
        }
        else if (lowerValue == "userattrprefixes") {
          splitListArg(valuePair[1], userPrefixFilters);
        }
        else if (lowerValue == "userattrs") {
          splitListArg(valuePair[1], userAttributes);
        }
        else {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }
      }

      // now check the object strings
      for (unsigned int k = 0; k < objectStrings.length(); k++) {
        MSelectionList sl;
        MString objectString = objectStrings[k];
        sl.add(objectString);
        MDagPath dag;
        for (unsigned int l = 0; l < sl.length(); l++) {
          sl.getDagPath(l, dag);
          MObject objRef = dag.node();
          if (objRef.isNull()) {
            MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" +
                                    objectStrings[k] + "', not found.");
            break;
          }

          // get all parents
          MObjectArray parents;

          // check if this is a camera
          bool isCamera = false;
          for (unsigned int m = 0; m < dag.childCount(); ++m) {
            MFnDagNode child(dag.child(m));
            MFn::Type ctype = child.object().apiType();
            if (ctype == MFn::kCamera) {
              isCamera = true;
              break;
            }
          }

          if (dag.node().apiType() == MFn::kTransform && !isCamera &&
              !globalspace && !withouthierarchy) {
            MDagPath ppath = dag;
            while (!ppath.node().isNull() && ppath.length() > 0 &&
                   ppath.isValid()) {
              parents.append(ppath.node());
              if (ppath.pop() != MStatus::kSuccess) {
                break;
              }
            }
          }
          else {
            parents.append(dag.node());
          }

          // push all parents in
          while (parents.length() > 0) {
            bool found = false;
            for (unsigned int m = 0; m < objects.length(); m++) {
              if (objects[m] == parents[parents.length() - 1]) {
                found = true;
                break;
              }
            }
            if (!found) {
              objects.append(parents[parents.length() - 1]);
            }
            parents.remove(parents.length() - 1);
          }

          // check all of the shapes below
          if (!transformcache) {
            sl.getDagPath(l, dag);
            for (unsigned int m = 0; m < dag.childCount(); m++) {
              MFnDagNode child(dag.child(m));
              if (child.isIntermediateObject()) {
                continue;
              }
              objects.append(child.object());
            }
          }
        }
      }

      // check if we have incompatible subframes
      if (maxSubsteps > 1.0 && frameSubSteps > 1.0) {
        const double part = (frameSubSteps > maxSubsteps)
                                ? (frameSubSteps / maxSubsteps)
                                : (maxSubsteps / frameSubSteps);
        if (abs(part - floor(part)) > 0.001) {
          MString frameSubStepsStr, maxSubstepsStr;
          frameSubStepsStr.set(frameSubSteps);
          maxSubstepsStr.set(maxSubsteps);
          MGlobal::displayError(
              "[ExocortexAlembic] You cannot combine substeps " +
              frameSubStepsStr + " and " + maxSubstepsStr +
              " in one export. Aborting.");
          return MStatus::kInvalidParameter;
        }
      }

      // remember the min and max values for the frames
      if (frameIn < minFrame) {
        minFrame = frameIn;
      }
      if (frameOut > maxFrame) {
        maxFrame = frameOut;
      }
      if (frameSteps > maxSteps) {
        maxSteps = frameSteps;
      }
      if (frameSteps > 1.0) {
        frameSubSteps = 1.0;
      }
      if (frameSubSteps > maxSubsteps) {
        maxSubsteps = frameSubSteps;
      }

      // check if we have a filename
      if (filename.length() == 0) {
        MGlobal::displayError("[ExocortexAlembic] No filename specified.");
        for (size_t k = 0; k < jobPtrs.size(); k++) {
          delete (jobPtrs[k]);
        }
        MPxCommand::setResult(
            "Error caught in AlembicExportCommand::doIt: no filename "
            "specified");
        return MStatus::kFailure;
      }

      // construct the frames
      MDoubleArray frames;
      {
        const double frameIncr = frameSteps / frameSubSteps;
        for (double frame = frameIn; frame <= frameOut; frame += frameIncr) {
          frames.append(frame);
        }
      }

      AlembicWriteJob *job =
          new AlembicWriteJob(filename, objects, frames, useOgawa,
              prefixFilters, attributes, userPrefixFilters, userAttributes);
      job->SetOption("exportNormals", normals ? "1" : "0");
      job->SetOption("exportUVs", uvs ? "1" : "0");
      job->SetOption("exportFaceSets", facesets ? "1" : "0");
      job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0");
      job->SetOption("exportBindPose", bindpose ? "1" : "0");
      job->SetOption("exportPurePointCache", purepointcache ? "1" : "0");
      job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0");
      job->SetOption("indexedNormals", "1");
      job->SetOption("indexedUVs", "1");
      job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0");
      job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0");
      job->SetOption("transformCache", transformcache ? "1" : "0");

      // check if the search/replace strings are valid!
      if (search_str.length() ? !replace_str.length()
                              : replace_str.length())  // either search or
                                                       // replace string is
                                                       // missing or empty!
      {
        ESS_LOG_WARNING(
            "Missing search or replace parameter. No strings will be "
            "replaced.");
        job->replacer = SearchReplace::createReplacer();
      }
      else {
        job->replacer = SearchReplace::createReplacer(search_str, replace_str);
      }

      // check if the job is satifsied
      if (job->PreProcess() != MStatus::kSuccess) {
        MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied.");
        delete (job);
        failure = true;
        break;
      }

      // push the job to our registry
      MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" +
                           jobStrings[i]);
      jobPtrs.push_back(job);
    }

    if (failure) {
      for (size_t k = 0; k < jobPtrs.size(); k++) {
        delete (jobPtrs[k]);
      }
      return MS::kFailure;
    }

    // compute the job count
    unsigned int jobFrameCount = 0;
    for (size_t i = 0; i < jobPtrs.size(); i++)
      jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() *
                       (unsigned int)jobPtrs[i]->GetFrames().size();

    // now, let's run through all frames, and process the jobs
    const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit());
    const double incrSteps = maxSteps / maxSubsteps;
    double nextFrame = minFrame + incrSteps;

    for (double frame = minFrame; frame <= maxFrame;
         frame += incrSteps, nextFrame += incrSteps) {
      MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds));
      MAnimControl::setAnimationEndTime(
          MTime(nextFrame / frameRate, MTime::kSeconds));
      MAnimControl::playForward();  // this way, it forces Maya to play exactly
      // one frame! and particles are updated!

      AlembicCurveAccumulator::StartRecordingFrame();
      for (size_t i = 0; i < jobPtrs.size(); i++) {
        MStatus status = jobPtrs[i]->Process(frame);
        if (status != MStatus::kSuccess) {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :" +
                                jobPtrs[i]->GetFileName());
          for (size_t k = 0; k < jobPtrs.size(); k++) {
            delete (jobPtrs[k]);
          }
          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                         curMinTime, curMaxTime);
          return status;
        }
      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
  }
  catch (...) {
    MGlobal::displayError(
        "[ExocortexAlembic] Jobs aborted, force closing all archives!");
    for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin();
         beg != jobPtrs.end(); ++beg) {
      (*beg)->forceCloseArchive();
    }
    restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                   curMinTime, curMaxTime);
    MPxCommand::setResult("Error caught in AlembicExportCommand::doIt");
    status = MS::kFailure;
  }
  MAnimControl::stop();
  AlembicCurveAccumulator::Destroy();

  // restore the animation start/end time and the current time!
  restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                 curMinTime, curMaxTime);

  // delete all jobs
  for (size_t k = 0; k < jobPtrs.size(); k++) {
    delete (jobPtrs[k]);
  }

  // remove all known archives
  deleteAllArchives();
  return status;
}
/*
	Draw a scene full of bounding boxes
*/
bool
MCustomSceneDraw::draw(MDagPath &cameraPath, unsigned int width, unsigned int height)
{
	if (!cameraPath.isValid())
		return false;

	MDrawTraversal *trav = NULL;
	trav = new MSurfaceDrawTraversal;

	if (!trav)
		return false;

	trav->enableFiltering( true );
	trav->setFrustum( cameraPath, width, height );
	if (!trav->frustumValid())
	{
		delete trav; trav = NULL;
		return false;
	}
	trav->traverse();

	unsigned int numItems = trav->numberOfItems();
	unsigned int i;
	for (i=0; i<numItems; i++)
	{
		MDagPath path;
		trav->itemPath(i, path);

		if (path.isValid())
		{
			bool drawIt = false;

			//
			// Draw surfaces (polys, nurbs, subdivs)
			//
			if ( path.hasFn( MFn::kMesh) ||
				path.hasFn( MFn::kNurbsSurface) ||
				path.hasFn( MFn::kSubdiv) )
			{
				drawIt = true;
				if (trav->itemHasStatus( i, MDrawTraversal::kActiveItem ))
				{
					gGLFT->glColor3f( 1.0f, 1.0f, 1.0f );
				}
				else if (trav->itemHasStatus( i, MDrawTraversal::kTemplateItem ))
				{
					gGLFT->glColor3f( 0.2f, 0.2f, 0.2f );
				}
				else
				{
					if (path.hasFn( MFn::kMesh ))
						gGLFT->glColor3f( 0.286f, 0.706f, 1.0f );
					else if (path.hasFn( MFn::kNurbsSurface))
						gGLFT->glColor3f( 0.486f, 0.306f, 1.0f );
					else
						gGLFT->glColor3f( 0.886f, 0.206f, 1.0f );
				}
			}

			if (drawIt)
			{
				MFnDagNode dagNode(path);
				MBoundingBox box = dagNode.boundingBox();
				drawBounds( path, box );
			}
		}
	}

	if (trav)
	{
		delete trav;
		trav = NULL;
	}
	return true;
}
MStatus testExCameraSetCmd::doIt( const MArgList& args)
//
// Parses the given command line arguments and executes them.
//
{
	MStatus status = parseArgs(args);
	if (status != MS::kSuccess)
	{
		MGlobal::displayError("Error parsing argument list");
		return status;
	}

	bool nothingSet = (	!createUsed && !appendCameraUsed && !appendCameraAndSetUsed && !deleteLayerUsed && !cameraUsed && 
						!layerUsed && !helpUsed && !setUsed && !layerTypeUsed && !numLayersUsed);

	if (nothingSet)
	{
		MGlobal::displayError("A flag must be used. testCameraSet -help for availible flags.");
		return MS::kFailure;
	}

	if (helpUsed) {
		MGlobal::displayInfo("testExCameraSet -help");
		MGlobal::displayInfo("\ttestExCameraSet tests the functionality of the exCameraSet node.");
		MGlobal::displayInfo("");
		MGlobal::displayInfo("\t-h -help : This message is printed");
		MGlobal::displayInfo("\t-a -active [true/false]: Set/get whether a particular layer is active");
		MGlobal::displayInfo("\t-ac -appendCamera <cameraName>: Append a new camera layer to the cameraSet using the specified camera");
		MGlobal::displayInfo("\t-acs -appendCameraAndSet <cameraName> <setName>: Append a new camera layer to the cameraSet using the specified camera and set");
		MGlobal::displayInfo("\t-cam -camera [<cameraName>]: Set/get the camera for a particular layer");
		MGlobal::displayInfo("\t-c -create : Create a new cameraSet node");
		MGlobal::displayInfo("\t-d -deleteLayer <layerIndex>: Delete the layer at the given index");
		MGlobal::displayInfo("\t-nl -numLayers: Returns the number of layers defined in the specified cameraSet");
		MGlobal::displayInfo("\t-l -layer <layerIndex>: Specifies the layer index to be used when accessing layer information");
		MGlobal::displayInfo("\t-lt -layerType [<layerTypeName>]: Set/get the layer type for a particular layer.  Possible values are Mono, Left, and Right.");
		MGlobal::displayInfo("\t-s -set [<setName>]: Set/get the set for a particular layer");
		MGlobal::displayInfo("\t-e -edit : Perform an edit operation");
		MGlobal::displayInfo("\t-q -query : Perform a query operation");
		MGlobal::displayInfo("");
	}

	unsigned nObjs = list.length();
	if (nObjs == 0)
	{
		if (createUsed)
		{
			// Create a new cameraSet node.
			MFnDependencyNode dirFn;
			MString noName;
			MObject dirObj = dirFn.create(exCameraSet::id, noName, &status);
			if (!status)
			{
				MGlobal::displayError("Could not create a cameraSet node");
				return status;
			}

			MGlobal::select(dirObj, MGlobal::kReplaceList);
			return status;
		}

		if (appendCameraUsed || appendCameraAndSetUsed || deleteLayerUsed || editUsed || cameraUsed || 
				setUsed || layerTypeUsed || activeUsed || numLayersUsed) {
			MGlobal::displayError("Must specify a cameraSet node");
			status = MS::kFailure;
			return status;
		}
	}
	else
	{
		if (createUsed)
		{
			MGlobal::displayError("-create cannot have any object specifed");
			status = MS::kFailure;
			return status;
		}

		if (appendCameraUsed)
		{
			if (nObjs != 1)
			{
				MGlobal::displayError("-appendCamera must have a single cameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-appendCamera must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			// Get a dag path to the specified camera.
			MSelectionList camList;
			camList.add(camName);
			MDagPath camPath;
			camList.getDagPath(0, camPath);
			if (!camPath.isValid())
			{
				MGlobal::displayError("-appendCamera must have a valid camera node specified");
				status = MS::kFailure;
				return status;
			}

			// Call the MFnCameraSet method to append the layer.
			MFnCameraSet dirFn(dirNode);
			dirFn.appendLayer(camPath, MObject::kNullObj);

			return status;
		}

		if (appendCameraAndSetUsed)
		{
			if (nObjs != 1)
			{
				MGlobal::displayError("-appendCameraAndSet must have a single cameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-appendCameraAndSet must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			// Get a dag path to the specified camera.
			MSelectionList camList;
			camList.add(camName);
			MDagPath camPath;
			camList.getDagPath(0, camPath);
			if (!camPath.isValid())
			{
				MGlobal::displayError("-appendCameraAndSet must have a valid camera node specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified set node.
			MSelectionList setList;
			setList.add(setName);
			MObject setObj = MObject::kNullObj;
			setList.getDependNode(0, setObj);
			if (setObj == MObject::kNullObj)
			{
				MGlobal::displayError("-appendCameraAndSet must have a valid set node specified");
				status = MS::kFailure;
				return status;
			}

			// Call the MFnCameraSet method to append the layer.
			MFnCameraSet dirFn(dirNode);
			dirFn.appendLayer(camPath, setObj);

			return status;
		}


		if (deleteLayerUsed)
		{
			if (nObjs != 1)
			{
				MGlobal::displayError("-deleteLayer must have a single cameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-deleteLayer must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			// Call the MFnCameraSet method to delete the layer.
			MFnCameraSet dirFn(dirNode);
			dirFn.deleteLayer(cameraLayer);
	
			return status;
		}

		if (numLayersUsed)
		{
			if (queryUsed)
			{
				// Get the specified cameraSet node.
				MObject dirNode = MObject::kNullObj;
				if (!getExCameraSetNode(dirNode))
				{
					MGlobal::displayError("-numLayers must have a valid exCameraSet node specified");
					status = MS::kFailure;
					return status;
				}

				// Call the MFnCameraSet method to get the number of layers.
				MFnCameraSet dirFn(dirNode);
				unsigned int numLayers = dirFn.getNumLayers(&status);
				if (status != MS::kSuccess)	
					MGlobal::displayError("Error getting the number of layers");
				setResult((int)numLayers);
			}
			else
			{
				MGlobal::displayError("-numLayers requires the query flag to be used");
				status = MS::kFailure;
			}
			return status;
		}

		if (cameraUsed)
		{
			if ((nObjs != 1) || (!layerUsed))
			{
				MGlobal::displayError("-camera must have a cameraSet node and layer specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-camera must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			if (editUsed)
			{
				// Get a dag path to the specified camera.
				MSelectionList camList;
				camList.add(camName);
				MDagPath camPath;
				camList.getDagPath(0, camPath);
				if (!camPath.isValid())
				{
					MGlobal::displayError("-camera must have a valid camera node specified");
					status = MS::kFailure;
					return status;
				}

				// Call the MFnCameraSet method to set the camera.
				MFnCameraSet dirFn(dirNode);
				dirFn.setLayerCamera((unsigned int)cameraLayer, camPath);
			}
			else if (queryUsed)
			{
				// Call the MFnCameraSet method to get the camera.
				MDagPath camPath;
				MFnCameraSet dirFn(dirNode);
				status = dirFn.getLayerCamera((unsigned int)cameraLayer, camPath);
				if (status == MS::kSuccess)
				{
					MObject camNode = camPath.node();
					MFnDependencyNode nodeFn(camNode);
					setResult(nodeFn.name());
				}
				else
					setResult("");
			}
		}

		if (setUsed)
		{
			if ((nObjs != 1) || (!layerUsed))
			{
				MGlobal::displayError("-set must have a cameraSet node and layer specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-set must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			if (editUsed)
			{
				// Get the specified set node.
				MObject setObj = MObject::kNullObj;
				if (setName != "")
				{
					MSelectionList setList;
					setList.add(setName);
					setList.getDependNode(0, setObj);
					if (setObj == MObject::kNullObj)
					{
						MGlobal::displayError("-set must have a valid set node specified");
						status = MS::kFailure;
						return status;
					}
				}

				// Call the MFnCameraSet method to set the set node.
				MFnCameraSet dirFn(dirNode);
				dirFn.setLayerSceneData((unsigned int)cameraLayer, setObj);
			}
			else if (queryUsed)
			{
				// Call the MFnCameraSet method to get the set node.
				MObject setObj;
				MFnCameraSet dirFn(dirNode);
				status = dirFn.getLayerSceneData((unsigned int)cameraLayer, setObj);
				if (status == MS::kSuccess)
				{
					MFnDependencyNode nodeFn(setObj);
					setResult(nodeFn.name());
				}
				else
					setResult("");
			}
		}

		if (layerTypeUsed)
		{
			if ((nObjs != 1) || (!layerUsed))
			{
				MGlobal::displayError("-layerType must have a cameraSet node and layer specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-layerType must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			MFnDependencyNode nodeFn(dirNode);
			exCameraSet *exDir = (exCameraSet *)nodeFn.userNode();

			if (editUsed)
			{
				// Get the specified layer type.
				int pt = -1;
				if (layerTypeVal == "Mono")
					pt = 0;
				else if (layerTypeVal == "Left")
					pt = 1;
				else if (layerTypeVal == "Right")
					pt = 2;
				else
				{
					MGlobal::displayError("-layerType must have a valid type specified");
					status = MS::kFailure;
					return status;
				}

				// Call the exCameraSet method to set the layer type.
				exDir->setLayerType((unsigned int)cameraLayer, pt);
			}
			else if (queryUsed)
			{
				// Call the exCameraSet method to get the layer type.
				int lt;
				status = exDir->getLayerType((unsigned int)cameraLayer, lt);
				if (status == MS::kSuccess)
				{
					if (lt == 0)
						setResult("Mono");
					else if (lt == 1)
						setResult("Left");
					else if (lt == 2)
						setResult("Right");
				}
				else
				{
					MGlobal::displayError("exCameraSet node does not have a valid layer type");
					status = MS::kFailure;
					return status;
				}
			}
		}

		if (activeUsed)
		{
			if ((nObjs != 1) || (!layerUsed))
			{
				MGlobal::displayError("-active must have a cameraSet node and layer specified");
				status = MS::kFailure;
				return status;
			}

			// Get the specified cameraSet node.
			MObject dirNode = MObject::kNullObj;
			if (!getExCameraSetNode(dirNode))
			{
				MGlobal::displayError("-active must have a valid exCameraSet node specified");
				status = MS::kFailure;
				return status;
			}

			if (editUsed)
			{
				// Call the MFnCameraSet method to set the set node.
				MFnCameraSet dirFn(dirNode);
				dirFn.setLayerActive((unsigned int)cameraLayer, activeVal);
			}
			else if (queryUsed)
			{
				// Call the MFnCameraSet method to get the active value.
				MStatus stat = MS::kSuccess;
				MFnCameraSet dirFn(dirNode);
				activeVal = dirFn.isLayerActive((unsigned int)cameraLayer, &stat);
				if (stat == MS::kSuccess)
					setResult(activeVal);
				else
					MGlobal::displayError("Could not get active value");
			}
		}
	}
	
	return status;
}