MStatus SelectRingContext1::doRelease( MEvent &event )
{
	// Get the mouse release position
	event.getPosition( releaseX, releaseY );

	// Didn't select a single point
	if( abs(pressX - releaseX) > 1 || abs(pressY - releaseY) > 1 )
	{
		MGlobal::displayWarning( "Click on a single edge" );
		return MS::kFailure;
	}
	
	// Set the selection surface area
	int halfClickBoxSize = clickBoxSize / 2;
	pressX -= halfClickBoxSize;
	pressY -= halfClickBoxSize;
	releaseX = pressX + clickBoxSize;
	releaseY = pressY + clickBoxSize;
	 
	/*
	// Record previous selection state
	prevSelMode = MGlobal::selectionMode();
	prevCompMask = MGlobal::componentSelectionMask();
	*/

	// Get the current selection
	MSelectionList curSel;
	MGlobal::getActiveSelectionList( curSel );

	//MGlobal::displayInfo( MString("Dim: ") + start_x + " " + start_y + " " + last_x + " " + last_y );
	
	// Change to object selection mode
	MGlobal::setSelectionMode( MGlobal::kSelectObjectMode );
	MGlobal::setComponentSelectionMask( MSelectionMask( MSelectionMask::kSelectObjectsMask ) );

	// Select the object under the selection area
	MGlobal::selectFromScreen( pressX, pressY, releaseX, releaseY, MGlobal::kReplaceList);
	MGlobal::executeCommand( "hilite" );
	
	// Change selection mode to mesh edges
	MGlobal::setSelectionMode( MGlobal::kSelectComponentMode );
	MGlobal::setComponentSelectionMask( MSelectionMask( MSelectionMask::kSelectMeshEdges ) );
	
	// Select the edges
	MGlobal::selectFromScreen( pressX, pressY, releaseX, releaseY, MGlobal::kReplaceList );
								   
	// Get the list of selected edges
	MSelectionList origEdgesSel;
	MGlobal::getActiveSelectionList( origEdgesSel );	
	
	MSelectionList newEdgesSel;
	MDagPath dagPath;
	MObject component;	
	
	// Only use the first edge in the selection
	MItSelectionList selIter( origEdgesSel, MFn::kMeshEdgeComponent );
	if( !selIter.isDone() )
	{
		selIter.getDagPath( dagPath, component );
		
		MIntArray faces;
		MItMeshEdge edgeIter( dagPath, component );
		
		MIntArray edgesVisited, facesVisited;
		int edgeIndex, faceIndex;
		int prevIndex;
		unsigned int i;
		bool finished = false;
		while( !finished )
		{
			edgeIndex = edgeIter.index();
			edgesVisited.append( edgeIndex );
			
			// Create an edge component the current edge
			MFnSingleIndexedComponent indexedCompFn;
			MObject newComponent = indexedCompFn.create( MFn::kMeshEdgeComponent );
			indexedCompFn.addElement( edgeIndex );
			newEdgesSel.add( dagPath, newComponent );
			
			//MGlobal::displayInfo( MString("ADDING: ") + edgeIter.index() );
			
			edgeIter.getConnectedFaces( faces );
			faceIndex = faces[0];
			if( faces.length() > 1 )
			{
				// Select the face that hasn't already been visited
				for( i=0; i < facesVisited.length(); i++ )
				{
					if( faceIndex == facesVisited[i] )
					{
						faceIndex = faces[1];
						break;
					}
				}
			}
				
			//MGlobal::displayInfo( MString("FACE: ") + faceIndex );
			facesVisited.append( faceIndex );
			
			MItMeshPolygon polyIter( dagPath );
		
			polyIter.setIndex( faceIndex, prevIndex );
		
			//MGlobal::displayInfo( MString( "faces: " ) + faces[0] + " " + faces[1] );
		
			MIntArray edges;
			polyIter.getEdges( edges );
		
			// Determine the face-relative index of the current
			// edge
			unsigned int edgeFaceIndex = 0;
			for( i=0; i < edges.length(); i++ )
			{
				if( edges[i] == edgeIter.index() )
				{
					edgeFaceIndex = i;
					break;
				}
			}
			
			// Determine the edge that is opposite the current edge
			edgeIndex = edges[ (edgeFaceIndex + (edges.length() / 2) ) % edges.length() ];
			
			//int index = edgeIter.index();
			//MGlobal::displayInfo( MString( "sel edge index: " ) + index + " next edge: " + edgeIndex );	
			
			// Set the current edge to the opposite edge
			edgeIter.setIndex( edgeIndex, prevIndex );	

			// Determine if the edge has already been visited
			for( i=0; i < edgesVisited.length(); i++ )
			{
				if( edgeIndex == edgesVisited[i] )
				{
					finished = true;
					break;
				}							
			}
		}
	}
	
	// Set the active selection to the one previous to edge loop selection
	MGlobal::setActiveSelectionList( curSel, MGlobal::kReplaceList);

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

	return MS::kSuccess;		
}
Пример #2
0
MStatus LSystemNode::compute(const MPlug& plug, MDataBlock& data)

