Beispiel #1
0
MStatus PtexUVNode::compute( const MPlug &plug, MDataBlock &data )
{
	MStatus stat;
	bool hasNoEffect = false;
	
	MDataHandle inMeshHnd = data.inputValue( inMesh );
	MDataHandle outMeshHnd = data.outputValue( outMesh );
	 
	MDataHandle stateHnd = data.inputValue( state );
	int state = stateHnd.asInt();

	if( state == 1 ) // No Effect/Pass through
		hasNoEffect = true;
		
	if( !hasNoEffect && plug == outMesh )
	{
	    MObject inMeshData = inMeshHnd.asMesh();
				
		if( !hasNoEffect )
		{
			MFnMeshData meshDataFn;
			MObject newMeshData = meshDataFn.create();
			MFnMesh inMeshFn( inMeshData );
			inMeshFn.copy( inMeshData, newMeshData );
			
			MFnMesh meshFn( newMeshData );
			MPointArray pts;
			meshFn.getPoints( pts );

			MStringArray uvSetNames;
			meshFn.getUVSetNames( uvSetNames );
			unsigned int defaultUvSetCount = (unsigned int)uvSetNames.length();

			int num_faces = meshFn.numPolygons();

			MIntArray uvCounts;
			uvCounts.setLength( num_faces );

			for ( int i_f = 0; i_f < num_faces; i_f++ )
			{
				int deg = meshFn.polygonVertexCount( i_f );
				uvCounts[ i_f ] = deg;

				if ( deg != 4 )
				{
					return MS::kFailure;
				}
			}

			MIntArray uvIds;
			uvIds.setLength( 4 * num_faces );

			if ( defaultUvSetCount == 1 )
			{
				int currentUVCount = meshFn.numUVs( uvSetNames[0] );

				MFloatArray us, vs; 
				us.setLength( 4 * num_faces ); 
				vs.setLength( 4 * num_faces );

				for ( int i_f = 0; i_f < num_faces; i_f++ )
				{
					float f = (float)i_f;

					uvIds[ 4 * i_f + 0 ] = 4 * i_f + 0;
					uvIds[ 4 * i_f + 1 ] = 4 * i_f + 1;
					uvIds[ 4 * i_f + 2 ] = 4 * i_f + 2;
					uvIds[ 4 * i_f + 3 ] = 4 * i_f + 3;

					us[ 4 * i_f + 0 ] = (float)i_f;         vs[ 4 * i_f + 0 ] = 0.0f;
					us[ 4 * i_f + 1 ] = (float)i_f + 1.0f;  vs[ 4 * i_f + 1 ] = 0.0f;
					us[ 4 * i_f + 2 ] = (float)i_f + 1.0f;  vs[ 4 * i_f + 2 ] = 1.0f;
					us[ 4 * i_f + 3 ] = (float)i_f;         vs[ 4 * i_f + 3 ] = 1.0f;
				}

				stat = meshFn.setUVs( us, vs, &uvSetNames[0] );
				stat = meshFn.assignUVs( uvCounts, uvIds, &uvSetNames[0] );
			}

			meshFn.updateSurface();
			meshFn.syncObject();

			outMeshHnd.set( newMeshData );
		}	
	}
	else 
		return MS::kUnknownParameter;

	if( hasNoEffect )
		outMeshHnd.set( inMeshHnd.asMesh() );
	
	data.setClean( plug );

	return stat;
}
Beispiel #2
0
// ====================================
// Compute
// ====================================
//
//  Description:
//      This method computes the value of the given output plug based
//      on the values of the input attributes.
//
//  Arguments:
//      plug - the plug to compute
//      data - object that provides access to the attributes for this node
//
MStatus OsdPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {

    MStatus returnStatus;

    // Check which output attribute we have been asked to compute.  If this
    // node doesn't know how to compute it, we must return
    // MS::kUnknownParameter.
    //
    if( plug == a_output ) {
        bool createdSubdMesh = false;

        int subdivisionLevel = data.inputValue(a_subdivisionLevels).asInt();
        short stateH = data.inputValue(state).asShort();

        if ((subdivisionLevel > 0) and (stateH !=1)) {

            // == Retrieve input mesh ====================================
            // Get attr values
            MObject inMeshObj        = data.inputValue(a_inputPolymesh).asMesh();
            short vertBoundaryMethod = data.inputValue(a_vertBoundaryMethod).asShort();
            short fvarBoundaryMethod = data.inputValue(a_fvarBoundaryMethod).asShort();
            bool  fvarPropCorners    = data.inputValue(a_fvarPropagateCorners).asBool();
            bool  smoothTriangles    = data.inputValue(a_smoothTriangles).asBool();
            short creaseMethodVal    = data.inputValue(a_creaseMethod).asShort();

            // Convert attr values to OSD enums
            HMesh::InterpolateBoundaryMethod vertInterpBoundaryMethod =
                ConvertMayaBoundaryMethodShortToOsdInterpolateBoundaryMethod(vertBoundaryMethod);

            HMesh::InterpolateBoundaryMethod fvarInterpBoundaryMethod =
                ConvertMayaBoundaryMethodShortToOsdInterpolateBoundaryMethod(fvarBoundaryMethod);

            HCatmark::CreaseSubdivision creaseMethod =
                (creaseMethodVal == k_creaseMethod_chaikin) ?
                    HCatmark::k_CreaseChaikin : HCatmark::k_CreaseNormal;

            HCatmark::TriangleSubdivision triangleSubdivision =
                smoothTriangles ? HCatmark::k_New : HCatmark::k_Normal;

            // == Get Mesh Functions and Iterators ==========================
            MFnMeshData inMeshDat(inMeshObj);
            MFnMesh inMeshFn(inMeshObj, &returnStatus);
            MCHECKERR(returnStatus, "ERROR getting inMeshFn\n");
            MItMeshPolygon inMeshItPolygon(inMeshObj, &returnStatus);
            MCHECKERR(returnStatus, "ERROR getting inMeshItPolygon\n");

            // == Convert MFnMesh to OpenSubdiv =============================
            // Create the hbrMesh
            // Note: These fvar values only need to be kept alive through the life of the farMesh
            std::vector<int> fvarIndices;
            std::vector<int> fvarWidths;

            HMesh *hbrMesh = createOsdHbrFromPoly(
                inMeshFn, inMeshItPolygon, fvarIndices, fvarWidths);
            assert(hbrMesh);

            // Create the farMesh if successfully created the hbrMesh

            if (hbrMesh) {
                // Set Boundary methods and other hbr paramters
                hbrMesh->SetInterpolateBoundaryMethod( vertInterpBoundaryMethod );
                hbrMesh->SetFVarInterpolateBoundaryMethod( fvarInterpBoundaryMethod );
                hbrMesh->SetFVarPropagateCorners(fvarPropCorners);
                hbrMesh->GetSubdivision()->SetCreaseSubdivisionMethod(creaseMethod);

                // Set HBR Catmark Subdivision parameters
                HCatmark *catmarkSubdivision = dynamic_cast<HCatmark *>(hbrMesh->GetSubdivision());
                if (catmarkSubdivision) {
                    catmarkSubdivision->SetTriangleSubdivisionMethod(triangleSubdivision);
                }

                // Finalize subd calculations -- apply boundary interpolation rules and resolves singular verts, etc.
                // NOTE: This HAS to be called after all HBR parameters are set
                hbrMesh->Finish();

                int ncoarseverts = hbrMesh->GetNumVertices();

                // Create a FarMesh from the HBR mesh and pass into
                // It will be owned by the OsdMesh and deleted in the ~OsdMesh()
                FMeshFactory meshFactory(hbrMesh, subdivisionLevel, false);

                FMesh *farMesh = meshFactory.Create((hbrMesh->GetTotalFVarWidth() > 0));

                // == Setup OSD Data Structures =========================
                int numVertexElements  = 3; // only track vertex positions
                int numVaryingElements = 0; // XXX Future: Revise to include varying ColorSets
                int numVertices = inMeshFn.numVertices();

                int numFarVerts = farMesh->GetNumVertices();

                static OpenSubdiv::OsdCpuComputeController computeController = OpenSubdiv::OsdCpuComputeController();

                OpenSubdiv::OsdCpuComputeController::ComputeContext *computeContext =
                    OpenSubdiv::OsdCpuComputeController::ComputeContext::Create(farMesh);

                OpenSubdiv::OsdCpuVertexBuffer *vertexBuffer =
                    OpenSubdiv::OsdCpuVertexBuffer::Create(numVertexElements, numFarVerts );

                OpenSubdiv::OsdCpuVertexBuffer *varyingBuffer =
                    (numVaryingElements) ? OpenSubdiv::OsdCpuVertexBuffer::Create(numVaryingElements, numFarVerts) : NULL;

                // == UPDATE VERTICES (can be done after farMesh generated from topology) ==
                float const * vertex3fArray = inMeshFn.getRawPoints(&returnStatus);
                vertexBuffer->UpdateData(vertex3fArray, 0, numVertices );

                // Hbr dupes singular vertices during Mesh::Finish() - we need
                // to duplicate their positions in the vertex buffer.
                if (ncoarseverts > numVertices) {

                    MIntArray polyverts;

                    for (int i=numVertices; i<ncoarseverts; ++i) {

                        HVertex const * v = hbrMesh->GetVertex(i);

                        HFace const * f = v->GetIncidentEdge()->GetFace();

                        int vidx = -1;
                        for (int j=0; j<f->GetNumVertices(); ++j) {
                            if (f->GetVertex(j)==v) {
                                vidx = j;
                                break;
                            }
                        }
                        assert(vidx>-1);

                        inMeshFn.getPolygonVertices(f->GetID(), polyverts);

                        int vert = polyverts[vidx];

                        vertexBuffer->UpdateData(&vertex3fArray[0]+vert*numVertexElements, i, 1);
                    }
                }

                // == Delete HBR
                // Can now delete the hbrMesh as we will only be referencing the farMesh from this point on
                delete hbrMesh;
                hbrMesh = NULL;

                // == Subdivide OpenSubdiv mesh ==========================
                computeController.Refine(computeContext, farMesh->GetKernelBatches(), vertexBuffer, varyingBuffer);
                computeController.Synchronize();

                // == Convert subdivided OpenSubdiv mesh to MFnMesh Data outputMesh =============

                // Create New Mesh Data Object
                MFnMeshData newMeshData;
                MObject     newMeshDataObj = newMeshData.create(&returnStatus);
                MCHECKERR(returnStatus, "ERROR creating outputData");

                // Create out mesh
                returnStatus = convertOsdFarToMayaMeshData(farMesh, vertexBuffer, subdivisionLevel, inMeshFn, newMeshDataObj);
                MCHECKERR(returnStatus, "ERROR convertOsdFarToMayaMesh");

                // Propagate objectGroups from inMesh to outMesh (for per-facet shading, etc)
                returnStatus = createSmoothMesh_objectGroups(inMeshDat, subdivisionLevel, newMeshData );

                // Write to output plug
                MDataHandle outMeshH = data.outputValue(a_output, &returnStatus);
                MCHECKERR(returnStatus, "ERROR getting polygon data handle\n");
                outMeshH.set(newMeshDataObj);

                // == Cleanup OSD ============================================
                // REVISIT: Re-add these deletes
                delete(vertexBuffer);
                delete(varyingBuffer);
                delete(computeContext);
                delete(farMesh);

                // note that the subd mesh was created (see the section below if !createdSubdMesh)
                createdSubdMesh = true;
            }
        }

        // Pass-through inMesh to outMesh if not created the subd mesh
        if (!createdSubdMesh) {
            MDataHandle outMeshH = data.outputValue(a_output, &returnStatus);
            returnStatus = outMeshH.copy(data.outputValue(a_inputPolymesh, &returnStatus));
            MCHECKERR(returnStatus, "ERROR getting polygon data handle\n");
        }

        // Clean up Maya Plugs
        data.setClean(plug);
    }
    else {
        // Unhandled parameter in this compute function, so return MS::kUnknownParameter
        // so it is handled in a parent compute() function.
        return MS::kUnknownParameter;
    }
    return MS::kSuccess;
}
Beispiel #3
0
MStatus AlembicNode::initialize()
{
    MStatus status;

    MFnUnitAttribute    uAttr;
    MFnTypedAttribute   tAttr, tAttr2;
    MFnNumericAttribute nAttr;
    MFnGenericAttribute gAttr;
    MFnEnumAttribute    eAttr;

    // add the input attributes: time, file, sequence time
    mTimeAttr = uAttr.create("time", "tm", MFnUnitAttribute::kTime, 0.0);
    status = uAttr.setStorable(true);
    status = addAttribute(mTimeAttr);

    // input file name
    MFnStringData fileFnStringData;
    MObject fileNameDefaultObject = fileFnStringData.create("");
    mAbcFileNameAttr = tAttr.create("abc_File", "fn",
        MFnData::kString, fileNameDefaultObject);
    status = tAttr.setStorable(true);
    status = tAttr.setUsedAsFilename(true);
    status = addAttribute(mAbcFileNameAttr);

    // input layer file names
	MFnStringArrayData fileFnStringArrayData;
	MStringArray dummyStringArray;
	MObject layerFileNamesDefaultObject = fileFnStringArrayData.create(dummyStringArray);
	mAbcLayerFileNamesAttr = tAttr2.create("abc_layerFiles", "fns",
		MFnData::kStringArray, layerFileNamesDefaultObject);
	status = tAttr2.setStorable(true);
	status = tAttr2.setUsedAsFilename(true);
	status = tAttr2.setKeyable(false);
	status = tAttr2.setWritable(true);
	status = addAttribute(mAbcLayerFileNamesAttr);

    // playback speed
    mSpeedAttr = nAttr.create("speed", "sp",
        MFnNumericData::kDouble, 1.0, &status);
    status = nAttr.setWritable(true);
    status = nAttr.setStorable(true);
    status = nAttr.setKeyable(true);
    status = addAttribute(mSpeedAttr);

    // frame offset
    mOffsetAttr = nAttr.create("offset", "of",
        MFnNumericData::kDouble, 0, &status);
    status = nAttr.setWritable(true);
    status = nAttr.setStorable(true);
    status = nAttr.setKeyable(true);
    status = addAttribute(mOffsetAttr);

    // cycle type
    mCycleTypeAttr = eAttr.create("cycleType", "ct", 0,  &status );
    status = eAttr.addField("Hold", PLAYTYPE_HOLD);
    status = eAttr.addField("Loop", PLAYTYPE_LOOP);
    status = eAttr.addField("Reverse", PLAYTYPE_REVERSE);
    status = eAttr.addField("Bounce", PLAYTYPE_BOUNCE);
    status = eAttr.setWritable(true);
    status = eAttr.setStorable(true);
    status = eAttr.setKeyable(true);
    status = addAttribute(mCycleTypeAttr);

    // Regex Filter
    // This is a hidden variable to preserve a regexIncludefilter string
    // into a .ma file.
    mIncludeFilterAttr = tAttr.create("regexIncludeFilter", "ift",
        MFnData::kString);
    status = tAttr.setStorable(true);
    status = tAttr.setHidden(true);
    status = addAttribute(mIncludeFilterAttr);

    // Regex Filter
    // This is a hidden variable to preserve a regexExcludefilter string
    // into a .ma file.
    mExcludeFilterAttr = tAttr.create("regexExcludeFilter", "eft",
        MFnData::kString);
    status = tAttr.setStorable(true);
    status = tAttr.setHidden(true);
    status = addAttribute(mExcludeFilterAttr);

    // sequence min and max in frames
    mStartFrameAttr = nAttr.create("startFrame", "sf",
        MFnNumericData::kDouble, 0, &status);
    status = nAttr.setWritable(false);
    status = nAttr.setStorable(true);
    status = addAttribute(mStartFrameAttr);

    mEndFrameAttr = nAttr.create("endFrame", "ef",
        MFnNumericData::kDouble, 0, &status);
    status = nAttr.setWritable(false);
    status = nAttr.setStorable(true);
    status = addAttribute(mEndFrameAttr);

    // add the output attributes
    // sampled subD mesh
    MFnMeshData fnMeshData;
    MObject meshDefaultObject = fnMeshData.create(&status);
    mOutSubDArrayAttr = tAttr.create("outSubDMesh", "osubd",
        MFnData::kMesh, meshDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutSubDArrayAttr);

    // sampled poly mesh
    mOutPolyArrayAttr = tAttr.create("outPolyMesh", "opoly",
        MFnData::kMesh, meshDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutPolyArrayAttr);

    // sampled nurbs surface
    MFnNurbsSurfaceData fnNSData;
    MObject nsDefaultObject = fnNSData.create(&status);
    mOutNurbsSurfaceArrayAttr = tAttr.create("outNSurface", "ons",
        MFnData::kNurbsSurface, nsDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutNurbsSurfaceArrayAttr);

    // sampled nurbs curve group
    MFnNurbsCurveData fnNCData;
    MObject ncDefaultObject = fnNCData.create(&status);
    mOutNurbsCurveGrpArrayAttr = tAttr.create("outNCurveGrp", "onc",
        MFnData::kNurbsCurve, ncDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutNurbsCurveGrpArrayAttr);

    // sampled locator
    mOutLocatorPosScaleArrayAttr = nAttr.create("outLoc", "olo",
        MFnNumericData::kDouble, 0.0, &status);
    status = nAttr.setStorable(false);
    status = nAttr.setWritable(false);
    status = nAttr.setArray(true);
    status = nAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutLocatorPosScaleArrayAttr);

    // sampled transform operations
    mOutTransOpArrayAttr = nAttr.create("transOp", "to",
        MFnNumericData::kDouble, 0.0, &status);
    status = nAttr.setStorable(false);
    status = nAttr.setWritable(false);
    status = nAttr.setArray(true);
    status = nAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutTransOpArrayAttr);

    // sampled camera
    // assume the boolean variables cannot be keyed
    mOutCameraArrayAttr = nAttr.create("outCamera", "ocam",
        MFnNumericData::kDouble, 0.0, &status);
    status = nAttr.setStorable(false);
    status = nAttr.setWritable(false);
    status = nAttr.setArray(true);
    status = nAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutCameraArrayAttr);

    // sampled custom-attributes
    mOutPropArrayAttr = gAttr.create("prop", "pr", &status);
    status = gAttr.addNumericDataAccept(MFnNumericData::kBoolean);
    status = gAttr.addNumericDataAccept(MFnNumericData::kByte);
    status = gAttr.addNumericDataAccept(MFnNumericData::kShort);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Short);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Short);
    status = gAttr.addNumericDataAccept(MFnNumericData::kInt);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Int);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Int);
    status = gAttr.addNumericDataAccept(MFnNumericData::kFloat);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Float);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Float);
    status = gAttr.addNumericDataAccept(MFnNumericData::kDouble);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Double);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Double);
    status = gAttr.addNumericDataAccept(MFnNumericData::k4Double);
    status = gAttr.addDataAccept(MFnData::kString);
    status = gAttr.addDataAccept(MFnData::kIntArray);
    status = gAttr.addDataAccept(MFnData::kDoubleArray);
    status = gAttr.addDataAccept(MFnData::kVectorArray);
    status = gAttr.addDataAccept(MFnData::kPointArray);

    status = gAttr.setWritable(false);
    status = gAttr.setKeyable(false);
    status = gAttr.setArray(true);
    status = gAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutPropArrayAttr);

    // set up affection relationships
    status = attributeAffects(mTimeAttr, mOutSubDArrayAttr);
    status = attributeAffects(mTimeAttr, mOutPolyArrayAttr);
    status = attributeAffects(mTimeAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mTimeAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mTimeAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mTimeAttr, mOutCameraArrayAttr);
    status = attributeAffects(mTimeAttr, mOutPropArrayAttr);
    status = attributeAffects(mTimeAttr, mOutLocatorPosScaleArrayAttr);

    status = attributeAffects(mSpeedAttr, mOutSubDArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutPolyArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutCameraArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutPropArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutLocatorPosScaleArrayAttr);

    status = attributeAffects(mOffsetAttr, mOutSubDArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutPolyArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutCameraArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutPropArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutLocatorPosScaleArrayAttr);

    status = attributeAffects(mCycleTypeAttr, mOutSubDArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutPolyArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutCameraArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutPropArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutLocatorPosScaleArrayAttr);

    MGlobal::executeCommand( UITemplateMELScriptStr );

    return status;
}
/*! Compute function, gets the input surface, determines what type it is and calls the appropriate conversion function
    Encapsulates an cowpointer to the body into the naiadBodyData type and outputs it */
