MStatus arcLen::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; if( plug == output ) { MDataHandle inputData = data.inputValue( inputCurve, &status ); if( !status ) { status.perror("ERROR getting data"); } else { MObject curve = inputData.asNurbsCurveTransformed(); MFnNurbsCurve curveFn( curve, &status ); if( !status ) { status.perror("ERROR creating curve function set"); } else { double result = curveFn.length(); MDataHandle outputHandle = data.outputValue( arcLen::output ); outputHandle.set( result ); data.setClean(plug); } } } else { return MS::kUnknownParameter; } return MS::kSuccess; }
// // The span is being setup for evaluation. Just store the start time // and time range over the span. // void interpHalf::initialize(const MObject &animCurve, unsigned int interval) { // Determine whether the span before and span after this span has this // tangent type. If so, begin the interpolation halfway between the // starting keyframe value of this span and the starting keyframe value // of the previous span. Otherwise, just begin this span at the starting // key value. Likewise for the ending key. // Determine the starting time and value. MFnAnimCurve curveFn(animCurve); sTime = curveFn.time(interval).as(MTime::kSeconds); bool isBeforeHalf = false; int beforeInd = interval - 1; if (beforeInd < 0) beforeInd = 0; else { // Check the previous span's tangent type to see if it is this type. MFnAnimCurve::TangentType beforeType = curveFn.outTangentType(beforeInd); if (beforeType == MFnAnimCurve::kTangentShared1) isBeforeHalf = true; } if (isBeforeHalf) beforeVal = 0.5 * curveFn.value(beforeInd) + 0.5 * curveFn.value(interval); else beforeVal = curveFn.value(interval); // Determine the ending value based on its tangent type. int afterInd = interval + 1; MFnAnimCurve::TangentType afterType = curveFn.outTangentType(afterInd); if (afterType == MFnAnimCurve::kTangentShared1) afterVal = 0.5 * curveFn.value(interval) + 0.5 * curveFn.value(afterInd); else afterVal = curveFn.value(afterInd); // Set the time range. range = curveFn.time(afterInd).as(MTime::kSeconds) - sTime; }
MStatus helix2::undoIt() { MStatus status; MFnNurbsCurve curveFn( fDagPath ); status = curveFn.setCVs( fCVs ); if ( MS::kSuccess != status) { cerr << "undoIt: array length is " << fCVs.length() << "bad status: " << status << endl; return status; } status = curveFn.updateCurve(); if ( MS::kSuccess != status ) { cerr << "undoIt: updateCurve() failed status: " << status << endl; return status; } fCVs.clear(); return MS::kSuccess; }
MStatus helix2::redoIt() { unsigned i, numCVs; MStatus status; MFnNurbsCurve curveFn( fDagPath ); numCVs = curveFn.numCVs(); status = curveFn.getCVs( fCVs ); if ( MS::kSuccess != status ) { cerr << "redoIt: could not get cvs status: " << status << endl; return MS::kFailure; } MPointArray points(fCVs); for (i = 0; i < numCVs; i++) points[i] = MPoint( radius * cos( (double)i ), pitch * (double)i, radius * sin( (double)i ) ); status = curveFn.setCVs( points ); if ( MS::kSuccess != status ) { cerr << "redoIt: could not setCVs status: " << status << endl; fCVs.clear(); return status; } status = curveFn.updateCurve(); if ( MS::kSuccess != status ) { cerr << "redoIt: updateCurve() failed status: " << status << endl; return status; } return MS::kSuccess; }
// virtual bool MayaNurbsCurveWriter::writeNurbsCurveAttrs(const UsdTimeCode &usdTime, UsdGeomNurbsCurves &primSchema) { MStatus status = MS::kSuccess; // Write parent class attrs writeTransformAttrs(usdTime, primSchema); // Return if usdTime does not match if shape is animated if (usdTime.IsDefault() == isShapeAnimated() ) { // skip shape as the usdTime does not match if shape isAnimated value return true; } MFnDependencyNode fnDepNode(getDagPath().node(), &status); MString name = fnDepNode.name(); MFnNurbsCurve curveFn( getDagPath(), &status ); if (!status) { MGlobal::displayError("MFnNurbsCurve() failed for MayaNurbsCurveWriter"); return false; } // Get curve attrs ====== unsigned int numCurves = 1; // Assuming only 1 curve for now VtArray<int> curveOrder(numCurves); VtArray<int> curveVertexCounts(numCurves); VtArray<float> curveWidths(numCurves); VtArray<GfVec2d> ranges(numCurves); curveOrder[0] = curveFn.degree()+1; curveVertexCounts[0] = curveFn.numCVs(); TF_AXIOM(curveOrder[0] <= curveVertexCounts[0] ); curveWidths[0] = 1.0; // TODO: Retrieve from custom attr double mayaKnotDomainMin; double mayaKnotDomainMax; status = curveFn.getKnotDomain(mayaKnotDomainMin, mayaKnotDomainMax); TF_AXIOM(status == MS::kSuccess); ranges[0][0] = mayaKnotDomainMin; ranges[0][1] = mayaKnotDomainMax; MPointArray mayaCurveCVs; status = curveFn.getCVs(mayaCurveCVs, MSpace::kObject); TF_AXIOM(status == MS::kSuccess); VtArray<GfVec3f> points(mayaCurveCVs.length()); // all CVs batched together for (unsigned int i=0; i < mayaCurveCVs.length(); i++) { points[i].Set(mayaCurveCVs[i].x, mayaCurveCVs[i].y, mayaCurveCVs[i].z); } MDoubleArray mayaCurveKnots; status = curveFn.getKnots(mayaCurveKnots); TF_AXIOM(status == MS::kSuccess); VtArray<double> curveKnots(mayaCurveKnots.length()); // all knots batched together for (unsigned int i=0; i < mayaCurveKnots.length(); i++) { curveKnots[i] = mayaCurveKnots[i]; } // Gprim VtArray<GfVec3f> extent(2); UsdGeomCurves::ComputeExtent(points, curveWidths, &extent); primSchema.CreateExtentAttr().Set(extent, usdTime); // Curve primSchema.GetOrderAttr().Set(curveOrder); // not animatable primSchema.GetCurveVertexCountsAttr().Set(curveVertexCounts); // not animatable primSchema.GetWidthsAttr().Set(curveWidths); // not animatable primSchema.GetKnotsAttr().Set(curveKnots); // not animatable primSchema.GetRangesAttr().Set(ranges); // not animatable primSchema.GetPointsAttr().Set(points, usdTime); // CVs // TODO: Handle periodic and non-periodic cases return true; }
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; }