{
	MStatus returnStatus;

	if (plug == outputMesh) {
		/* Get time */
		MDataHandle timeData = data.inputValue( time, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		MTime time = timeData.asTime();

		MDataHandle angleData = data.inputValue( angle, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		double angle_value = angleData.asDouble();

		MDataHandle stepsData = data.inputValue( steps, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		double steps_value = stepsData.asDouble();

		MDataHandle grammarData = data.inputValue( grammar, &returnStatus ); 
		McheckErr(returnStatus, "Error getting time data handle\n");
		MString grammar_value = grammarData.asString();

		/* Get output object */

		MDataHandle outputHandle = data.outputValue(outputMesh, &returnStatus);
		McheckErr(returnStatus, "ERROR getting polygon data handle\n");

		MFnMeshData dataCreator;
		MObject newOutputData = dataCreator.create(&returnStatus);
		McheckErr(returnStatus, "ERROR creating outputData");

		MFnMesh	myMesh;
		MPointArray points;
		MIntArray faceCounts;
		MIntArray faceConnects;

		//MString grammar = ("F\\nF->F[+F]F[-F]F");

		CylinderMesh *cm;


		LSystem system;
		system.loadProgramFromString(grammar_value.asChar());
		system.setDefaultAngle(angle_value);
		system.setDefaultStep(steps_value);



			std::vector<LSystem::Branch> branches;
			system.process(time.value(), branches);

			int k = branches.size();
			for(int j = 0; j < branches.size(); j++)
			{
				//1. find the position for start and end point of current branch
				//2. generate a cylinder
				MPoint start(branches[j].first[0],branches[j].first[1],branches[j].first[2]);
				MPoint end(branches[j].second[0],branches[j].second[1],branches[j].second[2]);
				cm = new CylinderMesh(start, end);
				cm->appendToMesh(points, faceCounts, faceConnects); 
			}

		MObject newMesh = myMesh.create(points.length(), faceCounts.length(),
			points, faceCounts, faceConnects,
			newOutputData, &returnStatus);

		McheckErr(returnStatus, "ERROR creating new mesh");

		outputHandle.set(newOutputData);
		data.setClean( plug );
	} else
		return MS::kUnknownParameter;

	return MS::kSuccess;
}
Пример #3
0
// write a normal mesh
//
MStatus vxCache::writeMesh(const char* filename, MDagPath meshDag, const MObject& meshObj)
{	
	struct meshInfo mesh;

	MString uvset("map1");
	
	MStatus status;
	MFnMesh meshFn(meshDag, &status );
	MItMeshPolygon faceIter( meshDag, MObject::kNullObj, &status );
	MItMeshVertex vertIter(meshDag, MObject::kNullObj, &status);
	MItMeshEdge edgeIter(meshDag, MObject::kNullObj, &status);
	
	mesh.numPolygons = meshFn.numPolygons();
	mesh.numVertices = meshFn.numVertices();
	mesh.numFaceVertices = meshFn.numFaceVertices();
	mesh.numUVs = meshFn.numUVs(uvset, &status);
	mesh.skip_interreflection = mesh.skip_scattering = 0;
	
	//if(zWorks::hasNamedAttribute(meshObj, "_prt_ig_intr") == 1) mesh.skip_interreflection = 1;
	//if(zWorks::hasNamedAttribute(meshObj, "_prt_ig_scat") == 1) mesh.skip_scattering = 1;

	//zWorks::displayIntParam("N Face", mesh.numPolygons);
	//zWorks::displayIntParam("N Vertex", mesh.numVertices);
	//zWorks::displayIntParam("N Facevertex", mesh.numFaceVertices);
	//zWorks::displayIntParam("N UV", mesh.numUVs);
	
	int *fcbuf = new int[mesh.numPolygons];
	faceIter.reset();
	for( ; !faceIter.isDone(); faceIter.next() ) 
	{
		fcbuf[ faceIter.index() ] = faceIter.polygonVertexCount();
	}

	int* vertex_id = new int[mesh.numFaceVertices];
	int* uv_id = new int[mesh.numFaceVertices];
// output face loop
	int acc = 0;
	faceIter.reset();
	for( ; !faceIter.isDone(); faceIter.next() ) 
	{
		MIntArray  vexlist;
		faceIter.getVertices ( vexlist );
		for( unsigned int i=0; i < vexlist.length(); i++ ) 
		{
			vertex_id[acc] = vexlist[i];
			faceIter.getUVIndex ( i, uv_id[acc] );
			acc++;
		}
	}
	
// output vertices
	MPointArray pArray;
	
	if(worldSpace) meshFn.getPoints ( pArray, MSpace::kWorld);
	else meshFn.getPoints ( pArray, MSpace::kObject );
	
	XYZ *pbuf = new XYZ[pArray.length()];
	
	for( unsigned int i=0; i<pArray.length(); i++) 
	{
		pbuf[i].x = pArray[i].x;
		pbuf[i].y = pArray[i].y;
		pbuf[i].z= pArray[i].z;
	}

//output texture coordinate
	MFloatArray uArray, vArray;
	meshFn.getUVs ( uArray, vArray, &uvset );

	double* ubuf = new double[mesh.numUVs];
	double* vbuf = new double[mesh.numUVs];
	
	for( unsigned int i=0; i<uArray.length(); i++) 
	{
		ubuf[i] = uArray[i];
		vbuf[i] = vArray[i];
	}
/*
	XYZ *norbuf = new XYZ[mesh.numVertices];
	vertIter.reset();
	MVector tnor;
	
	for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ )
	{
		if(worldSpace) vertIter.getNormal(tnor, MSpace::kWorld);
		else vertIter.getNormal(tnor, MSpace::kObject);
		tnor.normalize();
		norbuf[i].x = tnor.x;
		norbuf[i].y = tnor.y;
		norbuf[i].z = tnor.z;
	}

	MStatus hasAttr;
	MString sColorSet("set_prt_attr");
	meshFn.numColors( sColorSet,  &hasAttr );
	
	XYZ *colbuf = new XYZ[mesh.numVertices];
	vertIter.reset();
	if(hasAttr)
	{
		MColor col;
		for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ )
		{
			MIntArray conn_face;
			vertIter.getConnectedFaces(conn_face);
			vertIter.getColor(col, conn_face[0], &sColorSet);
			colbuf[i].x = col.r;
			colbuf[i].y = col.g;
			colbuf[i].z = col.b;
		}
	}
	else
	{
		for( unsigned int i=0; i<vertIter.count(); i++ ) colbuf[i] = XYZ(1.0f);
	}
	
	vertIter.reset();
	XYZ *vsbuf = new XYZ[mesh.numVertices];
	for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ )
	{
		MIntArray conn_face, conn_edge;
		vertIter.getConnectedFaces(conn_face);
		vertIter.getConnectedEdges(conn_edge);
		MPoint Q;
		for(unsigned j=0; j<conn_face.length(); j++)
		{
			int pre_id;
			faceIter.setIndex(conn_face[j],pre_id);
			Q += faceIter.center(MSpace::kWorld);
		}
		Q = Q/(double)conn_face.length();
		
		MPoint R;
		for(unsigned j=0; j<conn_edge.length(); j++)
		{
			int pre_id;
			edgeIter.setIndex(conn_edge[j], pre_id);
			R += edgeIter.center(MSpace::kWorld);
		}
		R = R/(double)conn_edge.length();
		
		MPoint S = vertIter.position(MSpace::kWorld);
		
		int nv = conn_edge.length();
		MPoint nS = (Q + R*2 + S*(nv-3))/nv;

		vsbuf[i].x = nS.x;
		vsbuf[i].y = nS.y;
		vsbuf[i].z = nS.z;
	}
	
	XYZ *tangbuf = new XYZ[mesh.numVertices];
	
	vertIter.reset();
	for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ )
	{
		MIntArray conn_face;
		MVector tang(0,0,0);
		vertIter.getConnectedFaces(conn_face);
		
		//for(int j = 0; j<conn_face.length(); j++) 
		{
			MVector ttang;
			meshFn.getFaceVertexTangent (conn_face[0], i,  ttang,  MSpace::kWorld, &uvset);
			tang += ttang;
		}
		tang.normalize();
		tangbuf[i].x = tang.x;
		tangbuf[i].y = tang.y;
		tangbuf[i].z = tang.z;
		
		tangbuf[i] = norbuf[i].cross(tangbuf[i]);
		tangbuf[i].normalize();
	}
*/	
	FMCFMesh fmesh;
	fmesh.save(mesh.numVertices, 
			mesh.numFaceVertices, 
			mesh.numPolygons, 
			mesh.numUVs, 
			mesh.skip_interreflection,
			mesh.skip_scattering,
			fcbuf, 
			vertex_id, 
			uv_id,
			pbuf,
			//vsbuf,
			//norbuf,
			//tangbuf,
			//colbuf,
			ubuf,
			vbuf,
			filename);
			
	delete[] fcbuf;
	delete[] vertex_id;
	delete[] uv_id;
	delete[] pbuf;
	//delete[] vsbuf;
	//delete[] norbuf;
	//delete[] tangbuf;
	//delete[] colbuf;
	delete[] ubuf;
	delete[] vbuf;

	return MS::kSuccess;
}
Пример #4
0
void MayaMeshWriter::getPolyNormals(std::vector<float> & oNormals)
{
    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    // no normals bail early
    if (mNoNormals)
    {
        return;
    }

    MPlug plug = lMesh.findPlug("noNormals", true, &status);
    if (status == MS::kSuccess && plug.asBool() == true)
    {
        return;
    }
    // we need to check the locked state of the normals
    else if ( status != MS::kSuccess )
    {
        bool userSetNormals = false;

        // go through all per face-vertex normals and verify if any of them
        // has been tweaked by users
        unsigned int numFaces = lMesh.numPolygons();
        for (unsigned int faceIndex = 0; faceIndex < numFaces; faceIndex++)
        {
            MIntArray normals;
            lMesh.getFaceNormalIds(faceIndex, normals);
            unsigned int numNormals = normals.length();
            for (unsigned int n = 0; n < numNormals; n++)
            {
                if (lMesh.isNormalLocked(normals[n]))
                {
                    userSetNormals = true;
                    break;
                }
            }
        }

        // we looped over all the normals and they were all calculated by Maya
        // so we just need to check to see if any of the edges are hard
        // before we decide not to write the normals.
        if (!userSetNormals)
        {
            bool hasHardEdges   = false;

            // go through all edges and verify if any of them is hard edge
            unsigned int numEdges = lMesh.numEdges();
            for (unsigned int edgeIndex = 0; edgeIndex < numEdges; edgeIndex++)
            {
                if (!lMesh.isEdgeSmooth(edgeIndex))
                {
                    hasHardEdges = true;
                    break;
                }
            }

            // all the edges were smooth, we don't need to write the normals
            if (!hasHardEdges)
            {
                return;
            }
        }
    }

    bool flipNormals = false;
    plug = lMesh.findPlug("flipNormals", true, &status);
    if ( status == MS::kSuccess )
        flipNormals = plug.asBool();

    // get the per vertex per face normals (aka vertex)
    unsigned int numFaces = lMesh.numPolygons();

    for (unsigned int faceIndex = 0; faceIndex < numFaces; faceIndex++ )
    {
        MIntArray vertexList;
        lMesh.getPolygonVertices(faceIndex, vertexList);

        // re-pack the order of normals in this vector before writing into prop
        // so that Renderman can also use it
        unsigned int numVertices = vertexList.length();
        for ( int v = numVertices-1; v >=0; v-- )
        {
            unsigned int vertexIndex = vertexList[v];
            MVector normal;
            lMesh.getFaceVertexNormal(faceIndex, vertexIndex, normal);

            if (flipNormals)
                normal = -normal;

            oNormals.push_back(static_cast<float>(normal[0]));
            oNormals.push_back(static_cast<float>(normal[1]));
            oNormals.push_back(static_cast<float>(normal[2]));
        }
    }
}
MStatus DDConvexHullUtils::componentToVertexIDs(MIntArray &outIndices,
                                                const MObject &mesh,
                                                const MObject &component)
{
    // Create the funciton sets
    MFnSingleIndexedComponent compFn(component);
    MFnMesh meshFn(mesh);
        
    MIntArray elems;
    compFn.getElements(elems);
    uint elemLen = elems.length();
    
    // Convert the components to vertices based on component type
    uint compType = compFn.componentType();
    if (compType == MFn::kMeshVertComponent)
    {
        outIndices = elems;
    }
    else if (compType == MFn::kMeshEdgeComponent)
    {
        for (uint i=0; i < elemLen; i++)
        {
            int2 edgeVerts;
            meshFn.getEdgeVertices(elems[i], edgeVerts);
            outIndices.append(edgeVerts[0]);
            outIndices.append(edgeVerts[1]);
        }
    }
    else if (compType == MFn::kMeshPolygonComponent)
    {
        for (uint i=0; i < elemLen; i++)
        {
            // Grab verts for the current poly
            MIntArray polyVerts;
            meshFn.getPolygonVertices(elems[i], polyVerts);
            uint polyVertsLen = polyVerts.length();
            for (uint j=0; j < polyVertsLen; j++)
            {
                outIndices.append(polyVerts[j]);
            }
        }
    }
    else if (compType == MFn::kMeshFaceVertComponent)
    {
        // I think this is how you convert face to object
        // relative vertices...
        MIntArray faceCounts;
        MIntArray faceVerts;
        meshFn.getVertices(faceCounts, faceVerts);
        for (uint j=0; j < elemLen; j++)
        {
            outIndices.append(faceVerts[j]);
        }
    }
    else
    {
        // Not supported
        return MStatus::kNotImplemented;
    }
    return MStatus::kSuccess;
}
Пример #6
0
bool CXRayObjectExport::initializeSetsAndLookupTables( bool exportAll )
//
// Description :
//    Creates a list of all sets in Maya, a list of mesh objects,
//    and polygon/vertex lookup tables that will be used to
//    determine which sets are referenced by the poly components.
//
{
	int i=0,j=0, length;
	MStatus stat;
	
	// Initialize class data.
	// Note: we cannot do this in the constructor as it
	// only gets called upon registry of the plug-in.
	//
	numSets = 0;
	sets = NULL;
	lastSets = NULL;
	lastMaterials = NULL;
	objectId = 0;
	objectCount = 0;
	polygonTable = NULL;
	vertexTable = NULL;
	polygonTablePtr = NULL;
	vertexTablePtr = NULL;
	objectGroupsTablePtr = NULL;
	objectNodeNamesArray.clear();
	transformNodeNameArray.clear();

	//////////////////////////////////////////////////////////////////
	//
	// Find all sets in Maya and store the ones we care about in
	// the 'sets' array. Also make note of the number of sets.
	//
	//////////////////////////////////////////////////////////////////
	
	// Get all of the sets in maya and put them into
	// a selection list
	// 
	MStringArray result;
	MGlobal::executeCommand( "ls -sets", result );
	MSelectionList * setList = new MSelectionList();
	length = result.length();
	for ( i=0; i<length; i++ )
	{	
		setList->add( result[i] );
	}
	
	// Extract each set as an MObject and add them to the
	// sets array.
	// We may be excluding groups, matierials, or ptGroups
	// in which case we can ignore those sets. 
	//
	MObject mset;
	sets = new MObjectArray();
	length = setList->length();
	for ( i=0; i<length; i++ )
	{
		setList->getDependNode( i, mset );
		
		MFnSet fnSet( mset, &stat );
		if ( stat ) {
			if ( MFnSet::kRenderableOnly == fnSet.restriction(&stat) ) {
				sets->append( mset );
			}
		}	
	}
	xr_delete(setList);
	
	numSets = sets->length();
			
	//////////////////////////////////////////////////////////////////
	//
	// Do a dag-iteration and for every mesh found, create facet and
	// vertex look-up tables. These tables will keep track of which
	// sets each component belongs to.
	//
	// If exportAll is false then iterate over the activeSelection 
	// list instead of the entire DAG.
	//
	// These arrays have a corrisponding entry in the name
	// stringArray.
	//
	//////////////////////////////////////////////////////////////////
	MIntArray vertexCounts;
	MIntArray polygonCounts;	
			
	if ( exportAll ) {
		MItDag dagIterator( MItDag::kBreadthFirst, MFn::kInvalid, &stat);

    	if ( MS::kSuccess != stat) {
    	    fprintf(stderr,"Failure in DAG iterator setup.\n");
    	    return false;
    	}
		
		objectNames = new MStringArray();
		
    	for ( ; !dagIterator.isDone(); dagIterator.next() ) 
		{
    	    MDagPath dagPath;
    	    stat = dagIterator.getPath( dagPath );

			if ( stat ) 
			{
				// skip over intermediate objects
				//
				MFnDagNode dagNode( dagPath, &stat );
				if (dagNode.isIntermediateObject()) 
				{
					continue;
				}

				if (( dagPath.hasFn(MFn::kMesh)) &&
					( dagPath.hasFn(MFn::kTransform)))
				{
					// We want only the shape, 
					// not the transform-extended-to-shape.
					continue;
				}
				else if ( dagPath.hasFn(MFn::kMesh))
				{
					// We have a mesh so create a vertex and polygon table
					// for this object.
					//
					MFnMesh fnMesh( dagPath );
					int vtxCount = fnMesh.numVertices();
					int polygonCount = fnMesh.numPolygons();
					// we do not need this call anymore, we have the shape.
					// dagPath.extendToShape();
					MString name = dagPath.fullPathName();
					objectNames->append( name );
					objectNodeNamesArray.append( fnMesh.name() );

					vertexCounts.append( vtxCount );
					polygonCounts.append( polygonCount );

					objectCount++;
				}
			}
		}	
	}else{
		MSelectionList slist;
    	MGlobal::getActiveSelectionList( slist );
    	MItSelectionList iter( slist );
		MStatus status;

		objectNames = new MStringArray();

		// We will need to interate over a selected node's heirarchy
		// in the case where shapes are grouped, and the group is selected.
		MItDag dagIterator( MItDag::kDepthFirst, MFn::kInvalid, &status);

    	for ( ; !iter.isDone(); iter.next() ){
			MDagPath objectPath;
			stat = iter.getDagPath( objectPath );

			// reset iterator's root node to be the selected node.
			status = dagIterator.reset (objectPath.node(), 
										MItDag::kDepthFirst, MFn::kInvalid );

			// DAG iteration beginning at at selected node
			for ( ; !dagIterator.isDone(); dagIterator.next() ){
				MDagPath dagPath;
				MObject  component = MObject::kNullObj;
				status = dagIterator.getPath(dagPath);

				if (!status){
					fprintf(stderr,"Failure getting DAG path.\n");
					freeLookupTables();
					return false;
				}

                // skip over intermediate objects
                //
                MFnDagNode dagNode( dagPath, &stat );
                if (dagNode.isIntermediateObject()) continue;

				if (( dagPath.hasFn(MFn::kMesh)) && ( dagPath.hasFn(MFn::kTransform))){
					// We want only the shape, 
					// not the transform-extended-to-shape.
					continue;
				}else if ( dagPath.hasFn(MFn::kMesh)){
					// We have a mesh so create a vertex and polygon table
					// for this object.
					//
					MFnMesh fnMesh( dagPath );
					int vtxCount = fnMesh.numVertices();
					int polygonCount = fnMesh.numPolygons();

					// we do not need this call anymore, we have the shape.
					// dagPath.extendToShape();
					MString name = dagPath.fullPathName();
					objectNames->append( name );
					objectNodeNamesArray.append( fnMesh.name() );
									
					vertexCounts.append( vtxCount );
					polygonCounts.append( polygonCount );

					objectCount++;	
				}
    		}
		}
	}

	// Now we know how many objects we are dealing with 
	// and we have counts of the vertices/polygons for each
	// object so create the maya group look-up table.
	//
	if( objectCount > 0 ) {
		// To export Maya groups we traverse the hierarchy starting at
		// each objectNodeNamesArray[i] going towards the root collecting transform
		// nodes as we go.
		length = objectNodeNamesArray.length();
		for( i=0; i<length; i++ ) {
			MIntArray transformNodeNameIndicesArray;
			recFindTransformDAGNodes( objectNodeNamesArray[i], transformNodeNameIndicesArray );
		}

		if( transformNodeNameArray.length() > 0 ) {
			objectGroupsTablePtr = xr_alloc<bool*>(objectCount);// (bool**) malloc( sizeof(bool*)*objectCount );
			length = transformNodeNameArray.length();
			for ( i=0; i<objectCount; i++ )
			{
//				objectGroupsTablePtr[i] = (bool*)calloc( length, sizeof(bool) );	
				objectGroupsTablePtr[i] = xr_alloc<bool>(length);
				ZeroMemory(objectGroupsTablePtr[i],length*sizeof(bool));
                // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there
				if ( objectGroupsTablePtr[i] == NULL ) {
					Log("! calloc returned NULL (objectGroupsTablePtr)");
					return false;
				}
			}
		}
//		else{
//			Log("! Can't find transform for node.");
//			return false;
//		}
	}

	// Create the vertex/polygon look-up tables.
	//
	if ( objectCount > 0 ) {
		
		vertexTablePtr = xr_alloc<bool*>(objectCount);	//(bool**) malloc( sizeof(bool*)*objectCount );
		polygonTablePtr = xr_alloc<bool*>(objectCount);	//(bool**) malloc( sizeof(bool*)*objectCount );
	
		for ( i=0; i<objectCount; i++ )
		{
//			vertexTablePtr[i] = (bool*)calloc( vertexCounts[i]*numSets, sizeof(bool) );	
			vertexTablePtr[i] = xr_alloc<bool>(vertexCounts[i]*numSets);
			ZeroMemory(vertexTablePtr[i],vertexCounts[i]*numSets*sizeof(bool));
            // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there
			if ( vertexTablePtr[i] == NULL ) {
				Log("! calloc returned NULL (vertexTable)");
				return false;
			}
	
//			polygonTablePtr[i] = (bool*)calloc( polygonCounts[i]*numSets, sizeof(bool) );
			polygonTablePtr[i] = xr_alloc<bool>(polygonCounts[i]*numSets);
			ZeroMemory(polygonTablePtr[i],polygonCounts[i]*numSets*sizeof(bool));
            // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there
			if ( polygonTablePtr[i] == NULL ) {
				Log("! calloc returned NULL (polygonTable)");
				return false;
			}
		}	
	}

	// If we found no meshes then return
	//	
	if ( objectCount == 0 ) {
		return false;
	}
	
	//////////////////////////////////////////////////////////////////
	//
	// Go through all of the set members (flattened lists) and mark
	// in the lookup-tables, the sets that each mesh component belongs
	// to.
	//
	//
	//////////////////////////////////////////////////////////////////
	bool flattenedList = true;
	MDagPath object;
	MObject component;
	MSelectionList memberList;
	
	
	for ( i=0; i<numSets; i++ )
	{
		MFnSet fnSet( (*sets)[i] );		
		memberList.clear();
		stat = fnSet.getMembers( memberList, flattenedList );

		if (MS::kSuccess != stat) {
			fprintf(stderr,"Error in fnSet.getMembers()!\n");
		}

		int m, numMembers;
		numMembers = memberList.length();
		for ( m=0; m<numMembers; m++ )
		{
			if ( memberList.getDagPath(m,object,component) ) {

				if ( (!component.isNull()) && (object.apiType() == MFn::kMesh) )
				{
					if (component.apiType() == MFn::kMeshVertComponent) {
						MItMeshVertex viter( object, component );	
						for ( ; !viter.isDone(); viter.next() )
						{
							int compIdx = viter.index();
							MString name = object.fullPathName();
							
							// Figure out which object vertexTable
							// to get.
							//

							int o, numObjectNames;
							numObjectNames = objectNames->length();
							for ( o=0; o<numObjectNames; o++ ) {
								if ( (*objectNames)[o] == name ) {
									// Mark set i as true in the table
									//		
									vertexTable = vertexTablePtr[o];
									*(vertexTable + numSets*compIdx + i) = true;
									break;
								}
							}
						}
					}
					else if (component.apiType() == MFn::kMeshPolygonComponent) 
					{
						MItMeshPolygon piter( object, component );
						for ( ; !piter.isDone(); piter.next() )
						{
							int compIdx = piter.index();
							MString name = object.fullPathName();
							
							// Figure out which object polygonTable
							// to get.
							//							
							int o, numObjectNames;
							numObjectNames = objectNames->length();
							for ( o=0; o<numObjectNames; o++ ) {
								if ( (*objectNames)[o] == name ) {
									
									// Mark set i as true in the table
									//

									// Check for bad components in the set
									//									
									if ( compIdx >= polygonCounts[o] ) {
										Msg("! Bad polygon index '%d' found. Polygon skipped",compIdx);
										break;
									}
									
									polygonTable = polygonTablePtr[o];
									*(polygonTable + numSets*compIdx + i) = true;
									break;
								}
							}	
						}
					}										
				}
				else { 

				// There are no components, therefore we can mark
				// all polygons as members of the given set.
				//

				if (object.hasFn(MFn::kMesh)) {

					MFnMesh fnMesh( object, &stat );
					if ( MS::kSuccess != stat) {
						fprintf(stderr,"Failure in MFnMesh initialization.\n");
						return false;
					}

					// We are going to iterate over all the polygons.
					//
					MItMeshPolygon piter( object, MObject::kNullObj, &stat );
					if ( MS::kSuccess != stat) {
						fprintf(stderr,
								"Failure in MItMeshPolygon initialization.\n");
						return false;
					}
					for ( ; !piter.isDone(); piter.next() )
					{
						int compIdx = piter.index();
						MString name = object.fullPathName();

						// Figure out which object polygonTable to get.
						//
						int o, numObjectNames;
						numObjectNames = objectNames->length();
						for ( o=0; o<numObjectNames; o++ ) {
							if ( (*objectNames)[o] == name ) {
								// Check for bad components in the set
								//
								if ( compIdx >= polygonCounts[o] ) {
									Msg("! Bad polygon index '%d' found. Polygon skipped",compIdx);
									break;
								}
								// Mark set i as true in the table
								//
								polygonTable = polygonTablePtr[o];
								*(polygonTable + numSets*compIdx + i) = true;
								break;
							}
						}
					} // end of piter.next() loop
				} // end of condition if (object.hasFn(MFn::kMesh))
				} // end of else condifion if (!component.isNull()) 
			} // end of memberList.getDagPath(m,object,component)
		} // end of memberList loop
	} // end of for-loop for sets

	// Go through all of the group members and mark in the
	// lookup-table, the group that each shape belongs to.
	length = objectNodeNamesArray.length();
	if (objectGroupsTablePtr){
		for( i=0; i<length; i++ ) {
			MIntArray groupTableIndicesArray;
			bool *objectGroupTable = objectGroupsTablePtr[i];
			int length2;
			recFindTransformDAGNodes( objectNodeNamesArray[i], groupTableIndicesArray );
			length2 = groupTableIndicesArray.length();
			for( j=0; j<length2; j++ ) {
				int groupIdx = groupTableIndicesArray[j];
				objectGroupTable[groupIdx] = true;
			}
		}
	}
	return true;
}
Пример #7
0
//
// Main routine
///////////////////////////////////////////////////////////////////////////////
MStatus particleSystemInfoCmd::doIt( const MArgList& args )
{
	MStatus stat = parseArgs( args );
	if( stat != MS::kSuccess ) return stat;

	if( particleNode.isNull() ) {
	        MObject parent;
		MFnParticleSystem dummy;
		particleNode = dummy.create(&stat);
		CHECKRESULT(stat,"MFnParticleSystem::create(status) failed!");

		MFnParticleSystem ps( particleNode, &stat );
		CHECKRESULT(stat,"MFnParticleSystem::MFnParticleSystem(MObject,status) failed!");

		MPointArray posArray;
		posArray.append(MPoint(-5,  5, 0));
		posArray.append(MPoint(-5, 10, 0));

		MVectorArray velArray;
		velArray.append(MPoint(1, 1, 0));
		velArray.append(MPoint(1, 1, 0));
		stat = ps.emit(posArray, velArray);
		CHECKRESULT(stat,"MFnParticleSystem::emit(posArray,velArray) failed!");

		stat = ps.emit(MPoint(5,  5, 0));
		CHECKRESULT(stat,"MFnParticleSystem::emit(pos) failed!");
		stat = ps.emit(MPoint(5, 10, 0));
		CHECKRESULT(stat,"MFnParticleSystem::emit(pos) failed!");

		stat = ps.saveInitialState();
		CHECKRESULT(stat,"MFnParticleSystem::saveInitialState() failed!");

		MVectorArray accArray;
		accArray.setLength(4);
		for( unsigned int i=0; i<accArray.length(); i++ )
		{
		        MVector& acc = accArray[i];
			acc.x = acc.y = acc.z = 3.0;
		}
		MString accName("acceleration");
		ps.setPerParticleAttribute( accName, accArray, &stat );
		CHECKRESULT(stat,"MFnParticleSystem::setPerParticleAttribute(vectorArray) failed!");
	} 

	MFnParticleSystem ps( particleNode, &stat );
	CHECKRESULT(stat,"MFnParticleSystem::MFnParticleSystem(MObject,status) failed!");

	if( ! ps.isValid() )
	{
		MGlobal::displayError( "The function set is invalid!" );
		return MS::kFailure;
	}

	const MString name = ps.particleName();
	const MFnParticleSystem::RenderType psType = ps.renderType();
	const unsigned int count = ps.count();

	const char* typeString = NULL;
	switch( psType )
	{
	case MFnParticleSystem::kCloud:
		typeString = "Cloud";
		break;
	case MFnParticleSystem::kTube:
		typeString = "Tube system";
		break;
	case MFnParticleSystem::kBlobby:
		typeString = "Blobby";
		break;
	case MFnParticleSystem::kMultiPoint:
		typeString = "MultiPoint";
		break;
	case MFnParticleSystem::kMultiStreak:
		typeString = "MultiStreak";
		break;
	case MFnParticleSystem::kNumeric:
		typeString = "Numeric";
		break;
	case MFnParticleSystem::kPoints:
		typeString = "Points";
		break;
	case MFnParticleSystem::kSpheres:
		typeString = "Spheres";
		break;
	case MFnParticleSystem::kSprites:
		typeString = "Sprites";
		break;
	case MFnParticleSystem::kStreak:
		typeString = "Streak";
		break;
	default:
		typeString = "Particle system";
		assert( false );
		break;
	}

	char buffer[256];

	sprintf( buffer, "%s \"%s\" has %u primitives.", typeString, name.asChar(), count );
	MGlobal::displayInfo( buffer );

	unsigned i;

	MIntArray ids;
	ps.particleIds( ids );

	sprintf( buffer, "count : %u ", count );
	MGlobal::displayInfo( buffer );
	sprintf( buffer, "%u ids.", ids.length() );
	MGlobal::displayInfo( buffer );

	assert( ids.length() == count );
	for( i=0; i<ids.length(); i++ )
	{
		sprintf( buffer, "id %d  ", ids[i] );
		MGlobal::displayInfo( buffer );
	}

	MVectorArray positions;
	ps.position( positions );
	assert( positions.length() == count );
	for( i=0; i<positions.length(); i++ )
	{
		MVector& p = positions[i];
		sprintf( buffer, "pos %f %f %f  ", p[0], p[1], p[2] );
		MGlobal::displayInfo( buffer );
	}

	MVectorArray vels;
	ps.velocity( vels );
	assert( vels.length() == count );
	for( i=0; i<vels.length(); i++ )
	{
		const MVector& v = vels[i];
		sprintf( buffer, "vel %f %f %f  ", v[0], v[1], v[2] );
		MGlobal::displayInfo( buffer );
	}

	MVectorArray accs;
	ps.acceleration( accs );
	assert( accs.length() == count );
	for( i=0; i<accs.length(); i++ )
	{
		const MVector& a = accs[i];
		sprintf( buffer, "acc %f %f %f  ", a[0], a[1], a[2] );
		MGlobal::displayInfo( buffer );
	}

	bool flag = ps.isDeformedParticleShape(&stat);
	CHECKRESULT(stat,"MFnParticleSystem::isDeformedParticleShape() failed!");
	if( flag ) {
	        MObject obj = ps.originalParticleShape(&stat);
		CHECKRESULT(stat,"MFnParticleSystem::originalParticleShape() failed!");
		if( obj != MObject::kNullObj ) {
		        MFnParticleSystem ps( obj );
			sprintf( buffer, "original particle shape : %s ", ps.particleName().asChar() );
			MGlobal::displayInfo( buffer );
		}
	}

	flag = ps.isDeformedParticleShape(&stat);
	CHECKRESULT(stat,"MFnParticleSystem::isDeformedParticleShape() failed!");
	if( !flag ) {
	        MObject obj = ps.deformedParticleShape(&stat);
		CHECKRESULT(stat,"MFnParticleSystem::deformedParticleShape() failed!");
		if( obj != MObject::kNullObj ) {
		        MFnParticleSystem ps( obj );
			sprintf( buffer, "deformed particle shape : %s ", ps.particleName().asChar() );
			MGlobal::displayInfo( buffer );
		}
	}

	if( ids.length() == positions.length() &&
	    ids.length() == vels.length()      &&
	    ids.length() == accs.length()       ) { 
	        setResult( int(ids.length()) );
	} else {
	        setResult( int(-1) );
	}

	return MS::kSuccess;
}
Пример #8
0
bool tm_polyExtract::extractFaces_Func( MSelectionList &selectionList, MStringArray &node_names)
{
	MStatus status;
	MObject meshObj;
	status = selectionList.getDependNode( 0, meshObj);
	if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Can't find object !");return false;}
	MFnMesh meshFn( meshObj, &status);
	if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Non mesh object founded !");return false;}

	MDagPath meshDagPath_first, meshDagPath;
	selectionList.getDagPath( 0, meshDagPath_first);
	MObject multiFaceComponent;
	MIntArray inputFacesArray;
	inputFacesArray.clear();
	inputFacesArray.setSizeIncrement( 4096);
	MFnComponentListData compListFn;
	compListFn.create();
	for (MItSelectionList faceComponentIter(selectionList, MFn::kMeshPolygonComponent); !faceComponentIter.isDone(); faceComponentIter.next())
	{
		faceComponentIter.getDagPath(meshDagPath, multiFaceComponent);
		if(!(meshDagPath_first == meshDagPath))
		{
			MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Different meshes faces founded !");
			return false;
		}
		if (!multiFaceComponent.isNull())
		{
			for (MItMeshPolygon faceIter(meshDagPath, multiFaceComponent); !faceIter.isDone(); faceIter.next())
			{
				int faceIndex = faceIter.index();
#ifdef _DEBUG
				infoMStr += faceIndex;
				infoMStr += " ";
#endif
				inputFacesArray.append( faceIndex);
				compListFn.add( multiFaceComponent );
			}
		}
	}
	if( inputFacesArray.length() == 0)
	{
		MGlobal::displayError("tm_polyExtract::extractFaces_Func:   No faces founded !");
		return false;
	}
#ifdef _DEBUG
	MGlobal::displayInfo( infoMStr);
#endif

	meshFn.setObject( meshDagPath_first);
	meshObj = meshFn.object();

//	MDagModifier dagModifier;
	MFnDagNode meshDagNodeFn;
	MFnDependencyNode depNodeFn;
	meshDagNodeFn.setObject( meshDagPath_first);
	MString meshName = meshDagNodeFn.name();
	MObject outMesh_attrObject = meshDagNodeFn.attribute( "outMesh");

// ----------------------------------- duplicate shape

	MObject duplicated_meshObjectA;
	MObject duplicated_meshObjectB;
	MObject inMesh_attrObjectA;
	MObject inMesh_attrObjectB;
/*
	MStringArray commandResult;
	MSelectionList selList;

	MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1);
	selList.add( commandResult[0]);
	selList.getDependNode( 0, duplicated_meshObjectA);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_tA");
	duplicated_meshObjectA = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_sA");
	inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh");

	meshDagNodeFn.setObject( meshDagPath_first);
	selList.clear();

	MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1);
	selList.add( commandResult[0]);
	selList.getDependNode( 0, duplicated_meshObjectB);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_tB");
	duplicated_meshObjectB = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_sB");
	inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh");
*/
	duplicated_meshObjectA = meshDagNodeFn.duplicate();
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_tA");
	duplicated_meshObjectA = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_sA");
	inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh");

	meshDagNodeFn.setObject( meshDagPath_first);

	duplicated_meshObjectB = meshDagNodeFn.duplicate();
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_tB");
	duplicated_meshObjectB = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_sB");
	inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh");

// ----------------------------------- create node deleteComponent

	MDGModifier dgModifier;

	MObject deleteComponent_nodeObjectA = dgModifier.createNode( MString("deleteComponent"));
	depNodeFn.setObject( deleteComponent_nodeObjectA );
	MObject deleteComponent_attrObjectA( depNodeFn.attribute( "deleteComponents" ));
	MObject inputGeometry_attrObjectA( depNodeFn.attribute( "inputGeometry" ));
	MObject outputGeometry_attrObjectA( depNodeFn.attribute( "outputGeometry" ));
	dgModifier.doIt();
	depNodeFn.setName( "dfA_" + meshName);
	node_names.append( depNodeFn.name());

	MObject deleteComponent_nodeObjectB = dgModifier.createNode( MString("deleteComponent"));
	depNodeFn.setObject( deleteComponent_nodeObjectB );
	MObject deleteComponent_attrObjectB( depNodeFn.attribute( "deleteComponents" ));
	MObject inputGeometry_attrObjectB( depNodeFn.attribute( "inputGeometry" ));
	MObject outputGeometry_attrObjectB( depNodeFn.attribute( "outputGeometry" ));
	dgModifier.doIt();
	depNodeFn.setName( "dfB_" + meshName);
	node_names.append( depNodeFn.name());

// ----------------------------------- set attribute deleteComponent.deleteComponents

	MObject componentList_object = compListFn.object();

	MPlug deleteComponents_plugA( deleteComponent_nodeObjectA, deleteComponent_attrObjectA );
	status = deleteComponents_plugA.setValue( componentList_object );

	MIntArray invertedFaces;
	int numPolygons = meshFn.numPolygons();
	invertedFaces.setLength( numPolygons - inputFacesArray.length());
	int selFace = 0;
	int invFace = 0;
	for( int f = 0; f < numPolygons; f++)
	{
		if( f == inputFacesArray[selFace])
			selFace++;
		else
			invertedFaces[invFace++] = f;
	}
	MFnSingleIndexedComponent singleIndexedComponentFn( meshObj);
	singleIndexedComponentFn.create( MFn::kMeshPolygonComponent);
	singleIndexedComponentFn.addElements( invertedFaces);
	compListFn.clear();
	compListFn.create();
   componentList_object = singleIndexedComponentFn.object();
	compListFn.add( componentList_object);
	componentList_object = compListFn.object();
	MPlug deleteComponents_plugB( deleteComponent_nodeObjectB, deleteComponent_attrObjectB );
	status = deleteComponents_plugB.setValue( componentList_object );

// ------------------------------------- connecting plugs
/**/
	dgModifier.connect(
			meshObj, outMesh_attrObject,
			deleteComponent_nodeObjectA, inputGeometry_attrObjectA
		);
	dgModifier.connect(
			deleteComponent_nodeObjectA, outputGeometry_attrObjectA,
			duplicated_meshObjectA, inMesh_attrObjectA
		);

	dgModifier.connect(
			meshObj, outMesh_attrObject,
			deleteComponent_nodeObjectB, inputGeometry_attrObjectB
		);
	dgModifier.connect(
			deleteComponent_nodeObjectB, outputGeometry_attrObjectB,
			duplicated_meshObjectB, inMesh_attrObjectB
		);

	dgModifier.doIt();

// ---------------------------------- assigning shading group
/**/
	meshDagNodeFn.setObject( meshDagPath_first);
	MObject instObjGroups_attrObject = meshDagNodeFn.attribute( "instObjGroups");
	MPlug instObjGroups_plug( meshObj, instObjGroups_attrObject);
	instObjGroups_plug = instObjGroups_plug.elementByPhysicalIndex(0);
	MPlugArray instObjGroups_plug_connectionsArray;
	instObjGroups_plug.connectedTo( instObjGroups_plug_connectionsArray, false, true);
	if( instObjGroups_plug_connectionsArray.length() > 0)
	{
		MPlug dagSetMembers_plug = instObjGroups_plug_connectionsArray[0];
		MObject shadingSetNode_object = dagSetMembers_plug.node();
		MFnSet setFn( shadingSetNode_object);
		setFn.addMember( duplicated_meshObjectA);
		setFn.addMember( duplicated_meshObjectB);
//depNodeFn.setObject(shadingSetNode_object);
//MGlobal::displayInfo( depNodeFn.name());
	}

// ------------------------------------------------------------
	return true;
}
MStatus testNpassiveNode::compute(const MPlug &plug, MDataBlock &data)
{
    MStatus stat;
    if ( plug == currentState )
    { 
      // get old positions and numVerts
      // if num verts is different, reset topo and zero velocity
      // if num verts is the same, compute new velocity
        int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
                
        MFnMesh inputMesh(inMeshObj);       
        unsigned int numVerts = 0;
        numVerts = inputMesh.numVertices();
        unsigned int prevNumVerts;
        fNObject.getNumVertices(prevNumVerts);
        if(numVerts != prevNumVerts) {
                int numPolygons = inputMesh.numPolygons();
                int * faceVertCounts = new int[numPolygons];
                
        
                int facesArrayLength = 0;
                for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                faceVertCounts[ii] = verts.length();
                facesArrayLength += verts.length();
                }
                int * faces = new int[facesArrayLength];
                int currIndex = 0;
                for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                for(jj=0;jj<(int)verts.length();jj++) {
                    faces[currIndex++] = verts[jj];
                }
            }
                int numEdges = inputMesh.numEdges();
                int * edges = new int[2*numEdges];
                currIndex = 0;
                for(ii=0;ii<numEdges;ii++) {
                int2 edge;
                inputMesh.getEdgeVertices(ii,edge);
                edges[currIndex++] = edge[0];
                edges[currIndex++] = edge[1];
                }
                // When you are doing the initialization, the first call must to be setTopology().  All other
                // calls must come after this.
            fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
                delete[] faceVertCounts;
                delete[] faces;
                delete[] edges;        
                MFloatPointArray vertexArray;
                inputMesh.getPoints(vertexArray, MSpace::kWorld);
                fNObject.setPositions(vertexArray,true);
                MFloatPointArray velocitiesArray;
                velocitiesArray.setLength(numVerts);
                for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = 0.0f;
                velocitiesArray[ii].y = 0.0f;
                velocitiesArray[ii].z = 0.0f;
                velocitiesArray[ii].w = 0.0f;
            }
            fNObject.setVelocities(velocitiesArray);
        } else {
                MFloatPointArray vertexArray;
                MFloatPointArray prevVertexArray;
                inputMesh.getPoints(vertexArray, MSpace::kWorld);
                fNObject.getPositions(prevVertexArray);
            // you may want to get the playback rate for the dt
            // double dt = MAnimControl::playbackBy() \ 24.0;
            // or get the real dt by caching the last eval time
            double dt = 1.0/24.0;
                MFloatPointArray velocitiesArray;
                velocitiesArray.setLength(numVerts);
                for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = (float)( (vertexArray[ii].x - prevVertexArray[ii].x)/dt);
                velocitiesArray[ii].y = (float)( (vertexArray[ii].y - prevVertexArray[ii].y)/dt);
                velocitiesArray[ii].z = (float)( (vertexArray[ii].x - prevVertexArray[ii].z)/dt);
                velocitiesArray[ii].w = 0.0f;
            }
            fNObject.setVelocities(velocitiesArray);
            fNObject.setPositions(vertexArray,true);
        }
        // in real life, you'd get these attribute values each frame and set them
        fNObject.setThickness(0.1f);
        fNObject.setBounce(0.0f);
        fNObject.setFriction(0.1f);
        fNObject.setCollisionFlags(true, true, true);               
        MFnNObjectData outputData;
        MObject mayaNObjectData = outputData.create();
        outputData.setObject(mayaNObjectData);
        
        outputData.setObjectPtr(&fNObject);        
        outputData.setCached(false);
        MDataHandle currStateOutputHandle = data.outputValue(currentState);
        currStateOutputHandle.set(outputData.object());
      
    }
    if ( plug == startState )
    {
        int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
                
        MFnMesh inputMesh(inMeshObj);       
        int numPolygons = inputMesh.numPolygons();
            int * faceVertCounts = new int[numPolygons];
                
        
            int facesArrayLength = 0;
            for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                faceVertCounts[ii] = verts.length();
                facesArrayLength += verts.length();
            }
            int * faces = new int[facesArrayLength];
            int currIndex = 0;
            for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                for(jj=0;jj<(int)verts.length();jj++) {
                    faces[currIndex++] = verts[jj];
               }
           }
            int numEdges = inputMesh.numEdges();
            int * edges = new int[2*numEdges];
            currIndex = 0;
            for(ii=0;ii<numEdges;ii++) {
                int2 edge;
                inputMesh.getEdgeVertices(ii,edge);
                edges[currIndex++] = edge[0];
                edges[currIndex++] = edge[1];
            }
            // When you are doing the initialization, the first call must to be setTopology().  All other
            // calls must come after this.
            fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
            delete[] faceVertCounts;
            delete[] faces;
            delete[] edges;        
            unsigned int numVerts = 0;
            numVerts = inputMesh.numVertices();        
            MFloatPointArray vertexArray;
            inputMesh.getPoints(vertexArray, MSpace::kWorld);
            fNObject.setPositions(vertexArray,true);
            MFloatPointArray velocitiesArray;
            velocitiesArray.setLength(numVerts);
            for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = 0.0f;
                velocitiesArray[ii].y = 0.0f;
                velocitiesArray[ii].z = 0.0f;
                velocitiesArray[ii].w = 0.0f;
           }
           fNObject.setVelocities(velocitiesArray);
           fNObject.setThickness(0.1f);
            fNObject.setBounce(0.0f);
            fNObject.setFriction(0.1f);
            fNObject.setCollisionFlags(true, true, true);               
        
            MFnNObjectData outputData;
            MObject mayaNObjectData = outputData.create();
            outputData.setObject(mayaNObjectData);
        
            outputData.setObjectPtr(&fNObject);        
            outputData.setCached(false);
            MDataHandle startStateOutputHandle = data.outputValue(startState);
            startStateOutputHandle.set(outputData.object());
    }
    else {
        stat = MS::kUnknownParameter;
    }
    return stat;
}
MStatus ColorSplineParameterHandler<S>::doSetValue( IECore::ConstParameterPtr parameter, MPlug &plug ) const
{
	assert( parameter );
	typename IECore::TypedParameter< S >::ConstPtr p = IECore::runTimeCast<const IECore::TypedParameter< S > >( parameter );
	if( !p )
	{
		return MS::kFailure;
	}

	MRampAttribute fnRAttr( plug );
	if ( !fnRAttr.isColorRamp() )
	{
		return MS::kFailure;
	}

	const S &spline = p->getTypedValue();

	MStatus s;
	MIntArray indicesToReuse;
	plug.getExistingArrayAttributeIndices( indicesToReuse, &s );
	assert( s );

	int nextNewLogicalIndex = 0;
	if( indicesToReuse.length() )
	{
		nextNewLogicalIndex = 1 + *std::max_element( MArrayIter<MIntArray>::begin( indicesToReuse ), MArrayIter<MIntArray>::end( indicesToReuse ) );
	}
	
	assert( indicesToReuse.length() == fnRAttr.getNumEntries() );

	size_t pointsSizeMinus2 = spline.points.size() - 2;
	unsigned pointIndex = 0;
	unsigned numExpectedPoints = 0;
	for ( typename S::PointContainer::const_iterator it = spline.points.begin(); it != spline.points.end(); ++it, ++pointIndex )
	{
		// we commonly double up the endpoints on cortex splines to force interpolation to the end.
		// maya does this implicitly, so we skip duplicated endpoints when passing the splines into maya.
		// this avoids users having to be responsible for managing the duplicates, and gives them some consistency
		// with the splines they edit elsewhere in maya.
		if( ( pointIndex==1 && *it == *spline.points.begin() ) || ( pointIndex==pointsSizeMinus2 && *it == *spline.points.rbegin() ) )
		{
			continue;
		}

		MPlug pointPlug;
		if( indicesToReuse.length() )
		{
			pointPlug = plug.elementByLogicalIndex( indicesToReuse[0] );
			indicesToReuse.remove( 0 );
		}
		else
		{
			pointPlug = plug.elementByLogicalIndex( nextNewLogicalIndex++ );		
		}
		
		s = pointPlug.child( 0 ).setValue( it->first ); assert( s );
		MPlug colorPlug = pointPlug.child( 1 );
		colorPlug.child( 0 ).setValue( it->second[0] );
		colorPlug.child( 1 ).setValue( it->second[1] );
		colorPlug.child( 2 ).setValue( it->second[2] );
		// hardcoding interpolation of 3 (spline) because the MRampAttribute::MInterpolation enum values don't actually
		// correspond to the necessary plug values at all.
		s = pointPlug.child( 2 ).setValue( 3 ); assert( s );

		numExpectedPoints++;
	}

	// delete any of the original indices which we didn't reuse. we can't use MRampAttribute::deleteEntries
	// here as it's utterly unreliable.
	if( indicesToReuse.length() )
	{
		MString plugName = plug.name();
		MObject node = plug.node();
		MFnDagNode fnDAGN( node );
		if( fnDAGN.hasObj( node ) )
		{
			plugName = fnDAGN.fullPathName() + "." + plug.partialName();
		}
		for( unsigned i=0; i<indicesToReuse.length(); i++ )
		{
			// using mel because there's no equivalant api method as far as i know.
			MString command = "removeMultiInstance -b true \"" + plugName + "[" + indicesToReuse[i] + "]\"";
			s = MGlobal::executeCommand( command );
			assert( s );
			if( !s )
			{
				return s;
			}
		}
	}

#ifndef NDEBUG
	{
		assert( fnRAttr.getNumEntries() == numExpectedPoints );

		MIntArray indices;
		MFloatArray positions;
		MColorArray colors;
		MIntArray interps;
		fnRAttr.getEntries( indices, positions, colors, interps, &s );
		assert( s );
		assert( numExpectedPoints == positions.length() );
		assert( numExpectedPoints == colors.length() );
		assert( numExpectedPoints == interps.length() );
		assert( numExpectedPoints == indices.length() );

		for ( unsigned i = 0; i < positions.length(); i++ )
		{
			float position = positions[ i ];
			const MVector color( colors[ i ][ 0 ], colors[ i ][ 1 ], colors[ i ][ 2 ] );

			bool found = false;

			for ( typename S::PointContainer::const_iterator it = spline.points.begin(); it != spline.points.end() && !found; ++it )
			{
				MVector color2( it->second[0], it->second[1], it->second[2] );
				if ( fabs( it->first - position ) < 1.e-3f && ( color2 - color ).length() < 1.e-3f )
				{
					found = true;
				}
			}
			assert( found );
		}
	}
#endif

	return MS::kSuccess;
}
MStatus ColorSplineParameterHandler<S>::doSetValue( const MPlug &plug, IECore::ParameterPtr parameter ) const
{
	assert( parameter );

	typename IECore::TypedParameter< S >::Ptr p = IECore::runTimeCast<IECore::TypedParameter< S > >( parameter );
	if( !p )
	{
		return MS::kFailure;
	}

	S spline;

	MStatus s;
	MRampAttribute fnRAttr( plug, &s );
	assert( s );

	if ( !fnRAttr.isColorRamp() )
	{
		return MS::kFailure;
	}

	MIntArray indices;
	(const_cast<MPlug &>( plug )).getExistingArrayAttributeIndices( indices, &s );

	for( unsigned i = 0; i < indices.length(); i++ )
	{
		MPlug pointPlug = plug.elementByLogicalIndex( indices[i] );
		MPlug colorPlug = pointPlug.child( 1 );
				
		typename S::YType y( 1 );
		y[0] = colorPlug.child( 0 ).asDouble();
		y[1] = colorPlug.child( 1 ).asDouble();
		y[2] = colorPlug.child( 2 ).asDouble();
		
		spline.points.insert(
			typename S::PointContainer::value_type( pointPlug.child( 0 ).asDouble(), y )
		);
	}

	// maya seems to do an implicit doubling up of the end points to cause interpolation to the ends.
	// our spline has no such implicit behaviour so we explicitly double up.
	if( spline.points.size() )
	{
#ifndef NDEBUG
		size_t oldSplineSize = spline.points.size();
#endif

		assert( spline.points.begin()->first <= spline.points.rbegin()->first );
		spline.points.insert( *spline.points.begin() );
		spline.points.insert( *spline.points.rbegin() );
		assert( spline.points.size() == oldSplineSize + 2 );
	}

	p->setTypedValue( spline );

	if( spline.points.size() )
	{
		assert( spline.points.size() >= 2 );
		assert( spline.points.size() == fnRAttr.getNumEntries() + 2 );
	}

	return MS::kSuccess;
}
//setEdgeVertexIndexListShear
//-----------------------------------------------
void TesselationVisualization::setEdgeVertexPositionListShear(MDataBlock &data)
{
	//clear edgeVertexPositionList
	drawData.edgeVertexPositionList.clear();

	//inputGeo
	MObject oInputGeo = data.inputValue(aInputGeo).asMesh();

	//fnMeshInputGeo
	MFnMesh fnMeshInputGeo(oInputGeo);

	//vertexPositionList
	MPointArray vertexPositionList;
	fnMeshInputGeo.getPoints(vertexPositionList);

	//itMeshPolyInputGeo
	MItMeshPolygon itMeshPolyInputGeo(oInputGeo);

	//for each poly
	while(!itMeshPolyInputGeo.isDone())
	{
		//get edges
		MIntArray edgeIndexList;
		itMeshPolyInputGeo.getEdges(edgeIndexList);
		
		//edgeVertexIndices
		int2* edgeVertexIndices = new int2[4];

		for(int index = 0; index < edgeIndexList.length(); index++)
		{
			fnMeshInputGeo.getEdgeVertices(edgeIndexList[index], edgeVertexIndices[index]);
		};

		//edgeVertexIndicesNoDuplicates
		std::set<int> setEdgeVertexIndicesNoDuplicates;

		for(int index = 0; index < edgeIndexList.length(); index++)
		{
			setEdgeVertexIndicesNoDuplicates.insert(edgeVertexIndices[index][0]);
			setEdgeVertexIndicesNoDuplicates.insert(edgeVertexIndices[index][1]);
		};

		//vecEdgeVertexIndicesNoDuplicates
		std::vector<int> vecEdgeVertexIndicesNoDuplicates(setEdgeVertexIndicesNoDuplicates.begin(), setEdgeVertexIndicesNoDuplicates.end());


		//get faceVertexList
		MPointArray faceVertexPointList = MPointArray(4);

		for(int index = 0; index < edgeIndexList.length(); index++)
		{
			MPoint faceVertexPoint = vertexPositionList[vecEdgeVertexIndicesNoDuplicates[index]];
			faceVertexPointList.set(faceVertexPoint, index);
		};

		
		
		//edge01
		std::vector<float> edge01;
		edge01.push_back(faceVertexPointList[0].x);edge01.push_back(faceVertexPointList[0].y);edge01.push_back(faceVertexPointList[0].z);
		edge01.push_back(faceVertexPointList[1].x);edge01.push_back(faceVertexPointList[1].y);edge01.push_back(faceVertexPointList[1].z);

		//edge13
		std::vector<float> edge13;
		edge13.push_back(faceVertexPointList[1].x);edge13.push_back(faceVertexPointList[1].y);edge13.push_back(faceVertexPointList[1].z);
		edge13.push_back(faceVertexPointList[3].x);edge13.push_back(faceVertexPointList[3].y);edge13.push_back(faceVertexPointList[3].z);

		//edge32
		std::vector<float> edge32;
		edge32.push_back(faceVertexPointList[3].x);edge32.push_back(faceVertexPointList[3].y);edge32.push_back(faceVertexPointList[3].z);
		edge32.push_back(faceVertexPointList[2].x);edge32.push_back(faceVertexPointList[2].y);edge32.push_back(faceVertexPointList[2].z);

		//edge20
		std::vector<float> edge20;
		edge20.push_back(faceVertexPointList[2].x);edge20.push_back(faceVertexPointList[2].y);edge20.push_back(faceVertexPointList[2].z);
		edge20.push_back(faceVertexPointList[0].x);edge20.push_back(faceVertexPointList[0].y);edge20.push_back(faceVertexPointList[0].z);

		//edge03
		std::vector<float> edge03;
		edge03.push_back(faceVertexPointList[0].x);edge03.push_back(faceVertexPointList[0].y);edge03.push_back(faceVertexPointList[0].z);
		edge03.push_back(faceVertexPointList[3].x);edge03.push_back(faceVertexPointList[3].y);edge03.push_back(faceVertexPointList[3].z);

		//edge12
		std::vector<float> edge12;
		edge12.push_back(faceVertexPointList[1].x);edge12.push_back(faceVertexPointList[1].y);edge12.push_back(faceVertexPointList[1].z);
		edge12.push_back(faceVertexPointList[2].x);edge12.push_back(faceVertexPointList[2].y);edge12.push_back(faceVertexPointList[2].z);

		
		//add to drawData.edgeVertexPositionList
		drawData.edgeVertexPositionList.push_back(edge01);
		drawData.edgeVertexPositionList.push_back(edge13);
		drawData.edgeVertexPositionList.push_back(edge32);
		drawData.edgeVertexPositionList.push_back(edge20);
		drawData.edgeVertexPositionList.push_back(edge03);
		drawData.edgeVertexPositionList.push_back(edge12);
		
		//del edgeVertexIndices
		delete [] edgeVertexIndices;
		
		//Advance
		itMeshPolyInputGeo.next();
	};
};
MStatus genRod(
	const MPoint &p0,
	const MPoint &p1,
	const double radius,
	const unsigned int nSegs,
	
	int &nPolys,
	MPointArray &verts,
	MIntArray &polyCounts,
	MIntArray &polyConnects
)
{
	verts.clear();
	polyCounts.clear();
	polyConnects.clear();
	
	unsigned int nCirclePts = nSegs; 
	unsigned int nVerts = 2 * nCirclePts;
	
	// Calculate the local axiis of the rod
	MVector vec( p1 - p0 );
	MVector up( 0.0, 1.0, 0.0 );
	MVector xAxis, yAxis, zAxis;
	
	yAxis = vec.normal();
	if( up.isParallel( yAxis, 0.1 ) )
		up = MVector( 1.0, 0.0, 0.0 );
	xAxis = yAxis ^ up;
	zAxis = (xAxis ^ yAxis).normal();
	xAxis = (yAxis ^ zAxis ).normal(); 
	
	// Calculate the vertex positions
	verts.setLength( nVerts );
	double angleIncr = 2.0 * M_PI / nSegs;
	double angle;
	MPoint p;
	double x, z;
	unsigned int i;
	for( i=0, angle=0; i < nCirclePts; i++, angle += angleIncr )
	{
		// Calculate position in circle
		x = radius * cos( angle );
		z = radius * sin( angle );
		
		p = p0 + x * xAxis + z * zAxis;

		verts[ i ] = p;
		
		p += vec;

		verts[ i + nCirclePts ] = p;
	}
	
	nPolys = nSegs;
	
	// Generate polycounts
	polyCounts.setLength( nPolys );
	for( i=0; i < polyCounts.length(); i++ )
		polyCounts[i] = 4;
	
	// Generate polyconnects
	polyConnects.setLength( nPolys * 4 );
	polyConnects.clear();
	for( i=0; i < nSegs; i++ )
	{
		polyConnects.append( linearIndex( 0, i, 2, nCirclePts ) );
		polyConnects.append( linearIndex( 0, i+1, 2, nCirclePts ) );
		polyConnects.append( linearIndex( 1, i+1, 2, nCirclePts ) );
		polyConnects.append( linearIndex( 1, i, 2, nCirclePts ) );
	}
		
	return MS::kSuccess;
}
Пример #14
0
MStatus skinClusterWeights::redoIt()
{
    MStatus status;
    unsigned int ptr = 0;
	
    MSelectionList selList;
    int geomLen = geometryArray.length();
    fDagPathArray.setLength(geomLen);
    fComponentArray.setLength(geomLen);
    fInfluenceIndexArrayPtrArray = new MIntArray[geomLen];
    fWeightsPtrArray = new MDoubleArray[geomLen];

    for (int i = 0; i < geomLen; i++) {
	MDagPath dagPath;
	MObject  component;
	
	selList.clear();
	selList.add(geometryArray[i]);
	MStatus status = selList.getDagPath(0, dagPath, component);
	if (status != MS::kSuccess) {
	    continue;
	}
	if (component.isNull()) dagPath.extendToShape();

	MObject skinCluster = findSkinCluster(dagPath);
	if (!isSkinClusterIncluded(skinCluster)) {
	    continue;
	}

	MFnSkinCluster skinClusterFn(skinCluster, &status);
	if (status != MS::kSuccess) {
	    continue; 
	}

	MIntArray influenceIndexArray;
	populateInfluenceIndexArray(skinClusterFn, influenceIndexArray);

	unsigned numInf = influenceIndexArray.length();
	if (numInf == 0) continue;
	  
	unsigned numCV = 0;
	if (dagPath.node().hasFn(MFn::kMesh)) {
	    MItMeshVertex polyIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		numCV = polyIter.count();
	    } 
	} else if (dagPath.node().hasFn(MFn::kNurbsSurface)) {
	    MItSurfaceCV nurbsIter(dagPath, component, true, &status);
	    if (status == MS::kSuccess) {
		while (!nurbsIter.isDone()) {
		    numCV++;
		    nurbsIter.next();
		}
	    }
	} else if (dagPath.node().hasFn(MFn::kNurbsCurve)) {
	    MItCurveCV curveIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		while (!curveIter.isDone()) {
		    numCV++;
		    curveIter.next();
		}
	    }
	}
	unsigned numEntry = numCV * numInf;

	if (numEntry > 0) {
	    MDoubleArray weights(numEntry);
	    unsigned int numWeights = weightArray.length();
	    if (assignAllToSingle) {
		if (numInf <= numWeights) {
		    for (unsigned j = 0; j < numEntry; j++) {
			weights[j] = weightArray[j % numInf];
		    }
		} else {
		    MGlobal::displayError("Not enough weights specified\n");
		    return MS::kFailure;
		}
	    } else {
		for (unsigned j = 0; j < numEntry; j++, ptr++) {
		    if (ptr < numWeights) {
			weights[j] = weightArray[ptr];
		    } else {
			MGlobal::displayError("Not enough weights specified\n");
			return MS::kFailure;
		    }
		}
	    }

	    // support for undo
	    fDagPathArray[i] = dagPath;
	    fComponentArray[i] = component;
	    fInfluenceIndexArrayPtrArray[i] = influenceIndexArray;
	    MDoubleArray oldWeights;
	    skinClusterFn.getWeights(dagPath, component, influenceIndexArray, oldWeights);
	    fWeightsPtrArray[i] = oldWeights;
	    
	    skinClusterFn.setWeights(dagPath, component, influenceIndexArray, weights);
	}
    }
    return MS::kSuccess;
}
Пример #15
0
void ExportACache::save(const char* filename, int frameNumber, char bfirst)
{	
	MStatus status;
	FXMLScene xml_f;
	xml_f.begin(filename, frameNumber, bfirst);
	for(unsigned it=0; it<m_mesh_list.length(); it++) {
		m_mesh_list[it].extendToShape();
		
		MString surface = m_mesh_list[it].partialPathName();
	
		AHelper::validateFilePath(surface);
		
		MFnDependencyNode fnode(m_mesh_list[it].node());
		MString smsg("prtMsg");
		MStatus hasMsg;
		MPlug pmsg = fnode.findPlug( smsg, 1,  &hasMsg );
		
		char bNoChange = 0;
		if(hasMsg) {
			MObject oattrib;
			AHelper::getConnectedNode(oattrib, pmsg);
			fnode.setObject(oattrib);

			bool iattr = 0;
			
			AHelper::getBoolAttributeByName(fnode, "noChange", iattr);
			if(iattr) bNoChange = 1;
		}

		xml_f.meshBegin(surface.asChar(), bNoChange);
	
		MFnMesh meshFn(m_mesh_list[it], &status );
		MItMeshPolygon faceIter(m_mesh_list[it], MObject::kNullObj, &status );
		MItMeshVertex vertIter(m_mesh_list[it], MObject::kNullObj, &status);
		MItMeshEdge edgeIter(m_mesh_list[it], MObject::kNullObj, &status);
		
		int n_tri = 0;
		float f_area = 0;
		double area;
		
		faceIter.reset();
		for( ; !faceIter.isDone(); faceIter.next() ) {
			MIntArray vexlist;
			faceIter.getVertices ( vexlist );
			n_tri += vexlist.length() - 2;
			
			faceIter.getArea( area,  MSpace::kWorld );
			f_area += (float)area;
		}
		
		xml_f.triangleInfo(n_tri, f_area);
		
		float avg_grid = sqrt(f_area/n_tri)/2;
		
		double light_intensity = 1.0;
		
		if(hasMsg) {
			MObject oattrib;
			AHelper::getConnectedNode(oattrib, pmsg);
			fnode.setObject(oattrib);

			bool iattr = 0;
			
			AHelper::getBoolAttributeByName(fnode, "noChange", iattr);
			if(iattr) xml_f.addAttribute("noChange", 1);
			
			AHelper::getBoolAttributeByName(fnode, "skipIndirect", iattr);
			if(iattr) xml_f.addAttribute("skipIndirect", 1);
			
			iattr = 0;
			AHelper::getBoolAttributeByName(fnode, "skipScatter", iattr);
			if(iattr) xml_f.addAttribute("skipScatter", 1);
			
			iattr = 0;
			AHelper::getBoolAttributeByName(fnode, "skipBackscatter", iattr);
			if(iattr) xml_f.addAttribute("skipBackscatter", 1);
			
			iattr = 0;
			AHelper::getBoolAttributeByName(fnode, "asLightsource", iattr);
			if(iattr) xml_f.addAttribute("asLightsource", 1);
			
			iattr = 0;
			AHelper::getBoolAttributeByName(fnode, "asGhost", iattr);
			if(iattr) xml_f.addAttribute("invisible", 1);
			
			iattr = 0;
			AHelper::getBoolAttributeByName(fnode, "castNoShadow", iattr);
			if(iattr) xml_f.addAttribute("noShadow", 1);
			
			double td;
			if(AHelper::getDoubleAttributeByName(fnode, "lightIntensity", td)) light_intensity = td;
			
			fnode.setObject(m_mesh_list[it].node());
		}

		xml_f.staticBegin();
		
		int n_poly = meshFn.numPolygons();
		int n_vert = meshFn.numVertices();
		int* polycount = new int[n_poly];
		
		faceIter.reset();
		for( ; !faceIter.isDone(); faceIter.next() ) polycount[ faceIter.index() ] = faceIter.polygonVertexCount();
		
		xml_f.addFaceCount(n_poly, polycount);
		delete[] polycount;
		
		int n_facevertex = meshFn.numFaceVertices();
		int* polyconnect = new int[n_facevertex];
		
		int acc = 0;
		faceIter.reset();
		for( ; !faceIter.isDone(); faceIter.next() ) 
		{
			MIntArray  vexlist;
			faceIter.getVertices ( vexlist );
			for( int i=vexlist.length()-1; i >=0; i-- ) 
			{
				polyconnect[acc] = vexlist[i];
				acc++;
			}
		}
		
		xml_f.addFaceConnection(n_facevertex, polyconnect);
		delete[] polyconnect;
		
		int* triconnect = new int[3*n_tri];
		acc = 0;
		faceIter.reset();
		for( ; !faceIter.isDone(); faceIter.next() ) 
		{
			MIntArray  vexlist;
			faceIter.getVertices ( vexlist );
			for( int i=vexlist.length()-2; i >0; i-- ) 
			{
				triconnect[acc] = vexlist[vexlist.length()-1];
				acc++;
				triconnect[acc] = vexlist[i];
				acc++;
				triconnect[acc] = vexlist[i-1];
				acc++;
			}
		}
		
		xml_f.addTriangleConnection(3*n_tri, triconnect);
		delete[] triconnect;

		if(meshFn.numUVSets() > 0)
		{
			MStringArray setNames;
			meshFn.getUVSetNames(setNames);
			for(unsigned i=0; i< setNames.length(); i++)
			{
				float* scoord = new float[n_facevertex];
				float* tcoord = new float[n_facevertex];
				
				acc = 0;
				faceIter.reset();
				MFloatArray uarray, varray;
				if(faceIter.hasUVs (setNames[i], &status))
				{
					for( ; !faceIter.isDone(); faceIter.next() ) 
					{
						faceIter.getUVs ( uarray, varray, &setNames[i] );
						for( int j=uarray.length()-1; j >=0 ; j-- ) 
						{
							scoord[acc] = uarray[j];
							tcoord[acc] = 1.0 - varray[j];
							acc++;
						}
					}
					
					
					if(setNames[i] == "map1")
					{
						xml_f.uvSetBegin(setNames[i].asChar());
						xml_f.addS("facevarying float s", meshFn.numFaceVertices(), scoord);
						xml_f.addT("facevarying float t", meshFn.numFaceVertices(), tcoord);
						xml_f.uvSetEnd();
					}
					else
					{
						xml_f.uvSetBegin(setNames[i].asChar());
						std::string paramname("facevarying float u_");
						paramname.append(setNames[i].asChar());
						xml_f.addS(paramname.c_str(), meshFn.numFaceVertices(), scoord);
						
						paramname = "facevarying float v_";
						paramname.append(setNames[i].asChar());
						xml_f.addT(paramname.c_str(), meshFn.numFaceVertices(), tcoord);
						xml_f.uvSetEnd();
					}
				}
				else MGlobal::displayWarning(MString("Skip empty uv set: ") + setNames[i]);
				
				delete[] scoord;
				delete[] tcoord;
			}
		}
		
		MStringArray colorSetNames;
		meshFn.getColorSetNames (colorSetNames);
		
		for(unsigned int i=0; i<colorSetNames.length(); i++)
		{
			MStatus hasColor;
			
			XYZ *colors = new XYZ[n_vert];
			vertIter.reset();
			MString aset = colorSetNames[i];
			MColor col;
			for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) {
					MIntArray conn_face;
					vertIter.getConnectedFaces(conn_face);
					vertIter.getColor(col, conn_face[0], &aset);
					colors[i].x = col.r*light_intensity;
					colors[i].y = col.g*light_intensity;
					colors[i].z = col.b*light_intensity;
			}
				
			xml_f.addVertexColor(aset.asChar(), n_vert, colors);
			delete[] colors;
		}
		
		//if(!bNoChange) {

			
		//}
		
		MPointArray p_vert;
		
		meshFn.getPoints ( p_vert, MSpace::kWorld );
		
		MPoint corner_l(10e6, 10e6, 10e6);
		MPoint corner_h(-10e6, -10e6, -10e6);
		
		for( unsigned int i=0; i<p_vert.length(); i++) {
			if( p_vert[i].x < corner_l.x ) corner_l.x = p_vert[i].x;
			if( p_vert[i].y < corner_l.y ) corner_l.y = p_vert[i].y;
			if( p_vert[i].z < corner_l.z ) corner_l.z = p_vert[i].z;
			if( p_vert[i].x > corner_h.x ) corner_h.x = p_vert[i].x;
			if( p_vert[i].y > corner_h.y ) corner_h.y = p_vert[i].y;
			if( p_vert[i].z > corner_h.z ) corner_h.z = p_vert[i].z;
		}
		
		
		
		XYZ *cv = new XYZ[n_vert];
		
		for( unsigned int i=0; i<p_vert.length(); i++) 
		{
			cv[i].x = p_vert[i].x;
			cv[i].y = p_vert[i].y;
			cv[i].z= p_vert[i].z;
		}
		
		//if(!bNoChange) 
		//else 
		xml_f.addStaticP(n_vert, cv);
		
		
		
		XYZ *nor = new XYZ[n_vert];
		XYZ *tang = new XYZ[n_vert];
		
		vertIter.reset();
		MVector vnor;
		
		for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ )
		{
			vertIter.getNormal(vnor, MSpace::kWorld);
			vnor.normalize();
			nor[i].x = vnor.x;
			nor[i].y = vnor.y;
			nor[i].z = vnor.z;
		}
		
		MString uvset("map1");
		
		vertIter.reset();
		for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ )
		{
			MIntArray conn_face;
			vertIter.getConnectedFaces(conn_face);
			
			MVector ctang(0,0,0);
			MVector ttang;
			for(unsigned j = 0; j<conn_face.length(); j++) 
			{
				meshFn.getFaceVertexTangent (conn_face[j], i,  ttang,  MSpace::kWorld, &uvset);
				ttang.normalize();
				ctang += ttang;
			}
			ctang.normalize();
			tang[i].x = ctang.x;
			tang[i].y = ctang.y;
			tang[i].z = ctang.z;
			
			tang[i] = nor[i].cross(tang[i]);
			tang[i].normalize();
		}

		//if(!bNoChange) 
		//else 
		xml_f.addStaticN(n_vert, nor);
		//xml_f.addTangent(n_vert, tang);
		
		
