コード例 #1
0
		void exportShadingInputs()
		{
			MObject proceduralNode = m_dagPath.node();
			MPlug nullPlug;
			
			MIteratorType filter;
			MIntArray filterTypes;
			filterTypes.append( MFn::kShadingEngine );
			filterTypes.append( MFn::kDisplacementShader );			
			filter.setFilterList( filterTypes );
			
			MItDependencyGraph itDG( proceduralNode, nullPlug, filter, MItDependencyGraph::kUpstream );
			while( !itDG.isDone() )
			{
				MObject node = itDG.currentItem();
				MFnDependencyNode fnNode( node );
				MPlug plug;
				if( fnNode.typeName() == "displacementShader" )
				{
					plug = fnNode.findPlug( "displacement" );
				}
				else
				{
					plug = fnNode.findPlug( "dsm" );
				}
				ExportNode( plug );
				itDG.next();
			}
		}
コード例 #2
0
void skinClusterWeights::populateInfluenceIndexArray(MFnSkinCluster &skinClusterFn, MIntArray &influenceIndexArray)
{
   MStatus status;

   MIntArray  allIndexArray;
   MDagPathArray pathArray;
   skinClusterFn.influenceObjects(pathArray, &status);
   for (unsigned j = 0; j < pathArray.length(); j++) {
	allIndexArray.append(skinClusterFn.indexForInfluenceObject(pathArray[j]));
   }

   if (influenceArray.length() > 0) {
        // Add the influence indices for the influence objects specified in the cmd
        for (unsigned j = 0; j < influenceArray.length(); j++) {
	    unsigned int index = skinClusterFn.indexForInfluenceObject(influenceArray[j], &status);
	    for (unsigned k = 0; k < allIndexArray.length(); k++) {
	        if ((int)index == allIndexArray[k]) {
		    influenceIndexArray.append(k);
		}
	    }
	}
    } else {
        // Add the influence indices for all the influence objects of the skinCluster
	for (unsigned j = 0; j < allIndexArray.length(); j++) {
	    influenceIndexArray.append(j);
	}
    }
}
コード例 #3
0
ファイル: MG_poseReader.cpp プロジェクト: bungnoid/MG_Tools
MObject MG_poseReader::makePlane(const MVector& p1,const MVector& p2,const MVector& p3){

	MFnMesh meshFn;

	MPoint p1p (p1);
	MPoint p2p (p2);
	MPoint p3p (p3);
	MPointArray pArray;
	pArray.append(p1p);
	pArray.append(p2p);
	pArray.append(p3p);

	MIntArray polyCount;
	polyCount.append(3);
	MIntArray polyConnect;
	polyConnect.append(0);
	polyConnect.append(1);
	polyConnect.append(2);
	

	MFnMeshData data;
	MObject polyData = data.create();

	MStatus stat;
	meshFn.create(3,1,pArray,polyCount,polyConnect,polyData,&stat);
		


	
	return polyData;

}
コード例 #4
0
ファイル: MayaReader.cpp プロジェクト: nkostelnik/importer
MIntArray GetLocalIndex( MIntArray & getVertices, MIntArray & getTriangle )
{
	MIntArray   localIndex;
	unsigned    gv, gt;

	assert ( getTriangle.length() == 3 );    // Should always deal with a triangle

	for ( gt = 0; gt < getTriangle.length(); gt++ )
	{
		for ( gv = 0; gv < getVertices.length(); gv++ )
		{
			if ( getTriangle[gt] == getVertices[gv] )
			{
				localIndex.append( gv );
				break;
			}
		}

		// if nothing was added, add default "no match"
		if ( localIndex.length() == gt )
			localIndex.append( -1 );
	}

	return localIndex;
}
コード例 #5
0
MStatus metro_model_translator::create_shape( const m2033::mesh_ptr m )
{
	MFloatPointArray v;
	MVectorArray norm;
	MIntArray p;
	MIntArray idx;

	MFnTransform transform_fn;
	MObject transform_obj = transform_fn.create( MObject::kNullObj );
	transform_fn.setName( m->get_name().c_str() );

	m2033::mesh::vertices mv = m->get_vertices();
	m2033::mesh::indices mi = m->get_indices();
	m2033::mesh::texcoords mt = m->get_tex_coords();
	m2033::mesh::normals mn = m->get_normals();

	for( unsigned i = 0; i < mv.size(); i++ ) {
		v.append( -mv[i].x, mv[i].y, mv[i].z );
		norm.append( MVector( -mn[i].x, mn[i].y, mn[i].z ) );
	}

	for( unsigned i = 0; i < mi.size() / 3; i++ ) {
		idx.append( mi[i*3+2] );
		idx.append( mi[i*3+1] );
		idx.append( mi[i*3] );
		p.append( 3 );
	}

	MFloatArray u_values, v_values;
	for( unsigned i = 0; i < mt.size(); i++ ) {
		u_values.append( mt[i].x );
		v_values.append( -mt[i].y );
	}

	MFnMesh meshFn;
	MObject mesh = meshFn.create( v.length(), p.length(), v, p, idx, u_values, v_values, transform_obj );
	MString name = m->get_name().c_str();
	meshFn.setName( name + MString("_shape") );

	MStatus s = meshFn.assignUVs( p, idx, 0 );
	if( !s ) {
		return s;
	}

	s = meshFn.unlockVertexNormals( idx );
	if( !s ) {
		return s;
	}
	meshFn.setVertexNormals( norm, idx );

	MObject mat = create_material( m->get_texture_name(), &s );
	if( !s ) {
		return s;
	}
	MFnSet mat_fn(mat);
	mat_fn.addMember(mesh);

	return MS::kSuccess;
}
コード例 #6
0
ファイル: MVGMesh.cpp プロジェクト: jonntd/mayaMVG
MStatus MVGMesh::unsetAllBlindData() const
{
    MStatus status;

    // Get all vertices
    MItMeshVertex vIt(_dagpath, MObject::kNullObj, &status);
    vIt.updateSurface();
    vIt.geomChanged();
    MIntArray componentId;
    while(!vIt.isDone())
    {
        const int index = vIt.index(&status);
        componentId.append(index);
        vIt.next();
    }
    MVGEditCmd* cmd = new MVGEditCmd();
    if(cmd)
    {
        cmd->clearBD(_dagpath, componentId);
        MArgList args;
        if(cmd->doIt(args))
            cmd->finalize();
    }
    delete cmd;

    return status;
}
コード例 #7
0
ファイル: sweptEmitter.cpp プロジェクト: DimondTheCat/xray
MStatus sweptEmitter::emitCountPerPoint
	(
		const MPlug &plug,
		MDataBlock &block,
		int length,					// length of emitCountPP
		MIntArray &emitCountPP		// output: emitCount for each point
	)
//
//	Descriptions:
//		Compute emitCount for each point where new particles come from.
//
{
	MStatus status;

	int plugIndex = plug.logicalIndex( &status );
	McheckErr(status, "ERROR in emitCountPerPoint: when plug.logicalIndex.\n");

	// Get rate and delta time.
	//
	double rate = rateValue( block );
	MTime dt = deltaTimeValue( plugIndex, block );

	// Compute emitCount for each point.
	//
	double dblCount = rate * dt.as( MTime::kSeconds );

	int intCount = (int)dblCount;
	for( int i = 0; i < length; i++ )
	{
		emitCountPP.append( intCount );
	}

	return( MS::kSuccess );
}
コード例 #8
0
ファイル: componentConverter.cpp プロジェクト: Byron/bsuite
//---------------------------------------------------------------------------
void		componentConverter::getConnectedFaces(MIntArray& edgeIDs,
												  MIntArray& result		)