MStatus NBuddySurfaceToBodyNode::compute( const MPlug& plug, MDataBlock& data )
{
    MStatus status;
    if (plug == _outBody)
    {
        //Get the body name
        MDataHandle bodyNameHndl = data.inputValue( _bodyName, &status );
        MString bodyName = bodyNameHndl.asString();

        //Create the MFnPluginData for the naiadBody
        MFnPluginData dataFn;
        dataFn.create( MTypeId( naiadBodyData::id ), &status);
        NM_CheckMStatus( status, "Failed to create naiadBodyData in MFnPluginData");

        //Get subdivision info from plugs so better approximations of meshes can be done
        int divisions = data.inputValue( _subDivide, &status ).asBool();
	
        //Getting genericAttribute handle containing the surface and pick the correct conversion function
        MObject meshObj;
        MDataHandle inSurfaceHdl = data.inputValue( _inSurface, &status );
        if (inSurfaceHdl.type() == MFnData::kNurbsSurface)
        {
            MFnNurbsSurface nurbsFn(inSurfaceHdl.asNurbsSurface());

            // Create the data holder for the tesselated mesh
            MFnMeshData dataCreator;
            MObject newOutputData = dataCreator.create(&status);

            //Setup the tesselation parameters
            MTesselationParams tParams;
            tParams.setOutputType( MTesselationParams::kTriangles );
            tParams.setFormatType( MTesselationParams::kGeneralFormat );
            tParams.setUIsoparmType( MTesselationParams::kSpanEquiSpaced );
            tParams.setVIsoparmType( MTesselationParams::kSpanEquiSpaced );
            tParams.setUNumber( divisions+1 );
            tParams.setVNumber( divisions+1 );

            // Tesselate and get the returned mesh
            meshObj = nurbsFn.tesselate( tParams, newOutputData, &status );
            NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate nurbs surface to poly");
        }
        else if (inSurfaceHdl.type() == MFnData::kMesh)
        {
            meshObj = inSurfaceHdl.asMesh();

            if ( divisions > 0 )
            {
                MFnMeshData dataCreator;
                MObject newOutputData = dataCreator.create(&status);

                MFnMesh meshFn(meshObj);
                MIntArray faceIds;
                for ( unsigned int i(0); i < meshFn.numPolygons(); ++i )
                    faceIds.append(i);

                meshFn.subdivideFaces( faceIds , divisions );
            }
        }
        else if (inSurfaceHdl.type() == MFnData::kSubdSurface)
        {
            // Create the subd function set so we can tesselate
            MFnSubd subDfn(inSurfaceHdl.asSubdSurface());

            // Create the data holder for the tesselated mesh
            MFnMeshData dataCreator;
            MObject newOutputData = dataCreator.create(&status);

            // Tesselate the subD surface
            meshObj = subDfn.tesselate(true, 1 , divisions , newOutputData, &status );
            NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate SubD surface to poly");
        }
        else
            return status ;

	//Get the handle for the input transform
        MDataHandle inTransformHdl = data.inputValue( _inTransform, &status );
	NM_CheckMStatus( status, "Failed to get inTransform handle");

	MDataHandle useTransformHdl = data.inputValue( _useTransform, &status);
	NM_CheckMStatus( status, "Failed to get worldSpaceHdl ");
	bool useTransform = useTransformHdl.asBool();

        //Get a new naiadBodyData
        naiadBodyData * newBodyData = (naiadBodyData*)dataFn.data( &status );
        NM_CheckMStatus( status, "Failed to get naiadBodyData handle from MFnPluginData");

        try {
            newBodyData->nBody = mayaMeshToNaiadBody( meshObj, std::string(bodyName.asChar()), useTransform, inTransformHdl.asMatrix() );
        }
        catch(std::exception& ex) {
            NM_ExceptionPlugDisplayError("NBuddySurfaceToBodyNode::compute ", plug, ex );
        }

        //Give the data to the output handle and set it clean
        MDataHandle bodyDataHnd = data.outputValue( _outBody, &status );
        NM_CheckMStatus( status, "Failed to get outputData handle for outBody");
        bodyDataHnd.set( newBodyData );
        data.setClean( plug );
    }

    return status;
}
Beispiel #5
0
MStatus TCC::createSubdividedMesh(int sdRes, int sdRefRes, MFnMesh &srcMesh, TCCData &tccData, MDataHandle outMeshHandle, float lineThickness, MStatus& stat)
{   
    HDS hds;
    bool shouldCreateUVs = true;
    
    size_t nV = srcMesh.numVertices();
    size_t nF = srcMesh.numPolygons();
    size_t nIHE = tccData.F.length();
    
    bool consistentSizes= (tccData.pole.length()==nV) && (tccData.T.length()==nIHE) && (tccData.itv.length()==nIHE) & (tccData.corner.length()==nV);
    
    if ((nV==0)||(nF==0)||(!consistentSizes)) return MS::kFailure;

    MFloatArray uArray, vArray, sc_uArray, sc_vArray;
    MIntArray uvIdx;
    if (shouldCreateUVs)
    {
        createUVset(tccData, sdRes, uArray, vArray, sc_uArray, sc_vArray, uvIdx, lineThickness);
    }
    
    
    MFloatPointArray points;
    srcMesh.getPoints(points);
    
    store_in_hds(hds, points, tccData.nFV, tccData.F);     // convert to HDS

    finalize_HDS(hds);
    size_t nHE = hds.nHE();

    hds.T.setDims(1, nHE);
    hds.itv.setDims(1, nHE);
    hds.corner.setDims(1, nV);
    
    // interior halfedge tags
    for (size_t k=0; k<nV; k++) 
    {
        hds.corner[k] = tccData.corner[k];
    }

    // interior halfedge tags
    for (size_t k=0; k<nIHE; k++) 
    {
        hds.T[k] = tccData.T[k];
        hds.itv[k] = tccData.itv[k];
    }
    
    // border halfedge tags
    for (size_t k=nIHE; k<nHE; k++) 
    {
        hds.T[k] = false;
        hds.itv[k] = hds.itv[hds.twin[k]];
    }
        
    TCC_MAX::subdivide(hds, sdRes);
    
    if (sdRefRes>0)
    {
        HDS hds2;
        copy_HDS(hds, hds2);
        TCC_MAX::subdivide(hds2, sdRefRes);
        memcpy(&hds.V[0], &hds2.V[0], hds.V.size() * sizeof(double));
    }
    

    
    MObject outMeshObj = outMeshHandle.asMesh();
    MFnMesh outMeshFn(outMeshObj);
    
    // if no topology change necessary, just update points!
    if ( (outMeshFn.numFaceVertices() == hds.nIHE()) && (outMeshFn.numPolygons() == hds.nF()) )
    {
        size_t nV   = hds.nV();
        points.setLength(nV);
        for (size_t k=0; k<nV; k++) 
        {
            points[k](0) = hds.V[3*k+0];
            points[k](1) = hds.V[3*k+1];
            points[k](2) = hds.V[3*k+2];
        }
        stat = outMeshFn.setPoints(points); McheckErr(stat, "ERROR creating outputData");
        
        if (shouldCreateUVs)
        {
            MString uvSet = "UnitPatchUVs";
            MString sc_uvSet = "ScaledPatchUVs";
            stat = outMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
            stat = outMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        }
        
        return MS::kSuccess;
    }

    
    // Have to update connectivity and geometry

    load_from_hds(hds, points, tccData.nFV, tccData.F);

    nV = points.length();
    nF = tccData.nFV.length();
    
    MFnMeshData dataCreator;
    MObject newOutputData = dataCreator.create(&stat); McheckErr(stat, "ERROR creating outputData");
    MFnMesh newOutMeshFn;
    
    MObject newMesh;
    
    newMesh = newOutMeshFn.create(nV, nF, points, tccData.nFV, tccData.F, newOutputData, &stat); McheckErr(stat, "ERROR in MFnMesh.create\n");

    if (shouldCreateUVs)
    {
        MString uvSet = "UnitPatchUVs";
        MString sc_uvSet = "ScaledPatchUVs";
        
        uvSet = newOutMeshFn.createUVSetDataMeshWithName(uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&uvSet);
        stat = newOutMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &uvSet); McheckErr(stat, "ERROR assigning UVs");
        
        sc_uvSet = newOutMeshFn.createUVSetDataMeshWithName(sc_uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&sc_uvSet);
        stat = newOutMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &sc_uvSet); McheckErr(stat, "ERROR assigning UVs");
    }
    
    
    if (stat == MS::kSuccess)
    {
        outMeshHandle.set(newOutputData);
    }
    
    
    return MS::kSuccess;
}
Beispiel #6
0
MStatus ropeGenerator::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	if ( plug == outMesh )
	{
		//Get Curve
		MDataHandle inCurve_Hdl = data.inputValue( inCurve, &status );
		if (status != MS::kSuccess ){
			MGlobal::displayError( "Node ropeGenerator needs an Input Curve" );
			return MS::kSuccess;
		}
		MObject inCurveObj = inCurve_Hdl.asNurbsCurve();
		MFnNurbsCurve curveFn( inCurveObj );
		
		//Get Attributes
		int inDiv = data.inputValue( divisions ).asInt();
		bool inCreateRope = data.inputValue( createRope ).asBool();
		int inRopesCount = data.inputValue( ropesCount ).asInt();
		int inPointsPerRope = data.inputValue( pointsPerRope ).asInt();
		int inPointsCount = data.inputValue( pointsCount ).asInt();
		float inRopesStrength = data.inputValue( ropesStrength ).asFloat();
		float inRadius = data.inputValue( radius ).asFloat();
		MRampAttribute inRadRamp( thisMObject(), taperRamp );
		float inTwist = data.inputValue( twist ).asFloat();
		MRampAttribute inTwistRamp( thisMObject(), twistRamp );
		float inUvWidth = data.inputValue( uvWidth ).asFloat();
		float inUvHeight = data.inputValue( uvHeight ).asFloat();
		float inUvCapSize = data.inputValue( uvCapSize ).asFloat();

		MFnMesh fnMesh;
		MFnMeshData dataCreator;
		MObject outMeshData;
		outMeshData = dataCreator.create();
		MDataHandle outputHandle = data.outputValue(outMesh);
		//createBase 
		MIntArray faceCounts, faceConnects, uvIds;
		MFloatArray uArray, vArray;
		MFloatPointArray points;
		faceCounts.clear();
		faceConnects.clear();
		points.clear();
		if (inCreateRope)
			inPointsCount = ( inPointsPerRope + 2 ) * inRopesCount;
		int numVertices = ( inDiv + 1 ) * inPointsCount;
		int numFaces = ( inPointsCount * inDiv ) + 2;
		float param;
		float lengPerDiv = curveFn.length() / inDiv;
		PrevNormal = MVector( curveFn.normal( 0.0, MSpace::kWorld ).normal() );
		float baseLeng = lengPerDiv;
		float baseParamForRamp = 0;
		float paramForRamp = 1.0 / float( inDiv );
		float uDivNumber = inUvWidth / float( inPointsCount );
		float vDivNumber = inUvHeight / float( inDiv );
		for (int d = 0; d < inDiv + 1; d++)
		{
			if (d == 0)
			{
				param = 0;
				faceCounts.append( inPointsCount );
				for ( int i = inPointsCount - 1; i >= 0; i-- )
				{
					faceConnects.append( i );
				}
				for ( int i = 0; i < inPointsCount; i++ )
				{
					uvIds.append( i );
				}
				MFloatArray uTmpArray, vTmpArray;
				if (inCreateRope)
					createRopesUvs( inRopesCount, inPointsPerRope, inRopesStrength, inUvCapSize, uTmpArray, vTmpArray, 1.0 );
				else
					createCircleUvs( inPointsCount, inUvCapSize, uTmpArray, vTmpArray, 1.0 );
				for ( int u = uTmpArray.length() - 1; u >= 0 ; u-- )
				{
					uArray.append( uTmpArray[u] + 1.0 );
					vArray.append( vTmpArray[u] );
				}
				for ( int i = 0; i < inPointsCount + 1; i++ )
				{
					uArray.append( uDivNumber * float( i ) );
					vArray.append( vDivNumber * float( d ) );
				}
			}else{
				param = curveFn.findParamFromLength( baseLeng );
				for ( int i = 0; i < inPointsCount + 1; i++ )
				{
					uArray.append( uDivNumber * float( i ) );
					vArray.append( vDivNumber * float( d ) );
				}
				for ( int f = 0; f < inPointsCount; f++ )
				{
					faceCounts.append( 4 );
					if( f == ( inPointsCount - 1 ))
					{
						faceConnects.append( ( f + 1 + ( d * inPointsCount ) ) - inPointsCount - inPointsCount );
						faceConnects.append( ( f + 1 + ( d * inPointsCount ) - inPointsCount ) );
						faceConnects.append( f + 1 + ( d * inPointsCount )  - 1 );
						faceConnects.append( f + 1 + ( d * inPointsCount ) - inPointsCount - 1 );
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d - 1 )) + 1 + f );
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d )) + 1 + f);
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d )) + f);
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d - 1 )) + f);
					}else{
						faceConnects.append( ( f + ( d * inPointsCount ) ) - inPointsCount );
						faceConnects.append( f + 1 + ( d * inPointsCount ) - inPointsCount );
						faceConnects.append( f + 1 + ( d * inPointsCount ) );
						faceConnects.append( ( f + ( d * inPointsCount )) );
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d - 1 )) + f);
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d - 1 )) + 1 + f );
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d )) + 1 + f);
						uvIds.append( inPointsCount + (( inPointsCount + 1 ) * float( d )) + f);
					}
				}
				if ( d == inDiv )
				{
					faceCounts.append( inPointsCount );
					for ( int i = 0; i <  inPointsCount; i++ )
					{
						faceConnects.append( ( inPointsCount * inDiv ) + i );
						uvIds.append( ( inPointsCount * ( inDiv + 2)) + i + inDiv + 1 );
					}
					MFloatArray uTmpArray, vTmpArray;
					if (inCreateRope)
						createRopesUvs( inRopesCount, inPointsPerRope, inRopesStrength, inUvCapSize, uTmpArray, vTmpArray, -1.0 );
					else
						createCircleUvs( inPointsCount, inUvCapSize, uTmpArray, vTmpArray, -1.0 );
					for ( int u = 0; u < uTmpArray.length(); u++ )
					{
						uArray.append( uTmpArray[u] + 2.0 );
						vArray.append( vTmpArray[u] );
					}
				}
				baseLeng += lengPerDiv;
			}
			float divTwist;
			inTwistRamp.getValueAtPosition( baseParamForRamp, divTwist );
			float divTaper;
			inRadRamp.getValueAtPosition( baseParamForRamp, divTaper );
			baseParamForRamp += paramForRamp;
			if (inCreateRope)
				createRopesRings( inRopesCount, 
								getMatrixFromParamCurve( curveFn, param, inTwist, MAngle( divTwist, MAngle::kDegrees )  ),
								points, inPointsPerRope, inRopesStrength, inRadius * divTaper);
			else
				createCriclePoints( inPointsCount, 
									getMatrixFromParamCurve( curveFn, param, inTwist, MAngle( divTwist, MAngle::kDegrees ) ),
									points, inRadius * divTaper );
		}
		fnMesh.create( numVertices, numFaces, points, faceCounts, faceConnects, uArray, vArray, outMeshData );
		fnMesh.assignUVs( faceCounts, uvIds );
		outputHandle.set(outMeshData);
		outputHandle.setClean();
	}
	return MS::kSuccess;
}
Beispiel #7
0
MStatus
MayaPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {

    MStatus status;

    // Check which output attribute we have been asked to compute.  If this
    // node doesn't know how to compute it, we must return
    // MS::kUnknownParameter.
    //

    if( plug == a_output ) {

        bool createdSubdMesh = false;

        int subdivisionLevel = data.inputValue(a_subdivisionLevels).asInt();
        short stateH = data.inputValue(state).asShort();

        if ((subdivisionLevel > 0) and (stateH !=1)) {

            // == Retrieve input mesh ====================================
            // Get attr values
            MObject inMeshObj        = data.inputValue(a_inputPolymesh).asMesh();
            short vertBoundaryMethod = data.inputValue(a_vertBoundaryMethod).asShort();
            short fvarBoundaryMethod = data.inputValue(a_fvarBoundaryMethod).asShort();
            bool  fvarPropCorners    = data.inputValue(a_fvarPropagateCorners).asBool();
            bool  smoothTriangles    = data.inputValue(a_smoothTriangles).asBool();
            short creaseMethodVal    = data.inputValue(a_creaseMethod).asShort();

            // == Get Mesh Functions and Iterators ==========================
            MFnMeshData inMeshDat(inMeshObj);
            MFnMesh inMeshFn(inMeshObj, &status);
            MCHECKERR(status, "ERROR getting inMeshFn\n");
            MItMeshPolygon inMeshItPolygon(inMeshObj, &status);
            MCHECKERR(status, "ERROR getting inMeshItPolygon\n");

            // Convert attr values to OSD enums
            OpenSubdiv::Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK;

            //
            // Create Far topology
            //
            OpenSubdiv::Sdc::Options options;
            options.SetVtxBoundaryInterpolation(ConvertMayaVtxBoundary(vertBoundaryMethod));
            options.SetFVarLinearInterpolation(ConvertMayaFVarBoundary(fvarBoundaryMethod, fvarPropCorners));
            options.SetCreasingMethod(creaseMethodVal ?
                 OpenSubdiv::Sdc::Options::CREASE_CHAIKIN : OpenSubdiv::Sdc::Options::CREASE_UNIFORM);
            options.SetTriangleSubdivision(smoothTriangles ?
                 OpenSubdiv::Sdc::Options::TRI_SUB_SMOOTH : OpenSubdiv::Sdc::Options::TRI_SUB_CATMARK);

            float maxCreaseSharpness=0.0f;
            OpenSubdiv::Far::TopologyRefiner * refiner =
                gatherTopology(inMeshFn, inMeshItPolygon, type, options, &maxCreaseSharpness);

            assert(refiner);

            // Refine & Interpolate
            refiner->RefineUniform(OpenSubdiv::Far::TopologyRefiner::UniformOptions(subdivisionLevel));

            Vertex const * controlVerts =
                reinterpret_cast<Vertex const *>(inMeshFn.getRawPoints(&status));

            std::vector<Vertex> refinedVerts(
                refiner->GetNumVerticesTotal() - refiner->GetLevel(0).GetNumVertices());
            
            Vertex const * srcVerts = controlVerts;
            Vertex * dstVerts = &refinedVerts[0];
            for (int level = 1; level <= subdivisionLevel; ++level) {
                OpenSubdiv::Far::PrimvarRefiner(*refiner).Interpolate(level, srcVerts, dstVerts);
                srcVerts = dstVerts;
                dstVerts += refiner->GetLevel(level).GetNumVertices();
            }

            // == Convert subdivided OpenSubdiv mesh to MFnMesh Data outputMesh =============

            // Create New Mesh Data Object
            MFnMeshData newMeshData;
            MObject     newMeshDataObj = newMeshData.create(&status);
            MCHECKERR(status, "ERROR creating outputData");

            // Create out mesh
            status = convertToMayaMeshData(*refiner, refinedVerts, inMeshFn, newMeshDataObj);
            MCHECKERR(status, "ERROR convertOsdFarToMayaMesh");

            // Propagate objectGroups from inMesh to outMesh (for per-facet shading, etc)
            status = createSmoothMesh_objectGroups(inMeshFn, inMeshDat,
                newMeshData, subdivisionLevel, refiner->GetLevel(subdivisionLevel).GetNumFaces());

            // Write to output plug
            MDataHandle outMeshH = data.outputValue(a_output, &status);
            MCHECKERR(status, "ERROR getting polygon data handle\n");
            outMeshH.set(newMeshDataObj);

            int isolation = std::min(10,(int)ceil(maxCreaseSharpness)+1);
            data.outputValue(a_recommendedIsolation).set(isolation);

            // == Cleanup OSD ============================================
            // REVISIT: Re-add these deletes
            delete refiner;

            // note that the subd mesh was created (see the section below if !createdSubdMesh)
            createdSubdMesh = true;
        }

        // Pass-through inMesh to outMesh if not created the subd mesh
        if (!createdSubdMesh) {
            MDataHandle outMeshH = data.outputValue(a_output, &status);
            status = outMeshH.copy(data.outputValue(a_inputPolymesh, &status));
            MCHECKERR(status, "ERROR getting polygon data handle\n");
        }

        // Clean up Maya Plugs
        data.setClean(plug);

    } else {
        // Unhandled parameter in this compute function, so return MS::kUnknownParameter
        // so it is handled in a parent compute() function.
        return MS::kUnknownParameter;
    }
    return MS::kSuccess;
}
Beispiel #8
0
// Propagate objectGroups from inMesh to subdivided outMesh
// Note: Currently only supporting facet groups (for per-facet shading)
MStatus
createSmoothMesh_objectGroups( MFnMesh const & inMeshFn,
    MFnMeshData const & inMeshDat, MFnMeshData &newMeshDat, int level, int numSubfaces ) {

    MStatus status;

    MIntArray newCompElems;

    std::vector<unsigned int> offsets; // mapping of offsets for subdivided faces

    for(unsigned int gi=0; gi<inMeshDat.objectGroupCount(); gi++) {

        unsigned int compId = inMeshDat.objectGroup(gi, &status);
        MCHECKERR(status, "cannot get objectGroup() comp ID.");

        MFn::Type compType = inMeshDat.objectGroupType(compId, &status);
        MCHECKERR(status, "cannot get objectGroupType().");

        // Only supporting kMeshPolygonComponent ObjectGroups at this time
        // Skip the other types
        if (compType == MFn::kMeshPolygonComponent) {

            // get elements from inMesh objectGroupComponent
            MIntArray compElems;
            MFnSingleIndexedComponent compFn(inMeshDat.objectGroupComponent(compId), &status );

            MCHECKERR(status, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent().");
            compFn.getElements(compElems);

            if (compElems.length()==0) {
                continue;
            }

            // over-allocation to maximum possible length
            newCompElems.setLength( numSubfaces );

            if (offsets.empty()) {
                // lazy population of the subface offsets table
                int nfaces = inMeshFn.numPolygons();

                offsets.resize(nfaces);

                for (int i=0, count=0; i<nfaces; ++i) {

                    int nverts = inMeshFn.polygonVertexCount(i),
                        nsubfaces = computeNumSubfaces(nverts, level);

                    offsets[i] = count;
                    count+=nsubfaces;
                }
            }

            unsigned int idx = 0;

            // convert/populate newCompElems from compElems of inMesh
            // (with new face indices) to outMesh
            for (unsigned int i=0; i < compElems.length(); i++) {

                int nverts = inMeshFn.polygonVertexCount(compElems[i]),
                    nsubfaces = computeNumSubfaces(nverts, level);

                unsigned int subFaceOffset = offsets[compElems[i]];

                for (int j=0; j<nsubfaces; ++j) {
                    newCompElems[idx++] = subFaceOffset++;
                }
            }

            // resize to actual length
            newCompElems.setLength( idx );

            // create comp
            createComp(newMeshDat, compType, compId, newCompElems);
        }
    }
    return MS::kSuccess;
}
Beispiel #9
0
MStatus fishVizNode::compute( const MPlug& plug, MDataBlock& data )
{    
    MStatus status;
	
	MObject arbitaryMesh = data.inputValue(aInMesh).asMesh();

	MDoubleArray ptc_time_offset;
	MDoubleArray ptc_amplitude;
	MDoubleArray ptc_bend;
	MDoubleArray ptc_scale;
	MDoubleArray masses;
	
	MString cacheName = data.inputValue(acachename, &status).asString();
	MTime currentTime = data.inputValue(atime, &status).asTime();
	cacheName = cacheName+"."+250*int(currentTime.value())+".pdc";
	
	pdcFile* fpdc = new pdcFile();
	if(fpdc->load(cacheName.asChar())==1)
	{
		//MGlobal::displayInfo(MString("FishViz loaded cache file: ")+cacheName);
		fpdc->readPositions(ptc_positions, ptc_velocities, ptc_ups, ptc_views, ptc_time_offset, ptc_amplitude, ptc_bend, ptc_scale, masses);
	}
	else MGlobal::displayWarning(MString("FishViz cannot open cache file: ")+cacheName);
	
	if(currentTime.value()!=int(currentTime.value())) 
	{
		float delta_t = currentTime.value()-int(currentTime.value());
		
		
		for(int i=0; i<fpdc->getParticleCount(); i++)
		{
			ptc_positions[i] += ptc_velocities[i]*delta_t/24.0f;
		}
	}
	
	delete fpdc;
	
	double flapping = zGetDoubleAttr(data, aFlapping);
	double bending= zGetDoubleAttr(data, aBending);
	double oscillate= zGetDoubleAttr(data, aOscillate);
	double length = zGetDoubleAttr(data, aLength);
	m_fish_length = length;
	double frequency = zGetDoubleAttr(data, aFrequency);
	unsigned num_bones = zGetIntAttr(data, aNBone);
	
	unsigned int nptc = ptc_positions.length();
	MPointArray vertices;
	MATRIX44F mat44, mat_bone;
	XYZ vert, front, up, side;
	MDataHandle outputHandle = data.outputValue(outMesh, &status);
	zCheckStatus(status, "ERROR getting polygon data handle\n");
	if(m_num_fish != nptc || m_num_bone != num_bones)
	{
		m_num_bone = num_bones;
		m_num_fish = nptc;
		unsigned int vertex_count;
		unsigned int face_count;
		MIntArray pcounts;
		MIntArray pconnect;
		
		
		
		unsigned  inmeshnv, inmeshnp;
		MPointArray pinmesh;
		MIntArray count_inmesh;
		MIntArray connect_inmesh;
		zWorks::extractMeshParams(arbitaryMesh, inmeshnv, inmeshnp, pinmesh, count_inmesh, connect_inmesh);
		vertex_count = inmeshnv * nptc;
		face_count = inmeshnp * nptc;
		
		for(unsigned int i=0; i<nptc; i++)
		{
			
			// calculate the bone transformations
			poseBones(length, num_bones, ptc_time_offset[i], frequency, ptc_amplitude[i], ptc_bend[i], flapping, bending, oscillate);
			
			front.x = ptc_views[i].x;
			front.y = ptc_views[i].y;
			front.z = ptc_views[i].z;
			up.x = ptc_ups[i].x;
			up.y = ptc_ups[i].y;
			up.z = ptc_ups[i].z;
			
			side = front.cross(up);
			side.normalize();
			
			up = side.cross(front);
			up.normalize();
			
			mat44.setIdentity();
			mat44.setOrientations(side, up, front);
			mat44.scale(ptc_scale[i]);
			mat44.setTranslation(ptc_positions[i].x, ptc_positions[i].y, ptc_positions[i].z);
			
			for(unsigned int j=0; j<inmeshnv; j++)
			{
				vert.x = pinmesh[j].x;
				vert.y = pinmesh[j].y;
				vert.z = pinmesh[j].z;
				
				int bone_id;
				if(vert.z>0) bone_id = 0;
				else if(-vert.z>length)  bone_id = num_bones-1;
				else bone_id = int(-vert.z/length*(num_bones-1));
				
				mat_bone = m_pBone->getBoneById(bone_id);
				vert.z -= -length/(num_bones-1)*bone_id;
				
				mat_bone.transform(vert);
				mat44.transform(vert);
				
				vertices.append(MPoint(vert.x, vert.y, vert.z));
			}
			for(unsigned int j=0; j<inmeshnp; j++)
			{
				pcounts.append(count_inmesh[j]);
			}
		}
		
		int acc=0;
		for(unsigned int i=0; i<nptc; i++)
		{
			for(unsigned int j=0; j<connect_inmesh.length(); j++)
			{
				pconnect.append(connect_inmesh[j]+acc);
			}
			acc += inmeshnv;
		}
		
		
		MObject m_mesh = outputHandle.asMesh();
		
		
		MFnMeshData dataCreator;
		MObject newOutputData = dataCreator.create(&status);
		zCheckStatusNR(status, "ERROR creating outputData");
		
		MFnMesh meshFn;
		m_mesh= meshFn.create(
		  vertex_count,				// number of vertices
		  face_count,		// number of polygons
		  vertices,			// The points
		  pcounts,			// # of vertex for each poly
		  pconnect,			// Vertices index for each poly
		  newOutputData,      // Dependency graph data object
		  &status
		  );
		
		zCheckStatusNR(status, "ERROE creating mesh");
		
		// Update surface 
		//
		outputHandle.set(newOutputData);
		
		
	}
	else
	{
		
		MObject m_mesh = outputHandle.asMesh();
		MFnMesh meshFn(m_mesh);

		unsigned  inmeshnv, inmeshnp;
		MPointArray pinmesh;
		MIntArray count_inmesh;
		MIntArray connect_inmesh;
		zWorks::extractMeshParams(arbitaryMesh, inmeshnv, inmeshnp, pinmesh, count_inmesh, connect_inmesh);
		vertices.setLength(nptc*inmeshnv);
		int acc=0;
		for(unsigned int i=0; i<nptc; i++)
		{
			// calculate the bone transformations
			poseBones(length, num_bones, ptc_time_offset[i], frequency, ptc_amplitude[i], ptc_bend[i], flapping, bending, oscillate);
			
			front.x = ptc_views[i].x;
			front.y = ptc_views[i].y;
			front.z = ptc_views[i].z;
			up.x = ptc_ups[i].x;
			up.y = ptc_ups[i].y;
			up.z = ptc_ups[i].z;
			
			side = front.cross(up);
			side.normalize();
			
			up = side.cross(front);
			up.normalize();
			
			mat44.setIdentity();
			mat44.setOrientations(side, up, front);
			mat44.scale(ptc_scale[i]);
			mat44.setTranslation(ptc_positions[i].x, ptc_positions[i].y, ptc_positions[i].z);
			
			for(unsigned int j=0; j<inmeshnv; j++)
			{
				vert.x = pinmesh[j].x;
				vert.y = pinmesh[j].y;
				vert.z = pinmesh[j].z;
				
				int bone_id;
				if(vert.z>0) bone_id = 0;
				else if(-vert.z>length)  bone_id = num_bones-1;
				else bone_id = int(-vert.z/length*(num_bones-1));
				
				mat_bone = m_pBone->getBoneById(bone_id);
				vert.z -= -length/(num_bones-1)*bone_id;
				
				mat_bone.transform(vert);
				mat44.transform(vert);
				
				vertices[j+acc] = MPoint(vert.x, vert.y, vert.z);
			}
			acc += inmeshnv;
		}
		
		meshFn.setPoints(vertices);
		outputHandle.set(meshFn.object());
		
		
		
	}
	//delete fmat;
	data.setClean( plug );
	
	
	return MS::kSuccess;
}
Beispiel #10
0
MStatus meshCacheNode::compute( const MPlug& plug, MDataBlock& data )
{
	
	MStatus stat;
	
	MString path =  data.inputValue( input ).asString();
	
	double time = data.inputValue( frame ).asTime().value();
	int minfrm = data.inputValue( aminframe ).asInt();
	//int maxfrm = data.inputValue( amaxframe ).asInt();
	int frmstep = data.inputValue( aframestep ).asInt();
	
	if( time < minfrm ) time = minfrm;
		
	int frame_lo = minfrm + int(time-minfrm)/frmstep*frmstep;
	int frame_hi = frame_lo+frmstep;

	char filename[256];
	sprintf( filename, "%s.%d.mcf", path.asChar(), frame_lo );
	
	FMCFMesh mesh;
	if(mesh.load(filename) != 1)
	{
		sprintf( filename, "%s.mcf", path.asChar());
		if(mesh.load(filename) != 1)
		{
			MGlobal::displayError( MString("Failed to open file: ") + filename );
			return MS::kFailure;
		}
	}
	
	int lo_n_vertex = mesh.getNumVertex();

	vertexArray.clear();
	vertexFArray.clear();
	uArray.clear();
	vArray.clear();
	polygonCounts.clear();
	polygonConnects.clear();
	polygonUVs.clear();

	for(unsigned int i = 0; i < mesh.getNumFace(); i++ ) 
	{
		polygonCounts.append( mesh.getFaceCount(i) );
	}

	for(unsigned int i = 0; i < mesh.getNumFaceVertex(); i++) 
	{
		polygonConnects.append( mesh.getVertexId(i) );
		polygonUVs.append( mesh.getUVId(i) );
	}

	XYZ tp;
	for(unsigned int i = 0; i < mesh.getNumVertex(); i++) 
	{
		mesh.getVertex(tp, i);
		vertexArray.append( MPoint( tp.x, tp.y, tp.z ) );
	}

	for(unsigned int i = 0; i < mesh.getNumUV(); i++) 
	{
		uArray.append( mesh.getS(i) );
		vArray.append( mesh.getT(i) );
	}
	
	

	if( time > frame_lo ) 
	{
		sprintf( filename, "%s.%d.mcf", path.asChar(), frame_hi );

		if(mesh.load(filename) != 1)
		{
			MGlobal::displayError( MString("Failed to open file: ") + filename );
		}
		else if(mesh.getNumVertex() == lo_n_vertex)
		{
			XYZ tp;
			for(unsigned int i = 0; i < mesh.getNumVertex(); i++) 
			{
				mesh.getVertex(tp, i);
				vertexFArray.append( MPoint( tp.x, tp.y, tp.z ) );
			}
			
			double alpha = double(time-frame_lo) / (double)frmstep;

			for(unsigned int i = 0; i < mesh.getNumVertex(); i++) 
			{
				vertexArray[i] = vertexArray[i] + alpha * ( vertexFArray[i] - vertexArray[i] );
			}
		}
	}

	if( plug == outMesh ) 
	{
	
		MDataHandle meshh = data.outputValue(outMesh, &stat);
		
		MFnMeshData dataCreator;
		MObject outMeshData = dataCreator.create(&stat);

		int numVertex = vertexArray.length();
		int numPolygon = polygonCounts.length();
		
		MFnMesh meshFn;
		meshFn.create( numVertex, numPolygon, vertexArray, polygonCounts, polygonConnects, outMeshData, &stat );
		
			
		if( !stat ) 
		{
			char log[256];
			sprintf( log, "Failed to create mesh %s", filename );
			MGlobal::displayError( log );
			return MS::kFailure;
		}

		if( polygonUVs.length() != 0 ) 
		{
			meshFn.setUVs ( uArray, vArray );
			meshFn.assignUVs ( polygonCounts, polygonUVs );
		}

		meshh.set(outMeshData);
	    
		data.setClean(plug);

	} 
	else 
	{
		return MS::kUnknownParameter;
	}

		return MS::kSuccess;
}
Beispiel #11
0
MStatus testNobjectNode::compute(const MPlug &plug, MDataBlock &data)
{
	MStatus stat;

	if ( plug == outputGeom )
	{
		MObject inMeshObj = data.inputValue(inputGeom).asMesh();
		
        cerr<<"pull on outputGeom\n";

		MFnMeshData meshDataFn;
        MFnMesh inputMesh(inMeshObj);
		MObject newMeshObj = meshDataFn.create();
		MFnMesh newMeshFn;
		newMeshFn.copy( inMeshObj, newMeshObj );        

        //get the value of the currentTime so it can correctly dirty the
        //startState, currentState.
        data.inputValue(currentTime).asTime();

		// pull on next state.  This will cause the solver to pull on either
        // the startState or the currentState, depending on the time of solve.
        // When we return the state to the solver, it will do the solve and update
        // The N Object data directly.
		MObject nextNObj = data.inputValue(nextState).data();
        MFloatPointArray pts;        

        //At this point the N Object's internal state should have been updated
        //by the solver.  Read it out and set the output mesh.
        fNObject.getPositions(pts);
        if(pts.length() == (unsigned int) inputMesh.numVertices()) {
            newMeshFn.setPoints(pts);
        }

		newMeshFn.setObject( newMeshObj );

		data.outputValue(outputGeom).set(newMeshObj);
		data.setClean(plug);

	}
	if ( plug == currentState )
	{               
        MFnNObjectData outputData;
        MObject mayaNObjectData = outputData.create();
        outputData.setObject(mayaNObjectData);
        
        outputData.setObjectPtr(&fNObject);        
        outputData.setCached(false);

        MDataHandle currStateOutputHandle = data.outputValue(currentState);
        currStateOutputHandle.set(outputData.object());
	  
        cerr<<"pull on currentState\n";
	}
	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);
        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.05f);
        fNObject.setInverseMass(1.0f);
        fNObject.setBounce(0.0f);
        fNObject.setFriction(0.1f);
        fNObject.setDamping(0.0f);
        fNObject.setBendResistance(0.0f);
        fNObject.setMaxIterations(100);        
        fNObject.setMaxSelfCollisionIterations(100);
        fNObject.setStretchAndCompressionResistance(20.0f,10.0f);
        fNObject.setSelfCollisionFlags(false);
        fNObject.setCollisionFlags(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());

        cerr<<"pull on startState\n";
	}
	else {
		stat = MS::kUnknownParameter;
	}
	return stat;
}