// export per-vertex thickness
		float* vgrd = new float[n_vert];
		int pidx;
		vertIter.reset();
		for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) {
			MIntArray connfaces;
			vertIter.getConnectedFaces( connfaces );
			float connarea = 0;
			for(unsigned j=0; j<connfaces.length(); j++)
			{
				faceIter.setIndex(connfaces[j], pidx);
				faceIter.getArea(area, MSpace::kWorld );
				connarea += (float)area/faceIter.polygonVertexCount();
			}
			vgrd[i] = sqrt(connarea)/2;
			if(vgrd[i] > avg_grid) vgrd[i] = avg_grid;
		}
		
		//if(!bNoChange) 
		//else 
		xml_f.addStaticGridSize(n_vert, vgrd);
		
		
		
		// 
		//else 
		xml_f.staticEnd();
		
		if(!bNoChange) {
			
			xml_f.dynamicBegin();
		
			xml_f.addP(n_vert, cv);
			xml_f.addN(n_vert, nor);
			xml_f.addGridSize(n_vert, vgrd);
			
			xml_f.dynamicEnd();
		}
		
		delete[] cv;
		delete[] tang;
		delete[] nor;
		delete[] vgrd;
		
		xml_f.addBBox(corner_l.x, corner_l.y, corner_l.z, corner_h.x, corner_h.y, corner_h.z);

		xml_f.meshEnd(bNoChange);
	}