//---------------------------------------------------------------------------
{
	
	MItMeshEdge edgeIter(mesh);
	MIntArray connectedFaces;
	
	result.clear();
	
	unsigned int l = edgeIDs.length();


	for(unsigned int i = 0; i < l; i++)
	{
		edgeIter.setIndex(edgeIDs[i],tmp);
		edgeIter.getConnectedFaces(connectedFaces);
		
		for(unsigned int x = 0; x < connectedFaces.length();x++)
		{
			result.append(connectedFaces[x]);
		}		
	}

}
コード例 #9
0
ファイル: mesh.cpp プロジェクト: siqihuang/Movable-Tree
void mesh::appendToMesh(MPointArray& points, MIntArray& faceCounts,MIntArray& faceConnects){
	for(int i=0;i<gPoints.length();i++){
		points.append(gPoints[i]);
	}
	for(int i=0;i<gFaceCounts.length();i++){
		faceCounts.append(gFaceCounts[i]);
	}
	for(int i=0;i<gFaceConnects.length();i++){
		faceConnects.append(gFaceConnects[i]);
	}
	if(gPoints.length()==0){
		std::string s=std::to_string((long double)gPoints.length());
		MGlobal::displayInfo(MString(s.c_str()));
		s=std::to_string((long double)gFaceCounts[0]);
		MGlobal::displayInfo(MString(s.c_str()));
		s=std::to_string((long double)gFaceConnects.length());
		MGlobal::displayInfo(MString(s.c_str()));
	}
}
コード例 #10
0
void ParameterisedHolderModificationCmd::restoreClassParameterStates( const IECore::CompoundData *classes, IECore::Parameter *parameter, const std::string &parentParameterPath )
{
	std::string parameterPath = parentParameterPath;
	if( parentParameterPath.size() )
	{
		parameterPath += ".";
	}
	parameterPath += parameter->name();
		
	if( parameter->isInstanceOf( "ClassParameter" ) )
	{				
		const CompoundData *c = classes->member<const CompoundData>( parameterPath );
		if( c )
		{
			ClassParameterHandler::setClass(
				parameter,
				c->member<const IECore::StringData>( "className" )->readable().c_str(),
				c->member<const IECore::IntData>( "classVersion" )->readable(),
				c->member<const IECore::StringData>( "searchPathEnvVar" )->readable().c_str()
			);
		}
	}
	else if( parameter->isInstanceOf( "ClassVectorParameter" ) )
	{		
		const CompoundData *c = classes->member<const CompoundData>( parameterPath );
		if( c )
		{
			IECore::ConstStringVectorDataPtr parameterNames = c->member<const IECore::StringVectorData>( "parameterNames" );
			IECore::ConstStringVectorDataPtr classNames = c->member<const IECore::StringVectorData>( "classNames" );
			IECore::ConstIntVectorDataPtr classVersions = c->member<const IECore::IntVectorData>( "classVersions" );
			MStringArray mParameterNames;
			MStringArray mClassNames;
			MIntArray mClassVersions;
			int numClasses = parameterNames->readable().size();
			for( int i=0; i<numClasses; i++ )
			{
				mParameterNames.append( parameterNames->readable()[i].c_str() );
				mClassNames.append( classNames->readable()[i].c_str() );
				mClassVersions.append( classVersions->readable()[i] );
			}
			ClassVectorParameterHandler::setClasses( parameter, mParameterNames, mClassNames, mClassVersions );
		}
	}
	
	if( parameter->isInstanceOf( IECore::CompoundParameter::staticTypeId() ) )
	{
		CompoundParameter *compoundParameter = static_cast<CompoundParameter *>( parameter );
		const CompoundParameter::ParameterVector &childParameters = compoundParameter->orderedParameters();
		for( CompoundParameter::ParameterVector::const_iterator it = childParameters.begin(); it!=childParameters.end(); it++ )
		{
			restoreClassParameterStates( classes, it->get(), parameterPath );
		}
	}
}
コード例 #11
0
ファイル: maTranslator.cpp プロジェクト: 2asoft/xray
void CXRayObjectExport::recFindTransformDAGNodes( MString& nodeName, MIntArray& transformNodeIndicesArray )
{
	// To handle Maya groups we traverse the hierarchy starting at
	// each objectNames[i] going towards the root collecting transform
	// nodes as we go.
	MStringArray result;
	MString cmdStr = "listRelatives -ap " + nodeName;
	MGlobal::executeCommand( cmdStr, result );
	
	if( result.length() == 0 )
		// nodeName must be at the root of the DAG.  Stop recursing
		return;

	for( unsigned int j=0; j<result.length(); j++ ) {
		// check if the node result[i] is of type transform
		MStringArray result2;
		MGlobal::executeCommand( "nodeType " + result[j], result2 );
		
		if( result2.length() == 1 && result2[0] == "transform" ) {
			// check if result[j] is already in result[j]
			bool found=false;
			unsigned int i;
			for( i=0; i<transformNodeNameArray.length(); i++) {
				if( transformNodeNameArray[i] == result[j] ) {
					found = true;
					break;
				}
			}

			if( !found ) {
				transformNodeIndicesArray.append(transformNodeNameArray.length());
				transformNodeNameArray.append(result[j]);
			}
			else {
				transformNodeIndicesArray.append(i);
			}
			recFindTransformDAGNodes(result[j], transformNodeIndicesArray);
		}
	}
}
コード例 #12
0
ファイル: mengercmd.cpp プロジェクト: skurmedel/mayamenger
static void addCube(
    float scale,
    MFloatVector pos,
    int index_offset,
    MFloatPointArray &points,
    MIntArray &faceCounts,
    MIntArray &faceConnects)
{
#define mkpoint(x, y, z) points.append((MFloatPoint(x, y, z) * scale) + pos)

    mkpoint( 0.5, 0.5, 0.5);
    mkpoint(-0.5, 0.5, 0.5);
    mkpoint(-0.5,-0.5, 0.5);
    mkpoint( 0.5,-0.5, 0.5);

    mkpoint( 0.5, 0.5,-0.5);
    mkpoint(-0.5, 0.5,-0.5);
    mkpoint(-0.5,-0.5,-0.5);
    mkpoint( 0.5,-0.5,-0.5);

#undef mkpoint

    for (int i = 0; i < 6; i++)
        faceCounts.append(4);

    int face_connects[6 * 4] =
    {
        0, 1, 2, 3,
        7, 6, 5, 4,
        3, 7, 4, 0,
        2, 1, 5, 6,
        0, 4, 5, 1,
        2, 6, 7, 3
    };
    for (int i = 0; i < 6 * 4; i++)
    {
        faceConnects.append(face_connects[i] + index_offset);
    }
}
コード例 #13
0
ファイル: cylinder.cpp プロジェクト: adairrabbit/LiuSalon
void CylinderMesh::appendToMesh(
    MPointArray& points, 
    MIntArray& faceCounts, 
    MIntArray& faceConnects)
{
    MPointArray cpoints;
    MVectorArray cnormals; 
    transform(cpoints, cnormals);    

    int startIndex = points.length(); // offset for indexes
    for (int i = 0; i < cpoints.length(); i++)
    {
        points.append(cpoints[i]);
    }
    for (int i = 0; i < gFaceCounts.length(); i++)
    {
        faceCounts.append(gFaceCounts[i]);
    }

    for (int i = 0; i < gFaceConnects.length(); i++)
    {
        faceConnects.append(gFaceConnects[i]+startIndex);
    }
}
コード例 #14
0
void MayaGeoAttribute::transferValueToMaya(MPlug &plug, MDataBlock &data){
	coral::Geo *coralGeo = value();
	const std::vector<Imath::V3f> &coralPoints = coralGeo->points();
	
	// transfer points
	MFloatPointArray mayaPoints;
	for(int i = 0; i < coralPoints.size(); ++i){
		const Imath::V3f *coralPoint = &coralPoints[i];
		mayaPoints.append(MFloatPoint(coralPoint->x, coralPoint->y, coralPoint->z));
	}
	
	// transfer faces
	MIntArray mayaFaceCount;
	MIntArray mayaFaceVertices;
	
	const std::vector<std::vector<int> > coralFaces = coralGeo->rawFaces();
	for(int polyId = 0; polyId < coralFaces.size(); ++polyId){
		const std::vector<int> *coralFace = &coralFaces[polyId];
		int faceVertexCount = coralFace->size();
		mayaFaceCount.append(faceVertexCount);
		
		for(int i = 0; i < faceVertexCount; ++i){
			mayaFaceVertices.append(coralFace->at(i));
		}
	}
	
	// create maya mesh
	MDataHandle dataHandle = data.outputValue(plug);
	
	MFnMeshData dataCreator;
	MObject newOutputData = dataCreator.create();
	
	MFnMesh newMesh;
	newMesh.create(mayaPoints.length(), coralFaces.size(), mayaPoints, mayaFaceCount, mayaFaceVertices, newOutputData);
	dataHandle.set(newOutputData);
}
コード例 #15
0
ファイル: MayaExport.cpp プロジェクト: 2asoft/xray
//-----------------------------------------------------------------------------------------
LPCSTR CXRayObjectExport::getMaterialName(MDagPath & mdagPath, int cid, int objectIdx)
{
    MStatus stat;
	
    int i, length;
	MIntArray * currentMaterials = new MIntArray();
	MStringArray mArray;


	for ( i=0; i<numSets; i++ )	{
		if ( lookup(mdagPath,i,cid) ) {
			MFnSet fnSet( (*sets)[i] );
			if ( MFnSet::kRenderableOnly == fnSet.restriction(&stat) ) {
				currentMaterials->append( i );
				mArray.append( fnSet.name() );
			}
		}
	}

	// Test for equivalent materials
	//
	bool materialsEqual = false;
	if ((lastMaterials != NULL) && (lastMaterials->length() == currentMaterials->length())){
		materialsEqual = true;
		length = lastMaterials->length();
		for (i=0; i<length; i++){
			if ((*lastMaterials)[i]!=(*currentMaterials)[i]){
				materialsEqual = false;
				break;
			}
		}			
	}

	if (!materialsEqual){
		if (lastMaterials!=NULL) xr_delete(lastMaterials);

		lastMaterials = currentMaterials;

		int mLength = mArray.length(); 
		if (mLength==0) xrDebug::Fatal(DEBUG_INFO,"Object '%s' has polygon '%d' without material.",0,cid);
		if (mLength>1){
			xrDebug::Fatal(DEBUG_INFO,"Object '%s' has polygon '%d' with more than one material.",0,cid);
		}
	}else{
		xr_delete(currentMaterials);
	}
	return mArray[0].asChar();
}
コード例 #16
0
ファイル: splitUVCmd.cpp プロジェクト: BigRoy/Maya-devkit
MStatus splitUV::pruneUVs( MIntArray& validUVIndices )
//
// Description:
//
//		This method will remove any invalid UVIds from the component list and UVId array.
//		The benefit of this is to reduce the amount of extra processing that the node would
//		have to perform. It will result in less iterations through the mesh as there are
//		less UVs to search for.
//
{
	MStatus status;

	unsigned i;
	MIntArray validUVIds;

	for( i = 0; i < validUVIndices.length(); i++ )
	{
		int uvIndex = validUVIndices[i];
		validUVIds.append( fSelUVs[uvIndex] );
	}

	// Replace the local int array of UVIds
	//
	fSelUVs.clear();
	fSelUVs = validUVIds;

	// Build the list of valid components
	//
	MFnSingleIndexedComponent compFn;
	compFn.create( MFn::kMeshMapComponent, &status );
	MCheckStatus( status, "compFn.create( MFn::kMeshMapComponent )" );
	status = compFn.addElements( validUVIds );
	MCheckStatus( status, "compFn.addElements( validUVIds )" );
	MObject component = compFn.object();

	// Replace the component list
	//
	MFnComponentListData compListFn;
	compListFn.create();
	status = compListFn.add( component );
	MCheckStatus( status, "compListFn.add( component )" );

	fComponentList = compListFn.object();

	return status;
}
コード例 #17
0
void StartChunck(){
	int tempo;
	int temp = ::output.tellp();
	posfichier.append(temp);
		
		info = " start position: ";
		tempo = posfichier.length()-1;
		info += tempo;
	
		
		
		info += " rec adress : ";
		info += temp;
		//MGlobal::displayInfo(info);

		write_int(1); // écriture d'une valeur quelconque
}
コード例 #18
0
ファイル: componentConverter.cpp プロジェクト: Byron/bsuite
//---------------------------------------------------------------------
void	componentConverter::getContainedEdges(	MIntArray& vtxIDs,
												MIntArray& result	)