/* disable nurbs for now

	float aspace[4][4];
	for(unsigned it=0; it<m_nurbs_list.length(); it++) {
		MVector scale = AHelper::getTransformWorldNoScale(m_nurbs_list[it].fullPathName(), aspace);
		
		MString surfacename = m_nurbs_list[it].fullPathName();
		AHelper::validateFilePath(surfacename);
		xml_f.transformBegin(surfacename.asChar(), aspace);
		xml_f.addScale(scale.x, scale.y, scale.z);
		
		m_nurbs_list[it].extendToShape();
		
		surfacename = m_nurbs_list[it].fullPathName();
		AHelper::validateFilePath(surfacename);
		
		MFnNurbsSurface fsurface(m_nurbs_list[it]);
		
		int degreeU = fsurface.degreeU();
		int degreeV = fsurface.degreeV();
		
		int formU, formV;
		
		if(fsurface.formInU() == MFnNurbsSurface::kOpen ) formU = 0;
		else if(fsurface.formInU() == MFnNurbsSurface::kClosed ) formU = 1;
		else formU = 2;

		if(fsurface.formInV() == MFnNurbsSurface::kOpen ) formV = 0;
		else if(fsurface.formInV() == MFnNurbsSurface::kClosed ) formV = 1;
		else formV = 2;
		
		xml_f.nurbssurfaceBegin(surfacename.asChar(), degreeU, degreeV, formU, formV);
		
		xml_f.staticBegin();
		
		MPointArray p_cvs;
	
		fsurface.getCVs( p_cvs, MSpace::kObject );
		
		unsigned n_cvs = p_cvs.length();
		XYZ *cv = new XYZ[n_cvs];
	
		for(unsigned i=0; i<n_cvs; i++) {
			cv[i].x = p_cvs[i].x;
			cv[i].y = p_cvs[i].y;
			cv[i].z= p_cvs[i].z;
		}
	
		xml_f.addStaticVec("cvs", n_cvs, cv);
		delete[] cv;
		
		MDoubleArray knotu, knotv;
		
		fsurface.getKnotsInU(knotu);
		fsurface.getKnotsInV(knotv);
		
		unsigned n_ku = knotu.length();
		unsigned n_kv = knotv.length();
		
		float *ku = new float[n_ku];
		for(unsigned i=0; i<n_ku; i++) ku[i] = knotu[i];
		
		float *kv = new float[n_kv];
		for(unsigned i=0; i<n_kv; i++) kv[i] = knotv[i];

		xml_f.addStaticFloat("knotu", n_ku, ku);
		xml_f.addStaticFloat("knotv", n_kv, kv);
		
		delete[] ku;
		delete[] kv;
		
		xml_f.staticEnd();
		
		xml_f.nurbssurfaceEnd();
		
		xml_f.transformEnd();
	}
*/	
	xml_f.cameraBegin("backscat_camera", m_space);
	xml_f.cameraEnd();
	
	xml_f.cameraBegin("eye_camera", m_eye);
	p_eye.extendToShape();
	MFnCamera feye(p_eye);
	xml_f.addAttribute("focal_length", (float)feye.focalLength());
	xml_f.addAttribute("horizontal_film_aperture", (float)feye.horizontalFilmAperture());
	xml_f.addAttribute("vertical_film_aperture", (float)feye.verticalFilmAperture());
	xml_f.addAttribute("near_clipping_plane", (float)feye.nearClippingPlane());
	xml_f.addAttribute("far_clipping_plane", (float)feye.farClippingPlane());
	xml_f.cameraEnd();
	
	xml_f.end(filename);
}
Пример #16
0
// #### rebuildHbrMeshIfNeeded
//
//      If the topology of the mesh changes, or any attributes that affect
//      how the mesh is computed the original HBR needs to be rebuilt
//      which will trigger a rebuild of the FAR mesh and subsequent buffers.
//
void
OsdMeshData::rebuildHbrMeshIfNeeded(OpenSubdivShader *shader)
{
    MStatus status = MS::kSuccess;

    if (!_meshTopoDirty && !shader->getHbrMeshDirty())
        return;

    MFnMesh meshFn(_meshDagPath);

    // Cache attribute values
    _level      = shader->getLevel();
    _kernel     = shader->getKernel();
    _adaptive   = shader->isAdaptive();
    _uvSet      = shader->getUVSet();

    // Get Maya vertex topology and crease data
    MIntArray vertexCount;
    MIntArray vertexList;
    meshFn.getVertices(vertexCount, vertexList);

    MUintArray edgeIds;
    MDoubleArray edgeCreaseData;
    meshFn.getCreaseEdges(edgeIds, edgeCreaseData);

    MUintArray vtxIds;
    MDoubleArray vtxCreaseData;
    meshFn.getCreaseVertices(vtxIds, vtxCreaseData);

    if (vertexCount.length() == 0) return;

    // Copy Maya vectors into std::vectors
    std::vector<int> numIndices(&vertexCount[0], &vertexCount[vertexCount.length()]);
    std::vector<int> faceIndices(&vertexList[0], &vertexList[vertexList.length()]);
    std::vector<int> vtxCreaseIndices(&vtxIds[0], &vtxIds[vtxIds.length()]);
    std::vector<double> vtxCreases(&vtxCreaseData[0], &vtxCreaseData[vtxCreaseData.length()]);
    std::vector<double> edgeCreases(&edgeCreaseData[0], &edgeCreaseData[edgeCreaseData.length()]);

    // Edge crease index is stored as pairs of vertex ids
    int nEdgeIds = edgeIds.length();
    std::vector<int> edgeCreaseIndices;
    edgeCreaseIndices.resize(nEdgeIds*2);
    for (int i = 0; i < nEdgeIds; ++i) {
        int2 vertices;
        status = meshFn.getEdgeVertices(edgeIds[i], vertices);
        if (status.error()) {
            MERROR(status, "OpenSubdivShader: Can't get edge vertices");
            continue;
        }
        edgeCreaseIndices[i*2] = vertices[0];
        edgeCreaseIndices[i*2+1] = vertices[1];
    }

    // Convert attribute enums to HBR enums (this is why the enums need to match)
    HbrMeshUtil::SchemeType hbrScheme = (HbrMeshUtil::SchemeType) shader->getScheme();
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) shader->getInterpolateBoundary();
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpUVBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) shader->getInterpolateUVBoundary();


    // clear any existing face-varying descriptor
    if (_fvarDesc) {
        delete _fvarDesc;
        _fvarDesc = NULL;
    }

    // read UV data from maya and build per-face per-vert list of UVs for HBR face-varying data
    std::vector< float > uvList;
    status = buildUVList( meshFn, uvList );
    if (! status.error()) {
        // Create face-varying data descriptor.  The memory required for indices
        // and widths needs to stay alive as the HBR library only takes in the
        // pointers and assumes the client will maintain the memory so keep _fvarDesc
        // around as long as _hbrmesh is around.
        int fvarIndices[] = { 0, 1 };
        int fvarWidths[] = { 1, 1 };
        _fvarDesc = new FVarDataDesc( 2, fvarIndices, fvarWidths, 2, hbrInterpUVBoundary );
    }

    if (_fvarDesc && hbrScheme != HbrMeshUtil::kCatmark) {
        MGlobal::displayWarning("Face-varying not yet supported for Loop/Bilinear, using Catmull-Clark");
        hbrScheme = HbrMeshUtil::kCatmark;
    }

    // Convert Maya mesh to internal HBR representation
    _hbrmesh = ConvertToHBR(meshFn.numVertices(), numIndices, faceIndices,
                            vtxCreaseIndices, vtxCreases,
                            std::vector<int>(), std::vector<float>(),
                            edgeCreaseIndices, edgeCreases,
                            hbrInterpBoundary, 
                            hbrScheme,
                            false,                      // no ptex
                            _fvarDesc, 
                            _fvarDesc?&uvList:NULL);    // yes fvar (if have UVs)

    // note: GL function can't be used in prepareForDraw API.
    _needsInitializeMesh = true;

    // Mesh topology data is up to date
    _meshTopoDirty = false;
    shader->setHbrMeshDirty(false);
}
Пример #17
0
void collisionShapeNode::computeCollisionShape(const MPlug& plug, MDataBlock& data)
{
  //  std::cout << "collisionShapeNode::computeCollisionShape" << std::endl;

    MObject thisObject(thisMObject());

    MPlug plgInShape(thisObject, ia_shape);

    MPlug plgType(thisObject, ia_type);
    int type;
    plgType.getValue(type);
    switch(type) {
    case 0:  
        {
        //convex hull
        MPlugArray plgaConnectedTo;
        plgInShape.connectedTo(plgaConnectedTo, true, true);
        if(plgaConnectedTo.length() > 0) {
            MObject node = plgaConnectedTo[0].node();
            if(node.hasFn(MFn::kMesh)) {
                MDagPath dagPath;
                MDagPath::getAPathTo(node, dagPath);
                MFnMesh fnMesh(dagPath);
                MFloatPointArray mpoints;
                MFloatVectorArray mnormals;
                MIntArray mtrianglecounts;
                MIntArray mtrianglevertices;
                fnMesh.getPoints(mpoints, MSpace::kObject);
                fnMesh.getNormals(mnormals, MSpace::kObject);
                fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                std::vector<vec3f> vertices(mpoints.length());
                std::vector<vec3f> normals(mpoints.length());
                std::vector<unsigned int> indices(mtrianglevertices.length());

                for(size_t i = 0; i < vertices.size(); ++i) {
                    vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                    normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                }
                for(size_t i = 0; i < indices.size(); ++i) {
                    indices[i] = mtrianglevertices[i];
                }
                m_collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                                                                       &(indices[0]), indices.size());
            }
        }
        }
        break;
    case 1:
        //mesh
        {
        //convex hull
        MPlugArray plgaConnectedTo;
        plgInShape.connectedTo(plgaConnectedTo, true, true);
        if(plgaConnectedTo.length() > 0) {
            MObject node = plgaConnectedTo[0].node();
            if(node.hasFn(MFn::kMesh)) {
                MDagPath dagPath;
                MDagPath::getAPathTo(node, dagPath);
                MFnMesh fnMesh(dagPath);
                MFloatPointArray mpoints;
                MFloatVectorArray mnormals;
                MIntArray mtrianglecounts;
                MIntArray mtrianglevertices;
                fnMesh.getPoints(mpoints, MSpace::kObject);
                fnMesh.getNormals(mnormals, MSpace::kObject);
                fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                std::vector<vec3f> vertices(mpoints.length());
                std::vector<vec3f> normals(mpoints.length());
                std::vector<unsigned int> indices(mtrianglevertices.length());

                for(size_t i = 0; i < vertices.size(); ++i) {
                    vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                    normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                }
                for(size_t i = 0; i < indices.size(); ++i) {
                    indices[i] = mtrianglevertices[i];
                }
                m_collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                                                                &(indices[0]), indices.size());
            }
        }
        }
        break;
    case 2:
        //cylinder
        break;
    case 3:
        //capsule
        break;
    case 4:
        //box
        m_collision_shape = solver_t::create_box_shape();
        break;
    case 5:
        //sphere
        m_collision_shape = solver_t::create_sphere_shape();
        break;
    case 6:
        //plane
        m_collision_shape = solver_t::create_plane_shape();
        break;
    }

    assert(m_collision_shape);

    data.setClean(plug);
}
void CageDeformerNode::tetMatrix(const MPointArray& p, const MIntArray& triangles, short cageMode, std::vector<Matrix4d>& m)
/// prepare cage tetrahedra from points and triangulation
{
    if(cageMode == 10 || cageMode == 11){
        MVector u, v, q ;
        for(unsigned int i=0;i<triangles.length()/3;i++){
            u=MVector(p[triangles[3*i+1]]-p[triangles[3*i]]);
            v=MVector(p[triangles[3*i+2]]-p[triangles[3*i]]);
			q=u^v;
			q.normalize();
            
            m[i] << p[triangles[3*i]].x, p[triangles[3*i]].y, p[triangles[3*i]].z, 1,
            p[triangles[3*i+1]].x, p[triangles[3*i+1]].y, p[triangles[3*i+1]].z, 1,
            p[triangles[3*i+2]].x, p[triangles[3*i+2]].y, p[triangles[3*i+2]].z, 1,
            (p[triangles[3*i]]+q).x, (p[triangles[3*i]]+q).y, (p[triangles[3*i]]+q).z,1;
        }
    }else if (cageMode == 0){
        for(unsigned int i=0;i<triangles.length()/4;i++){
            m[i] << p[triangles[4*i]].x, p[triangles[4*i]].y, p[triangles[4*i]].z, 1,
            p[triangles[4*i+1]].x, p[triangles[4*i+1]].y, p[triangles[4*i+1]].z, 1,
            p[triangles[4*i+2]].x, p[triangles[4*i+2]].y, p[triangles[4*i+2]].z, 1,
            p[triangles[4*i+3]].x, p[triangles[4*i+3]].y, p[triangles[4*i+3]].z, 1;
        }
    }else if (cageMode == 1){
        MVector u, v, q;
        for(unsigned int i=0;i<triangles.length()/4;i++){
            u=MVector(p[triangles[4*i+1]]-p[triangles[4*i]]);
            v=MVector(p[triangles[4*i+2]]-p[triangles[4*i]]);
            q=MVector(p[triangles[4*i+3]]-p[triangles[4*i]]);
            u.normalize();
            v.normalize();
            q.normalize();
            m[i] << p[triangles[4*i]].x, p[triangles[4*i]].y, p[triangles[4*i]].z, 1,
            u[0]+p[triangles[4*i]].x,u[1]+p[triangles[4*i]].y,u[2]+p[triangles[4*i]].z,1,
            v[0]+p[triangles[4*i]].x,v[1]+p[triangles[4*i]].y,v[2]+p[triangles[4*i]].z,1,
            q[0]+p[triangles[4*i]].x,q[1]+p[triangles[4*i]].y,q[2]+p[triangles[4*i]].z,1;
        }
    }else if (cageMode == 5 || cageMode == 6){
        std::vector<Vector3d> normal(p.length(),Vector3d::Zero());           //averaged normal vector for vertex mode
        for(unsigned int i=0;i<triangles.length()/3;i++){
            MVector q = MVector(p[triangles[3*i+1]]-p[triangles[3*i]]) ^ MVector(p[triangles[3*i+2]]-p[triangles[3*i]]);
            normal[triangles[3*i]] += Vector3d(q[0], q[1], q[2]);
        }
        if (cageMode == 5){
            for(unsigned int i=0;i<triangles.length()/3;i++){
                m[i] << p[triangles[3*i]].x, p[triangles[3*i]].y, p[triangles[3*i]].z, 1,
                p[triangles[3*i+1]].x, p[triangles[3*i+1]].y, p[triangles[3*i+1]].z, 1,
                p[triangles[3*i+2]].x, p[triangles[3*i+2]].y, p[triangles[3*i+2]].z, 1,
                p[triangles[3*i]].x + normal[triangles[3*i]][0], p[triangles[3*i]].y + normal[triangles[3*i]][1], p[triangles[3*i]].z + normal[triangles[3*i]][2],1;
            }
        }else if (cageMode == 6){
            MVector u,v,q;
            for(unsigned int i=0;i<triangles.length()/3;i++){
                u=MVector(p[triangles[3*i+1]]-p[triangles[3*i]]);
                v=MVector(p[triangles[3*i+2]]-p[triangles[3*i]]);
                u.normalize();
                v.normalize();
                normal[triangles[3*i]].normalize();
                m[i] << p[triangles[3*i]].x, p[triangles[3*i]].y, p[triangles[3*i]].z, 1,
                u[0]+p[triangles[3*i]].x,u[1]+p[triangles[3*i]].y,u[2]+p[triangles[3*i]].z,1,
                v[0]+p[triangles[3*i]].x,v[1]+p[triangles[3*i]].y,v[2]+p[triangles[3*i]].z,1,
                normal[triangles[3*i]][0]+p[triangles[3*i]].x,normal[triangles[3*i]][1]+p[triangles[3*i]].y,normal[triangles[3*i]][2]+p[triangles[3*i]].z,1;
            }
        }
    }
}
Пример #19
0
bool CXRayObjectExport::smoothingAlgorithm( int polyId, MFnMesh& fnMesh )
{
    MIntArray vertexList;
    fnMesh.getPolygonVertices( polyId, vertexList );
    int vcount = vertexList.length();
    bool smoothEdgeFound = false;
    
    for ( int vid=0; vid<vcount;vid++ ) {
        int a = vertexList[vid];
        int b = vertexList[ vid==(vcount-1) ? 0 : vid+1 ];
        
        SXREdgeInfoPtr elem = findEdgeInfo( a, b );
        if ( NULL != elem ) {
            // NOTE: We assume there are at most 2 polygons per edge
            //       halfEdge polygons get a smoothing group of
            //       NO_SMOOTHING_GROUP which is equivalent to "s off"
            //
            if ( NO_SMOOTHING_GROUP != elem->polyIds[1] ) { // Edge not a border
                
                // We are starting a new smoothing group
                //                
                if ( newSmoothingGroup ) {
                    currSmoothingGroup = nextSmoothingGroup++;
                    newSmoothingGroup = false;
                    
                    // This is a SEED (starting) polygon and so we always
                    // give it the new smoothing group id.
                    // Even if all edges are hard this must be done so
                    // that we know we have visited the polygon.
                    //
                    polySmoothingGroups[polyId] = currSmoothingGroup;
                }
                
                // If we have a smooth edge then this poly must be a member
                // of the current smoothing group.
                //
                if ( elem->smooth ) {
                    polySmoothingGroups[polyId] = currSmoothingGroup;
                    smoothEdgeFound = true;
                }
                else { // Hard edge so ignore this polygon
                    continue;
                }
                
                // Find the adjacent poly id
                //
                int adjPoly = elem->polyIds[0];
                if ( adjPoly == polyId ) {
                    adjPoly = elem->polyIds[1];
                }                             
                
                // If we are this far then adjacent poly belongs in this
                // smoothing group.
                // If the adjacent polygon's smoothing group is not
                // NO_SMOOTHING_GROUP then it has already been visited
                // so we ignore it.
                //
                if ( NO_SMOOTHING_GROUP == polySmoothingGroups[adjPoly] ) {
                    smoothingAlgorithm( adjPoly, fnMesh );
                }
                else if ( polySmoothingGroups[adjPoly] != currSmoothingGroup ) {
					Msg("! smoothing group problem at polygon %d",adjPoly);
                }
            }
        }
    }
    return smoothEdgeFound;
}
MStatus CageDeformerNode::deform( MDataBlock& data, MItGeometry& itGeo, const MMatrix &localToWorldMatrix, unsigned int mIndex )
{
    /// main
    MStatus status;
    MThreadUtils::syncNumOpenMPThreads();    // for OpenMP
    // load cage mesh and other attributes
    MObject oCageMesh = data.inputValue( aCageMesh ).asMesh();
    short blendMode = data.inputValue(aBlendMode).asShort();
	bool rotationCosistency = data.inputValue( aRotationConsistency ).asBool();
	bool frechetSum = data.inputValue( aFrechetSum ).asBool();
    short newConstraintMode = data.inputValue(aConstraintMode).asShort();
    double newConstraintWeight = data.inputValue( aConstraintWeight ).asDouble();
    if ( oCageMesh.isNull() || blendMode == 99)
        return MS::kSuccess;
    short newCageMode = data.inputValue(aCageMode).asShort();
    MFnMesh fnCageMesh( oCageMesh, &status );
    CHECK_MSTATUS_AND_RETURN_IT( status );
    MPointArray cagePoints;
    fnCageMesh.getPoints( cagePoints,  MSpace::kWorld );
    // save initial cage state
    if (initCagePoints.length() != cagePoints.length()){
        initCageMesh = oCageMesh;
        initCagePoints=cagePoints;
    }
    // when cage mode is changed
    if(newCageMode != cageMode || newConstraintMode != constraintMode || newConstraintWeight != constraintWeight)
    {
        cageMode = newCageMode;
        constraintMode = newConstraintMode;
        constraintWeight = newConstraintWeight;
	    std::vector<double> tetWeight;
        // read target mesh data
        MArrayDataHandle hInput = data.outputArrayValue( input, &status );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        status = hInput.jumpToElement( mIndex );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        MObject oInputGeom = hInput.outputValue().child( inputGeom ).asMesh();
        MFnMesh inputMesh(oInputGeom);
        inputMesh.getPoints( pts );
		numPts=pts.length();
        for(int j=0; j<numPts; j++ )
            pts[j] *= localToWorldMatrix;
        MIntArray count;
        inputMesh.getTriangles( count, meshTriangles );
		numTet=meshTriangles.length()/3;
		std::vector<Matrix4d> P(numTet);
        tetCenter.resize(numTet);
        tetMatrixC(pts, meshTriangles, P, tetCenter);
        PI.resize(numTet);
		for(int i=0;i<numTet;i++)
			PI[i] = P[i].inverse();
        // prepare cage tetrahedra
        MFnMesh fnInitCageMesh( initCageMesh, &status );
        if(cageMode == 10 || cageMode == 11)  // face mode
        {
			if(cageMode == 10){       // triangulate faces by MAYA standard
                MIntArray count;
                fnInitCageMesh.getTriangles( count, triangles );
                tetWeight.resize(triangles.length()/3, 1.0f);
			}else if(cageMode ==11){  // trianglate faces with more than 3 edges in a symmetric way
				triangles.clear();
				MItMeshPolygon iter(initCageMesh);
				MIntArray tmp;
                MVector normal;
				tetWeight.reserve(4*iter.count());
                unsigned int l;
				for(unsigned int i=0; ! iter.isDone(); i++){
					iter.getVertices(tmp);
					l=tmp.length();
					if(l==3){
						tetWeight.push_back(1.0);
						triangles.append(tmp[0]);
						triangles.append(tmp[1]);
						triangles.append(tmp[2]);
					}else{
						for(unsigned int j=0;j<l;j++){
                            tetWeight.push_back((l-2.0)/l);
							triangles.append(tmp[j]);
							triangles.append(tmp[(j+1) % l]);
							triangles.append(tmp[(j+2) % l]);
						}
					}
					iter.next();
				}
            }
            // face mode compute init matrix
            numPrb=triangles.length()/3;
            initMatrix.resize(numPrb);
            tetMatrix(initCagePoints, triangles, cageMode, initMatrix);
            // compute weight
            w.resize(numTet);
            std::vector< std::vector<double> > idist(numTet);
            for(int j=0;j<numTet;j++){
                idist[j].resize(numPrb);
                w[j].resize(numPrb);
                double sidist = 0.0;
                for(int i=0;i<numPrb;i++){
                    idist[j][i] = tetWeight[i]/distPtTri(tetCenter[j],initMatrix[i]);
                    sidist += idist[j][i];
                }
                assert(sidist>0.0f);
                for(int i=0;i<numPrb;i++)
                    w[j][i] = idist[j][i] /sidist;
            }// face mode end
        }else if(cageMode == 0 || cageMode == 1){   // vertex mode
            triangles.clear();
            std::vector<int> tetCount(initCagePoints.length());
            MItMeshVertex iter(initCageMesh);
            for(int j=0; ! iter.isDone(); j++){
                MIntArray v;
                iter.getConnectedVertices(v);     // at each vertex, construct tetrahedra from connected edges
                int l=v.length();
                if(l==3){
                    if(isDegenerate(initCagePoints[j],initCagePoints[v[0]],initCagePoints[v[1]],initCagePoints[v[2]]) != 0){
                        tetCount[j]++;
                        triangles.append(j);
                        triangles.append(v[0]);
                        triangles.append(v[1]);
                        triangles.append(v[2]);
                    }
                }else{
                    for(int k=0;k<l;k++){
                        if(isDegenerate(initCagePoints[j],initCagePoints[v[k]],initCagePoints[v[(k+1) % l]],initCagePoints[v[(k+2) % l]]) != 0){
                            tetCount[j]++;
                            triangles.append(j);
                            triangles.append(v[k]);
                            triangles.append(v[(k+1) % l]);
                            triangles.append(v[(k+2) % l]);
                        }
                    }
                }
                iter.next();
            }
            numPrb=triangles.length()/4;
            initMatrix.resize(numPrb);
            tetMatrix(initCagePoints, triangles, cageMode, initMatrix);
            // vertex mode compute weight
            w.resize(numTet);
            std::vector< std::vector<double> > idist(numTet);
            tetWeight.resize(numPrb);
            for(int i=0;i<numPrb;i++)
                tetWeight[i]=1.0/(double)tetCount[triangles[4*i]];
            for(int j=0;j<numTet;j++){
                idist[j].resize(numPrb);
                w[j].resize(numPrb);
                double sidist = 0.0;
                for(int i=0;i<numPrb;i++){
                    Vector3d c(initCagePoints[triangles[4*i]].x,initCagePoints[triangles[4*i]].y,initCagePoints[triangles[4*i]].z);
                    idist[j][i] = tetWeight[i] / ((tetCenter[j]-c).squaredNorm());
                    sidist += idist[j][i];
                }
                assert(sidist>0.0f);
                for(int i=0;i<numPrb;i++)
                    w[j][i] = idist[j][i] /sidist;
            }
        }else if(cageMode == 5 || cageMode == 6 ){ // vertex averaged normal mode
            triangles.clear();
            std::vector<int> tetCount(initCagePoints.length());
            MItMeshVertex iter(initCageMesh);
            for(int j=0; ! iter.isDone(); j++){
                MIntArray v;
                iter.getConnectedVertices(v);
                int l=v.length();
                for(int k=0;k<l;k++){
                    tetCount[j]++;
                    triangles.append(j);
                    triangles.append(v[k]);
                    triangles.append(v[(k+1) % l]);
                }
                iter.next();
            }
            numPrb=triangles.length()/3;
            initMatrix.resize(numPrb);
            tetMatrix(initCagePoints, triangles, cageMode, initMatrix);
            // vertex mode compute weight
            w.resize(numTet);
            std::vector< std::vector<double> > idist(numTet);
            tetWeight.resize(numPrb);
            for(int i=0;i<numPrb;i++)
                tetWeight[i]=1.0/(double)tetCount[triangles[3*i]];
            for(int j=0;j<numTet;j++){
                idist[j].resize(numPrb);
                w[j].resize(numPrb);
                double sidist = 0.0;
                for(int i=0;i<numPrb;i++){
                    Vector3d c(initCagePoints[triangles[3*i]].x,initCagePoints[triangles[3*i]].y,initCagePoints[triangles[3*i]].z);
                    idist[j][i] = tetWeight[i] / ((tetCenter[j]-c).squaredNorm());
                    sidist += idist[j][i];
                }
                assert(sidist>0.0f);
                for(int i=0;i<numPrb;i++)
                    w[j][i] = idist[j][i] /sidist;
            }
        }// end of cage setup
        
        // find constraint points
        if(constraintMode == 1){
            numConstraint = numPrb;
        }else{
            numConstraint = 1;    // at least one constraint is necessary to determine global translation
        }
        constraintTet.resize(numConstraint);
        constraintVector.resize(numConstraint);
        // for each cage tetrahedra, constraint the point on the mesh with largest weight
        for(int i=0;i<numConstraint;i++){
            constraintTet[i] = 0;
            for(int j=1;j<numTet;j++){
                if(w[j][i] > w[constraintTet[i]][i]){
                    constraintTet[i] = j;
                }
            }
            constraintVector[i] << tetCenter[constraintTet[i]](0), tetCenter[constraintTet[i]](1), tetCenter[constraintTet[i]](2), 1.0;
        }
        // precompute arap solver
        arapHI(PI, meshTriangles);
    }
    // compute deformation
    if( ! rotationCosistency || numPrb != prevNs.size()){        // clear previous rotation
        prevThetas.clear();
        prevThetas.resize(numPrb, 0.0);
        prevNs.clear();
        prevNs.resize(numPrb, Vector3d::Zero());
    }
    //  find affine transformations for tetrahedra
    std::vector<Matrix4d> cageMatrix(numPrb), SE(numPrb), logSE(numPrb),logAff(numPrb),aff(numPrb);
    std::vector<Matrix3d> logR(numPrb),R(numPrb),logS(numPrb),logGL(numPrb);
    std::vector<Vector3d> L(numPrb);
    std::vector<Vector4d> quat(numPrb);
    tetMatrix(cagePoints, triangles, cageMode, cageMatrix);
    for(int i=0; i<numPrb; i++)
        aff[i]=initMatrix[i].inverse()*cageMatrix[i];
    // compute parametrisation
    if(blendMode == 0 || blendMode == 1 || blendMode == 5)  // polarexp or quaternion
    {
        for(unsigned int i=0;i<numPrb;i++){
            parametriseGL(aff[i].block(0,0,3,3), logS[i] ,R[i]);
            L[i] = transPart(aff[i]);
            if(blendMode == 0){  // Rotational log
                logR[i]=logSOc(R[i], prevThetas[i], prevNs[i]);
            }else if(blendMode == 1){ // Eucledian log
                SE[i]=affine(R[i], L[i]);
                logSE[i]=logSEc(SE[i], prevThetas[i], prevNs[i]);
            }else if(blendMode == 5){ // quaternion
                Quaternion<double> Q(R[i].transpose());
                quat[i] << Q.x(), Q.y(), Q.z(), Q.w();
            }
        }
    }else if(blendMode == 2){    //logmatrix3
        for(unsigned int i=0;i<numPrb;i++){
            logGL[i] = aff[i].block(0,0,3,3).log();
            L[i] = transPart(aff[i]);
        }
    }else if(blendMode == 3){   // logmatrix4
        for(unsigned int i=0;i<numPrb;i++){
            logAff[i] = aff[i].log();
        }
    }
    // compute blended matrices
#pragma omp parallel for
    std::vector<Matrix4d> At(numTet);
    for(int j=0; j<numTet; j++ ){
        if(blendMode==0){
            Matrix3d RR=Matrix3d::Zero();
            Matrix3d SS=Matrix3d::Zero();
            Vector3d l=Vector3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                RR += w[j][i] * logR[i];
                SS += w[j][i] * logS[i];
                l += w[j][i] * L[i];
            }
            SS = expSym(SS);
            if(frechetSum){
                RR = frechetSO(R, w[j]);
            }else{
                RR = expSO(RR);
            }
            At[j] = affine(SS*RR, l);
        }else if(blendMode==1){    // rigid transformation
            Matrix4d EE=Matrix4d::Zero();
            Matrix3d SS=Matrix3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                EE +=  w[j][i] * logSE[i];
                SS +=  w[j][i] * logS[i];
            }
            if(frechetSum){
                EE = frechetSE(SE, w[j]);
            }else{
                EE = expSE(EE);
            }
            At[j] = affine(expSym(SS),Vector3d::Zero())*EE;
        }else if(blendMode == 2){    //logmatrix3
            Matrix3d G=Matrix3d::Zero();
            Vector3d l=Vector3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                G +=  w[j][i] * logGL[i];
                l += w[j][i] * L[i];
            }
            At[j] = affine(G.exp(), l);
        }else if(blendMode == 3){   // logmatrix4
            Matrix4d A=Matrix4d::Zero();
            for(unsigned int i=0; i<numPrb; i++)
                A +=  w[j][i] * logAff[i];
            At[j] = A.exp();
        }else if(blendMode == 5){ // quaternion
            Vector4d q=Vector4d::Zero();
            Matrix3d SS=Matrix3d::Zero();
            Vector3d l=Vector3d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                q += w[j][i] * quat[i];
                SS += w[j][i] * logS[i];
                l += w[j][i] * L[i];
            }
            SS = expSym(SS);
            Quaternion<double> Q(q);
            Matrix3d RR = Q.matrix().transpose();
            At[j] = affine(SS*RR, l);
        }else if(blendMode==10){
            At[j] = Matrix4d::Zero();
            for(unsigned int i=0; i<numPrb; i++){
                At[j] += w[j][i] * aff[i];
            }
        }
    }
    
    // compute target vertices position
    MatrixXd G=MatrixXd::Zero(numTet+numPts,3);
    arapG(At, PI, meshTriangles, aff, G);
    MatrixXd Sol = solver.solve(G);
    for(unsigned int i=0;i<numPts;i++){
        pts[i].x=Sol(i,0);
        pts[i].y=Sol(i,1);
        pts[i].z=Sol(i,2);
        pts[i] *= localToWorldMatrix.inverse();
    }
    itGeo.setAllPositions(pts);
    return MS::kSuccess;
}
Пример #21
0
MayaMeshWriter::MayaMeshWriter(MDagPath & iDag,
    Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex,
    const JobArgs & iArgs, GetMembersMap& gmMap, util::InstanceRecorder& instanceRecorder)
  : mNoNormals(iArgs.noNormals),
    mWriteUVs(iArgs.writeUVs),
    mWriteColorSets(iArgs.writeColorSets),
    mIsGeometryAnimated(false),
    mDagPath(iDag)
{
    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    // intermediate objects aren't translated
    MObject surface = iDag.node();

    if (iTimeIndex != 0 && util::isAnimated(surface))
        mIsGeometryAnimated = true;

    std::vector<float> uvs;
    std::vector<Alembic::Util::uint32_t> indices;

    MString name = lMesh.name();
    name = util::stripNamespaces(name, iArgs.stripNamespace);

    // check to see if this poly has been tagged as a SubD
    MPlug plug = lMesh.findPlug("SubDivisionMesh");
    if ( !plug.isNull() && plug.asBool() )
    {
        Alembic::AbcGeom::OSubD obj(iParent, name.asChar(), iTimeIndex);

        instanceRecorder.recordMaster(iDag,obj);

        mSubDSchema = obj.getSchema();

        Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;
        if ( mWriteUVs )
        {
            getUVs(uvs, indices);

            if (!uvs.empty())
            {
                uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
                uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                    (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
                if (!indices.empty())
                {
                    uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                        &indices.front(), indices.size()));
                }
            }
        }

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(lMesh, iArgs))
        {
            cp = mSubDSchema.getArbGeomParams();
            up = mSubDSchema.getUserProperties();
        }
        mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh,
            iTimeIndex, iArgs));

        writeSubD(uvSamp);
    }
    else
    {
        Alembic::AbcGeom::OPolyMesh obj(iParent, name.asChar(), iTimeIndex);
        instanceRecorder.recordMaster(iDag,obj);

        mPolySchema = obj.getSchema();

        Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;

        if ( mWriteUVs )
        {
            getUVs(uvs, indices);

            if (!uvs.empty())
            {

                uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
                uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                    (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
                if (!indices.empty())
                {
                    uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                        &indices.front(), indices.size()));
                }
            }
        }

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(lMesh, iArgs))
        {
            cp = mPolySchema.getArbGeomParams();
            up = mPolySchema.getUserProperties();
        }

        // set the rest of the props and write to the writer node
        mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh,
            iTimeIndex, iArgs));

        writePoly(uvSamp);
    }

    if (mWriteColorSets)
    {
        MStringArray colorSetNames;
        lMesh.getColorSetNames(colorSetNames);

        if (colorSetNames.length() > 0)
        {

            // Create the color sets compound prop
            Alembic::Abc::OCompoundProperty arbParams;
            if (mPolySchema)
            {
                arbParams =  mPolySchema.getArbGeomParams();
            }
            else
            {
                arbParams =  mSubDSchema.getArbGeomParams();
            }

            std::string currentColorSet = lMesh.currentColorSetName().asChar();
            for (unsigned int i=0; i < colorSetNames.length(); ++i)
            {
                // Create an array property for each color set
                std::string colorSetPropName = colorSetNames[i].asChar();

                Alembic::AbcCoreAbstract::MetaData md;
                if (currentColorSet == colorSetPropName)
                {
                    md.set("mayaColorSet", "1");
                }
                else
                {
                    md.set("mayaColorSet", "0");
                }

                if (lMesh.getColorRepresentation(colorSetNames[i]) ==
                    MFnMesh::kRGB)
                {
                    Alembic::AbcGeom::OC3fGeomParam colorProp(arbParams,
                        colorSetPropName, true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md);
                    mRGBParams.push_back(colorProp);
                }
                else
                {
                    Alembic::AbcGeom::OC4fGeomParam colorProp(arbParams,
                        colorSetPropName, true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md);
                    mRGBAParams.push_back(colorProp);
                }
            }
            writeColor();
        }
    }

    // write out facesets
    if(!iArgs.writeFaceSets)
        return;

    // get the connected shading engines
    MObjectArray connSGObjs (getOutConnectedSG(mDagPath));
    const unsigned int sgCount = connSGObjs.length();

    for (unsigned int i = 0; i < sgCount; ++i)
    {
        MObject connSGObj, compObj;

        connSGObj = connSGObjs[i];

        MFnDependencyNode fnDepNode(connSGObj);
        MString connSgObjName = fnDepNode.name();

        // retrive the component MObject
        status = getSetComponents(mDagPath, connSGObj, gmMap, compObj);

        if (status != MS::kSuccess)
        {
            MFnDependencyNode fnDepNode(connSGObj);
            MString message;
            message.format("Could not retrive face indices from set ^1s.",  connSgObjName);
            MGlobal::displayError(message);
            continue;
        }

        // retrieve the face indices
        MIntArray indices;
        MFnSingleIndexedComponent compFn;
        compFn.setObject(compObj);
        compFn.getElements(indices);
        const unsigned int numData = indices.length();

        // encountered the whole object mapping. skip it.
        if (numData == 0)
            continue;

        std::vector<Alembic::Util::int32_t> faceIndices(numData);
        for (unsigned int j = 0; j < numData; ++j)
        {
            faceIndices[j] = indices[j];
        }

        connSgObjName = util::stripNamespaces(connSgObjName,
                                              iArgs.stripNamespace);

        Alembic::AbcGeom::OFaceSet faceSet;
        std::string faceSetName(connSgObjName.asChar());

        if (mPolySchema)
        {
            if (mPolySchema.hasFaceSet(faceSetName))
            {
                faceSet = mPolySchema.getFaceSet(faceSetName);
            }
            else
            {
                faceSet = mPolySchema.createFaceSet(faceSetName);
            }
        }
        else
        {
            if (mSubDSchema.hasFaceSet(faceSetName))
            {
                faceSet = mSubDSchema.getFaceSet(faceSetName);
            }
            else
            {
                faceSet = mSubDSchema.createFaceSet(faceSetName);
            }
        }
        Alembic::AbcGeom::OFaceSetSchema::Sample samp;
        samp.setFaces(Alembic::Abc::Int32ArraySample(faceIndices));

        Alembic::AbcGeom::OFaceSetSchema faceSetSchema = faceSet.getSchema();

        faceSetSchema.set(samp);
        faceSetSchema.setFaceExclusivity(Alembic::AbcGeom::kFaceSetExclusive);

        MFnDependencyNode iNode(connSGObj);

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(iNode, iArgs))
        {
            cp = faceSetSchema.getArbGeomParams();
            up = faceSetSchema.getUserProperties();
        }

        AttributesWriter attrWriter(cp, up, faceSet, iNode, iTimeIndex, iArgs);
        attrWriter.write();
    }
}
Пример #22
0
collision_shape_t::pointer boingRbCmd::createCollisionShape(const MObject& node)
{

    collision_shape_t::pointer collision_shape = 0;

    //MObject thisObject(thisMObject());
    //MPlug plgType(thisObject, ia_type);
    int type=0;
    //plgType.getValue(type);

    switch(type) {
    case 0:  
        {
            //convex hull
            {
                cout<<"going on creating a convex hull collision shape"<<endl;
                if(node.hasFn(MFn::kMesh)) {
                    MDagPath dagPath;
                    MDagPath::getAPathTo(node, dagPath);
                    MFnMesh fnMesh(dagPath);
                    cout<<"going on creating a convex hull from : "<<fnMesh.name()<<endl;
                    MFloatPointArray mpoints;
                    MFloatVectorArray mnormals;
                    MIntArray mtrianglecounts;
                    MIntArray mtrianglevertices;
                    fnMesh.getPoints(mpoints, MSpace::kObject);
                    fnMesh.getNormals(mnormals, MSpace::kObject);
                    fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                    std::vector<vec3f> vertices(mpoints.length());
                    std::vector<vec3f> normals(mpoints.length());
                    std::vector<unsigned int> indices(mtrianglevertices.length());

                    btAlignedObjectArray<btVector3> btVerts; //mb

                    for(size_t i = 0; i < vertices.size(); ++i) {
                        vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                        normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);

#if UPDATE_SHAPE //future collision margin adjust
                        btVerts.push_back(btVector3(mpoints[i].x, mpoints[i].y, mpoints[i].z)); //mb
#endif
                    }
                    for(size_t i = 0; i < indices.size(); ++i) {
                        indices[i] = mtrianglevertices[i];
                    }

#if UPDATE_SHAPE //future collision margin adjust
                    btAlignedObjectArray<btVector3> planeEquations;
                    btGeometryUtil::getPlaneEquationsFromVertices(btVerts, planeEquations);

                    btAlignedObjectArray<btVector3> shiftedPlaneEquations;
                    for (int p=0;p<planeEquations.size();p++)
                    {
                        btVector3 plane = planeEquations[p];
                        plane[3] += collisionShapeNode::collisionMarginOffset;
                        shiftedPlaneEquations.push_back(plane);
                    }

                    btAlignedObjectArray<btVector3> shiftedVertices;
                    btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations, shiftedVertices);

                    std::vector<vec3f> shiftedVerticesVec3f(shiftedVertices.size());
                    for(size_t i = 0; i < shiftedVertices.size(); ++i) 
                    {
                        shiftedVerticesVec3f[i] = vec3f(shiftedVertices[i].getX(), shiftedVertices[i].getY(), shiftedVertices[i].getZ());
                        //std::cout << "orig verts: " << vertices[i][0] << " " << vertices[i][1] << " " << vertices[i][2] << std::endl;
                        //std::cout << "shft verts: " << shiftedVertices[i].getX() << " " << shiftedVertices[i].getY() << " " << shiftedVertices[i].getZ() << std::endl;
                        //std::cout << std::endl;
                    }

                    collision_shape = solver_t::create_convex_hull_shape(&(shiftedVerticesVec3f[0]), shiftedVerticesVec3f.size(), &(normals[0]), &(indices[0]), indices.size());

#endif

#if UPDATE_SHAPE == 0
                    collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size()); //original
#endif
                }
            }
        }

        break;
    case 1:
        {
            //mesh
            {
                if(node.hasFn(MFn::kMesh)) {
                    MDagPath dagPath;
                    MDagPath::getAPathTo(node, dagPath);
                    MFnMesh fnMesh(dagPath);
                    MFloatPointArray mpoints;
                    MFloatVectorArray mnormals;
                    MIntArray mtrianglecounts;
                    MIntArray mtrianglevertices;
                    fnMesh.getPoints(mpoints, MSpace::kObject);
                    fnMesh.getNormals(mnormals, MSpace::kObject);
                    fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                    std::vector<vec3f> vertices(mpoints.length());
                    std::vector<vec3f> normals(mpoints.length());
                    std::vector<unsigned int> indices(mtrianglevertices.length());

                    for(size_t i = 0; i < vertices.size(); ++i) {
                        vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                        normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                    }
                    for(size_t i = 0; i < indices.size(); ++i) {
                        indices[i] = mtrianglevertices[i];
                    }
                    bool dynamicMesh = true;
                    collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                        &(indices[0]), indices.size(),dynamicMesh);
                }
            }
        }
        break;
    case 2:
        //cylinder
        break;
    case 3:
        //capsule
        break;

    case 7:
        //btBvhTriangleMeshShape
        {

                if(node.hasFn(MFn::kMesh)) {
                    MDagPath dagPath;
                    MDagPath::getAPathTo(node, dagPath);
                    MFnMesh fnMesh(dagPath);
                    MFloatPointArray mpoints;
                    MFloatVectorArray mnormals;
                    MIntArray mtrianglecounts;
                    MIntArray mtrianglevertices;
                    fnMesh.getPoints(mpoints, MSpace::kObject);
                    fnMesh.getNormals(mnormals, MSpace::kObject);
                    fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                    std::vector<vec3f> vertices(mpoints.length());
                    std::vector<vec3f> normals(mpoints.length());
                    std::vector<unsigned int> indices(mtrianglevertices.length());

                    for(size_t i = 0; i < vertices.size(); ++i) {
                        vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                        normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                    }
                    for(size_t i = 0; i < indices.size(); ++i) {
                        indices[i] = mtrianglevertices[i];
                    }
                    bool dynamicMesh = false;
                    collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                        &(indices[0]), indices.size(),dynamicMesh);
            }
        }
        break;
    case 8:
        //hacd convex decomposition
        {

            {
                if(node.hasFn(MFn::kMesh)) {
                    MDagPath dagPath;
                    MDagPath::getAPathTo(node, dagPath);
                    MFnMesh fnMesh(dagPath);
                    MFloatPointArray mpoints;
                    MFloatVectorArray mnormals;
                    MIntArray mtrianglecounts;
                    MIntArray mtrianglevertices;
                    fnMesh.getPoints(mpoints, MSpace::kObject);
                    fnMesh.getNormals(mnormals, MSpace::kObject);
                    fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

                    std::vector<vec3f> vertices(mpoints.length());
                    std::vector<vec3f> normals(mpoints.length());
                    std::vector<unsigned int> indices(mtrianglevertices.length());

                    for(size_t i = 0; i < vertices.size(); ++i) {
                        vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
                        normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
                    }
                    for(size_t i = 0; i < indices.size(); ++i) {
                        indices[i] = mtrianglevertices[i];
                    }
                    bool dynamicMesh = false;
                    collision_shape = solver_t::create_hacd_shape(&(vertices[0]), vertices.size(), &(normals[0]),
                        &(indices[0]), indices.size(),dynamicMesh);
                }
            }
        }
        break;
    default:
        {
        }
    }

    return collision_shape;
}
Пример #23
0
// the arrays being passed in are assumed to be empty
void MayaMeshWriter::fillTopology(
    std::vector<float> & oPoints,
    std::vector<Alembic::Util::int32_t> & oFacePoints,
    std::vector<Alembic::Util::int32_t> & oPointCounts)
{
    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    MFloatPointArray pts;

    lMesh.getPoints(pts);

    if (pts.length() < 3 && pts.length() > 0)
    {
        MString err = lMesh.fullPathName() +
            " is not a valid mesh, because it only has ";
        err += pts.length();
        err += " points.";
        MGlobal::displayError(err);
        return;
    }

    unsigned int numPolys = lMesh.numPolygons();

    if (numPolys == 0)
    {
        MGlobal::displayWarning(lMesh.fullPathName() + " has no polygons.");
        return;
    }

    unsigned int i;
    int j;

    oPoints.resize(pts.length() * 3);

    // repack the float
    for (i = 0; i < pts.length(); i++)
    {
        size_t local = i * 3;
        oPoints[local] = pts[i].x;
        oPoints[local+1] = pts[i].y;
        oPoints[local+2] = pts[i].z;
    }

    /*
        oPoints -
        oFacePoints - vertex list
        oPointCounts - number of points per polygon
    */

    MIntArray faceArray;

    for (i = 0; i < numPolys; i++)
    {
        lMesh.getPolygonVertices(i, faceArray);

        if (faceArray.length() < 3)
        {
            MGlobal::displayWarning("Skipping degenerate polygon");
            continue;
        }

        // write backwards cause polygons in Maya are in a different order
        // from Renderman (clockwise vs counter-clockwise?)
        int faceArrayLength = faceArray.length() - 1;
        for (j = faceArrayLength; j > -1; j--)
        {
            oFacePoints.push_back(faceArray[j]);
        }

        oPointCounts.push_back(faceArray.length());
    }
}
Пример #24
0
void vixo_hairStyleMaya::exportFollicle(int hairNumValue,MString uvFileName,MString hairRootInfo,MDataBlock& data)
{
	MObject meshObj=data.inputValue(inMesh).asMesh();
		
	MItMeshPolygon iterFace(meshObj);
	double area=0.0;
	int triTotNum=0;
	for(iterFace.reset();!iterFace.isDone();iterFace.next())
	{
		double areaTmp;
		iterFace.getArea(areaTmp);
		area+=areaTmp;
		int triTotNumTmp;
		iterFace.numTriangles(triTotNumTmp);
		triTotNum+=triTotNumTmp;

		if(iterFace.isDone())
			break;
	}
	MFnMesh fnMesh(meshObj);

	vector<vector<float>> uv(triTotNum);
	vector<int> triInfoIndex(triTotNum,0); //numFollicle
	vector<streampos> triInfoPosIndex(triTotNum);
	vector<int> vertexCtrl(triTotNum*3);
	vector<vector<float>> vertexWeight(triTotNum);
	
	double diff=sqrt(area/hairNumValue);

	int hairIter=0;
	int triIter=0;
	for(iterFace.reset();!iterFace.isDone();iterFace.next())
	{
		MIntArray faceVertexIndex;
		iterFace.getVertices(faceVertexIndex);

		MVectorArray faceNormals;
		iterFace.getNormals(faceNormals,MSpace::kWorld);

		MFloatVectorArray faceTangents;
		fnMesh.getFaceVertexTangents(iterFace.index(),faceTangents,MSpace::kWorld);

		map<int,int> vertexIndex2faceIndex;
		for(int i=0;i<faceVertexIndex.length();i++)
		{
			vertexIndex2faceIndex.insert(pair<int,int>(faceVertexIndex[i],i));
		}
		int triNum;
		iterFace.numTriangles(triNum);
		MString uvset("map1");
		for(int tri=0;tri<triNum;tri++)
		{
			MPointArray vertex;
			MIntArray vertexIndex;
			iterFace.getTriangle(tri,vertex,vertexIndex);
			int numLine1=MVector(vertex[1]-vertex[0]).length()/diff;
			int numLine2=MVector(vertex[2]-vertex[0]).length()/diff;

			MFloatArray uvs(6);
			float2 tempUV;
			iterFace.getUV(vertexIndex2faceIndex.find(vertexIndex[0])->second,tempUV,&uvset);
			uvs[0]=tempUV[0];
			uvs[1]=tempUV[1];
			iterFace.getUV(vertexIndex2faceIndex.find(vertexIndex[1])->second,tempUV,&uvset);
			uvs[2]=tempUV[0];
			uvs[3]=tempUV[1];
			iterFace.getUV(vertexIndex2faceIndex.find(vertexIndex[2])->second,tempUV,&uvset);
			uvs[4]=tempUV[0];
			uvs[5]=tempUV[1];

			vertexCtrl[3*triIter]=vertexIndex[1];
			vertexCtrl[3*triIter+1]=vertexIndex[2];
			vertexCtrl[3*triIter+2]=vertexIndex[0];

			

			for(int i=0;i<numLine1;i++)
			{
				for(int j=0;j<(1-(float)i/numLine1)*numLine2;j++)
				{
					vertexWeight[triIter].push_back((float)i/numLine1);
					vertexWeight[triIter].push_back((float)j/numLine2);
					vertexWeight[triIter].push_back(1-(float)i/numLine1-(float)j/numLine2);

					int localHairIter=triInfoIndex[triIter];

					uv[triIter].push_back(uvs[0]*vertexWeight[triIter][3*localHairIter+2]+uvs[2]*vertexWeight[triIter][3*localHairIter]+uvs[4]*vertexWeight[triIter][3*localHairIter+1]);
					uv[triIter].push_back(uvs[1]*vertexWeight[triIter][3*localHairIter+2]+uvs[3]*vertexWeight[triIter][3*localHairIter]+uvs[5]*vertexWeight[triIter][3*localHairIter+1]);
					
					hairIter++;
					triInfoIndex[triIter]++;
				}
			}

			triIter++;
		}
		if(iterFace.isDone())
			break;
	}

	//print uv
	fstream fout(uvFileName.asChar(),ios_base::out|ios_base::binary);
	fout.write((char*)&triTotNum,sizeof(int));
	fout.write((char*)&triInfoIndex[0],sizeof(int)*triTotNum);
	fout.write((char*)&vertexCtrl[0],sizeof(int)*3*triTotNum); //for cache export
	for(int i=0;i<triTotNum;i++) //for color info
	{
		fout.write((char*)&uv[i][0],sizeof(float)*2*triInfoIndex[i]);
	}
	fout.flush();
	fout.close();
	//~print uv

	/*
	//debug uv
	MString uvDebug=uvFileName+"debug";
	fout.open(uvDebug.asChar(),ios_base::out);
	fout<<triTotNum<<endl;
	for(int i=0;i<triTotNum;i++)
		fout<<"tri"<<i<<":"<<'\t'<<triInfoIndex[i]<<'\t'<<vertexCtrl[3*i]<<'\t'<<vertexCtrl[3*i+1]<<'\t'<<vertexCtrl[3*i+2]<<endl;
	for(int i=0;i<triTotNum;i++)
		for(int j=0;j<triInfoIndex[i];j++)
			fout<<"tri"<<i<<":"<<'\t'<<j<<'\t'<<uv[i][2*j]<<'\t'<<uv[i][2*j+1]<<endl;
	fout.flush();
	fout.close();
	//~debug uv
	*/
	//prepare streampos
	triInfoPosIndex[0]=sizeof(int)+sizeof(streampos)*triTotNum;
	for(int i=1;i<triTotNum;i++)
	{
		triInfoPosIndex[i]=triInfoPosIndex[i-1].operator+(sizeof(int)+sizeof(float)*3*triInfoIndex[i-1]);
	}
	//~prepare streampos
	
	//print infos
	fout.open(hairRootInfo.asChar(),ios_base::out|ios_base::binary);
	fout.write((char*)&triTotNum,sizeof(int));
	fout.write((char*)&triInfoPosIndex[0],sizeof(streampos)*triTotNum);
	for(int i=0;i<triTotNum;i++) //for color info
	{
		fout.write((char*)&triInfoIndex[i],sizeof(int));
		fout.write((char*)&vertexWeight[i][0],sizeof(float)*3*triInfoIndex[i]);
	}
	fout.flush();
	fout.close();
	//~print infos
	/*
	//debug info
	MString hairRootInfoDebug=hairRootInfo+"debug";
	fout.open(hairRootInfoDebug.asChar(),ios_base::out);
	fout<<triTotNum<<endl;
	for(int i=0;i<triTotNum;i++)
		fout<<"tri"<<i<<":"<<'\t'<<triInfoIndex[i]<<'\t'<<triInfoPosIndex[i]<<endl;
	for(int i=0;i<triTotNum;i++)
		for(int j=0;j<triInfoIndex[i];j++)
			fout<<"tri"<<i<<":"<<'\t'<<j<<'\t'<<vertexWeight[i][3*j]<<'\t'<<vertexWeight[i][3*j+1]<<'\t'<<vertexWeight[i][3*j+2]<<endl;
	fout.flush();
	fout.close();
	//~debug info
	*/
}
Пример #25
0
//! Create OSD HBR mesh.
//! Caller is expected to delete the resulting hbrMesh returned
HMesh *
createOsdHbrFromPoly( MFnMesh const & inMeshFn,
                      MItMeshPolygon & inMeshItPolygon,
                      std::vector<int> & fvarIndices,
                      std::vector<int> & fvarWidths)
{
    MStatus returnStatus;

    // == Mesh Properties

    // Gather FVarData
    MStringArray uvSetNames;
    MStringArray colorSetNames;
    std::vector<int> colorSetChannels;
    std::vector<MFnMesh::MColorRepresentation> colorSetReps;
    int totalColorSetChannels = 0;
    returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels);
    MWARNERR(returnStatus, "Failed to retrieve Maya face-varying parameters");

    // Create face-varying data with independent float channels of dimension 1
    // Note: This FVarData needs to be kept around for the duration of the HBR mesh
    int totalFvarWidth = 2*uvSetNames.length() + totalColorSetChannels;
    fvarIndices.resize(totalFvarWidth);
    fvarWidths.resize(totalFvarWidth);
    for (int i=0; i < totalFvarWidth; ++i) {
        fvarIndices[i] = i;
        fvarWidths[i] = 1;
    }

    // temp storage for UVs and ColorSets for a face
    MIntArray fvArray; // face vertex array
    std::vector<MFloatArray> uvSet_uCoords(uvSetNames.length());
    std::vector<MFloatArray> uvSet_vCoords(uvSetNames.length());
    std::vector<MColorArray> colorSet_colors(colorSetNames.length());

    // =====================================
    // Init HBR
    // =====================================

    // Determine HBR Subdiv Method
    static HCatmark _catmark;

    // Create HBR mesh
    assert(fvarIndices.size() == fvarWidths.size());
    HMesh * hbrMesh = new HMesh( &_catmark,
                                 (int)fvarIndices.size(),
                                 (fvarIndices.size() > 0) ? &fvarIndices[0] : NULL,
                                 (fvarWidths.size()  > 0) ? &fvarWidths[0] : NULL,
                                 totalFvarWidth );

    // Create Stub HBR Vertices
    int numVerts = inMeshFn.numVertices();
    OpenSubdiv::OsdVertex v;
    for(int i=0; i<numVerts; i++ ) {
        hbrMesh->NewVertex( i, v );
    }

    // ===================================================
    // Create HBR Topology
    // ===================================================

    assert(totalFvarWidth == hbrMesh->GetTotalFVarWidth());
    unsigned int ptxidx = 0;

    for( inMeshItPolygon.reset(); !inMeshItPolygon.isDone(); inMeshItPolygon.next() ) {

        // Verts for this face
        inMeshItPolygon.getVertices(fvArray);
        unsigned int nv = fvArray.length();

        bool valid = true;

        for(unsigned int j=0;j<fvArray.length(); j++) {

            HVertex const * origin      = hbrMesh->GetVertex( fvArray[j] ),
                          * destination = hbrMesh->GetVertex( fvArray[(j+1)%nv] );
            HHalfedge const * opposite = destination->GetEdge(origin);

            if(origin==NULL || destination==NULL) {
                fprintf(stderr, "Skipping face: An edge was specified that connected a nonexistent vertex\n");
                valid = false;
                break;
            }

            if(origin == destination) {
                fprintf(stderr, "Skipping face: An edge was specified that connected a vertex to itself\n");
                valid = false;
                break;
            }

            if(opposite && opposite->GetOpposite() ) {
                fprintf(stderr, "Skipping face: A non-manifold edge incident to more than 2 faces was found\n");
                valid = false;
                break;
            }

            if(origin->GetEdge(destination)) {
                fprintf(stderr, "Skipping face: An edge connecting two vertices was specified more than once."
                       " It's likely that an incident face was flipped\n");
                valid = false;
                break;
            }
        }

        // Update faces
        const int * fvArrayPtr = &(fvArray[0]); // get the raw int* array from std::vector<int>
        OpenSubdiv::HbrFace<OpenSubdiv::OsdVertex> * face = hbrMesh->NewFace(nv, fvArrayPtr, 0);

        // Increment ptex index
        face->SetPtexIndex(ptxidx);

        // Add FaceVaryingData (UVSets, ...)
        if (totalFvarWidth > 0) {

            // Retrieve all UV and ColorSet data
            MIntArray faceCounts;
            for (unsigned int i=0; i < uvSetNames.length(); ++i) {
                returnStatus = inMeshItPolygon.getUVs(uvSet_uCoords[i], uvSet_vCoords[i], &uvSetNames[i] );
                MWARNERR(returnStatus, "Cannot get UVs");
            }
            for (unsigned int i=0; i < colorSetNames.length(); ++i) {
                returnStatus = inMeshItPolygon.getColors (colorSet_colors[i], &colorSetNames[i]);
                MWARNERR(returnStatus, "Cannot get face vertex colors");
            }

            std::vector<float> fvarItem(totalFvarWidth); // storage for all the face-varying channels for this face-vertex

            // loop over each uvSet and the uvs within
            for (unsigned int fvid=0; fvid < fvArray.length(); ++fvid) {

                int fvarItemIndex = 0;
                // Handle uvSets
                for( unsigned int uvSetIt=0; uvSetIt < uvSetNames.length(); ++uvSetIt ) {
                    fvarItem[fvarItemIndex]   = uvSet_uCoords[uvSetIt][fvid];
                    fvarItem[fvarItemIndex+1] = uvSet_vCoords[uvSetIt][fvid];
                    fvarItemIndex +=2;
                }
                // Handle colorSets
                for( unsigned int colorSetIt=0; colorSetIt < colorSetNames.length(); ++colorSetIt ) {
                    if (colorSetChannels[colorSetIt] == 1) {
                        fvarItem[fvarItemIndex]   = colorSet_colors[colorSetIt][fvid].a;
                    }
                    else if (colorSetChannels[colorSetIt] == 3) {
                        fvarItem[fvarItemIndex]   = colorSet_colors[colorSetIt][fvid].r;
                        fvarItem[fvarItemIndex+1] = colorSet_colors[colorSetIt][fvid].g;
                        fvarItem[fvarItemIndex+2] = colorSet_colors[colorSetIt][fvid].b;
                    }
                    else { // colorSetChannels[colorSetIt] == 4
                        fvarItem[fvarItemIndex]   = colorSet_colors[colorSetIt][fvid].r;
                        fvarItem[fvarItemIndex+1] = colorSet_colors[colorSetIt][fvid].g;
                        fvarItem[fvarItemIndex+2] = colorSet_colors[colorSetIt][fvid].b;
                        fvarItem[fvarItemIndex+3] = colorSet_colors[colorSetIt][fvid].a;
                    }
                    fvarItemIndex += colorSetChannels[colorSetIt];
                }
                assert((fvarItemIndex) == totalFvarWidth); // For UVs, sanity check the resulting value

                // Insert into the HBR structure for that face
                HVertex * hbrVertex = hbrMesh->GetVertex( fvArray[fvid] );
                HFvarData & fvarData = hbrVertex->GetFVarData(face);

                if (not fvarData.IsInitialized()) {
                    fvarData.SetAllData(totalFvarWidth, &fvarItem[0]);
                } else if (not fvarData.CompareAll(totalFvarWidth, &fvarItem[0])) {

                    // If data exists for this face vertex, but is different
                    // (e.g. we're on a UV seam) create another fvar datum
                    OpenSubdiv::HbrFVarData<OpenSubdiv::OsdVertex> &fvarData_new = hbrVertex->NewFVarData(face);
                    fvarData_new.SetAllData( totalFvarWidth, &fvarItem[0] );
                }
            }
        }

        // Increment ptxidx and store off ptex index values
        //   The number of ptexIds needed is 1 if a quad.  Otherwise it is the number of
        //   vertices for the face.
        int numPtexIdsForFace;
        if (valid) {
            numPtexIdsForFace = ( nv != 4 ) ? nv : 1 ;
        }
        else {
            numPtexIdsForFace = 0;
        }
        ptxidx += numPtexIdsForFace;
    }

    // Apply Creases
    applyCreaseEdges( inMeshFn, hbrMesh );
    applyCreaseVertices( inMeshFn, hbrMesh );

    // Return the resulting HBR Mesh
    // Note that boundaryMethods and hbrMesh->Finish() still need to be called
    return hbrMesh;
}
Пример #26
0
MStatus getObject::readMesh(yafaray::yafrayInterface_t &yI,std::map<string , yafaray::material_t *> &materialMap)
{
	MStatus stat=MStatus::kSuccess;

	//select all the mesh in the scene
	MString readMeshCmd("ls -type mesh");
	MStringArray readMeshResult;
	MGlobal::executeCommand(readMeshCmd, readMeshResult);

	for(unsigned int i=0; i<readMeshResult.length(); i++)
	{
			MSelectionList meshList;
			MGlobal::getSelectionListByName(readMeshResult[i],meshList);

			for(unsigned int index=0; index<meshList.length(); index++)
			{
				MDagPath meshPath;
				meshList.getDagPath(index, meshPath);

				//this is for getting the number of faces of the mesh
				MFnMesh meshFn(meshPath);
				cout<<"==============mesh test=============="<<endl;
				cout<<"mesh name:"<<meshFn.name()<<endl;
				
				//find the material of the mesh
				MObjectArray sgArray;
				MIntArray indexSG;
				meshFn.getConnectedShaders(0, sgArray, indexSG);
				MFnDependencyNode sgFn(sgArray[0]);
				MPlug surfacePlug=sgFn.findPlug("surfaceShader");
				MPlugArray sourceArray;
				MString shaderName;
				if (surfacePlug.connectedTo(sourceArray, true, false))
				{
					MPlug sourcePlug=sourceArray[0];
					MObject sourceNode=sourcePlug.node();
					MFnDependencyNode sourceFn(sourceNode);
					shaderName=sourceFn.name();
				}
				string sName(shaderName.asChar());
				cout<<"material name:"<<sName<<endl;

				std::map<string , yafaray::material_t *>::iterator iter=materialMap.find(sName);
				if(iter==materialMap.end())
				{
					//if searched in the map and didn't find the shader name of this object(means this object didn't use yafaray's material)
					//we should give it an default shader
					//to implement this, should export a default shader first, in the read shader step
					//iter=materialMap.find("yafDefaultMaterial");

					//using method above got some problem...when two shape use one trasform node
					//found this problem when using ncloth
					//so still jump the ones who didn't use yafaray's material
					cout<<"this mesh doesn't use yafaray's material"<<endl;
					MGlobal::displayInfo("(yafaray mesh) this mesh doesn't use yafaray's material!");
					break;
				}

				unsigned int yafID=yI.getNextFreeID();

				//itorate all the vertices and print them out
				MItMeshVertex meshVertex(meshPath);

				yI.paramsClearAll();
				yI.startGeometry();

				//since MFnMesh does not provide the number of triangles directly, so have to get it in another way
				MItMeshPolygon forCountTriangle(meshPath);
				int numTriangle=0;
				int count;
				for(;!forCountTriangle.isDone();forCountTriangle.next())
				{
					forCountTriangle.numTriangles(count);
					numTriangle=numTriangle+count;
				}

				yI.startTriMesh(yafID, meshFn.numVertices(), numTriangle, false, false, 0);
				for(; !meshVertex.isDone();meshVertex.next())
				{
					MPoint locationV=meshVertex.position(MSpace::kWorld);
					yI.addVertex(locationV.x,locationV.y,locationV.z);
					
				}

				//find every triangle face by face
				MItMeshPolygon meshFace(meshPath);
				for(;!meshFace.isDone();meshFace.next())
				{
					MPointArray points;
					MIntArray pointIndices;
					float UV0[2];
					float UV1[2];
					float UV2[2];
					meshFace.getTriangles(points,pointIndices,MSpace::kWorld);
					//get the indices for each vertex of the triangle. the index will be correspond to the point array before
					for(unsigned int i=0;i<pointIndices.length();i++)
					{
						meshFace.getUVAtPoint(points[i],UV0,MSpace::kObject);
						meshFace.getUVAtPoint(points[i+1],UV1,MSpace::kObject);
						meshFace.getUVAtPoint(points[i+2],UV2,MSpace::kObject);

						////test output
						//cout<<"================="<<i<<"================"<<endl;
						//cout<<UV0[0]<<UV0[1]<<endl;
						//cout<<UV1[0]<<UV1[1]<<endl;
						//cout<<UV2[0]<<UV2[1]<<endl;
						int uvIndex0=yI.addUV(UV0[0],UV0[1]);
						int uvIndex1=yI.addUV(UV1[0],UV1[1]);
						int uvIndex2=yI.addUV(UV2[0],UV2[1]);
						yI.addTriangle(pointIndices[i],pointIndices[i+1],pointIndices[i+2],uvIndex0,uvIndex1,uvIndex2,iter->second);
						//yI.addTriangle(pointIndices[i],pointIndices[i+1],pointIndices[i+2],iter->second);
						i=i+2;
					}

				}
				yI.endTriMesh();
				yI.smoothMesh(0, 181);
				yI.endGeometry();

			}

	}
	return stat;
}
Пример #27
0
MObject LSystemNode::createMesh(const double & angle, const double & step, const MString & grammar,
			const MTime& time, MObject& outData, MStatus& stat)
{

        //int	numVertices, frame;
        //float	cubeSize;
        //MFloatPointArray points;
		MPointArray points;
		MIntArray faceCounts;
		MIntArray faceConnects;

        MFnMesh	meshFS;

		LSystem lsys;
		lsys.setDefaultAngle(angle);		//angle
		lsys.setDefaultStep(step);		//step size
		string gram = grammar.asChar();			//grammar
		lsys.loadProgramFromString(gram);

		std::vector<LSystem::Branch> branches;
		lsys.process((int)time.value(),branches);
		CylinderMesh*cm;
		for(int j = 0;j<branches.size();j++)
		{
			vec3 Bstart = branches[j].first;
			vec3 Bend = branches[j].second;
			MPoint b_start(Bstart[0],Bstart[1],Bstart[2]);
			MPoint b_end(Bend[0],Bend[1],Bend[2]);
			cm = new CylinderMesh(b_start,b_end);
			cm->appendToMesh(points,faceCounts,faceConnects);
		}

		/*
        // Scale the cube on the frame number, wrap every 10 frames.
        frame = (int)time.as( MTime::kFilm );
        if (frame == 0)
          frame = 1;
        cubeSize                                = 0.5f * (float)( frame % 10);

        const int numFaces                      = 6;
        numVertices                                     = 8;
        const int numFaceConnects       = 24;*/
		
		/*
        MFloatPoint vtx_1( -cubeSize, -cubeSize, -cubeSize );
        MFloatPoint vtx_2(  cubeSize, -cubeSize, -cubeSize );
        MFloatPoint vtx_3(  cubeSize, -cubeSize,  cubeSize );
        MFloatPoint vtx_4( -cubeSize, -cubeSize,  cubeSize );
        MFloatPoint vtx_5( -cubeSize,  cubeSize, -cubeSize );
        MFloatPoint vtx_6( -cubeSize,  cubeSize,  cubeSize );
        MFloatPoint vtx_7(  cubeSize,  cubeSize,  cubeSize );
        MFloatPoint vtx_8(  cubeSize,  cubeSize, -cubeSize );
        points.append( vtx_1 );
        points.append( vtx_2 );
        points.append( vtx_3 );
        points.append( vtx_4 );
        points.append( vtx_5 );
        points.append( vtx_6 );
        points.append( vtx_7 );
        points.append( vtx_8 );

        // Set up an array containing the number of vertices
        // for each of the 6 cube faces (4 verticies per face)
        //
        int face_counts[numFaces] = { 4, 4, 4, 4, 4, 4 };
        MIntArray faceCounts( face_counts, numFaces );

        // Set up and array to assign vertices from points to each face 
        //
        int face_connects[ numFaceConnects ] = 
		{	0, 1, 2, 3,
			4, 5, 6, 7,
			3, 2, 6, 5,
			0, 3, 5, 4,
			0, 4, 7, 1,
			1, 7, 6, 2  
		};
        MIntArray faceConnects( face_connects, numFaceConnects );
		
        MObject newMesh = meshFS.create(numVertices, numFaces, points, faceCounts, faceConnects, outData, &stat);

        return newMesh;*/
		MObject newMesh = meshFS.create(points.length()
										,faceCounts.length(),points,faceCounts
										,faceConnects,outData,&stat);
		return newMesh;
}
Пример #28
0
void
OsdPtexMeshData::rebuildHbrMeshIfNeeded(OpenSubdivPtexShader *shader)
{
    MStatus status;

    if (!_meshTopoDirty && !shader->getHbrMeshDirty())
        return;

    MFnMesh meshFn(_meshDagPath, &status);
    if (status != MS::kSuccess) return;

    int level = shader->getLevel();
    if (level < 1) level =1;

    SchemeType scheme = shader->getScheme();
    if (scheme == kLoop) scheme = kCatmark;  // XXX: avoid loop for now

    // Get Maya vertex topology and crease data
    MIntArray vertexCount;
    MIntArray vertexList;
    meshFn.getVertices(vertexCount, vertexList);

    MUintArray edgeIds;
    MDoubleArray edgeCreaseData;
    meshFn.getCreaseEdges(edgeIds, edgeCreaseData);

    MUintArray vtxIds;
    MDoubleArray vtxCreaseData;
    meshFn.getCreaseVertices(vtxIds, vtxCreaseData);

    if (vertexCount.length() == 0) return;

    // Cache attribute values
    _level              = shader->getLevel();
    _scheme             = shader->getScheme();
    _kernel             = shader->getKernel();
    _adaptive           = shader->isAdaptive();
    _interpBoundary     = shader->getInterpolateBoundary();

    // Copy Maya vectors into std::vectors
    std::vector<int> numIndices(&vertexCount[0], &vertexCount[vertexCount.length()]);
    std::vector<int> faceIndices(&vertexList[0], &vertexList[vertexList.length()]);
    std::vector<int> vtxCreaseIndices(&vtxIds[0], &vtxIds[vtxIds.length()]);
    std::vector<double> vtxCreases(&vtxCreaseData[0], &vtxCreaseData[vtxCreaseData.length()]);
    std::vector<double> edgeCreases(&edgeCreaseData[0], &edgeCreaseData[edgeCreaseData.length()]);

    // Edge crease index is stored as pairs of vertex ids
    int nEdgeIds = edgeIds.length();
    std::vector<int> edgeCreaseIndices;
    edgeCreaseIndices.resize(nEdgeIds*2);
    for (int i = 0; i < nEdgeIds; ++i) {
        int2 vertices;
        status = meshFn.getEdgeVertices(edgeIds[i], vertices);
        if (status.error()) {
            status.perror("ERROR can't get creased edge vertices");
            continue;
        }
        edgeCreaseIndices[i*2] = vertices[0];
        edgeCreaseIndices[i*2+1] = vertices[1];
    }

    // Convert attribute enums to HBR enums (this is why the enums need to match)
    // XXX use some sort of built-in transmorgification avoid assumption?
    HbrMeshUtil::SchemeType hbrScheme = (HbrMeshUtil::SchemeType) _scheme;
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) _interpBoundary;

    // Convert Maya mesh to internal HBR representation
    _hbrmesh = ConvertToHBR(meshFn.numVertices(), numIndices, faceIndices,
                            vtxCreaseIndices, vtxCreases,
                            std::vector<int>(), std::vector<float>(),
                            edgeCreaseIndices, edgeCreases,
                            hbrInterpBoundary, 
                            hbrScheme,
                            true );                     // add ptex indices to HBR

    // note: GL function can't be used in prepareForDraw API.
    _needsInitializeMesh = true;

    // Mesh topology data is up to date
    _meshTopoDirty = false;
    shader->setHbrMeshDirty(false);
}
Пример #29
0
bool ProceduralHolderUI::select( MSelectInfo &selectInfo, MSelectionList &selectionList, MPointArray &worldSpaceSelectPts ) const
{
	MStatus s;

	// early out if we're not selectable. we always allow components to be selected if we're highlighted,
	// but we don't allow ourselves to be selected as a whole unless meshes are in the selection mask.
	// it's not ideal that we act like a mesh, but it's at least consistent with the drawing mask we use.
	if( selectInfo.displayStatus() != M3dView::kHilite )
	{
		MSelectionMask meshMask( MSelectionMask::kSelectMeshes );
		if( !selectInfo.selectable( meshMask ) )
		{
			return false;
		}
	}

	// early out if we have no scene to draw
	ProceduralHolder *proceduralHolder = static_cast<ProceduralHolder *>( surfaceShape() );
	IECoreGL::ConstScenePtr scene = proceduralHolder->scene();
	if( !scene )
	{
		return false;
	}
	
	// we want to perform the selection using an IECoreGL::Selector, so we
	// can avoid the performance penalty associated with using GL_SELECT mode.
	// that means we don't really want to call view.beginSelect(), but we have to
	// call it just to get the projection matrix for our own selection, because as far
	// as i can tell, there is no other way of getting it reliably.
	
	M3dView view = selectInfo.view();
	view.beginSelect();
	Imath::M44d projectionMatrix;
	glGetDoublev( GL_PROJECTION_MATRIX, projectionMatrix.getValue() );
	view.endSelect();
	
	view.beginGL();
	
		glMatrixMode( GL_PROJECTION );
		glLoadMatrixd( projectionMatrix.getValue() );
		
		IECoreGL::Selector::Mode selectionMode = IECoreGL::Selector::IDRender;
		if( selectInfo.displayStatus() == M3dView::kHilite && !selectInfo.singleSelection() )
		{
			selectionMode = IECoreGL::Selector::OcclusionQuery;
		}
		
		IECoreGL::Selector selector;
		selector.begin( Imath::Box2f( Imath::V2f( 0 ), Imath::V2f( 1 ) ), selectionMode );
				
			IECoreGL::State::bindBaseState();
			selector.baseState()->bind();
			scene->render( selector.baseState() );
		
			if( selectInfo.displayStatus() != M3dView::kHilite )
			{
				// we're not in component selection mode. we'd like to be able to select the procedural
				// object using the bounding box so we draw it too.
				MPlug pDrawBound( proceduralHolder->thisMObject(), ProceduralHolder::aDrawBound );
				bool drawBound = true;
				pDrawBound.getValue( drawBound );
				if( drawBound )
				{
					IECoreGL::BoxPrimitive::renderWireframe( IECore::convert<Imath::Box3f>( proceduralHolder->boundingBox() ) );
				}
			}
			
		std::vector<IECoreGL::HitRecord> hits;
		selector.end( hits );
				
	view.endGL();
	
	if( !hits.size() )
	{
		return false;
	}

	// iterate over the hits, converting them into components and also finding
	// the closest one.
	MIntArray componentIndices;
	float depthMin = std::numeric_limits<float>::max();
	int depthMinIndex = -1;
	for( int i=0, e = hits.size(); i < e; i++ )
	{		
		if( hits[i].depthMin < depthMin )
		{
			depthMin = hits[i].depthMin;
			depthMinIndex = componentIndices.length();
		}
		
		ProceduralHolder::ComponentsMap::const_iterator compIt = proceduralHolder->m_componentsMap.find( hits[i].name.value() );
		assert( compIt != proceduralHolder->m_componentsMap.end() );
		componentIndices.append( compIt->second.first );		
	}
	
	assert( depthMinIndex >= 0 );

	// figure out the world space location of the closest hit
	
	MDagPath camera;
	view.getCamera( camera );
	MFnCamera fnCamera( camera.node() );
	float near = fnCamera.nearClippingPlane();
	float far = fnCamera.farClippingPlane();
	
	float z = -1;
	if( fnCamera.isOrtho() )
	{
		z = Imath::lerp( near, far, depthMin );
	}
	else
	{
		// perspective camera - depth isn't linear so linearise to get z
		float a = far / ( far - near );
		float b = far * near / ( near - far );
		z = b / ( depthMin - a );
	}	
	
	MPoint localRayOrigin;
	MVector localRayDirection;
	selectInfo.getLocalRay( localRayOrigin, localRayDirection );
	MMatrix localToCamera = selectInfo.selectPath().inclusiveMatrix() * camera.inclusiveMatrix().inverse();	
	MPoint cameraRayOrigin = localRayOrigin * localToCamera;
	MVector cameraRayDirection = localRayDirection * localToCamera;
	
	MPoint cameraIntersectionPoint = cameraRayOrigin + cameraRayDirection * ( -( z - near ) / cameraRayDirection.z );
	MPoint worldIntersectionPoint = cameraIntersectionPoint * camera.inclusiveMatrix();
	
	// turn the processed hits into appropriate changes to the current selection
				
	if( selectInfo.displayStatus() == M3dView::kHilite )
	{
		// selecting components
		MFnSingleIndexedComponent fnComponent;
		MObject component = fnComponent.create( MFn::kMeshPolygonComponent, &s ); assert( s );
	
		if( selectInfo.singleSelection() )
		{
			fnComponent.addElement( componentIndices[depthMinIndex] );
		}
		else
		{
			fnComponent.addElements( componentIndices );
		}
		
		MSelectionList items;
		items.add( selectInfo.multiPath(), component );
		
		selectInfo.addSelection(
			items, worldIntersectionPoint,
			selectionList, worldSpaceSelectPts,
			MSelectionMask::kSelectMeshFaces,
			true
		);		
	}
	else
	{
		// selecting objects
		MSelectionList item;
		item.add( selectInfo.selectPath() );

		selectInfo.addSelection(
			item, worldIntersectionPoint,
			selectionList, worldSpaceSelectPts,
			MSelectionMask::kSelectMeshes,
			false
		);
	}
	
	return true;
}
Пример #30
0
void RemapToOGLFmt(
	MFnMesh &mfnMesh,
	k3d::MeshData & outputMesh,
	MIntArray & triangleList, 
	MIntArray & triangleNList, 
	MIntArray & triangleUVList,
	MString & uvSetName) {
	assert(triangleList.length() == triangleNList.length());
	assert(triangleNList.length() == triangleUVList.length());

	typedef std::tuple<int, int, int> P_N_T;
	typedef std::map<P_N_T, int> PNTMap;
	typedef PNTMap::const_iterator PNTIter;

	PNTMap  h;
	MFloatPointArray vertex; mfnMesh.getPoints(vertex);
	MFloatVectorArray normal; mfnMesh.getNormals(normal);
	MFloatArray uArray, vArray; mfnMesh.getUVs(uArray, vArray, &uvSetName);

	bool hasUV = (uArray.length() > 0);
	bool hasNormal = (normal.length() > 0);
	
	VtxFormat defaultVtxFmt = VtxFormat::POS3_F32;
	if (hasNormal && hasUV) {
		defaultVtxFmt = VtxFormat::POS3_F32_NOR3_F32_UV2_F32;
	}
	else if (hasNormal && !hasUV) {
		defaultVtxFmt = VtxFormat::POS3_F32_NOR3_F32;
	}
	else if (hasUV && !hasNormal) {
		defaultVtxFmt = VtxFormat::POS3_F32_UV2_F32;
	}
	outputMesh.SetVertexFormat(defaultVtxFmt);

	std::vector<uint32> indexBuffer;

	std::vector<k3d::Vertex3F3F2F> vertex332List;
	std::vector<k3d::Vertex3F3F>   vertex33List;
	std::vector<k3d::Vertex3F>	   vertex3List;

	for (size_t i = 0, idx = 0; i < triangleList.length(); i++)
	{
		P_N_T p(triangleList[i], triangleNList[i], triangleUVList[i]);
		PNTIter match = h.find(p);
		// found
		if (match != h.end())
		{
			indexBuffer.push_back(match->second);
		}
		else //Not Found
		{
			h[p] = idx;
			indexBuffer.push_back(idx++);
			int vid = std::get<0>(p); 
			int nid = std::get<1>(p); 
			int tid = std::get<2>(p);
			if (defaultVtxFmt == VtxFormat::POS3_F32_NOR3_F32_UV2_F32) {
				vertex332List.push_back({
					vertex[vid].x, vertex[vid].y, vertex[vid].z,
					normal[nid].x, normal[nid].y, normal[nid].z,
					uArray[tid], vArray[tid]
				});
			}
			else if (defaultVtxFmt == VtxFormat::POS3_F32_NOR3_F32) {
				vertex33List.push_back({
					vertex[vid].x, vertex[vid].y, vertex[vid].z,
					normal[nid].x, normal[nid].y, normal[nid].z
				});
			}
			else if (defaultVtxFmt == VtxFormat::POS3_F32) {
				vertex3List.push_back({
					vertex[vid].x, vertex[vid].y, vertex[vid].z,
				});
			}
		}
	}

	outputMesh.SetIndexBuffer(indexBuffer);
	if (defaultVtxFmt == VtxFormat::POS3_F32_NOR3_F32_UV2_F32) {
		outputMesh.SetVertexNum(vertex332List.size());
		outputMesh.SetVertexBuffer(&vertex332List[0]);
	}
	else if (defaultVtxFmt == VtxFormat::POS3_F32_NOR3_F32) {
		outputMesh.SetVertexNum(vertex33List.size());
		outputMesh.SetVertexBuffer(&vertex33List[0]);
	}
	else if (defaultVtxFmt == VtxFormat::POS3_F32) {
		outputMesh.SetVertexNum(vertex3List.size());
		outputMesh.SetVertexBuffer(&vertex3List[0]);
	}

}