//---------------------------------------------------------------------
{
//	result.clear();

	MFnMesh meshFn(mesh);
	MItMeshVertex vertIter(mesh);

	BPT_BA searchArray(meshFn.numEdges());
	
	MIntArray conEdges;
	

	
	unsigned int l = vtxIDs.length();
	int indexValue;
	for(unsigned i = 0;i < l;i++)
	{
		vertIter.setIndex(vtxIDs[i],tmp);
		vertIter.getConnectedEdges(conEdges);
		
		
		
		for(unsigned int x = 0; x < conEdges.length(); x++)
		{
			indexValue = conEdges[x];
			if( searchArray[indexValue] )
			{
				result.append(indexValue);
			}
			else
				searchArray.setBitTrue(indexValue);
		}
	}




}
コード例 #19
0
static
bool
_AssignMaterialFaceSet(
        const MObject& shadingEngine,
        const MDagPath& shapeDagPath,
        const VtIntArray& faceIndices)
{
    MStatus status;

    // Create component object using single indexed
    // components, i.e. face indices.
    MFnSingleIndexedComponent compFn;
    MObject faceComp = compFn.create(MFn::kMeshPolygonComponent, &status);
    if (!status) {
        TF_RUNTIME_ERROR("Failed to create face component.");
        return false;
    }

    MIntArray mFaces;
    TF_FOR_ALL(fIdxIt, faceIndices) {
        mFaces.append(*fIdxIt);
    }
MStatus SelectRingToolCmd2::redoIt()
{	
	//MGlobal::displayInfo( "redoIt" );

	MItMeshPolygon polyIter( selEdgeObject );
	MItMeshEdge edgeIter( selEdgeObject, selEdgeComp );

	//MFnSingleIndexedComponent si( selEdgeComp );
	//MGlobal::displayInfo( MString("doing stuff on ") + selEdgeObject.fullPathName() + " " + si.element(0) );
	
	MFnSingleIndexedComponent indexedCompFn;
	MObject newComponent;		
	MSelectionList newSel;
	MIntArray edges;
	MIntArray faces;
	unsigned int i;
	const int initEdgeIndex = edgeIter.index();
	int initFaceIndex;
	int prevIndex, lastIndex;
	int faceIndex, edgeIndex;
	int newFaceIndex, newEdgeIndex;
	int nInitEdgeVisits;
	
	MIntArray remainFaces;
	MIntArray remainEdges;
	
	if( selType == RING )
	{
		nInitEdgeVisits = 0;
		
		// Push the face+edge combo on both sides 
		// of the current edge onto the stack
		edgeIter.getConnectedFaces( faces );
		if( faces.length() > 1 )
		{
			remainFaces.append( faces[1] );
			remainEdges.append( initEdgeIndex );
		}
		initFaceIndex = faces[0];
		remainFaces.append( initFaceIndex );
		remainEdges.append( initEdgeIndex );
		
		while( remainFaces.length() )
		{
			// Pop the face and edge indices
			lastIndex = remainFaces.length() - 1;
			faceIndex = remainFaces[ lastIndex ];
			edgeIndex = remainEdges[ lastIndex ];
			remainFaces.remove( lastIndex );
			remainEdges.remove( lastIndex );
			
			// If the current edge the initial edge
			if( faceIndex == initFaceIndex && 
				edgeIndex == initEdgeIndex )
			{
				// Reached back to the initial edge, so the loop is closed
				if( ++nInitEdgeVisits == 2 )
					break;
			}
			
			// Add edge to the new selection list
			if( selEdges )
			{
				newComponent = indexedCompFn.create( MFn::kMeshEdgeComponent );
				indexedCompFn.addElement( edgeIndex );
				newSel.add( selEdgeObject, newComponent );
			}
			
			// Add vertices to the new selection list
			if( selVertices )
			{
				newComponent = indexedCompFn.create( MFn::kMeshVertComponent );
				edgeIter.setIndex( edgeIndex, prevIndex );
				indexedCompFn.addElement( edgeIter.index(0) );
				indexedCompFn.addElement( edgeIter.index(1) );
				newSel.add( selEdgeObject, newComponent );
			}
			
			if( faceIndex != -1 ) // Not a boundary edge
			{
				// Add face to the new selection list
				if( selFaces )
				{
					newComponent = indexedCompFn.create( MFn::kMeshPolygonComponent );
					indexedCompFn.addElement( faceIndex );
					newSel.add( selEdgeObject, newComponent );		
				}
				
				// Get edge opposite the current edge
				//
				newEdgeIndex = navigateFace( selEdgeObject, faceIndex, 
											 edgeIndex, OPPOSITE );
				
				// Get the face on the other side of the opposite edge
				//
				edgeIter.setIndex( newEdgeIndex, prevIndex );
				edgeIter.getConnectedFaces( faces );
				
				newFaceIndex = -1; // Initialize to a boundary edge
				if( faces.length() > 1 )
					newFaceIndex = (faceIndex == faces[0]) ? 
									faces[1] : faces[0];
									
				// Push face and edge onto list
				remainFaces.append( newFaceIndex );
				remainEdges.append( newEdgeIndex );
			}
		}
	}
	else // Ring
	{
		int reflEdgeIndex;
		int newReflEdgeIndex;
		int initReflEdgeIndex;
		MIntArray remainReflEdges;
		
		nInitEdgeVisits = 0;
		
		// Push the face+edge+reflect combo on both sides 
		// of the current edge onto the stack
		//edgeIter.setIndex( initEdgeIndex, prevIndex );
		edgeIter.getConnectedFaces( faces );
		initFaceIndex = faces[0];
		for( i=0; i < 2; i++ )
		{
			remainFaces.append( initFaceIndex );
			remainEdges.append( initEdgeIndex );
			remainReflEdges.append(
				navigateFace( selEdgeObject, initFaceIndex, initEdgeIndex, 
							(i == 0) ? PREVIOUS : NEXT ) );
		}				
		initReflEdgeIndex = remainReflEdges[1];
				
		while( remainFaces.length() )
		{
			// Pop the face, edge, and reflEdge indices
			lastIndex = remainFaces.length() - 1;
			faceIndex = remainFaces[ lastIndex ];
			edgeIndex = remainEdges[ lastIndex ];
			reflEdgeIndex = remainReflEdges[ lastIndex ];
			remainFaces.remove( lastIndex );
			remainEdges.remove( lastIndex );
			remainReflEdges.remove( lastIndex );
									
			//MGlobal::displayInfo( MString("Face: ") + faceIndex + " edge: " + edgeIndex + " reflEdgeIndex: " + reflEdgeIndex );
		
			// If the current edge the initial edge
			if( faceIndex == initFaceIndex && 
				edgeIndex == initEdgeIndex &&
				reflEdgeIndex == initReflEdgeIndex )
			{
				// Reached back to the initial edge, so the ring is closed
				if( ++nInitEdgeVisits == 2 )
					break;
			}
										
			// Add edge to the new selection list
			if( selEdges )
			{
				newComponent = indexedCompFn.create( MFn::kMeshEdgeComponent );
				indexedCompFn.addElement( edgeIndex );
				newSel.add( selEdgeObject, newComponent );
			}
			
			// Add vertices to the new selection list
			if( selVertices )
			{
				newComponent = indexedCompFn.create( MFn::kMeshVertComponent );
				edgeIter.setIndex( edgeIndex, prevIndex );
				indexedCompFn.addElement( edgeIter.index(0) );
				indexedCompFn.addElement( edgeIter.index(1) );
				newSel.add( selEdgeObject, newComponent );
			}
			
			// Add face to the new selection list
			if( selFaces )
			{
				newComponent = indexedCompFn.create( MFn::kMeshPolygonComponent );
				indexedCompFn.addElement( faceIndex );
				newSel.add( selEdgeObject, newComponent );		
			}
			
			// Get the face on opposite side of reflEdge
			edgeIter.setIndex( reflEdgeIndex, prevIndex );
			edgeIter.getConnectedFaces( faces );

			// Only if there are two faces can their be an opposite face
			if( faces.length() > 1 )
			{
				newFaceIndex = (faceIndex == faces[0]) ?
								faces[1] : faces[0];			

				int edgePrev = navigateFace( selEdgeObject, newFaceIndex, reflEdgeIndex, PREVIOUS );
				int edgeNext = navigateFace( selEdgeObject, newFaceIndex, reflEdgeIndex, NEXT );
				
				// Determine which of the edges touches the original edge
				//
				edgeIter.setIndex( edgeIndex, prevIndex );
				if( edgeIter.connectedToEdge( edgePrev ) )
				{
					newEdgeIndex = edgePrev;
					newReflEdgeIndex = navigateFace( selEdgeObject, newFaceIndex, newEdgeIndex, PREVIOUS );
				}
				else
				{
					newEdgeIndex = edgeNext;
					newReflEdgeIndex = navigateFace( selEdgeObject, newFaceIndex, newEdgeIndex, NEXT );
				}
				
				// Push face, edge, and reflEdge onto list
				remainFaces.append( newFaceIndex );
				remainEdges.append( newEdgeIndex );
				remainReflEdges.append( newReflEdgeIndex );
			}
			
		}
	}	
		
	// Set the active selection to the one previous to edge loop selection
	MGlobal::setActiveSelectionList( prevSel, MGlobal::kReplaceList );

	// Update this selection based on the list adjustment setting
	MGlobal::selectCommand( newSel, listAdjust );

	return MS::kSuccess;	
}
コード例 #21
0
ファイル: meshOpFtyAction.cpp プロジェクト: OpenXRay/xray
MStatus meshOpFty::doIt()
//
//	Description:
//		Performs the operation on the selected mesh and components
//
{
	MStatus status;
	unsigned int i, j;

	// Get access to the mesh's function set
	//
	MFnMesh meshFn(fMesh);

	// The division count argument is used in many of the operations
	// to execute the operation multiple subsequent times. For example,
	// with a division count of 2 in subdivide face, the given faces will be
	// divide once and then the resulting inner faces will be divided again.
	//
	int divisionCount = 2;

	MFloatVector translation;
	if (fOperationType == kExtrudeEdges
		|| fOperationType == kExtrudeFaces
		|| fOperationType == kDuplicateFaces
		|| fOperationType == kExtractFaces)
	{
		// The translation vector is used for the extrude, extract and 
		// duplicate operations to move the result to a new position. For 
		// example, if you extrude an edge on a mesh without a subsequent 
		// translation, the extruded edge will be on at the position of the 
		// orignal edge and the created faces will have no area.
		// 
		// Here, we provide a translation that is in the same direction as the
		// average normal of the given components.
		//
		MFn::Type componentType = getExpectedComponentType(fOperationType);
		MIntArray adjacentVertexList;
		switch (componentType)
		{
		case MFn::kMeshEdgeComponent:
			for (i = 0; i < fComponentIDs.length(); ++i)
			{
				int2 vertices;
				meshFn.getEdgeVertices(fComponentIDs[i], vertices);
				adjacentVertexList.append(vertices[0]);
				adjacentVertexList.append(vertices[1]);
			}
			break;

		case MFn::kMeshPolygonComponent:
			for (i = 0; i < fComponentIDs.length(); ++i)
			{
				MIntArray vertices;
				meshFn.getPolygonVertices(fComponentIDs[i], vertices);
				for (j = 0; j < vertices.length(); ++j)
					adjacentVertexList.append(vertices[j]);
			}
			break;
		default:	
			break;
		}
		MVector averageNormal(0, 0, 0);
		for (i = 0; i < adjacentVertexList.length(); ++i)
		{
			MVector vertexNormal;
			meshFn.getVertexNormal(adjacentVertexList[i], vertexNormal,
				MSpace::kWorld);
			averageNormal += vertexNormal;
		}
		if (averageNormal.length() < 0.001)
			averageNormal = MVector(0.0, 1.0, 0.0);
		else averageNormal.normalize();
		translation = averageNormal;
	}

	// When doing an extrude operation, there is a choice of extrude the
	// faces/edges individually or together. If extrudeTogether is true and 
	// multiple adjacent components are selected, they will be extruded as if
	// it were one more complex component.
	//
	// The following variable sets that option.
	//
	bool extrudeTogether = true;

	// Execute the requested operation
	//
	switch (fOperationType)
	{
	case kSubdivideEdges: {
		status = meshFn.subdivideEdges(fComponentIDs, divisionCount);
		CHECK_STATUS(status);
		break; }

	case kSubdivideFaces: {
		status = meshFn.subdivideFaces(fComponentIDs, divisionCount);
		CHECK_STATUS(status);
		break; }

	case kExtrudeEdges: {
		status = meshFn.extrudeEdges(fComponentIDs, divisionCount,
			&translation, extrudeTogether);
		CHECK_STATUS(status);
		break; }

	case kExtrudeFaces: {
		status = meshFn.extrudeFaces(fComponentIDs, divisionCount,
			&translation, extrudeTogether);
		CHECK_STATUS(status);
		break; }

	case kCollapseEdges: {
		status = meshFn.collapseEdges(fComponentIDs);
		CHECK_STATUS(status);
		break; }

	case kCollapseFaces: {
		status = meshFn.collapseFaces(fComponentIDs);
		CHECK_STATUS(status);
		break; }

	case kDuplicateFaces: {
		status = meshFn.duplicateFaces(fComponentIDs, &translation);
		CHECK_STATUS(status);
		break; }

	case kExtractFaces: {
		status = meshFn.extractFaces(fComponentIDs, &translation);
		CHECK_STATUS(status);
		break; }

	case kSplitLightning: {
		status = doLightningSplit(meshFn);
		CHECK_STATUS(status);
		break; }

	default:
		status = MS::kFailure;
		break;
	}

	return status;
}
コード例 #22
0
ファイル: meshOpFtyAction.cpp プロジェクト: OpenXRay/xray
MStatus meshOpFty::doLightningSplit(MFnMesh& meshFn)
//
//	Description:
//		Performs the kSplitLightning operation on the selected mesh
//      and components. It may not split all the selected components.
//
{
	unsigned int i, j;

	// These are the input arrays to the split function. The following
	// algorithm fills them in with the arguments for a continuous
	// split that goes through some of the selected faces.
	//
	MIntArray placements;
	MIntArray edgeIDs;
	MFloatArray edgeFactors;
	MFloatPointArray internalPoints;
	
	// The following array is going to be used to determine which faces
	// have been split. Since the split function can only split faces
	// which are adjacent to the earlier face, we may not split
	// all the faces
	//
	bool* faceTouched = new bool[fComponentIDs.length()];
	for (i = 0; i < fComponentIDs.length(); ++i)
		faceTouched[i] = false;
	
	// We need a starting point. For this example, the first face in
	// the component list is picked. Also get a polygon iterator
	// to this face.
	// 
	MItMeshPolygon itPoly(fMesh);
	for (; !itPoly.isDone(); itPoly.next())
	{
		if (fComponentIDs[0] == itPoly.index()) break;
	}
	if (itPoly.isDone())
	{
		// Should never happen.
		//
		delete [] faceTouched;
		return MS::kFailure;
	}
	
	// In this example, edge0 is called the starting edge and
	// edge1 is called the destination edge. This algorithm will split
	// each face from the starting edge to the destination edge
	// while going through two inner points inside each face.
	//
	int edge0, edge1;
	MPoint innerVert0, innerVert1;
	int nextFaceIndex = 0;
	
	// We need a starting edge. For this example, the first edge in the
	// edge list is used.
	//
	MIntArray edgeList;
	itPoly.getEdges(edgeList);
	edge0 = edgeList[0];
	
	bool done = false;
	while (!done)
	{
		// Set this face as touched so that we don't try to split it twice
		//
		faceTouched[nextFaceIndex] = true;
		
		// Get the current face's center. It is used later in the
		// algorithm to calculate inner vertices.
		//
		MPoint faceCenter = itPoly.center();
			
		// Iterate through the connected faces to find an untouched,
		// selected face and get the ID of the shared edge. That face
		// will become the next face to be split.
		//
		MIntArray faceList;
		itPoly.getConnectedFaces(faceList);
		nextFaceIndex = -1;
		for (i = 0; i < fComponentIDs.length(); ++i)
		{
			for (j = 0; j < faceList.length(); ++j)
			{
				if (fComponentIDs[i] == faceList[j] && !faceTouched[i])
				{
					nextFaceIndex = i;
					break;
				}
			}
			if (nextFaceIndex != -1) break;
		}
		
		if (nextFaceIndex == -1)
		{
			// There is no selected and untouched face adjacent to this
			// face, so this algorithm is done. Pick the first edge that
			// is not the starting edge as the destination edge.
			//
			done = true;
			edge1 = -1;
			for (i = 0; i < edgeList.length(); ++i)
			{
				if (edgeList[i] != edge0)
				{
					edge1 = edgeList[i];
					break;
				}
			}
			if (edge1 == -1)
			{
				// This should not happen, since there should be more than
				// one edge for each face
				//
				delete [] faceTouched;
				return MS::kFailure;
			}
		}
		else
		{
			// The next step is to find out which edge is shared between
			// the two faces and use it as the destination edge. To do
			// that, we need to iterate through the faces and get the
			// next face's list of edges.
			//
			itPoly.reset();
			for (; !itPoly.isDone(); itPoly.next())
			{
				if (fComponentIDs[nextFaceIndex] == itPoly.index()) break;
			}
			if (itPoly.isDone()) 
			{
				// Should never happen.
				//
				delete [] faceTouched;
				return MS::kFailure;
			}
			
			// Look for a common edge ID in the two faces edge lists
			//
			MIntArray nextFaceEdgeList;
			itPoly.getEdges(nextFaceEdgeList);
			edge1 = -1;
			for (i = 0; i < edgeList.length(); ++i)
			{
				for (j = 0; j < nextFaceEdgeList.length(); ++j)
				{
					if (edgeList[i] == nextFaceEdgeList[j])
					{
						edge1 = edgeList[i];
						break;
					}
				}
				if (edge1 != -1) break;
			}
			if (edge1 == -1)
			{
				// Should never happen.
				//
				delete [] faceTouched;
				return MS::kFailure;
			}
			
			// Save the edge list for the next iteration
			//
			edgeList = nextFaceEdgeList;
		}
		
		// Calculate the two inner points that the split will go through.
		// For this example, the midpoints between the center and the two
		// farthest vertices of the edges are used.
		//
		// Find the 3D positions of the edges' vertices
		//
		MPoint edge0vert0, edge0vert1, edge1vert0, edge1vert1;
		MItMeshEdge itEdge(fMesh, MObject::kNullObj );
		for (; !itEdge.isDone(); itEdge.next())
		{
			if (itEdge.index() == edge0)
			{
				edge0vert0 = itEdge.point(0);
				edge0vert1 = itEdge.point(1);
			}
			if (itEdge.index() == edge1)
			{
				edge1vert0 = itEdge.point(0);
				edge1vert1 = itEdge.point(1);
			}
		}
		
		// Figure out which are the farthest from each other
		//
		double distMax = edge0vert0.distanceTo(edge1vert0);
		MPoint max0, max1;
		max0 = edge0vert0;
		max1 = edge1vert0;
		double newDist = edge0vert1.distanceTo(edge1vert0);
		if (newDist > distMax)
		{
			max0 = edge0vert1;
			max1 = edge1vert0;
			distMax = newDist;
		}
		newDist = edge0vert0.distanceTo(edge1vert1);
		if (newDist > distMax)
		{
			max0 = edge0vert0;
			max1 = edge1vert1;
			distMax = newDist;
		}
		newDist = edge0vert1.distanceTo(edge1vert1);
		if (newDist > distMax)
		{
			max0 = edge0vert1;
			max1 = edge1vert1;
		}
		
		// Calculate the two inner points
		//
		innerVert0 = (faceCenter + max0) / 2.0;
		innerVert1 = (faceCenter + max1) / 2.0;
		
		// Add this split's information to the input arrays. If this is
		// the last split, also add the destination edge's split information.
		//
		placements.append((int) MFnMesh::kOnEdge);
		placements.append((int) MFnMesh::kInternalPoint);
		placements.append((int) MFnMesh::kInternalPoint);
		if (done) placements.append((int) MFnMesh::kOnEdge);
		
		edgeIDs.append(edge0);
		if (done) edgeIDs.append(edge1);
		
		edgeFactors.append(0.5f);
		if (done) edgeFactors.append(0.5f);
		
		MFloatPoint point1((float)innerVert0[0], (float)innerVert0[1],
			(float)innerVert0[2], (float)innerVert0[3]);
		MFloatPoint point2((float)innerVert1[0], (float)innerVert1[1],
			(float)innerVert1[2], (float)innerVert1[3]);
		internalPoints.append(point1);
		internalPoints.append(point2);
		
		// For the next iteration, the current destination
		// edge becomes the start edge.
		//
		edge0 = edge1;
	}

	// Release the dynamically-allocated memory and do the actual split
	//
	delete [] faceTouched;
	return meshFn.split(placements, edgeIDs, edgeFactors, internalPoints);
}
コード例 #23
0
bool ToMayaMeshConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const
{
	MStatus s;

	IECore::ConstMeshPrimitivePtr mesh = IECore::runTimeCast<const IECore::MeshPrimitive>( from );
	assert( mesh );

	if ( !mesh->arePrimitiveVariablesValid() )
	{
		return false;
	}

	MFloatPointArray vertexArray;
	MIntArray polygonCounts;
	MIntArray polygonConnects;

	MFnMesh fnMesh;

	int numVertices = 0;
	IECore::PrimitiveVariableMap::const_iterator it = mesh->variables.find("P");
	if ( it != mesh->variables.end() )
	{
		/// \todo Employ some M*Array converters to simplify this
		IECore::ConstV3fVectorDataPtr p = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data);
		if (p)
		{
			numVertices = p->readable().size();

			vertexArray.setLength( numVertices );
			for (int i = 0; i < numVertices; i++)
			{
				vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3f>( p->readable()[i] );
			}
		}
		else
		{
			IECore::ConstV3dVectorDataPtr p = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
			if (p)
			{
				numVertices = p->readable().size();

				vertexArray.setLength( numVertices );
				for (int i = 0; i < numVertices; i++)
				{
					vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3d>( p->readable()[i] );
				}
			}
			else
			{
				// "P" is not convertible to an array of "points"
				return false;
			}
		}
	}


	IECore::ConstIntVectorDataPtr verticesPerFace = mesh->verticesPerFace();
	assert( verticesPerFace );
	int numPolygons = verticesPerFace->readable().size();

	polygonCounts.setLength( numPolygons );
	for (int i = 0; i < numPolygons; i++)
	{
		polygonCounts[i] = verticesPerFace->readable()[i];
	}

	IECore::ConstIntVectorDataPtr vertexIds = mesh->vertexIds();
	assert( vertexIds );
	int numPolygonConnects = vertexIds->readable().size();
	polygonConnects.setLength( numPolygonConnects );
	for (int i = 0; i < numPolygonConnects; i++)
	{
		polygonConnects[i] = vertexIds->readable()[i];
	}

	MObject mObj = fnMesh.create( numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, to, &s );

	if (!s)
	{
		return false;
	}

	it = mesh->variables.find("N");
	if ( it != mesh->variables.end() )
	{
		if (it->second.interpolation == IECore::PrimitiveVariable::FaceVarying )
		{
			/// \todo Employ some M*Array converters to simplify this
			MVectorArray vertexNormalsArray;
			IECore::ConstV3fVectorDataPtr n = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data);
			if (n)
			{
				int numVertexNormals = n->readable().size();

				vertexNormalsArray.setLength( numVertexNormals );
				for (int i = 0; i < numVertexNormals; i++)
				{
					vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3f>( n->readable()[i] );
				}
			}
			else
			{
				IECore::ConstV3dVectorDataPtr n = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
				if (n)
				{
					int numVertexNormals = n->readable().size();

					vertexNormalsArray.setLength( numVertexNormals );
					for (int i = 0; i < numVertexNormals; i++)
					{
						vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3d>( n->readable()[i] );
					}
				}
				else
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"N\" has unsupported type \"%s\"." ) % it->second.data->typeName() );
				}
			}
			
			if ( vertexNormalsArray.length() )
			{
				MStatus status;
				MItMeshPolygon itPolygon( mObj, &status );
				if( status != MS::kSuccess )
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to create mesh iterator" );
				}

				unsigned v = 0;
				MIntArray vertexIds;
				MIntArray faceIds;
				
				for ( ; !itPolygon.isDone(); itPolygon.next() )
				{
					for ( v=0; v < itPolygon.polygonVertexCount(); ++v )
					{
						faceIds.append( itPolygon.index() );
						vertexIds.append( itPolygon.vertexIndex( v ) );
					}
				}

				if( !fnMesh.setFaceVertexNormals( vertexNormalsArray, faceIds, vertexIds ) )
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Setting normals failed" );
				}
			}
		}
		else
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "PrimitiveVariable \"N\" has unsupported interpolation (expected FaceVarying)." );
		}
	}

	bool haveDefaultUVs = false;
	IECore::PrimitiveVariableMap::const_iterator sIt = mesh->variables.find( "s" );
	IECore::RefCountedPtr sDataRef = ( sIt == mesh->variables.end() ) ? 0 : static_cast<IECore::RefCountedPtr>( sIt->second.data );

	/// Add named UV sets
	std::set< std::string > uvSets;
	for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it )
	{
		const std::string &sName = it->first;

		size_t suffixOffset = sName.rfind( "_s" );

		if ( ( suffixOffset != std::string::npos) && ( suffixOffset == sName.length() - 2 ) )
		{
			std::string uvSetNameStr = sName.substr( 0, suffixOffset );

			if ( uvSetNameStr.size() )
			{
				MString uvSetName = uvSetNameStr.c_str();
				std::string tName = uvSetNameStr + "_t";
				std::string stIdName = uvSetNameStr + "Indices";

				addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName );

				uvSets.insert( uvSetNameStr );
				
				if ( sDataRef == static_cast<IECore::RefCountedPtr>( it->second.data ) )
				{
					haveDefaultUVs = true;
				}
			}
		}
	}

	/// Add default UV set if it isn't just a reference to a named set
	if ( !haveDefaultUVs )
	{
		addUVSet( fnMesh, polygonCounts, mesh, "s", "t", "stIndices" );
	}

	// We do the search again, but looking for primvars ending "_t", so we can catch cases where either "UVSETNAME_s" or "UVSETNAME_t" is present, but not both, taking care
	// not to attempt adding any duplicate sets
	for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it )
	{
		const std::string &tName = it->first;

		size_t suffixOffset = tName.rfind( "_t" );

		if ( ( suffixOffset != std::string::npos) && ( suffixOffset == tName.length() - 2 ) )
		{
			std::string uvSetNameStr = tName.substr( 0, suffixOffset );

			if ( uvSetNameStr.size() && uvSets.find( uvSetNameStr ) == uvSets.end() )
			{
				MString uvSetName = uvSetNameStr.c_str();
				std::string sName = uvSetNameStr + "_s";
				std::string stIdName = uvSetNameStr + "Indices";
				
				addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName );
				uvSets.insert( uvSetNameStr );
			}
		}
	}

	/// If we're making a mesh node (rather than a mesh data) then make sure it belongs
	/// to the default shading group and add the ieMeshInterpolation attribute.
	MObject oMesh = fnMesh.object();
	if( oMesh.apiType()==MFn::kMesh )
	{
		assignDefaultShadingGroup( oMesh );
		setMeshInterpolationAttribute( oMesh, mesh->interpolation() );
	}

	/// \todo Other primvars, e.g. vertex color ("Cs")

	return true;
}
コード例 #24
0
ファイル: volumeLightCmd.cpp プロジェクト: DimondTheCat/xray
MStatus volumeLight::doIt( const MArgList& args )
{
	MStatus stat;

	double arc = 180.0f;
	double coneEndRadius = 0.0f;
	MFnVolumeLight::MLightDirection volumeLightDirection = MFnVolumeLight::kOutward;
	MFnVolumeLight::MLightShape lightShape = MFnVolumeLight::kConeVolume;
	bool emitAmbient = true;

	unsigned	i;

	// Parse the arguments.
	for ( i = 0; i < args.length(); i++ )
	{
		if ( MString( "-a" ) == args.asString( i, &stat )
				&& MS::kSuccess == stat)
		{
			double tmp = args.asDouble( ++i, &stat );
			if ( MS::kSuccess == stat )
				arc = tmp;
		}
		else if ( MString( "-c" ) == args.asString( i, &stat )
				&& MS::kSuccess == stat)
		{
			double tmp = args.asDouble( ++i, &stat );
			if ( MS::kSuccess == stat )
				coneEndRadius = tmp;
		}
		else if ( MString( "-e" ) == args.asString( i, &stat )
				&& MS::kSuccess == stat)
		{
			bool tmp = args.asBool( ++i, &stat );
			if ( MS::kSuccess == stat )
				emitAmbient = tmp;
		}

	}

	MFnVolumeLight light;

	light.create( true, &stat);

	cout<<"What's up?";

	if ( MS::kSuccess != stat )
	{
		cout<<"Error creating light."<<endl;
		return stat;
	}
	
	stat = light.setArc ((float)arc);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error setting \"arc\" attribute."<<endl;
		return stat;
	}

	stat = light.setVolumeLightDirection (volumeLightDirection);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error setting \"volumeLightDirection\" attribute."<<endl;
		return stat;
	}

	stat = light.setConeEndRadius ((float)coneEndRadius);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error setting \"coneEndRadius\" attribute."<<endl;
		return stat;
	}

	stat = light.setEmitAmbient (emitAmbient);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error setting \"emitAmbient\" attribute."<<endl;
		return stat;
	}

	stat = light.setLightShape (lightShape);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error setting \"lightShape\" attribute."<<endl;
		return stat;
	}

	double arcGet = light.arc (&stat);
	if ( MS::kSuccess != stat || arcGet != arc)
	{
		cout<<"Error getting \"arc\" attribute."<<endl;
		return stat;
	}

	MFnVolumeLight::MLightDirection volumeLightDirectionGet = light.volumeLightDirection (&stat);
	if ( MS::kSuccess != stat || volumeLightDirectionGet != volumeLightDirection)
	{
		cout<<"Error getting \"volumeLightDirection\" attribute."<<endl;
		return stat;
	}

	double coneEndRadiusGet = light.coneEndRadius (&stat);
	if ( MS::kSuccess != stat || coneEndRadiusGet != coneEndRadius)
	{
		cout<<"Error getting \"coneEndRadius\" attribute."<<endl;
		return stat;
	}

	bool emitAmbientGet = light.emitAmbient (&stat);
	if ( MS::kSuccess != stat || emitAmbientGet != emitAmbient)
	{
		cout<<"Error getting \"emitAmbient\" attribute."<<endl;
		return stat;
	}

	MFnVolumeLight::MLightShape lightShapeGet = light.lightShape (&stat);
	if ( MS::kSuccess != stat || lightShapeGet != lightShape)
	{
		cout<<"Error getting \"lightShape\" attribute."<<endl;
		return stat;
	}

	// Get reference to the penumbra ramp.
	MRampAttribute ramp = light.penumbraRamp (&stat);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error getting \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	MFloatArray a, b;
	MIntArray c,d;

	// Get the entries in the ramp
	ramp.getEntries (d, a, b, c, &stat);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error getting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	// There should be 2 entries by default.
	if (d.length() != 2)
	{
		cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	MFloatArray a1, b1;
	MIntArray c1;

	// Prepare an array of entries to add.
	// In this case we are just adding 1 more entry
	// at position 0.5 with a curve value of 0.25 and a linear interpolation.
	a1.append (0.5f);
	b1.append (0.25f);
	c1.append (MRampAttribute::kLinear);

	// Add it to the curve ramp
	ramp.addEntries (a1, b1, c1, &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error adding entries to \"penumbraRamp\" attribute."<<endl;
		return stat;
	}


	// Get the entries to make sure that the above add actually worked.
	MFloatArray a2, b2;
	MIntArray c2,d2;
	ramp.getEntries (d2, a2, b2, c2, &stat);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error getting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}
	if ( a.length() + a1.length() != a2.length())
	{
		cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	// Now try to interpolate the value at a point
	float newVal = -1;
	ramp.getValueAtPosition(.3f, newVal, &stat);

	if ( MS::kSuccess != stat )
	{
		cout<<"Error interpolating value from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}
	if ( !EQUAL(newVal, .15f))
	{
		cout<<"Invalid interpolation in  \"penumbraRamp\" expected .15 got "<<newVal
			<<" ."<<endl;
	}

	// Try to delete an entry in an incorrect manner. 
	// This delete will work because there is an entry at 0, 
	// However we should never do it this way, because the entries
	// array can become sparse, so trying to delete an entry without 
	// checking whether an entry exists at that index can cause a failure.
	MIntArray entriesToDelete;
	entriesToDelete.append (0);
	ramp.deleteEntries (entriesToDelete, &stat);
	if ( MS::kSuccess != stat )
	{
		cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	// Check to see whether the above delete worked.
	// As mentioned earlier it did work, but we shouldn't do it this way.
	// To illustrate why we shouldn't do it this way, we'll try to delete
	// entry at index 0 ( this no longer exists)
	ramp.getEntries (d2, a2, b2, c2, &stat);

	if ( a2.length() != 2)
	{
		cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
		return stat;
	}
	// Trying to delete entry at 0.
	entriesToDelete.clear();
	entriesToDelete.append (0);
	ramp.deleteEntries (entriesToDelete, &stat);

	// It will fail because no entry exists.
	if ( MS::kSuccess == stat)
	{
		cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}
	if ( a2.length() != 2)
	{
		cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	// The proper way to delete is to retrieve the index by calling "getEntries"
	ramp.getEntries (d2, a2, b2, c2, &stat);
	entriesToDelete.clear();
	entriesToDelete.append (d2[0]);

	// Delete the first logical entry in the entry array.
	ramp.deleteEntries (entriesToDelete, &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	// There should be only 1 entry left.
	ramp.getEntries (d2, a2, b2, c2, &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error getting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}
	entriesToDelete.clear();
	entriesToDelete.append (d2[0]);

	// Can't delete the last entry, should return failure.
	ramp.deleteEntries (entriesToDelete, &stat);
	if ( MS::kSuccess == stat)
	{
		cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}

	ramp.setPositionAtIndex (0.0f, d2[0], &stat);
	if ( MS::kSuccess != stat)
	{
		printf("Error setting position at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]);
		return stat;
	}

	ramp.setValueAtIndex (1.0f, d2[0], &stat);
	if ( MS::kSuccess != stat)
	{
		printf("Error setting value at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]);
		return stat;
	}

	ramp.setInterpolationAtIndex (MRampAttribute::kNone, d2[0], &stat);
	if ( MS::kSuccess != stat)
	{
		printf("Error setting interpolation at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]);
		return stat;
	}

  	MRampAttribute ramp2 = light.colorRamp (&stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error getting  \"colorRamp\" attribute."<<endl;
		return stat;
	}	
	MFloatArray a3;
	MColorArray b3;
	MIntArray c3,d3;

  	// Get the entries in the ramp
	ramp2.getEntries (d3, a3, b3, c3, &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error getting entries from \"colorRamp\" attribute."<<endl;
		return stat;
	}
	// There should be 2 entries by default.
	if ( d3.length() != 2)
	{
		cout<<"Invalid number of entries in \"colorRamp\" attribute."<<endl;
		return stat;
	}

	MFloatArray a4;
	MColorArray b4;
	MIntArray c4;

	// Prepare an array of entries to add.
	// In this case we are just adding 1 more entry
	// at position 0.5 withe curve value of 0.5 and a linear interpolation.
	a4.append (0.5f);
	b4.append (MColor (0.0f, 0.0f, 0.75f));
	c4.append (MRampAttribute::kLinear);

	// Add it to the curve ramp
	ramp2.addEntries (a4, b4, c4, &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error adding entries to \"colorRamp\" attribute."<<endl;
		return stat;
	}
	// Get the entries to make sure that the above add actually worked.
	MFloatArray a5;
	MColorArray b5;
	MIntArray c5,d5;
	ramp2.getEntries (d5, a5, b5, c5, &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error getting entries from \"colorRamp\" attribute."<<endl;
		return stat;
	}
	if (  a3.length() + a4.length() != a5.length())
	{
		cout<<"Invalid number of entries in \"colorRamp\" attribute."<<endl;
		return stat;
	}

	// Now try to interpolate the color at a point
	MColor newCol(0.0, 0.0, 0.0);
	ramp2.getColorAtPosition(.3f, newCol, &stat);

	if ( MS::kSuccess != stat )
	{
		cout<<"Error interpolating color from \"penumbraRamp\" attribute."<<endl;
		return stat;
	}
	if ( !EQUAL(newCol[2], .45))
	{
		cout<<"Invalid color interpolation in  \"colorRamp\" expected .45 got "<<newCol[2]<<endl;
	}

	MColor clr (0.5, 0.5, 0.0);
	ramp2.setColorAtIndex (clr, d5[0], &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error setting color at index: "<<d5[0]
			<<", of \"colorRamp\" attribute."<<endl;
		return stat;
	}

	ramp2.setInterpolationAtIndex (MRampAttribute::kSpline, d5[1], &stat);
	if ( MS::kSuccess != stat)
	{
		cout<<"Error setting interpolation at index: "<<d5[1]
			<<", of \"colorRamp\" attribute."<<endl;
		return stat;
	}

	return stat;
}
コード例 #25
0
ファイル: field3D_Query.cpp プロジェクト: gatgui/Field3DMaya
MStatus QueryF3d::doIt(const MArgList &argList)
{
  MStatus stat;
  MSyntax syntax = newSyntax();
  MArgParser args(syntax, argList);
  char msg[4096];
  
  if (!args.isFlagSet("-file"))
  {
    MGlobal::displayError("queryF3d: missing -f/-file flag");
    return MS::kFailure;
  }
  
  bool verbose = args.isFlagSet("-verbose");
  
  MString sarg;
  
  stat = args.getFlagArgument("-file", 0, sarg);
  if (stat != MS::kSuccess)
  {
    stat.perror("queryF3d");
    return stat;
  }
  
  std::string pat = sarg.asChar();
  
  ToPrintfPattern(pat);
  
  if (verbose)
  {
    MGlobal::displayInfo("queryF3d: File pattern \"" + sarg + "\" -> \"" + MString(pat.c_str()) + "\"");
  }
  
  std::vector<std::string> files;
  int startFrame = -1;
  int endFrame = -1;
  
  if (GetFileList(pat, files, &startFrame, &endFrame) == 0)
  {
    MGlobal::displayError("queryF3d: No file matching " + sarg);
    return MS::kFailure;
  }
  
  if (verbose)
  {
    MGlobal::displayInfo("queryF3d: Found file(s)");
    for (size_t i=0; i<files.size(); ++i)
    {
      MGlobal::displayInfo("  " + MString(files[i].c_str()));
    }
  }
  
  if (args.isFlagSet("-range"))
  {
    MIntArray res;
    
    res.append(startFrame);
    res.append(endFrame);
    
    setResult(res);
    
    return MS::kSuccess;
  }
  else
  {
    Field3D::Field3DInputFile f3d;
    
    if (f3d.open(files[0]))
    {
      if (args.isFlagSet("-partitions"))
      {
        MStringArray rv;
        std::vector<std::string> names;
        
        f3d.getPartitionNames(names);
        
        if (verbose)
        {
          sprintf(msg, "queryF3d: Found %lu partition(s)", names.size());
          MGlobal::displayInfo(msg);
        }
        
        for (size_t i=0; i<names.size(); ++i)
        {
          rv.append(names[i].c_str());
        }
        
        setResult(rv);
        
        return MS::kSuccess;
      }
      else if (args.isFlagSet("-layers"))
      {
        if (!args.isFlagSet("-partition"))
        {
          MGlobal::displayError("queryF3d: Please specify the partition with -p/-partition flag");
          return MS::kFailure;
        }
        
        stat = args.getFlagArgument("-partition", 0, sarg);
        if (stat != MS::kSuccess)
        {
          stat.perror("queryF3d");
          return stat;
        }
        
        MStringArray rv;
        
        std::string partition = sarg.asChar();
        std::vector<std::string> names;
        
        bool scalar = args.isFlagSet("-scalar");
        bool vector = args.isFlagSet("-vector");
        
        if (!scalar && !vector)
        {
          // neither -scalar nor -vector flag were set, output both
          scalar = true;
          vector = true;
        }
        
        if (scalar)
        {
          f3d.getScalarLayerNames(names, partition);
          for (size_t i=0; i<names.size(); ++i)
          {
            rv.append(names[i].c_str());
          }
        }
        
        if (vector)
        {
          names.clear();
          
          f3d.getVectorLayerNames(names, partition);
          for (size_t i=0; i<names.size(); ++i)
          {
            rv.append(names[i].c_str());
          }
        }
        
        setResult(rv);
        
        return MS::kSuccess;
      }
      else if (args.isFlagSet("-resolution"))
      {
        if (!args.isFlagSet("-partition"))
        {
          MGlobal::displayError("queryF3d: Please specify the partition with -p/-partition flag");
          return MS::kFailure;
        }
        
        if (!args.isFlagSet("-layer"))
        {
          MGlobal::displayError("queryF3d: Please specify the layer with -l/-layer flag");
          return MS::kFailure;
        }
        
        stat = args.getFlagArgument("-partition", 0, sarg);
        if (stat != MS::kSuccess)
        {
          stat.perror("queryF3d");
          return stat;
        }
        
        std::string partition = sarg.asChar();
        
        stat = args.getFlagArgument("-layer", 0, sarg);
        if (stat != MS::kSuccess)
        {
          stat.perror("queryF3d");
          return stat;
        }
        
        std::string layer = sarg.asChar();
        
        if (verbose)
        {
          sprintf(msg, "queryF3d: Read resolution for %s.%s", partition.c_str(), layer.c_str());
          MGlobal::displayInfo(msg);
        }
        
        MIntArray rv;
        
        // When reading proxy layers, the type doesn't actually matters
        
        Field3D::EmptyField<Field3D::half>::Vec fields = f3d.readProxyLayer<Field3D::half>(partition, layer, false);
        
        if (fields.size() == 0)
        {
          fields = f3d.readProxyLayer<Field3D::half>(partition, layer, true);
          if (verbose && fields.size() > 0)
          {
            MGlobal::displayInfo("(vector field)");
          }
        }
        else if (verbose)
        {
          MGlobal::displayInfo("(scalar field)");
        }
        
        if (fields.size() > 0)
        {
          Field3D::V3i res = fields[0]->dataResolution();
          
          rv.append(res.x);
          rv.append(res.y);
          rv.append(res.z);
          
          setResult(rv);
          
          return MS::kSuccess;
        }
        
        MGlobal::displayWarning("queryF3d: Unsupported field type");
        
        return MS::kFailure;
      }
      else
      {
        MGlobal::displayInfo("queryF3d: Nothing to query");
        return MS::kFailure;
      }
    }
    else
    {
      MGlobal::displayError("queryF3d: Could not open file \"" + MString(files[0].c_str()) + "\"");
      return MS::kFailure;
    }
  }
}
コード例 #26
0
void OutputTextures(MSelectionList selected){
	
	
MString temp;
MString affich;
	

	
int MatExists=0;
	for(int i=0;i<selected.length();i++){
	

	MDagPath path;
	MObject obj;

	selected.getDagPath(i,path);

	
	obj=path.child(0);

	

	MFnMesh fn(path);
	obj=fn.parent(0);
	path.getAPathTo(fn.parent(0));
	MFnMesh fna(path);
	
	
	unsigned int instancenumbers;
	MObjectArray shaders;
	MIntArray indices;

	fna.getConnectedShaders(instancenumbers,shaders,indices);

	

switch(shaders.length()) {

		// if no shader applied to the mesh instance
		case 0:
			{
				//***************Affich("pas de matériaux");
			}
			break;

		// if all faces use the same material
	
		// if more than one material is used, write out the face indices the materials
		// are applied to.
		default:
			{
				//************************Affich("trouvé plusieurs matériaux");

				
				//write_int(shaders.length());

				// now write each material and the face indices that use them
				
				for(int j=0;j < shaders.length();++j)
				{						
					for(int matest=0;matest<Matid.length();matest++){
						//**************************Affich(Matid[matest].asChar());
						//*****************************Affich(GetShaderName( shaders[j] ).asChar());
						if(Matid[matest]== GetShaderName( shaders[j] )){
						MatExists = 1;
						
						}//fin if matid
						
						}// fin for matest
					if(MatExists != 1){
					//*****************************Affich("matériau absent de la liste, enregistrement");
					Matid.append(GetShaderName( shaders[j] ).asChar());
					nb_Tex_by_Brush.append(0);
						writeTexture(shaders[j],"color");

					//Affich(temp);
					}else {
					//*************************************	Affich("matériau existe dans la liste");
					}// fin if matexists
					
					MatExists = 0;
						

				}//fin for j shaders
			}// fin case default
			break;
		}//fin switches

	}//fin for selected
		

	Matid.clear();
}// fin output textures
コード例 #27
0
bool Outputtexture(MFnDependencyNode& fn,const char* name)
{
  	MPlug p;

MString r = name;
r += "R";
MString g = name;
g += "G";
MString b = name;
b += "B";
MString a = name;
a += "A";

// get the color value
MColor color;

// get a plug to the attribute
p = fn.findPlug(r);
p.getValue(color.r);
p = fn.findPlug(g.asChar());
p.getValue(color.g);
p = fn.findPlug(b.asChar());
p.getValue(color.b);
p = fn.findPlug(a.asChar());
p.getValue(color.a);
p = fn.findPlug(name);

// will hold the txture node name
MString texname;

// get plugs connected to colour attribute
MPlugArray plugs;
p.connectedTo(plugs,true,false);

// see if any file textures are present
	for(int i=0;i!=plugs.length();++i)
		{
  			// if file texture found
			if(plugs[i].node().apiType() == MFn::kFileTexture)
				{
  					// bind a function set to it ....
					MFnDependencyNode fnDep(plugs[i].node());

					// to get the node name
					texname = fnDep.name();
					

					int TexExists=0;
						for(int i=0;i<Texid.length();i++)
							{
								if(texname==Texid[i]) TexExists=1;
							}
							if(TexExists==0){
							// écrire la texture car absente
								Texid.append(texname);
								Affich(texname);
							
								
								//write_int(Matid.length());//id Brush
								//write_int(1);//textures per brush
								//::output << GetShaderName( shaders[j] ).asChar();
								
								
								
								// get the attribute for the full texture path
MPlug ftn = fnDep.findPlug("ftn");

// get the filename from the attribute
MString filename;
ftn.getValue(filename);

// write the file name
								


nb_Tex_by_Brush[Matid.length()-1]++;// une nouvelle texture dans la brush courante
Texids_by_brush.append(Texid.length()-1);
								::output << filename;
								
								
								
								::output << char(0x00);
								//write flags, blend default 1, 2
								write_int(1);
								write_int(2);
								// write position default O, O
								write_float(0);
								write_float(0);
								//write scale default 1, 1
								write_float(1);
								write_float(1);
								//rotation in radian default= 0
								write_float(0);

								//OutputColors(shaders[j],"color");

								//EndChunck();
							}else {
		nb_Tex_by_Brush[Matid.length()-1]=0;
		//Texids_by_brush.append(0);
				Texids_by_brush.append(0);
			}
					// stop looping
					//TexExists=0;

				}

			
		}



return true;

} 
コード例 #28
0
ファイル: translatorMesh.cpp プロジェクト: JT-a/USD
PXR_NAMESPACE_OPEN_SCOPE



/* static */
bool 
PxrUsdMayaTranslatorMesh::Create(
        const UsdGeomMesh& mesh,
        MObject parentNode,
        const PxrUsdMayaPrimReaderArgs& args,
        PxrUsdMayaPrimReaderContext* context)
{
    if (!mesh) {
        return false;
    }

    const UsdPrim& prim = mesh.GetPrim();

    MStatus status;

    // Create node (transform)
    MObject mayaNodeTransformObj;
    if (!PxrUsdMayaTranslatorUtil::CreateTransformNode(prim,
                                                          parentNode,
                                                          args,
                                                          context,
                                                          &status,
                                                          &mayaNodeTransformObj)) {
        return false;
    }

    VtArray<GfVec3f> points;
    VtArray<GfVec3f> normals;
    VtArray<int>     faceVertexCounts;
    VtArray<int>     faceVertexIndices;
    
    UsdAttribute fvc = mesh.GetFaceVertexCountsAttr();
    if (fvc.ValueMightBeTimeVarying()){
        // at some point, it would be great, instead of failing, to create a usd/hydra proxy node
        // for the mesh, perhaps?  For now, better to give a more specific error
        MGlobal::displayError(
            TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexCounts). Skipping...", 
                prim.GetPath().GetText()).c_str());
        return false;
    } else {
        // for any non-topo-varying mesh, sampling at zero will get us the right answer
        fvc.Get(&faceVertexCounts, 0);
    }

    UsdAttribute fvi = mesh.GetFaceVertexIndicesAttr();
    if (fvi.ValueMightBeTimeVarying()){
        // at some point, it would be great, instead of failing, to create a usd/hydra proxy node
        // for the mesh, perhaps?  For now, better to give a more specific error
        MGlobal::displayError(
            TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexIndices). Skipping...", 
                prim.GetPath().GetText()).c_str());
        return false;
    } else {
        // for any non-topo-varying mesh, sampling at zero will get us the right answer
        fvi.Get(&faceVertexIndices, 0);
    }
        
    // Sanity Checks. If the vertex arrays are empty, skip this mesh
    if (faceVertexCounts.size() == 0 || faceVertexIndices.size() == 0) {
        MGlobal::displayError(
            TfStringPrintf("FaceVertex arrays are empty [Count:%zu Indices:%zu] on Mesh <%s>. Skipping...", 
                faceVertexCounts.size(), faceVertexIndices.size(), 
                prim.GetPath().GetText()).c_str());
        return false; // invalid mesh, so exit
    }

    // Gather points and normals
    // If args.GetReadAnimData() is TRUE,
    // pick the first avaiable sample or default
    UsdTimeCode pointsTimeSample=UsdTimeCode::EarliestTime();
    UsdTimeCode normalsTimeSample=UsdTimeCode::EarliestTime();
    std::vector<double> pointsTimeSamples;
    size_t pointsNumTimeSamples = 0;
    if (args.GetReadAnimData()) {
        PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetPointsAttr(), args,
                &pointsTimeSamples);
        pointsNumTimeSamples = pointsTimeSamples.size();
        if (pointsNumTimeSamples>0) {
            pointsTimeSample = pointsTimeSamples[0];
        }
    	std::vector<double> normalsTimeSamples;
        PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetNormalsAttr(), args,
                &normalsTimeSamples);
        if (normalsTimeSamples.size()) {
            normalsTimeSample = normalsTimeSamples[0];
        }
    }
    mesh.GetPointsAttr().Get(&points, pointsTimeSample);
    mesh.GetNormalsAttr().Get(&normals, normalsTimeSample);
    
    if (points.size() == 0) {
        MGlobal::displayError(
            TfStringPrintf("Points arrays is empty on Mesh <%s>. Skipping...", 
                prim.GetPath().GetText()).c_str());
        return false; // invalid mesh, so exit
    }


    // == Convert data
    size_t mayaNumVertices = points.size();
    MPointArray mayaPoints(mayaNumVertices);
    for (size_t i=0; i < mayaNumVertices; i++) {
        mayaPoints.set( i, points[i][0], points[i][1], points[i][2] );
    }

    MIntArray polygonCounts( faceVertexCounts.cdata(),  faceVertexCounts.size() );
    MIntArray polygonConnects( faceVertexIndices.cdata(), faceVertexIndices.size() );

    // == Create Mesh Shape Node
    MFnMesh meshFn;
    MObject meshObj = meshFn.create(mayaPoints.length(), 
                           polygonCounts.length(), 
                           mayaPoints, 
                           polygonCounts, 
                           polygonConnects,
                           mayaNodeTransformObj,
                           &status
                           );
                           
    if (status != MS::kSuccess) {
        return false;
    }

    // Since we are "decollapsing", we will create a xform and a shape node for each USD prim
    std::string usdPrimName(prim.GetName().GetText());
    std::string shapeName(usdPrimName); shapeName += "Shape";
    // Set mesh name and register
    meshFn.setName(MString(shapeName.c_str()), false, &status);
    if (context) {
        std::string usdPrimPath(prim.GetPath().GetText());
        std::string shapePath(usdPrimPath);
        shapePath += "/";
        shapePath += shapeName;
        context->RegisterNewMayaNode( shapePath, meshObj ); // used for undo/redo
    }

    // If a material is bound, create (or reuse if already present) and assign it
    // If no binding is present, assign the mesh to the default shader    
    const TfToken& shadingMode = args.GetShadingMode();
    PxrUsdMayaTranslatorMaterial::AssignMaterial(shadingMode, mesh, meshObj,
            context);
    
    // Mesh is a shape, so read Gprim properties
    PxrUsdMayaTranslatorGprim::Read(mesh, meshObj, context);

    // Set normals if supplied
    MIntArray normalsFaceIds;
    if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) {

        for (size_t i=0; i < polygonCounts.length(); i++) {
            for (int j=0; j < polygonCounts[i]; j++) {
                normalsFaceIds.append(i);
            }
        }
        if (normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) {
            MVectorArray mayaNormals(normals.size());
            for (size_t i=0; i < normals.size(); i++) {
                mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i);
            }
            if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) {
            }
        }
     }

    // Determine if PolyMesh or SubdivMesh
    TfToken subdScheme = PxrUsdMayaMeshUtil::setSubdivScheme(mesh, meshFn, args.GetDefaultMeshScheme());

    // If we are dealing with polys, check if there are normals
    // If we are dealing with SubdivMesh, read additional attributes and SubdivMesh properties
    if (subdScheme == UsdGeomTokens->none) {
        if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) {
            PxrUsdMayaMeshUtil::setEmitNormals(mesh, meshFn, UsdGeomTokens->none);
        }
    } else {
        PxrUsdMayaMeshUtil::setSubdivInterpBoundary(mesh, meshFn, UsdGeomTokens->edgeAndCorner);
        PxrUsdMayaMeshUtil::setSubdivFVLinearInterpolation(mesh, meshFn);
        _AssignSubDivTagsToMesh(mesh, meshObj, meshFn);
    }
 
    // Set Holes
    VtArray<int> holeIndices;
    mesh.GetHoleIndicesAttr().Get(&holeIndices);   // not animatable
    if ( holeIndices.size() != 0 ) {
        MUintArray mayaHoleIndices;
        mayaHoleIndices.setLength( holeIndices.size() );
        for (size_t i=0; i < holeIndices.size(); i++) {
            mayaHoleIndices[i] = holeIndices[i];
        }
        if (meshFn.setInvisibleFaces(mayaHoleIndices) == MS::kFailure) {
            MGlobal::displayError(TfStringPrintf("Unable to set Invisible Faces on <%s>", 
                            meshFn.fullPathName().asChar()).c_str());
        }
    }

    // GETTING PRIMVARS
    std::vector<UsdGeomPrimvar> primvars = mesh.GetPrimvars();
    TF_FOR_ALL(iter, primvars) {
        const UsdGeomPrimvar& primvar = *iter;
        const TfToken& name = primvar.GetBaseName();
        const SdfValueTypeName& typeName = primvar.GetTypeName();

        // If the primvar is called either displayColor or displayOpacity check
        // if it was really authored from the user.  It may not have been
        // authored by the user, for example if it was generated by shader
        // values and not an authored colorset/entity.
        // If it was not really authored, we skip the primvar.
        if (name == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName || 
                name == PxrUsdMayaMeshColorSetTokens->DisplayOpacityColorSetName) {
            if (!PxrUsdMayaRoundTripUtil::IsAttributeUserAuthored(primvar)) {
                continue;
            }
        }

        // XXX: Maya stores UVs in MFloatArrays and color set data in MColors
        // which store floats, so we currently only import primvars holding
        // float-typed arrays. Should we still consider other precisions
        // (double, half, ...) and/or numeric types (int)?
        if (typeName == SdfValueTypeNames->Float2Array) {
            // We assume that Float2Array primvars are UV sets.
            if (!_AssignUVSetPrimvarToMesh(primvar, meshFn)) {
                MGlobal::displayWarning(
                    TfStringPrintf("Unable to retrieve and assign data for UV set <%s> on mesh <%s>", 
                                   name.GetText(),
                                   mesh.GetPrim().GetPath().GetText()).c_str());
            }
        } else if (typeName == SdfValueTypeNames->FloatArray   || 
                   typeName == SdfValueTypeNames->Float3Array  || 
                   typeName == SdfValueTypeNames->Color3fArray ||
                   typeName == SdfValueTypeNames->Float4Array  || 
                   typeName == SdfValueTypeNames->Color4fArray) {
            if (!_AssignColorSetPrimvarToMesh(mesh, primvar, meshFn)) {
                MGlobal::displayWarning(
                    TfStringPrintf("Unable to retrieve and assign data for color set <%s> on mesh <%s>",
                                   name.GetText(),
                                   mesh.GetPrim().GetPath().GetText()).c_str());
            }
        }
    }

    // We only vizualize the colorset by default if it is "displayColor".  
    MStringArray colorSetNames;
    if (meshFn.getColorSetNames(colorSetNames)==MS::kSuccess) {
        for (unsigned int i=0; i < colorSetNames.length(); i++) {
            const MString colorSetName = colorSetNames[i];
            if (std::string(colorSetName.asChar()) 
                    == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetString()) {
                MFnMesh::MColorRepresentation csRep=
                    meshFn.getColorRepresentation(colorSetName);
                if (csRep==MFnMesh::kRGB || csRep==MFnMesh::kRGBA) {

                    // both of these are needed to show the colorset.
                    MPlug plg=meshFn.findPlug("displayColors");
                    if ( !plg.isNull() ) {
                        plg.setBool(true);
                    }
                    meshFn.setCurrentColorSetName(colorSetName);
                }
                break;
            }
        }
    }
    
    // == Animate points ==
    //   Use blendShapeDeformer so that all the points for a frame are contained in a single node
    //
    if (pointsNumTimeSamples > 0) {
        MPointArray mayaPoints(mayaNumVertices);
        MObject meshAnimObj;

        MFnBlendShapeDeformer blendFn;
        MObject blendObj = blendFn.create(meshObj);
        if (context) {
            context->RegisterNewMayaNode( blendFn.name().asChar(), blendObj ); // used for undo/redo
        }

        for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) {
             mesh.GetPointsAttr().Get(&points, pointsTimeSamples[ti]);

            for (unsigned int i=0; i < mayaNumVertices; i++) {
                mayaPoints.set( i, points[i][0], points[i][1], points[i][2] );
            }

            // == Create Mesh Shape Node
            MFnMesh meshFn;
            if ( meshAnimObj.isNull() ) {
                meshAnimObj = meshFn.create(mayaPoints.length(), 
                                       polygonCounts.length(), 
                                       mayaPoints, 
                                       polygonCounts, 
                                       polygonConnects,
                                       mayaNodeTransformObj,
                                       &status
                                       );
                if (status != MS::kSuccess) {
                    continue;
                }
            }
            else {
                // Reuse the already created mesh by copying it and then setting the points
                meshAnimObj = meshFn.copy(meshAnimObj, mayaNodeTransformObj, &status);
                meshFn.setPoints(mayaPoints);
            }

            // Set normals if supplied
            //
            // NOTE: This normal information is not propagated through the blendShapes, only the controlPoints.
            //
             mesh.GetNormalsAttr().Get(&normals, pointsTimeSamples[ti]);
             if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices()) &&
                normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) {

                MVectorArray mayaNormals(normals.size());
                for (size_t i=0; i < normals.size(); i++) {
                    mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i);
                }
                if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) {
                }
             }

            // Add as target and set as an intermediate object
            blendFn.addTarget(meshObj, ti, meshAnimObj, 1.0);
            meshFn.setIntermediateObject(true);
            if (context) {
                context->RegisterNewMayaNode( meshFn.fullPathName().asChar(), meshAnimObj ); // used for undo/redo
            }
        }

        // Animate the weights so that mesh0 has a weight of 1 at frame 0, etc.
        MFnAnimCurve animFn;

        // Construct the time array to be used for all the keys
        MTimeArray timeArray;
        timeArray.setLength(pointsNumTimeSamples);
        for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) {
            timeArray.set( MTime(pointsTimeSamples[ti]), ti);
        }

        // Key/Animate the weights
        MPlug plgAry = blendFn.findPlug( "weight" );
        if ( !plgAry.isNull() && plgAry.isArray() ) {
            for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) {
                MPlug plg = plgAry.elementByLogicalIndex(ti, &status);
                MDoubleArray valueArray(pointsNumTimeSamples, 0.0);
                valueArray[ti] = 1.0; // Set the time value where this mesh's weight should be 1.0
                MObject animObj = animFn.create(plg, NULL, &status);
                animFn.addKeys(&timeArray, &valueArray);
                if (context) {
                    context->RegisterNewMayaNode(animFn.name().asChar(), animObj ); // used for undo/redo
                }
            }
        }
    }

    return true;
}
コード例 #29
0
ファイル: LuxGeometry.cpp プロジェクト: MassW/OpenMaya
void LuxRenderer::defineTriangleMesh(mtlu_MayaObject *obj, bool noObjectDef = false)
{
	MObject meshObject = obj->mobject;
	MStatus stat = MStatus::kSuccess;
	MFnMesh meshFn(meshObject, &stat);
	
	CHECK_MSTATUS(stat);
	MItMeshPolygon faceIt(meshObject, &stat);
	CHECK_MSTATUS(stat);

	MPointArray points;
	meshFn.getPoints(points);
    MFloatVectorArray normals;
    meshFn.getNormals( normals, MSpace::kWorld );
	MFloatArray uArray, vArray;
	meshFn.getUVs(uArray, vArray);

	logger.debug(MString("Translating mesh object ") + meshFn.name().asChar());
	MString meshFullName = obj->fullNiceName;


	MIntArray trianglesPerFace, triVertices;
	meshFn.getTriangles(trianglesPerFace, triVertices);
	int numTriangles = 0;
	for( size_t i = 0; i < trianglesPerFace.length(); i++)
		numTriangles += trianglesPerFace[i];

	// lux render does not have a per vertex per face normal definition, here we can use one normal and uv per vertex only
	// So I create the triangles with unique vertices, normals and uvs. Of course this way vertices etc. cannot be shared.
	int numPTFloats = numTriangles * 3 * 3;
	logger.debug(MString("Num Triangles: ") + numTriangles + " num tri floats " + numPTFloats);

	float *floatPointArray = new float[numPTFloats];
	float *floatNormalArray = new float[numPTFloats];
	float *floatUvArray = new float[numTriangles * 3 * 2];
	
	logger.debug(MString("Allocated ") + numPTFloats + " floats for point and normals");

	MIntArray triangelVtxIdListA;
	MFloatArray floatPointArrayA;

	MPointArray triPoints;
	MIntArray triVtxIds;
	MIntArray faceVtxIds;
	MIntArray faceNormalIds;
	
	int *triangelVtxIdList = new int[numTriangles * 3];

	for( uint sgId = 0; sgId < obj->shadingGroups.length(); sgId++)
	{
		MString slotName = MString("slot_") + sgId;
	}
	
	int triCount = 0;
	int vtxCount = 0;

	for(faceIt.reset(); !faceIt.isDone(); faceIt.next())
	{
		int faceId = faceIt.index();
		int numTris;
		faceIt.numTriangles(numTris);
		faceIt.getVertices(faceVtxIds);

		MIntArray faceUVIndices;

		faceNormalIds.clear();
		for( uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++)
		{
			faceNormalIds.append(faceIt.normalIndex(vtxId));
			int uvIndex;
			faceIt.getUVIndex(vtxId, uvIndex);
			faceUVIndices.append(uvIndex);
		}

		int perFaceShadingGroup = 0;
		if( obj->perFaceAssignments.length() > 0)
			perFaceShadingGroup = obj->perFaceAssignments[faceId];
		//logger.info(MString("Face ") + faceId + " will receive SG " +  perFaceShadingGroup);

		for( int triId = 0; triId < numTris; triId++)
		{
			int faceRelIds[3];
			faceIt.getTriangle(triId, triPoints, triVtxIds);

			for( uint triVtxId = 0; triVtxId < 3; triVtxId++)
			{
				for(uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++)
				{
					if( faceVtxIds[faceVtxId] == triVtxIds[triVtxId])
					{
						faceRelIds[triVtxId] = faceVtxId;
					}
				}
			}

			
			uint vtxId0 = faceVtxIds[faceRelIds[0]];
			uint vtxId1 = faceVtxIds[faceRelIds[1]];
			uint vtxId2 = faceVtxIds[faceRelIds[2]];
			uint normalId0 = faceNormalIds[faceRelIds[0]];
			uint normalId1 = faceNormalIds[faceRelIds[1]];
			uint normalId2 = faceNormalIds[faceRelIds[2]];
			uint uvId0 = faceUVIndices[faceRelIds[0]];
			uint uvId1 = faceUVIndices[faceRelIds[1]];
			uint uvId2 = faceUVIndices[faceRelIds[2]];
			
			floatPointArray[vtxCount * 3] = points[vtxId0].x;
			floatPointArray[vtxCount * 3 + 1] = points[vtxId0].y;
			floatPointArray[vtxCount * 3 + 2] = points[vtxId0].z;

			floatNormalArray[vtxCount * 3] = normals[normalId0].x;
			floatNormalArray[vtxCount * 3 + 1] = normals[normalId0].y;
			floatNormalArray[vtxCount * 3 + 2] = normals[normalId0].z;

			floatUvArray[vtxCount * 2] = uArray[uvId0];
			floatUvArray[vtxCount * 2 + 1] = vArray[uvId0];

			vtxCount++;

			floatPointArray[vtxCount * 3] = points[vtxId1].x;
			floatPointArray[vtxCount * 3 + 1] = points[vtxId1].y;
			floatPointArray[vtxCount * 3 + 2] = points[vtxId1].z;

			floatNormalArray[vtxCount * 3] = normals[normalId1].x;
			floatNormalArray[vtxCount * 3 + 1] = normals[normalId1].y;
			floatNormalArray[vtxCount * 3 + 2] = normals[normalId1].z;

			floatUvArray[vtxCount * 2] = uArray[uvId1];
			floatUvArray[vtxCount * 2 + 1] = vArray[uvId1];

			vtxCount++;

			floatPointArray[vtxCount * 3] = points[vtxId2].x;
			floatPointArray[vtxCount * 3 + 1] = points[vtxId2].y;
			floatPointArray[vtxCount * 3 + 2] = points[vtxId2].z;

			floatNormalArray[vtxCount * 3] = normals[normalId2].x;
			floatNormalArray[vtxCount * 3 + 1] = normals[normalId2].y;
			floatNormalArray[vtxCount * 3 + 2] = normals[normalId2].z;

			floatUvArray[vtxCount * 2] = uArray[uvId2];
			floatUvArray[vtxCount * 2 + 1] = vArray[uvId2];

			vtxCount++;
			
			//logger.debug(MString("Vertex count: ") + vtxCount + " maxId " + ((vtxCount - 1) * 3 + 2) + " ptArrayLen " + (numTriangles * 3 * 3));

			triangelVtxIdList[triCount * 3] = triCount * 3;
			triangelVtxIdList[triCount * 3 + 1] = triCount * 3 + 1;
			triangelVtxIdList[triCount * 3 + 2] = triCount * 3 + 2;

			triCount++;
		}		
	}

//generatetangents 	bool 	Generate tangent space using miktspace, useful if mesh has a normal map that was also baked using miktspace (such as blender or xnormal) 	false
//subdivscheme 	string 	Subdivision algorithm, options are "loop" and "microdisplacement" 	"loop"
//displacementmap 	string 	Name of the texture used for the displacement. Subdivscheme parameter must always be provided, as load-time displacement is handled by the loop-subdivision code. 	none - optional. (loop subdiv can be used without displacement, microdisplacement will not affect the mesh without a displacement map specified)
//dmscale 	float 	Scale of the displacement (for an LDR map, this is the maximum height of the displacement in meter) 	0.1
//dmoffset 	float 	Offset of the displacement. 	0
//dmnormalsmooth 	bool 	Smoothing of the normals of the subdivided faces. Only valid for loop subdivision. 	true
//dmnormalsplit 	bool 	Force the mesh to split along breaks in the normal. If a mesh has no normals (flat-shaded) it will rip open on all edges. Only valid for loop subdivision. 	false
//dmsharpboundary 	bool 	Try to preserve mesh boundaries during subdivision. Only valid for loop subdivision. 	false
//nsubdivlevels 	integer 	Number of subdivision levels. This is only recursive for loop subdivision, microdisplacement will need much larger values (such as 50). 	0

	bool generatetangents = false;
	getBool(MString("mtlu_mesh_generatetangents"), meshFn, generatetangents);
	int subdivscheme = 0;
	const char *subdAlgos[] = {"loop", "microdisplacement"};
	getInt(MString("mtlu_mesh_subAlgo"), meshFn, subdivscheme);
	const char *subdalgo =  subdAlgos[subdivscheme];
	float dmscale;
	getFloat(MString("mtlu_mesh_dmscale"), meshFn, dmscale);
	float dmoffset;
	getFloat(MString("mtlu_mesh_dmoffset"), meshFn, dmoffset);
	MString displacementmap;
	getString(MString("mtlu_mesh_displacementMap"), meshFn, displacementmap);
	const char *displacemap = displacementmap.asChar();
	bool dmnormalsmooth = true;
	getBool(MString("mtlu_mesh_dmnormalsmooth"), meshFn, dmnormalsmooth);
	bool dmnormalsplit = false;
	getBool(MString("mtlu_mesh_dmnormalsplit"), meshFn, dmnormalsplit);
	bool dmsharpboundary = false;
	getBool(MString("mtlu_mesh_dmsharpboundary"), meshFn, dmsharpboundary);
	int nsubdivlevels = 0;
	getInt(MString("mtlu_mesh_subdivlevel"), meshFn, nsubdivlevels);

	// a displacment map needs its own texture defintion
	MString displacementTextureName = "";
	if(displacementmap.length() > 0)
	{
		ParamSet dmParams = CreateParamSet();
		dmParams->AddString("filename", &displacemap);
		displacementTextureName = meshFn.name() + "_displacementMap";
		this->lux->texture(displacementTextureName.asChar(), "float", "imagemap", boost::get_pointer(dmParams));
	}

	ParamSet triParams = CreateParamSet();
	int numPointValues = numTriangles * 3;
	int numUvValues = numTriangles * 3 * 2;
	clock_t startTime = clock();
	logger.info(MString("Adding mesh values to params."));
	triParams->AddInt("indices", triangelVtxIdList, numTriangles * 3);
	triParams->AddPoint("P", floatPointArray, numPointValues);
	triParams->AddNormal("N", floatNormalArray, numPointValues);
	triParams->AddFloat("uv",  floatUvArray, numUvValues);
	if( nsubdivlevels > 0)
		triParams->AddInt("nsubdivlevels", &nsubdivlevels, 1);
	triParams->AddBool("generatetangents",  &generatetangents, 1);
	triParams->AddString("subdivscheme", &subdalgo , 1);
	if(displacementmap.length() > 0)
	{
		triParams->AddFloat("dmoffset",  &dmoffset, 1);
		triParams->AddFloat("dmscale",  &dmscale, 1);
		const char *dmft = displacementTextureName.asChar();
		triParams->AddString("displacementmap", &dmft);
	}
	triParams->AddBool("dmnormalsmooth",  &dmnormalsmooth, 1);
	triParams->AddBool("dmnormalsplit",  &dmnormalsplit, 1);
	triParams->AddBool("dmsharpboundary",  &dmsharpboundary, 1);


	clock_t pTime = clock();
	if(!noObjectDef)
		this->lux->objectBegin(meshFullName.asChar());
	this->lux->shape("trianglemesh", boost::get_pointer(triParams));
	if(!noObjectDef)
		this->lux->objectEnd();

	clock_t eTime = clock();
	logger.info(MString("Timing: Parameters: ") + ((pTime - startTime)/CLOCKS_PER_SEC) + " objTime " + ((eTime - pTime)/CLOCKS_PER_SEC) + " all " + ((eTime - startTime)/CLOCKS_PER_SEC));

	return;

}
コード例 #30
0
//----------------------------------------------------------------------------------------------------------------------
void OceanNode::createGrid(int _resolution, double _time, double _choppiness, MObject& _outputData, MStatus &_status){
    int numTris = (_resolution-1)*(_resolution-1)*2;

    MFloatPointArray vertices;
    MIntArray numFaceVertices;
    MIntArray faceVertices;
    int tris[numTris*3];

    int width = 500;
    int depth = 500;

    // calculate the deltas for the x,z values of our point
    float wStep=(float)width/(float)_resolution;
    float dStep=(float)depth/(float)_resolution;
    // now we assume that the grid is centered at 0,0,0 so we make
    // it flow from -w/2 -d/2
    float xPos=-((float)width/2.0);
    float zPos=-((float)depth/2.0);

    // now loop from top left to bottom right and generate points

    m_ocean->update(_time);

    float2* heights = m_ocean->getHeights();
    float2* chopXArray = m_ocean->getChopX();
    float2* chopZArray = m_ocean->getChopZ();

    // Sourced form Jon Macey's NGL library
    for(int z=0; z<_resolution; z++){
        for(int x=0; x<_resolution; x++){
            // Divide the values we get out of the FFT by 50000 to get them in a suitable range
            float height = heights[z * _resolution + x].x/50000.0;
            float chopX = _choppiness * chopXArray[z * _resolution + x].x/50000.0;
            float chopZ= _choppiness * chopZArray[z * _resolution + x].x/50000.0;
            int sign = 1.0;
            if ((x+z) % 2 != 0){
                sign = -1.0;
            }
            vertices.append((xPos + (chopX * sign)), height * sign, (zPos + (chopZ * sign)));
            // calculate the new position
            zPos+=dStep;
        }
        // now increment to next z row
        xPos+=wStep;
        // we need to re-set the xpos for new row
        zPos=-((float)depth/2.0);
    }

    // Array for num vertices in each face
    for (int i=0; i<numTris; i++){
        numFaceVertices.append(3);
    }

    // Assign vertices to each face
    int fidx = 0;
    for (int i=0; i<(_resolution-1); i++){
        for (int j=0; j<(_resolution-1); j++){
            tris[fidx*3+0] = (i+1)*_resolution+j;
            tris[fidx*3+1] = i*_resolution+j+1;
            tris[fidx*3+2] = i*_resolution+j;
            fidx++;
            tris[fidx*3+0] = (i+1)*_resolution+j;
            tris[fidx*3+1] = (i+1)*_resolution+j+1;
            tris[fidx*3+2] = i*_resolution+j+1;
            fidx++;
        }
    }

    for (uint i=0; i<sizeof(tris)/sizeof(int); i++){
        faceVertices.append(tris[i]);
    }

   MFnMesh grid;
   grid.create(vertices.length(), numTris, vertices, numFaceVertices, faceVertices, _outputData, &_status);
}