MStatus animCube::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(); /* 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"); createMesh(time, newOutputData, returnStatus); McheckErr(returnStatus, "ERROR creating new Cube"); outputHandle.set(newOutputData); data.setClean( plug ); } else return MS::kUnknownParameter; return MS::kSuccess; }
MStatus blindDataMesh::initialize() { MFnTypedAttribute typedAttr; MStatus returnStatus; blindDataMesh::outputMesh = typedAttr.create( "outputMesh", "out", MFnData::kMesh, &returnStatus ); McheckErr(returnStatus, "ERROR creating blindDataMesh output attribute\n"); typedAttr.setStorable(false); returnStatus = addAttribute(blindDataMesh::outputMesh); McheckErr(returnStatus, "ERROR adding outputMesh attribute\n"); MFnNumericAttribute numAttr; blindDataMesh::seed = numAttr.create( "randomSeed", "seed", MFnNumericData::kLong, 0, &returnStatus ); McheckErr(returnStatus, "ERROR creating blindDataMesh input attribute\n"); returnStatus = addAttribute(blindDataMesh::seed); McheckErr(returnStatus, "ERROR adding input attribute\n"); returnStatus = attributeAffects(blindDataMesh::seed, blindDataMesh::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); return MS::kSuccess; }
MStatus animCube::initialize() { MFnUnitAttribute unitAttr; MFnTypedAttribute typedAttr; MStatus returnStatus; animCube::time = unitAttr.create( "time", "tm", MFnUnitAttribute::kTime, 0.0, &returnStatus ); McheckErr(returnStatus, "ERROR creating animCube time attribute\n"); animCube::outputMesh = typedAttr.create( "outputMesh", "out", MFnData::kMesh, &returnStatus ); McheckErr(returnStatus, "ERROR creating animCube output attribute\n"); typedAttr.setStorable(false); returnStatus = addAttribute(animCube::time); McheckErr(returnStatus, "ERROR adding time attribute\n"); returnStatus = addAttribute(animCube::outputMesh); McheckErr(returnStatus, "ERROR adding outputMesh attribute\n"); returnStatus = attributeAffects(animCube::time, animCube::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); return MS::kSuccess; }
MStatus TCC::compute(const MPlug& plug, MDataBlock& data) { MStatus stat; if (plug == aOutputMesh) { /* Get time */ int subdivRes = data.inputValue(aRes, &stat).asInt(); int subdivRefRes = data.inputValue(aRefRes, &stat).asInt(); float lineThickness = data.inputValue(aLineThickness, &stat).asFloat(); MDataHandle inMeshHandle = data.inputValue( aInputMesh, &stat ); McheckErr(stat,"ERROR getting attribute"); MObject inMeshObj = inMeshHandle.asMesh(); MFnMesh inMeshFn(inMeshObj); MIntArray nFV, F; inMeshFn.getVertices(nFV, F); MIntArray nFVc = MFnIntArrayData( data.inputValue( anFVc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MIntArray Fc = MFnIntArrayData( data.inputValue( aFc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MIntArray pole = MFnIntArrayData( data.inputValue( aPole ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MIntArray corner = MFnIntArrayData( data.inputValue( aCorner ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MIntArray T = MFnIntArrayData( data.inputValue( aT ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MIntArray eqc = MFnIntArrayData( data.inputValue( aEqc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MDoubleArray itv = MFnDoubleArrayData( data.inputValue( aItv ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); MIntArray err = MFnIntArrayData( data.inputValue( aErr ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr"); TCCData tccData(nFV, F, nFVc, Fc, pole, corner, T, eqc, itv, err); /* Get output object */ MDataHandle outMeshHandle = data.outputValue(aOutputMesh, &stat); McheckErr(stat, "ERROR getting attribute\n"); if (validTopology(tccData)) { stat = createSubdividedMesh(subdivRes, subdivRefRes, inMeshFn, tccData, outMeshHandle, lineThickness, stat); } else { outMeshHandle.setMObject(inMeshObj); MFnMesh outMeshFn(outMeshHandle.asMesh()); stat = setErrorColors(outMeshFn, tccData); } data.setClean( plug ); } else return MS::kUnknownParameter; return stat; }
MStatus sweptEmitter::emitCountPerPoint ( const MPlug &plug, MDataBlock &block, int length, // length of emitCountPP MIntArray &emitCountPP // output: emitCount for each point ) // // Descriptions: // Compute emitCount for each point where new particles come from. // { MStatus status; int plugIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in emitCountPerPoint: when plug.logicalIndex.\n"); // Get rate and delta time. // double rate = rateValue( block ); MTime dt = deltaTimeValue( plugIndex, block ); // Compute emitCount for each point. // double dblCount = rate * dt.as( MTime::kSeconds ); int intCount = (int)dblCount; for( int i = 0; i < length; i++ ) { emitCountPP.append( intCount ); } return( MS::kSuccess ); }
MStatus blindDataMesh::compute(const MPlug& plug, MDataBlock& data) { MStatus returnStatus; if (plug == outputMesh) { // Get the given random number generator seed. We need to use a // seed, because a pseudo-random number generator will always give // the same random numbers for a constant seed. This means that the // mesh will not change when it is recalculated. // MDataHandle seedHandle = data.inputValue(seed, &returnStatus); McheckErr(returnStatus,"ERROR getting random number generator seed\n"); long seed = seedHandle.asLong(); // Get the handle to the output mesh. The creation of the output mesh // is done in two steps. First, the mesh is created. That involves // calculating the position of the vertices and their connectivity. // // Second, blind data is associated to the vertices on the mesh. // For this example, three double blind data values is associated // to each vertex: "red", "green" and "blue". // MFnMeshData dataCreator; MDataHandle outputHandle = data.outputValue(outputMesh, &returnStatus); McheckErr(returnStatus, "ERROR getting polygon data handle\n"); MObject newOutputData = dataCreator.create(&returnStatus); McheckErr(returnStatus, "ERROR creating outputData"); createMesh(seed, newOutputData, returnStatus); McheckErr(returnStatus, "ERROR creating new plane"); returnStatus = setMeshBlindData(newOutputData); McheckErr(returnStatus, "ERROR setting the blind Data on the plane"); outputHandle.set(newOutputData); data.setClean( plug ); } else return MS::kUnknownParameter; return MS::kSuccess; }
MStatus LSystemNode::compute(const MPlug& plug, MDataBlock& data) { MStatus returnStatus; if (plug == outputMesh) { //angle MDataHandle angleData = data.inputValue(angle,&returnStatus); McheckErr(returnStatus, "Error getting angle data handle\n"); double angle = angleData.asDouble(); //step MDataHandle stepData = data.inputValue(step,&returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); double step = stepData.asDouble(); //grammar MDataHandle grammarData = data.inputValue(grammar,&returnStatus); McheckErr(returnStatus, "Error getting grammar data handle\n"); MString grammar = grammarData.asString(); /* Get time */ MDataHandle timeData = data.inputValue( time, &returnStatus ); McheckErr(returnStatus, "Error getting time data handle\n"); MTime time = timeData.asTime(); /* 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"); createMesh(angle, step, grammar, time, newOutputData, returnStatus); McheckErr(returnStatus, "ERROR creating new Cube"); outputHandle.set(newOutputData); data.setClean( plug ); } else return MS::kUnknownParameter; return MS::kSuccess; }
MStatus LSystemNode::initialize() { MFnUnitAttribute unitAttr; MFnTypedAttribute typedAttr; MFnNumericAttribute numericAttr; MStatus returnStatus; //(i)angle LSystemNode::angle = numericAttr.create("angle","ag",MFnNumericData::kDouble,90.0,&returnStatus); McheckErr(returnStatus, "ERROR creating LSystemNode angle attribute\n"); //(ii)size step = numericAttr.create("step","st",MFnNumericData::kDouble,1.0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSystemNode step attribute\n");//(iv)time //(iii)grammar LSystemNode::grammar = typedAttr.create( "grammar", "grm", MFnData::kString, &returnStatus ); McheckErr(returnStatus, "ERROR creating LSystemNode grammar attribute\n"); //(iv)time LSystemNode::time = unitAttr.create( "time", "tm", MFnUnitAttribute::kTime, 0.0, &returnStatus ); McheckErr(returnStatus, "ERROR creating LSystemNode time attribute\n"); //(v)output LSystemNode::outputMesh = typedAttr.create( "outputMesh", "out", MFnData::kMesh, &returnStatus ); McheckErr(returnStatus, "ERROR creating LSystemNode output attribute\n"); typedAttr.setStorable(false); //(i)angle returnStatus = addAttribute(LSystemNode::angle); McheckErr(returnStatus, "ERROR adding angle attribute\n"); //(ii)step returnStatus = addAttribute(LSystemNode::step); McheckErr(returnStatus, "ERROR adding step attribute\n"); //(iii)grammar returnStatus = addAttribute(LSystemNode::grammar); McheckErr(returnStatus, "ERROR adding grammar attribute\n"); //(iv)time returnStatus = addAttribute(LSystemNode::time); McheckErr(returnStatus, "ERROR adding time attribute\n"); //(v)output returnStatus = addAttribute(LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR adding outputMesh attribute\n"); returnStatus = attributeAffects(LSystemNode::angle,LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); returnStatus = attributeAffects(LSystemNode::step,LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); returnStatus = attributeAffects(LSystemNode::grammar,LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); returnStatus = attributeAffects(LSystemNode::time,LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); return MS::kSuccess; }
MStatus weightList::compute( const MPlug& plug, MDataBlock& block) { MStatus status = MS::kSuccess; unsigned i, j; MObject thisNode = thisMObject(); MPlug wPlug(thisNode, aWeights); // Write into aWeightList for( i = 0; i < 3; i++) { status = wPlug.selectAncestorLogicalIndex( i, aWeightsList ); MDataHandle wHandle = wPlug.constructHandle(block); MArrayDataHandle arrayHandle(wHandle, &status); McheckErr(status, "arrayHandle construction failed\n"); MArrayDataBuilder arrayBuilder = arrayHandle.builder(&status); McheckErr(status, "arrayBuilder accessing/construction failed\n"); for( j = 0; j < i+2; j++) { MDataHandle handle = arrayBuilder.addElement(j,&status); McheckErr(status, "addElement to arrayBuilder failed\n"); float val = 1.0f*(i+j); handle.set(val); } status = arrayHandle.set(arrayBuilder); McheckErr(status, "set arrayBuilder failed\n"); wPlug.setValue(wHandle); wPlug.destructHandle(wHandle); } // Read from aWeightList and print out result MArrayDataHandle arrayHandle = block.inputArrayValue(aWeightsList, &status); McheckErr(status, "arrayHandle construction for aWeightsList failed\n"); unsigned count = arrayHandle.elementCount(); for( i = 0; i < count; i++) { arrayHandle.jumpToElement(i); MDataHandle eHandle = arrayHandle.inputValue(&status).child(aWeights); McheckErr(status, "handle evaluation failed\n"); MArrayDataHandle eArrayHandle(eHandle, &status); McheckErr(status, "arrayHandle construction for aWeights failed\n"); unsigned eCount = eArrayHandle.elementCount(); for( j = 0; j < eCount; j++) { eArrayHandle.jumpToElement(j); float weight = eArrayHandle.inputValue(&status).asFloat(); McheckErr(status, "weight evaluation error\n"); fprintf(stderr, "weightList[%u][%u] = %g\n",i,j,weight); } } // Read from aWeightList and print out result using the more // efficient jumpToArrayElement() call arrayHandle = block.inputArrayValue(aWeightsList, &status); McheckErr(status, "arrayHandle construction for aWeightsList failed\n"); count = arrayHandle.elementCount(); for( i = 0; i < count; i++) { arrayHandle.jumpToArrayElement(i); MDataHandle eHandle = arrayHandle.inputValue(&status).child(aWeights); McheckErr(status, "handle evaluation failed\n"); MArrayDataHandle eArrayHandle(eHandle, &status); McheckErr(status, "arrayHandle construction for aWeights failed\n"); unsigned eCount = eArrayHandle.elementCount(); for( j = 0; j < eCount; j++) { eArrayHandle.jumpToArrayElement(j); float weight = eArrayHandle.inputValue(&status).asFloat(); McheckErr(status, "weight evaluation error\n"); fprintf(stderr, "weightList[%d][%d] = %g\n",i,j,weight); } } return status; }
MStatus tm_noisePerlin::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& /*m*/, unsigned int /*multiIndex*/) { MStatus status = MS::kSuccess; // It's a fake data access try to workaround strange behavior on x86_64 linux systems... MDataHandle dummyData = block.inputValue(dummy,&status); MDataHandle lev_MampData = block.inputValue(lev_Mamp,&status); McheckErr(status, "Error getting lev_Mamp data handle\n"); double _lev_Mamp = lev_MampData.asDouble(); MDataHandle lev_MfreqData = block.inputValue(lev_Mfreq,&status); McheckErr(status, "Error getting lev_Mfreq data handle\n"); double lev_Mfreq = lev_MfreqData.asDouble(); MDataHandle levelsData = block.inputValue(levels,&status); McheckErr(status, "Error getting frequency data handle\n"); short levels = levelsData.asShort(); MDataHandle scaleData = block.inputValue(scale,&status); McheckErr(status, "Error getting scale data handle\n"); double scale = scaleData.asDouble(); MDataHandle scaleAmpXData = block.inputValue(scaleAmpX,&status); McheckErr(status, "Error getting scaleAmpX data handle\n"); double scaleAmpX = scaleAmpXData.asDouble(); MDataHandle scaleAmpYData = block.inputValue(scaleAmpY,&status); McheckErr(status, "Error getting scaleAmpY data handle\n"); double scaleAmpY = scaleAmpYData.asDouble(); MDataHandle scaleAmpZData = block.inputValue(scaleAmpZ,&status); McheckErr(status, "Error getting scaleAmpZ data handle\n"); double scaleAmpZ = scaleAmpZData.asDouble(); MDataHandle scaleFreqXData = block.inputValue(scaleFreqX,&status); McheckErr(status, "Error getting scaleFreqX data handle\n"); double scaleFreqX = scaleFreqXData.asDouble(); MDataHandle scaleFreqYData = block.inputValue(scaleFreqY,&status); McheckErr(status, "Error getting scaleFreqY data handle\n"); double scaleFreqY = scaleFreqYData.asDouble(); MDataHandle scaleFreqZData = block.inputValue(scaleFreqZ,&status); McheckErr(status, "Error getting scaleFreqZ data handle\n"); double scaleFreqZ = scaleFreqZData.asDouble(); MDataHandle variationData = block.inputValue(variation,&status); McheckErr(status, "Error getting variation data handle\n"); double variation = variationData.asDouble(); MDataHandle envData = block.inputValue(envelope,&status); McheckErr(status, "Error getting envelope data handle\n"); double env = envData.asDouble(); MDataHandle amplitudeData = block.inputValue(amplitude,&status); McheckErr(status, "Error getting amplitude data handle\n"); double amplitude = amplitudeData.asDouble(); MDataHandle frequencyData = block.inputValue(frequency,&status); McheckErr(status, "Error getting frequency data handle\n"); double frequency = frequencyData.asDouble(); amplitude = amplitude * scale; frequency = frequency * 0.01 / scale; for ( ; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); vector noisePnt; noisePnt.x = 0; noisePnt.y = 0; noisePnt.z = 0; double l_amp = amplitude; double x = scaleFreqX * pt.x * frequency; double y = scaleFreqY * pt.y * frequency; double z = scaleFreqZ * pt.z * frequency; for( int lev = 0; lev < levels; lev++) { x *= lev_Mfreq; y *= lev_Mfreq; z *= lev_Mfreq; vector lev_Pnt = INoise::noise4d_v(x, y, z, variation); noisePnt.x += lev_Pnt.x * l_amp; noisePnt.y += lev_Pnt.y * l_amp; noisePnt.z += lev_Pnt.z * l_amp; l_amp *= _lev_Mamp; } pt.x += noisePnt.x * scaleAmpX; pt.y += noisePnt.y * scaleAmpY; pt.z += noisePnt.z * scaleAmpZ; iter.setPosition(pt); } return status; }
MStatus pointOnSubd::initialize() // // Description: // This method is called to create and initialize all of the attributes // and attribute dependencies for this node type. This is only called // once when the node type is registered with Maya. // // Return Values: // MS::kSuccess // MS::kFailure // { MStatus stat; MFnTypedAttribute subdAttr; aSubd = subdAttr.create( "subd", "s", MFnSubdData::kSubdSurface, &stat ); McheckErr( stat, "cannot create pointOnSubd::aSubd" ); subdAttr.setStorable(true); subdAttr.setKeyable(false); subdAttr.setReadable( true ); subdAttr.setWritable( true ); subdAttr.setCached( false ); stat = addAttribute( pointOnSubd::aSubd ); McheckErr( stat, "cannot add pointOnSubd::aSubd" ); MFnNumericAttribute faceFirstAttr; aFaceFirst = faceFirstAttr.create( "faceFirst", "ff", MFnNumericData::kLong, 0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aFaceFirst" ); faceFirstAttr.setStorable(true); faceFirstAttr.setKeyable(true); faceFirstAttr.setSoftMin( 0.0 ); faceFirstAttr.setReadable( true ); faceFirstAttr.setWritable( true ); faceFirstAttr.setCached( false ); stat = addAttribute( pointOnSubd::aFaceFirst ); McheckErr( stat, "cannot add pointOnSubd::aFaceFirst" ); MFnNumericAttribute faceSecondAttr; aFaceSecond = faceSecondAttr.create( "faceSecond", "fs", MFnNumericData::kLong, 0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aFaceSecond" ); faceSecondAttr.setStorable(true); faceSecondAttr.setKeyable(true); faceSecondAttr.setSoftMin( 0.0 ); faceSecondAttr.setReadable( true ); faceSecondAttr.setWritable( true ); faceSecondAttr.setCached( false ); stat = addAttribute( pointOnSubd::aFaceSecond ); McheckErr( stat, "cannot add pointOnSubd::aFaceSecond" ); MFnNumericAttribute uAttr; aU = uAttr.create( "uValue", "u", MFnNumericData::kDouble, 0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aU" ); uAttr.setStorable(true); uAttr.setKeyable(true); uAttr.setSoftMin( 0.0 ); uAttr.setSoftMax( 1.0 ); uAttr.setReadable( true ); uAttr.setWritable( true ); uAttr.setCached( false ); stat = addAttribute( aU ); McheckErr( stat, "cannot add pointOnSubd::aU" ); MFnNumericAttribute vAttr; aV = vAttr.create( "vValue", "v", MFnNumericData::kDouble, 0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aV" ); vAttr.setStorable(true); vAttr.setKeyable(true); vAttr.setSoftMin( 0.0 ); vAttr.setSoftMax( 1.0 ); vAttr.setReadable( true ); vAttr.setWritable( true ); vAttr.setCached( false ); stat = addAttribute( aV ); McheckErr( stat, "cannot add pointOnSubd::aV" ); MFnNumericAttribute relAttr; aRelativeUV = relAttr.create( "relative", "rel", MFnNumericData::kBoolean, 0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aRelativeUV" ); relAttr.setStorable(true); relAttr.setKeyable(true); relAttr.setSoftMin( 0.0 ); relAttr.setSoftMax( 1.0 ); relAttr.setReadable( true ); relAttr.setWritable( true ); relAttr.setCached( false ); stat = addAttribute( pointOnSubd::aRelativeUV ); McheckErr( stat, "cannot add pointOnSubd::aRelativeUV" ); MFnNumericAttribute pointXAttr; aPointX = pointXAttr.create( "pointX", "px", MFnNumericData::kDouble, 0.0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aPointX" ); pointXAttr.setWritable(false); pointXAttr.setStorable(false); pointXAttr.setReadable( true ); pointXAttr.setCached( true ); stat = addAttribute( aPointX ); McheckErr( stat, "cannot add pointOnSubd::aPointX" ); MFnNumericAttribute pointYAttr; aPointY = pointYAttr.create( "pointY", "py", MFnNumericData::kDouble, 0.0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aPointY" ); pointYAttr.setWritable(false); pointYAttr.setStorable(false); pointYAttr.setReadable( true ); pointYAttr.setCached( true ); stat = addAttribute( aPointY ); McheckErr( stat, "cannot add pointOnSubd::aPointY" ); MFnNumericAttribute pointZAttr; aPointZ = pointZAttr.create( "pointZ", "pz", MFnNumericData::kDouble, 0.0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aPointZ" ); pointZAttr.setWritable(false); pointZAttr.setStorable(false); pointZAttr.setReadable( true ); pointZAttr.setCached( true ); stat = addAttribute( aPointZ ); McheckErr( stat, "cannot add pointOnSubd::aPointZ" ); MFnNumericAttribute pointAttr; aPoint = pointAttr.create( "point", "p", aPointX, aPointY, aPointZ, &stat); McheckErr( stat, "cannot create pointOnSubd::aPoint" ); pointAttr.setWritable(false); pointAttr.setStorable(false); pointAttr.setReadable( true ); pointAttr.setCached( true ); stat = addAttribute( aPoint ); McheckErr( stat, "cannot add pointOnSubd::aPoint" ); MFnNumericAttribute normalXAttr; aNormalX = normalXAttr.create( "normalX", "nx", MFnNumericData::kDouble, 0.0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aNormal" ); normalXAttr.setWritable(false); normalXAttr.setStorable(false); normalXAttr.setReadable( true ); normalXAttr.setCached( true ); stat = addAttribute( aNormalX ); McheckErr( stat, "cannot add pointOnSubd::aNormalX" ); MFnNumericAttribute normalYAttr; aNormalY = normalYAttr.create( "normalY", "ny", MFnNumericData::kDouble, 0.0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aNormal" ); normalYAttr.setWritable(false); normalYAttr.setStorable(false); normalYAttr.setReadable( true ); normalYAttr.setCached( true ); stat = addAttribute( aNormalY ); McheckErr( stat, "cannot add pointOnSubd::aNormalY" ); MFnNumericAttribute normalZAttr; aNormalZ = normalZAttr.create( "normalZ", "nz", MFnNumericData::kDouble, 0.0, &stat ); McheckErr( stat, "cannot create pointOnSubd::aNormal" ); normalZAttr.setWritable(false); normalZAttr.setStorable(false); normalZAttr.setReadable( true ); normalZAttr.setCached( true ); stat = addAttribute( aNormalZ ); McheckErr( stat, "cannot add pointOnSubd::aNormalZ" ); MFnNumericAttribute normalAttr; aNormal = normalAttr.create("normal","n",aNormalX,aNormalY,aNormalZ,&stat); McheckErr( stat, "cannot create pointOnSubd::aNormal" ); normalAttr.setWritable(false); normalAttr.setStorable(false); normalAttr.setReadable( true ); normalAttr.setCached( true ); stat = addAttribute( aNormal ); McheckErr( stat, "cannot add pointOnSubd::aNormal" ); // Set up a dependency between the input and the output. This will cause // the output to be marked dirty when the input changes. The output will // then be recomputed the next time the value of the output is requested. // stat = attributeAffects( aSubd, aPoint ); stat = attributeAffects( aSubd, aPointX ); stat = attributeAffects( aSubd, aPointY ); stat = attributeAffects( aSubd, aPointZ ); stat = attributeAffects( aSubd, aNormal ); stat = attributeAffects( aSubd, aNormalX ); stat = attributeAffects( aSubd, aNormalY ); stat = attributeAffects( aSubd, aNormalZ ); stat = attributeAffects( aFaceFirst, aPoint ); stat = attributeAffects( aFaceFirst, aPointX ); stat = attributeAffects( aFaceFirst, aPointY ); stat = attributeAffects( aFaceFirst, aPointZ ); stat = attributeAffects( aFaceFirst, aNormal ); stat = attributeAffects( aFaceFirst, aNormalX ); stat = attributeAffects( aFaceFirst, aNormalY ); stat = attributeAffects( aFaceFirst, aNormalZ ); stat = attributeAffects( aFaceSecond, aPoint ); stat = attributeAffects( aFaceSecond, aPointX ); stat = attributeAffects( aFaceSecond, aPointY ); stat = attributeAffects( aFaceSecond, aPointZ ); stat = attributeAffects( aFaceSecond, aNormal ); stat = attributeAffects( aFaceSecond, aNormalX ); stat = attributeAffects( aFaceSecond, aNormalY ); stat = attributeAffects( aFaceSecond, aNormalZ ); stat = attributeAffects( aU, aPoint ); stat = attributeAffects( aU, aPointX ); stat = attributeAffects( aU, aPointY ); stat = attributeAffects( aU, aPointZ ); stat = attributeAffects( aU, aNormal ); stat = attributeAffects( aU, aNormalX ); stat = attributeAffects( aU, aNormalY ); stat = attributeAffects( aU, aNormalZ ); stat = attributeAffects( aV, aPoint ); stat = attributeAffects( aV, aPointX ); stat = attributeAffects( aV, aPointY ); stat = attributeAffects( aV, aPointZ ); stat = attributeAffects( aV, aNormal ); stat = attributeAffects( aV, aNormalX ); stat = attributeAffects( aV, aNormalY ); stat = attributeAffects( aV, aNormalZ ); stat = attributeAffects( aRelativeUV, aPoint ); stat = attributeAffects( aRelativeUV, aPointX ); stat = attributeAffects( aRelativeUV, aPointY ); stat = attributeAffects( aRelativeUV, aPointZ ); stat = attributeAffects( aRelativeUV, aNormal ); stat = attributeAffects( aRelativeUV, aNormalX ); stat = attributeAffects( aRelativeUV, aNormalY ); stat = attributeAffects( aRelativeUV, aNormalZ ); return MS::kSuccess; }
MStatus LSSolverNode::compute(const MPlug& plug, MDataBlock& data) { MStatus stat; if( plug == deformed) { MDataHandle tetWorldMatrixData = data.inputValue(tetWorldMatrix, &returnStatus); McheckErr(returnStatus, "Error getting tetWorldMatrix data handle\n"); MDataHandle restShapeData = data.inputValue(restShape, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle restVerticesData = data.inputValue(restVertices, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle restElementsData = data.inputValue(restElements, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle selectedConstraintVertsData = data.inputValue(selectedConstraintVerts, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle selectedForceVertsData = data.inputValue(selectedForceVerts, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle timeData = data.inputValue(time, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle outputMeshData = data.outputValue(deformed, &returnStatus); McheckErr(returnStatus, "Error getting outputMesh data handle\n"); MMatrix twmat = tetWorldMatrixData.asMatrix(); MObject rs = restShapeData.asMesh(); double t = timeData.asDouble(); MDataHandle poissonRatioData = data.inputValue(poissonRatio, &returnStatus); McheckErr(returnStatus, "Error getting poissonRatio data handle\n"); MDataHandle youngsModulusData = data.inputValue(youngsModulus, &returnStatus); McheckErr(returnStatus, "Error getting youngsmodulus data handle\n"); MDataHandle objectDensityData = data.inputValue(objectDensity, &returnStatus); McheckErr(returnStatus, "Error getting objectDensity data handle\n"); MDataHandle frictionData = data.inputValue(friction, &returnStatus); McheckErr(returnStatus, "Error getting friction data handle\n"); MDataHandle restitutionData = data.inputValue(restitution, &returnStatus); McheckErr(returnStatus, "Error getting restitution data handle\n"); MDataHandle dampingData = data.inputValue(damping, &returnStatus); McheckErr(returnStatus, "Error getting damping data handle\n"); MDataHandle userSuppliedDtData = data.inputValue(userSuppliedDt, &returnStatus); McheckErr(returnStatus, "Error getting user supplied dt data handle\n"); MDataHandle integrationTypeData = data.inputValue(integrationType, &returnStatus); McheckErr(returnStatus, "Error getting user integrationTypeData\n"); MDataHandle forceModelTypeData = data.inputValue(forceModelType, &returnStatus); McheckErr(returnStatus, "Error getting user forceModelTypeData\n"); MDataHandle forceApplicationTimeData = data.inputValue(forceApplicationTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceApplicationTime\n"); MDataHandle forceReleasedTimeData = data.inputValue(forceReleasedTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceReleasedTime\n"); MDataHandle forceIncrementTimeData = data.inputValue(forceIncrementTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceIncrementTime\n"); MDataHandle forceStartTimeData = data.inputValue(forceStartTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceStartTime\n"); MDataHandle forceStopTimeData = data.inputValue(forceStopTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceStopTime\n"); MDataHandle forceMagnitudeData = data.inputValue(forceMagnitude, &returnStatus); McheckErr(returnStatus, "Error getting user forceIdleTime\n"); MDataHandle useSuppliedForceData = data.inputValue(useSuppliedForce, &returnStatus); McheckErr(returnStatus, "Error getting user forceIdleTime\n"); MDataHandle useSuppliedConstraintsData = data.inputValue(useSuppliedConstraints, &returnStatus); McheckErr(returnStatus, "Error getting user forceIdleTime\n"); MDataHandle forceDirectionData = data.inputValue(forceDirection, &returnStatus); McheckErr(returnStatus, "Error getting user forceDirection\n"); MDataHandle contactKsData = data.inputValue(contactKs, &returnStatus); McheckErr(returnStatus, "Error getting user forceDirection\n"); MDataHandle contactKdData = data.inputValue(contactKd, &returnStatus); McheckErr(returnStatus, "Error getting user forceDirection\n"); MTime currentTime, maxTime; currentTime = MAnimControl::currentTime(); maxTime = MAnimControl::maxTime(); if (currentTime == MAnimControl::minTime()) { // retrive restVertices and restElements sTime=0; MFnDoubleArrayData restVertArrayData(restVerticesData.data()); MDoubleArray verts = restVertArrayData.array(); int vertArrayLen = verts.length(); double *vertArray = new double[vertArrayLen]; verts.get(vertArray); for(int v=0;v<vertArrayLen;v=v+3) { MPoint mpoint = MPoint(vertArray[v],vertArray[v+1],vertArray[v+2])*twmat; vertArray[v] = mpoint.x; vertArray[v+1] = mpoint.y; vertArray[v+2] = mpoint.z; } MFnIntArrayData restEleArrayData(restElementsData.data()); MIntArray ele = restEleArrayData.array(); int eleArrayLen = ele.length(); int *eleArray = new int[eleArrayLen]; ele.get(eleArray); MFnIntArrayData selectedConstraintVertsArrayData(selectedConstraintVertsData.data()); MIntArray sv = selectedConstraintVertsArrayData.array(); // building selectedConstraintVerts vector<int> selectedConstraintVertIndices; for (int i = 0 ; i < sv.length() ; i++) { selectedConstraintVertIndices.push_back(sv[i]); } MGlobal::displayInfo("!!!!!"); //std::string tmp=std::to_string((long double)selectedConstraintVertIndices.size()); //MGlobal::displayInfo(MString(tmp.c_str())); //std::cout<<currentConstriant<<" up"<<std::endl; for(int i=0;i<constraintIndex[currentConstriant].size();i++){ if(domainParentIndex[currentConstriant]==-1) selectedConstraintVertIndices.push_back(constraintIndex[currentConstriant][i]); //std::cout<<constraintIndex[currentConstriant][i]<<std::endl; } //std::cout<<currentConstriant<<" up"<<std::endl; /*for(int i=0;i<10;i++){ selectedConstraintVertIndices.push_back(i+1); }*/ MFnIntArrayData selectedForceVertsArrayData(selectedForceVertsData.data()); MIntArray sf = selectedForceVertsArrayData.array(); vector<int> selectedForceVertIndices; for (int i = 0 ; i < sf.length() ; i++) { selectedForceVertIndices.push_back(sf[i]); } // temporarily create force direction vector double *forceDir = forceDirectionData.asDouble3(); vector<double> dir; dir.push_back(forceDir[0]); dir.push_back(forceDir[1]);dir.push_back(forceDir[2]); prevDeformed = 0; double youngsModulusDouble = youngsModulusData.asDouble(); double poissonRatioDouble = poissonRatioData.asDouble(); double objectDensityDouble = objectDensityData.asDouble(); double frictionDouble = frictionData.asDouble(); double restitutionDouble = restitutionData.asDouble(); double dampingDouble = dampingData.asDouble(); double userSuppliedDtDouble = userSuppliedDtData.asDouble(); double forceMagnitudeDouble = forceMagnitudeData.asDouble(); int fAppT = forceApplicationTimeData.asInt(); int fReleasedT = forceReleasedTimeData.asInt(); int fIncT = forceIncrementTimeData.asInt(); int fStartT = forceStartTimeData.asInt(); int fStopT = forceStopTimeData.asInt(); int integrationTypeInt = integrationTypeData.asShort(); int forceModelTypeInt = forceModelTypeData.asShort(); bool useSuppliedForceBool = useSuppliedForceData.asBool(); bool useSuppliedConstraintsBool = useSuppliedConstraintsData.asBool(); double contactKs = contactKsData.asDouble(); double contactKd = contactKdData.asDouble(); if( sm) { delete sm; } sm = new SoftBodySim(youngsModulusDouble,poissonRatioDouble,objectDensityDouble, frictionDouble,restitutionDouble,dampingDouble, eleArrayLen, eleArray, vertArrayLen, vertArray,integrationTypeInt,forceModelTypeInt); sm->setContactAttributes(contactKs,contactKd); if (useSuppliedConstraintsBool) sm->initialize("",userSuppliedDtDouble, selectedConstraintVertIndices); else { vector<int> empty; sm->initialize("",userSuppliedDtDouble, empty); } if (useSuppliedForceBool) sm->setUserForceAttributes(forceMagnitudeDouble, dir,selectedForceVertIndices,fAppT,fReleasedT,fIncT,fStartT,fStopT); std::vector<int> childList=fdg.GetDomainChild(currentConstriant); if(childList.size()!=0){//not the root for(int i=0;i<childList.size();i++){ int childIndex=-1; for(int j=0;j<fdomain_list.size();j++){ if(fdomain_list[j]->index==childList[i]){ childIndex=j; } }//j glm::dvec3 oldPos=glm::dvec3(0,0,0); for(int j=0;j<parentConstraintIndex[childIndex].size();j++){ int index=3*parentConstraintIndex[childIndex][j]; oldPos.x+=sm->m_vertices[index]; oldPos.y+=sm->m_vertices[index+1]; oldPos.z+=sm->m_vertices[index+2]; } oldPos=oldPos*(1.0/parentConstraintIndex[childIndex].size()); parentLastPosOld[childIndex]=oldPos; parentLastPosNew[childIndex]=oldPos; }//i } domainID=currentConstriant; currentConstriant++; if(currentConstriant==fdomain_list.size()) currentConstriant=0; } else { std::vector<int> childList=fdg.GetDomainChild(domainID); if(childList.size()!=0){//not the root for(int i=0;i<childList.size();i++){ int childIndex=-1; for(int j=0;j<fdomain_list.size();j++){ if(fdomain_list[j]->index==childList[i]){ childIndex=j; } }//j glm::dvec3 newPos=glm::dvec3(0,0,0); for(int j=0;j<parentConstraintIndex[childIndex].size();j++){ int index=3*parentConstraintIndex[childIndex][j]; newPos.x+=sm->m_vertices[index]; newPos.y+=sm->m_vertices[index+1]; newPos.z+=sm->m_vertices[index+2]; } //std::cout<<newPos.x<<","<<newPos.y<<","<<newPos.z<<std::endl; newPos=newPos*(1.0/parentConstraintIndex[childIndex].size()); parentLastPosOld[childIndex]=parentLastPosNew[childIndex]; parentLastPosNew[childIndex]=newPos; }//i } //update the parents' fixed point moving distance std::vector<float> pos; int num=0; if(domainParentIndex[domainID]!=-1){//has parent for(int i=0;i<constraintIndex[domainID].size();i++){ int index=3*constraintIndex[domainID][i]; pos.push_back(sm->m_vertices[index]); pos.push_back(sm->m_vertices[index+1]); pos.push_back(sm->m_vertices[index+2]); } } sm->update(sTime); sTime++; if(domainParentIndex[domainID]!=-1){//has parent //std::cout<<sm->numOfVertices<<std::endl; for(int i=0;i<constraintIndex[domainID].size();i++){ int index=3*constraintIndex[domainID][i]; if(index>3*sm->numOfVertices) std::cout<<index-3*sm->numOfVertices<<"big "<<currentConstriant<<std::endl; glm::dvec3 movePos=parentLastPosNew[domainID]-parentLastPosOld[domainID]; //std::cout<<sm->m_vertices[index]<<","<<sm->m_vertices[index+1]<<","<<sm->m_vertices[index+2]<<std::endl; sm->m_vertices[index]=pos[num++]+movePos.x; sm->m_vertices[index+1]=pos[num++]+movePos.y; sm->m_vertices[index+2]=pos[num++]+movePos.z; //std::cout<<sm->m_vertices[index]<<","<<sm->m_vertices[index+1]<<","<<sm->m_vertices[index+2]<<"end"<<std::endl; //std::cout<<constraintIndex[domainID][i]<<std::endl; } } } MFnMesh surfFn(rs,&stat); McheckErr( stat, "compute - MFnMesh error" ); MFnMeshData ouputMeshDataCreator; MObject oMesh = ouputMeshDataCreator.create(&stat); buildOutputMesh(surfFn, sm->m_vertices,oMesh); outputMeshData.set(oMesh); data.setClean(plug); } else stat = MS::kUnknownParameter; return stat; }
MStatus LSSolverNode::compute(const MPlug& plug, MDataBlock& data) { MStatus stat; if( plug == deformed) { MDataHandle tetWorldMatrixData = data.inputValue(tetWorldMatrix, &returnStatus); McheckErr(returnStatus, "Error getting tetWorldMatrix data handle\n"); MDataHandle restShapeData = data.inputValue(restShape, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle restVerticesData = data.inputValue(restVertices, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle restElementsData = data.inputValue(restElements, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle selectedConstraintVertsData = data.inputValue(selectedConstraintVerts, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle selectedForceVertsData = data.inputValue(selectedForceVerts, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle timeData = data.inputValue(time, &returnStatus); McheckErr(returnStatus, "Error getting step data handle\n"); MDataHandle outputMeshData = data.outputValue(deformed, &returnStatus); McheckErr(returnStatus, "Error getting outputMesh data handle\n"); MMatrix twmat = tetWorldMatrixData.asMatrix(); MObject rs = restShapeData.asMesh(); double t = timeData.asDouble(); MDataHandle poissonRatioData = data.inputValue(poissonRatio, &returnStatus); McheckErr(returnStatus, "Error getting poissonRatio data handle\n"); MDataHandle youngsModulusData = data.inputValue(youngsModulus, &returnStatus); McheckErr(returnStatus, "Error getting youngsmodulus data handle\n"); MDataHandle objectDensityData = data.inputValue(objectDensity, &returnStatus); McheckErr(returnStatus, "Error getting objectDensity data handle\n"); MDataHandle frictionData = data.inputValue(friction, &returnStatus); McheckErr(returnStatus, "Error getting friction data handle\n"); MDataHandle restitutionData = data.inputValue(restitution, &returnStatus); McheckErr(returnStatus, "Error getting restitution data handle\n"); MDataHandle dampingData = data.inputValue(damping, &returnStatus); McheckErr(returnStatus, "Error getting damping data handle\n"); MDataHandle userSuppliedDtData = data.inputValue(userSuppliedDt, &returnStatus); McheckErr(returnStatus, "Error getting user supplied dt data handle\n"); MDataHandle integrationTypeData = data.inputValue(integrationType, &returnStatus); McheckErr(returnStatus, "Error getting user integrationTypeData\n"); MDataHandle forceModelTypeData = data.inputValue(forceModelType, &returnStatus); McheckErr(returnStatus, "Error getting user forceModelTypeData\n"); MDataHandle forceApplicationTimeData = data.inputValue(forceApplicationTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceApplicationTime\n"); MDataHandle forceReleasedTimeData = data.inputValue(forceReleasedTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceReleasedTime\n"); MDataHandle forceIncrementTimeData = data.inputValue(forceIncrementTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceIncrementTime\n"); MDataHandle forceStartTimeData = data.inputValue(forceStartTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceStartTime\n"); MDataHandle forceStopTimeData = data.inputValue(forceStopTime, &returnStatus); McheckErr(returnStatus, "Error getting user forceStopTime\n"); MDataHandle forceMagnitudeData = data.inputValue(forceMagnitude, &returnStatus); McheckErr(returnStatus, "Error getting user forceIdleTime\n"); MDataHandle useSuppliedForceData = data.inputValue(useSuppliedForce, &returnStatus); McheckErr(returnStatus, "Error getting user forceIdleTime\n"); MDataHandle useSuppliedConstraintsData = data.inputValue(useSuppliedConstraints, &returnStatus); McheckErr(returnStatus, "Error getting user forceIdleTime\n"); MDataHandle forceDirectionData = data.inputValue(forceDirection, &returnStatus); McheckErr(returnStatus, "Error getting user forceDirection\n"); MDataHandle contactKsData = data.inputValue(contactKs, &returnStatus); McheckErr(returnStatus, "Error getting user forceDirection\n"); MDataHandle contactKdData = data.inputValue(contactKd, &returnStatus); McheckErr(returnStatus, "Error getting user forceDirection\n"); MTime currentTime, maxTime; currentTime = MAnimControl::currentTime(); maxTime = MAnimControl::maxTime(); if (currentTime == MAnimControl::minTime()) { // retrive restVertices and restElements MFnDoubleArrayData restVertArrayData(restVerticesData.data()); MDoubleArray verts = restVertArrayData.array(); int vertArrayLen = verts.length(); double *vertArray = new double[vertArrayLen]; verts.get(vertArray); for(int v=0;v<vertArrayLen;v=v+3) { MPoint mpoint = MPoint(vertArray[v],vertArray[v+1],vertArray[v+2])*twmat; vertArray[v] = mpoint.x; vertArray[v+1] = mpoint.y; vertArray[v+2] = mpoint.z; } MFnIntArrayData restEleArrayData(restElementsData.data()); MIntArray ele = restEleArrayData.array(); int eleArrayLen = ele.length(); int *eleArray = new int[eleArrayLen]; ele.get(eleArray); MFnIntArrayData selectedConstraintVertsArrayData(selectedConstraintVertsData.data()); MIntArray sv = selectedConstraintVertsArrayData.array(); // building selectedConstraintVerts vector<int> selectedConstraintVertIndices; for (int i = 0 ; i < sv.length() ; i++) { selectedConstraintVertIndices.push_back(sv[i]); } MFnIntArrayData selectedForceVertsArrayData(selectedForceVertsData.data()); MIntArray sf = selectedForceVertsArrayData.array(); vector<int> selectedForceVertIndices; for (int i = 0 ; i < sf.length() ; i++) { selectedForceVertIndices.push_back(sf[i]); } // temporarily create force direction vector double *forceDir = forceDirectionData.asDouble3(); vector<double> dir; dir.push_back(forceDir[0]); dir.push_back(forceDir[1]);dir.push_back(forceDir[2]); prevDeformed = 0; double youngsModulusDouble = youngsModulusData.asDouble(); double poissonRatioDouble = poissonRatioData.asDouble(); double objectDensityDouble = objectDensityData.asDouble(); double frictionDouble = frictionData.asDouble(); double restitutionDouble = restitutionData.asDouble(); double dampingDouble = dampingData.asDouble(); double userSuppliedDtDouble = userSuppliedDtData.asDouble(); double forceMagnitudeDouble = forceMagnitudeData.asDouble(); int fAppT = forceApplicationTimeData.asInt(); int fReleasedT = forceReleasedTimeData.asInt(); int fIncT = forceIncrementTimeData.asInt(); int fStartT = forceStartTimeData.asInt(); int fStopT = forceStopTimeData.asInt(); int integrationTypeInt = integrationTypeData.asShort(); int forceModelTypeInt = forceModelTypeData.asShort(); bool useSuppliedForceBool = useSuppliedForceData.asBool(); bool useSuppliedConstraintsBool = useSuppliedConstraintsData.asBool(); double contactKs = contactKsData.asDouble(); double contactKd = contactKdData.asDouble(); if( sm) { delete sm; } sm = new SoftBodySim(youngsModulusDouble,poissonRatioDouble,objectDensityDouble, frictionDouble,restitutionDouble,dampingDouble, eleArrayLen, eleArray, vertArrayLen, vertArray,integrationTypeInt,forceModelTypeInt); sm->setContactAttributes(contactKs,contactKd); if (useSuppliedConstraintsBool) sm->initialize("",userSuppliedDtDouble, selectedConstraintVertIndices); else { vector<int> empty; sm->initialize("",userSuppliedDtDouble, empty); } if (useSuppliedForceBool) sm->setUserForceAttributes(forceMagnitudeDouble, dir,selectedForceVertIndices,fAppT,fReleasedT,fIncT,fStartT,fStopT); } else { sm->update(); } MFnMesh surfFn(rs,&stat); McheckErr( stat, "compute - MFnMesh error" ); MFnMeshData ouputMeshDataCreator; MObject oMesh = ouputMeshDataCreator.create(&stat); buildOutputMesh(surfFn, sm->m_vertices,oMesh); outputMeshData.set(oMesh); data.setClean(plug); } else stat = MS::kUnknownParameter; return stat; }
// add some additional inputs MStatus HRBFSkinCluster::initialize() { std::cout << "called initialize" << std::endl; MFnNumericAttribute numAttr; MFnTypedAttribute typedAttr; //MFnCompoundAttribute cmpdAttr; MStatus returnStatus; HRBFSkinCluster::rebuildHRBF = numAttr.create("RebuildHRBF", "rbld", MFnNumericData::kInt, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating rbld attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::rebuildHRBF); McheckErr(returnStatus, "ERROR adding rbld attribute\n"); HRBFSkinCluster::exportComposition = numAttr.create("ExportComp", "exprtC", MFnNumericData::kInt, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating exprtC attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::exportComposition); McheckErr(returnStatus, "ERROR adding exprtC attribute\n"); HRBFSkinCluster::exportHRBFSamples = typedAttr.create("ExportHRBFs", "exprtS", MFnNumericData::kString, &returnStatus); McheckErr(returnStatus, "ERROR creating exprtS attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::exportHRBFSamples); McheckErr(returnStatus, "ERROR adding exprtS attribute\n"); HRBFSkinCluster::exportHRBFValues = typedAttr.create("ExportHRBFv", "exprtV", MFnNumericData::kString, &returnStatus); McheckErr(returnStatus, "ERROR creating exprtV attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::exportHRBFValues); McheckErr(returnStatus, "ERROR adding exprtV attribute\n"); HRBFSkinCluster::useDQ = numAttr.create("UseDualQuaternions", "useDQ", MFnNumericData::kInt, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating useDQ attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::useDQ); McheckErr(returnStatus, "ERROR adding useDQ attribute\n"); HRBFSkinCluster::useHRBF = numAttr.create("UseHRBFCorrection", "useHRBF", MFnNumericData::kInt, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating useHRBF attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::useHRBF); McheckErr(returnStatus, "ERROR adding useHRBF attribute\n"); HRBFSkinCluster::checkHRBFAt = numAttr.create("checkHRBFAt", "chkHRBF", MFnNumericData::k3Double, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating checkHRBFAt attribute\n"); returnStatus = addAttribute(HRBFSkinCluster::checkHRBFAt); McheckErr(returnStatus, "ERROR adding checkHRBFAt attribute\n"); // hierarchy information // http://download.autodesk.com/us/maya/2011help/API/weight_list_node_8cpp-example.html#a15 HRBFSkinCluster::jointParentIdcs = numAttr.create("parentJointIDCS", "pJIDCS", MFnNumericData::kInt, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating pIDCS attribute\n"); numAttr.setArray(true); returnStatus = addAttribute(HRBFSkinCluster::jointParentIdcs); McheckErr(returnStatus, "ERROR adding pIDCS attribute\n"); // joint names HRBFSkinCluster::jointNames = typedAttr.create("jointNames", "jNms", MFnData::kString, &returnStatus); McheckErr(returnStatus, "ERROR creating pIDCS attribute\n"); typedAttr.setArray(true); returnStatus = addAttribute(HRBFSkinCluster::jointNames); McheckErr(returnStatus, "ERROR adding jNms attribute\n"); // set up affects returnStatus = attributeAffects(HRBFSkinCluster::rebuildHRBF, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with rebuildHRBF\n"); returnStatus = attributeAffects(HRBFSkinCluster::exportComposition, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with exportComposition\n"); returnStatus = attributeAffects(HRBFSkinCluster::exportHRBFSamples, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with exportHRBFSamples\n"); returnStatus = attributeAffects(HRBFSkinCluster::exportHRBFValues, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with exportHRBFValues\n"); returnStatus = attributeAffects(HRBFSkinCluster::useDQ, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with useDQ\n"); returnStatus = attributeAffects(HRBFSkinCluster::useHRBF, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with useHRBF\n"); returnStatus = attributeAffects(HRBFSkinCluster::jointParentIdcs, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with jointParentIdcs\n"); returnStatus = attributeAffects(HRBFSkinCluster::checkHRBFAt, HRBFSkinCluster::outputGeom); McheckErr(returnStatus, "ERROR in attributeAffects with checkHRBFAt\n"); return returnStatus; }
MStatus HRBFSkinCluster::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& m, unsigned int multiIndex) // // Method: deform1 // // Description: Deforms the point with a simple smooth skinning algorithm // // Arguments: // block : the datablock of the node // iter : an iterator for the geometry to be deformed // m : matrix to transform the point into world space // multiIndex : the index of the geometry that we are deforming // // { MStatus returnStatus; // get HRBF status MDataHandle HRBFstatusData = block.inputValue(rebuildHRBF, &returnStatus); McheckErr(returnStatus, "Error getting rebuildHRBF handle\n"); int rebuildHRBFStatusNow = HRBFstatusData.asInt(); // handle signaling to the rest of deform that HRBFs must be rebuild bool signalRebuildHRBF = false; signalRebuildHRBF = (rebuildHRBFStatus != rebuildHRBFStatusNow); MMatrixArray bindTFs; // store just the bind transforms in here. MMatrixArray boneTFs; // ALWAYS store just the bone transforms in here. // get HRBF export status MDataHandle exportCompositionData = block.inputValue(exportComposition, &returnStatus); McheckErr(returnStatus, "Error getting exportComposition handle\n"); int exportCompositionStatusNow = exportCompositionData.asInt(); MDataHandle HRBFExportSamplesData = block.inputValue(exportHRBFSamples, &returnStatus); McheckErr(returnStatus, "Error getting exportHRBFSamples handle\n"); std::string exportHRBFSamplesStatusNow = HRBFExportSamplesData.asString().asChar(); MDataHandle HRBFExportValuesData = block.inputValue(exportHRBFValues, &returnStatus); McheckErr(returnStatus, "Error getting exportHRBFValues handle\n"); std::string exportHRBFValuesStatusNow = HRBFExportValuesData.asString().asChar(); // get skinning type MDataHandle useDQData = block.inputValue(useDQ, &returnStatus); McheckErr(returnStatus, "Error getting useDQ handle\n"); int useDQNow = useDQData.asInt(); // determine if we're using HRBF MDataHandle useHRBFData = block.inputValue(useHRBF, &returnStatus); McheckErr(returnStatus, "Error getting useHRBFData handle\n"); int useHRBFnow = useHRBFData.asInt(); // get envelope because why not MDataHandle envData = block.inputValue(envelope, &returnStatus); float env = envData.asFloat(); // get point in space for evaluating HRBF MDataHandle checkHRBFAtData = block.inputValue(checkHRBFAt, &returnStatus); McheckErr(returnStatus, "Error getting useDQ handle\n"); double* data = checkHRBFAtData.asDouble3(); // get the influence transforms // MArrayDataHandle transformsHandle = block.inputArrayValue( matrix ); // tell block what we want int numTransforms = transformsHandle.elementCount(); if ( numTransforms == 0 ) { // no transforms, no problems return MS::kSuccess; } MMatrixArray transforms; // fetch transform matrices -> actual joint matrices for ( int i=0; i<numTransforms; ++i ) { MMatrix worldTF = MFnMatrixData(transformsHandle.inputValue().data()).matrix(); transforms.append(worldTF); boneTFs.append(worldTF); transformsHandle.next(); } // inclusive matrices inverse of the driving transform at time of bind // matrices for transforming vertices to joint local space MArrayDataHandle bindHandle = block.inputArrayValue( bindPreMatrix ); // tell block what we want if ( bindHandle.elementCount() > 0 ) { for ( int i=0; i<numTransforms; ++i ) { MMatrix bind = MFnMatrixData(bindHandle.inputValue().data()).matrix(); transforms[i] = bind * transforms[i]; bindHandle.next(); if (signalRebuildHRBF) bindTFs.append(bind); } } MArrayDataHandle weightListHandle = block.inputArrayValue(weightList); if (weightListHandle.elementCount() == 0) { // no weights - nothing to do std::cout << "no weights!" << std::endl; //rebuildHRBFStatus = rebuildHRBFStatusNow - 1; // HRBFs will need to rebuilt no matter what return MS::kSuccess; } // print HRBF samples if requested if (exportHRBFSamplesStatusNow != exportHRBFSamplesStatus) { std::cout << "instructed to export HRBF samples: " << exportHRBFSamplesStatusNow.c_str() << std::endl; exportHRBFSamplesStatus = exportHRBFSamplesStatusNow; // TODO: handle exporting HRBFs to the text file format hrbfMan->debugSamplesToConsole(exportHRBFSamplesStatus); } // print HRBF values if requested if (exportHRBFValuesStatusNow != exportHRBFValuesStatus) { std::cout << "instructed to export HRBF values: " << exportHRBFValuesStatusNow.c_str() << std::endl; exportHRBFValuesStatus = exportHRBFValuesStatusNow; // TODO: handle exporting HRBFs to the text file format hrbfMan->debugValuesToConsole(exportHRBFValuesStatus); } // print HRBF composition if requested if (exportCompositionStatusNow != exportCompositionStatus) { std::cout << "instructed to export HRBF composition." << std::endl; exportCompositionStatus = exportCompositionStatusNow; // TODO: handle exporting HRBFs to the text file format hrbfMan->debugCompositionToConsole(boneTFs, numTransforms); } // check the HRBF value if the new point is significantly different MPoint checkHRBFHereNow(data[0], data[1], data[2]); if ((checkHRBFHereNow - checkHRBFHere).length() > 0.0001) { if (hrbfMan->m_HRBFs.size() == numTransforms) { std::cout << "checking HRBF at x:" << data[0] << " y: " << data[1] << " z: " << data[2] << std::endl; hrbfMan->compose(boneTFs); float val = 0.0f; float dx = 0.0f; float dy = 0.0f; float dz = 0.0f; float grad = 0.0f; hrbfMan->mf_vals->trilinear(data[0], data[1], data[2], val); hrbfMan->mf_gradX->trilinear(data[0], data[1], data[2], dx); hrbfMan->mf_gradY->trilinear(data[0], data[1], data[2], dy); hrbfMan->mf_gradZ->trilinear(data[0], data[1], data[2], dz); hrbfMan->mf_gradMag->trilinear(data[0], data[1], data[2], grad); std::cout << "val: " << val << " dx: " << dx << " dy: " << dy << " dz: " << dz << " grad: " << grad << std::endl; checkHRBFHere = checkHRBFHereNow; } } // rebuild HRBFs if needed if (signalRebuildHRBF) { std::cout << "instructed to rebuild HRBFs" << std::endl; rebuildHRBFStatus = rebuildHRBFStatusNow; MArrayDataHandle parentIDCsHandle = block.inputArrayValue(jointParentIdcs); // tell block what we want std::vector<int> jointParentIndices(numTransforms); if (parentIDCsHandle.elementCount() > 0) { for (int i = 0; i<numTransforms; ++i) { jointParentIndices[i] = parentIDCsHandle.inputValue().asInt(); parentIDCsHandle.next(); } } MArrayDataHandle jointNamesHandle = block.inputArrayValue(jointNames); // tell block what we want std::vector<std::string> jointNames(numTransforms); if (jointNamesHandle.elementCount() > 0) { for (int i = 0; i<numTransforms; ++i) { jointNames[i] = jointNamesHandle.inputValue().asString().asChar(); jointNamesHandle.next(); } } // debug //std::cout << "got joint hierarchy info! it's:" << std::endl; //for (int i = 0; i < numTransforms; ++i) { // std::cout << i << ": " << jointNames[i].c_str() << " : " << jointParentIndices[i] << std::endl; //} std::cout << "rebuilding HRBFs... " << std::endl; hrbfMan->buildHRBFs(jointParentIndices, jointNames, bindTFs, boneTFs, weightListHandle, iter, weights); std::cout << "done rebuilding!" << std::endl; weightListHandle.jumpToElement(0); // reset this, it's an iterator. trust me. iter.reset(); // reset this iterator so we can go do normal skinning } // perform traditional skinning if (useDQNow != 0) { returnStatus = skinDQ(transforms, numTransforms, weightListHandle, iter); } else { returnStatus = skinLB(transforms, numTransforms, weightListHandle, iter); } // do HRBF corrections if (useHRBFnow != 0) { if (hrbfMan->m_HRBFs.size() == numTransforms) { hrbfMan->compose(boneTFs); iter.reset(); hrbfMan->correct(iter); } } return returnStatus; }
MStatus sweptEmitter::compute(const MPlug& plug, MDataBlock& block) // // Descriptions: // Call emit emit method to generate new particles. // { MStatus status; // Determine if we are requesting the output plug for this emitter node. // if( !(plug == mOutput) ) return( MS::kUnknownParameter ); // Get the logical index of the element this plug refers to, // because the node can be emitting particles into more // than one particle shape. // int multiIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in plug.logicalIndex.\n"); // Get output data arrays (position, velocity, or parentId) // that the particle shape is holding from the previous frame. // MArrayDataHandle hOutArray = block.outputArrayValue(mOutput, &status); McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n"); // Create a builder to aid in the array construction efficiently. // MArrayDataBuilder bOutArray = hOutArray.builder( &status ); McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n"); // Get the appropriate data array that is being currently evaluated. // MDataHandle hOut = bOutArray.addElement(multiIndex, &status); McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n"); // Get the data and apply the function set. // MFnArrayAttrsData fnOutput; MObject dOutput = fnOutput.create ( &status ); McheckErr(status, "ERROR in fnOutput.create.\n"); // Check if the particle object has reached it's maximum, // hence is full. If it is full then just return with zero particles. // bool beenFull = isFullValue( multiIndex, block ); if( beenFull ) { return( MS::kSuccess ); } // Get deltaTime, currentTime and startTime. // If deltaTime <= 0.0, or currentTime <= startTime, // do not emit new pariticles and return. // MTime cT = currentTimeValue( block ); MTime sT = startTimeValue( multiIndex, block ); MTime dT = deltaTimeValue( multiIndex, block ); if( (cT <= sT) || (dT <= 0.0) ) { // We do not emit particles before the start time, // and do not emit particles when moving backwards in time. // // This code is necessary primarily the first time to // establish the new data arrays allocated, and since we have // already set the data array to length zero it does // not generate any new particles. // hOut.set( dOutput ); block.setClean( plug ); return( MS::kSuccess ); } // Get speed, direction vector, and inheritFactor attributes. // double speed = speedValue( block ); MVector dirV = directionVector( block ); double inheritFactor = inheritFactorValue( multiIndex, block ); // Get the position and velocity arrays to append new particle data. // MVectorArray fnOutPos = fnOutput.vectorArray("position", &status); MVectorArray fnOutVel = fnOutput.vectorArray("velocity", &status); // Convert deltaTime into seconds. // double dt = dT.as( MTime::kSeconds ); // Apply rotation to the direction vector MVector rotatedV = useRotation ( dirV ); // position, MVectorArray inPosAry; // velocity MVectorArray inVelAry; // emission rate MIntArray emitCountPP; // Get the swept geometry data // MObject thisObj = this->thisMObject(); MPlug sweptPlug( thisObj, mSweptGeometry ); if ( sweptPlug.isConnected() ) { MDataHandle sweptHandle = block.inputValue( mSweptGeometry ); // MObject sweptData = sweptHandle.asSweptGeometry(); MObject sweptData = sweptHandle.data(); MFnDynSweptGeometryData fnSweptData( sweptData ); // Curve emission // if (fnSweptData.lineCount() > 0) { int numLines = fnSweptData.lineCount(); for ( int i=0; i<numLines; i++ ) { inPosAry.clear(); inVelAry.clear(); emitCountPP.clear(); MDynSweptLine line = fnSweptData.sweptLine( i ); // ... process current line ... MVector p1 = line.vertex( 0 ); MVector p2 = line.vertex( 1 ); inPosAry.append( p1 ); inPosAry.append( p2 ); inVelAry.append( MVector( 0,0,0 ) ); inVelAry.append( MVector( 0,0,0 ) ); // emit Rate for two points on line emitCountPP.clear(); status = emitCountPerPoint( plug, block, 2, emitCountPP ); emit( inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel ); } } // Surface emission (nurb or polygon) // if (fnSweptData.triangleCount() > 0) { int numTriangles = fnSweptData.triangleCount(); for ( int i=0; i<numTriangles; i++ ) { inPosAry.clear(); inVelAry.clear(); emitCountPP.clear(); MDynSweptTriangle tri = fnSweptData.sweptTriangle( i ); // ... process current triangle ... MVector p1 = tri.vertex( 0 ); MVector p2 = tri.vertex( 1 ); MVector p3 = tri.vertex( 2 ); MVector center = p1 + p2 + p3; center /= 3.0; inPosAry.append( center ); inVelAry.append( MVector( 0,0,0 ) ); // emit Rate for two points on line emitCountPP.clear(); status = emitCountPerPoint( plug, block, 1, emitCountPP ); emit( inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel ); } } } // Update the data block with new dOutput and set plug clean. // hOut.set( dOutput ); block.setClean( plug ); return( MS::kSuccess ); }
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; }
MStatus TCC::initialize() { MFnNumericAttribute numAttr; MFnTypedAttribute attrFn; MFnIntArrayData defaultIArrayDataFn; MFnDoubleArrayData defaultDArrayDataFn; MStatus stat; aRes = numAttr.create( "SubdivisionResolution", "res", MFnNumericData::kInt, 3 ); aRefRes = numAttr.create( "SubdivisionRefinementResolution", "refres", MFnNumericData::kInt, 0 ); aLineThickness = numAttr.create( "UVLineThickness", "th", MFnNumericData::kFloat, 0 ); aInputMesh = attrFn.create("inputMesh", "inMesh", MFnMeshData::kMesh); defaultIArrayDataFn.create( ); anFVc = attrFn.create("nFVcached", "nFVc", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultIArrayDataFn.create( ); aFc = attrFn.create("Fcached", "Fc", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultIArrayDataFn.create( ); aPole = attrFn.create("pole", "pole", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultIArrayDataFn.create( ); aCorner = attrFn.create("corner", "corner", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultIArrayDataFn.create( ); aT = attrFn.create("T", "T", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultIArrayDataFn.create( ); aEqc = attrFn.create("eqc", "eqc", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultDArrayDataFn.create( ); aItv = attrFn.create("itv", "itv", MFnData::kDoubleArray, defaultDArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); defaultIArrayDataFn.create( ); aErr = attrFn.create("err", "err", MFnData::kIntArray, defaultIArrayDataFn.object()); attrFn.setConnectable(false); attrFn.setStorable(true); aOutputMesh = attrFn.create( "outputMesh", "out", MFnData::kMesh); attrFn.setStorable(false); attrFn.setWritable(false); stat = addAttribute(aRes); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aRefRes); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aLineThickness); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aInputMesh); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(anFVc); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aFc); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aPole); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aCorner); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aT); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aEqc); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aItv); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aErr); McheckErr(stat, "ERROR adding attribute\n"); stat = addAttribute(aOutputMesh); McheckErr(stat, "ERROR adding attribute\n"); stat = attributeAffects(aRes, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aRefRes, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aLineThickness, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aInputMesh, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(anFVc, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aFc, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aPole, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aCorner, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aT, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aEqc, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aItv, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); stat = attributeAffects(aErr, aOutputMesh); McheckErr(stat, "ERROR in attributeAffects\n"); return MS::kSuccess; }
MStatus LSSolverNode::initialize() { MFnNumericAttribute nAttr; MFnUnitAttribute uAttr; MFnTypedAttribute tAttr; MFnEnumAttribute eAttr; MFnMatrixAttribute mAttr; tetWorldMatrix = mAttr.create("tet_world_matrix","twm",MFnMatrixAttribute::kDouble,&returnStatus); McheckErr(returnStatus, "ERROR creating LSTetgenNode worldMatrix attribute\n"); MAKE_INPUT(mAttr); mAttr.setHidden(true); restShape = tAttr.create("restShape", "rs", MFnMeshData::kMesh, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode restShape attribute\n"); MAKE_INPUT(tAttr); restElements = tAttr.create("restElements", "re", MFnData::kIntArray, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode restShape attribute\n"); MAKE_INPUT(tAttr); restVertices = tAttr.create("restVertices", "rv", MFnData::kDoubleArray, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode restShape attribute\n"); MAKE_INPUT(tAttr); selectedConstraintVerts = tAttr.create("selectedConstraintVerts", "scv", MFnData::kIntArray, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode selectedConstraintVerts attribute\n"); MAKE_INPUT(tAttr); selectedForceVerts = tAttr.create("selectedForceVerts", "sfv", MFnData::kIntArray, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode selectedForceVerts attribute\n"); MAKE_INPUT(tAttr); time = uAttr.create("time", "t", MFnUnitAttribute::kTime,0.0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode time attribute\n"); MAKE_INPUT(uAttr); deformed = tAttr.create("deformed", "d", MFnMeshData::kMesh, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode deformed attribute\n"); MAKE_OUTPUT(tAttr); poissonRatio = nAttr.create("poissonRatio", "pr", MFnNumericData::kDouble, 0.45, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode poisson ratio\n"); MAKE_INPUT(nAttr); nAttr.setMax(0.45); nAttr.setMin(0); youngsModulus = nAttr.create("youngsModulus", "ym", MFnNumericData::kDouble, 90000000000, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode youngsModulus\n"); MAKE_INPUT(nAttr); //nAttr.setMax(50000); //nAttr.setMin(1); objectDensity = nAttr.create("density", "objd", MFnNumericData::kDouble, 1000, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode objectDensity\n"); MAKE_INPUT(nAttr); nAttr.setMax(10000); nAttr.setMin(1); friction = nAttr.create("friction", "f", MFnNumericData::kDouble, 0.98, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode friction\n"); MAKE_INPUT(nAttr); nAttr.setMax(1); nAttr.setMin(0); restitution = nAttr.create("restitution", "r", MFnNumericData::kDouble, 0.4, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode restitution\n"); MAKE_INPUT(nAttr); nAttr.setMax(1); nAttr.setMin(0); damping = nAttr.create("damping", "dmp", MFnNumericData::kDouble, 0.0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode damping\n"); MAKE_INPUT(nAttr); nAttr.setMax(1); nAttr.setMin(0); userSuppliedDt = nAttr.create("timeStep","ts",MFnNumericData::kDouble,0.01, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode userSuppliedDt\n"); MAKE_INPUT(nAttr); nAttr.setMax(1); nAttr.setMin(0.00001); forceApplicationTime = nAttr.create("forceApplicationTime", "fat", MFnNumericData::kInt, 50, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceApplicationTime ratio\n"); MAKE_INPUT(nAttr); forceReleasedTime = nAttr.create("forceReleasedTime", "frt", MFnNumericData::kInt, 100, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceReleasedTime ratio\n"); MAKE_INPUT(nAttr); forceIncrementTime = nAttr.create("forceIncrementTime", "fit", MFnNumericData::kInt, 10, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceIncrementTime ratio\n"); MAKE_INPUT(nAttr); forceStartTime = nAttr.create("forceStartTime", "fst", MFnNumericData::kInt,100, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceStartTime\n"); MAKE_INPUT(nAttr); forceStopTime = nAttr.create("forceStopTime", "fet", MFnNumericData::kInt, 200, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceStopTime\n"); MAKE_INPUT(nAttr); forceMagnitude = nAttr.create("forceMagnitude", "fm", MFnNumericData::kDouble, 10.0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceIdleTime ratio\n"); MAKE_INPUT(nAttr); forceDirection = nAttr.create("forceDirection", "fd", MFnNumericData::k3Double, 0.0 , &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceIdleTime ratio\n"); MAKE_INPUT(nAttr); useSuppliedConstraints = nAttr.create("useSuppliedConstraints", "usc", MFnNumericData::kBoolean,1, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode useSuppliedConstraints ratio\n"); MAKE_INPUT(nAttr); useSuppliedForce = nAttr.create("useSuppliedForce", "usf", MFnNumericData::kBoolean, 0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode useSuppliedForces ratio\n"); MAKE_INPUT(nAttr); integrationType = eAttr.create("timeIntegrationMethod","it",0,&returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode integrationType\n"); eAttr.addField("Implicit Backward Euler",0); eAttr.addField("Implicit Newmark",1); eAttr.addField("Central Differences",2); eAttr.addField("Symplectic Euler",3); MAKE_INPUT(eAttr); forceModelType = eAttr.create("system","ft",0,&returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode forceModelType\n"); eAttr.addField("Corotational Linear FEM",0); eAttr.addField("Mass Spring System",1); MAKE_INPUT(eAttr); contactKs = nAttr.create("contactSpringForce", "cKs", MFnNumericData::kDouble, 1000.0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode contactSpringForces\n"); MAKE_INPUT(nAttr); contactKd = nAttr.create("contactDampForce", "cKd", MFnNumericData::kDouble, 50.0, &returnStatus); McheckErr(returnStatus, "ERROR creating LSSolverNode contactDampForces\n"); MAKE_INPUT(nAttr); returnStatus = addAttribute(tetWorldMatrix); McheckErr(returnStatus, "ERROR adding LSSolverNode world matrix attribute\n"); returnStatus = addAttribute(restShape); McheckErr(returnStatus, "ERROR adding LSSolverNode step attribute\n"); returnStatus = addAttribute(restElements); McheckErr(returnStatus, "ERROR adding LSSolverNode restElements attribute\n"); returnStatus = addAttribute(restVertices); McheckErr(returnStatus, "ERROR adding LSSolverNode restVertices attribute\n"); returnStatus = addAttribute(selectedConstraintVerts); McheckErr(returnStatus, "ERROR adding LSSolverNode selectedConstraintVerts attribute\n"); returnStatus = addAttribute(selectedForceVerts); McheckErr(returnStatus, "ERROR adding LSSolverNode selectedForceVerts attribute\n"); returnStatus = addAttribute(time); McheckErr(returnStatus, "ERROR adding LSSolverNode time attribute\n"); returnStatus = addAttribute(deformed); McheckErr(returnStatus, "ERROR adding LSSolverNode deformed attribute\n"); returnStatus = addAttribute(youngsModulus); McheckErr(returnStatus, "ERROR adding LSSolverNode youngsModulus\n"); returnStatus = addAttribute(poissonRatio); McheckErr(returnStatus, "ERROR adding LSSolverNode poissonRation\n"); returnStatus = addAttribute(objectDensity); McheckErr(returnStatus, "ERROR adding LSSolverNode objectDensity\n"); returnStatus = addAttribute(friction); McheckErr(returnStatus, "ERROR adding LSSolverNode friction\n"); returnStatus = addAttribute(restitution); McheckErr(returnStatus, "ERROR adding LSSolverNode resitution\n"); returnStatus = addAttribute(damping); McheckErr(returnStatus, "ERROR adding LSSolverNode damping\n"); returnStatus = addAttribute(userSuppliedDt); McheckErr(returnStatus, "ERROR adding LSSolverNode userSuppliedDt\n"); returnStatus = addAttribute(useSuppliedConstraints); McheckErr(returnStatus, "ERROR adding LSSolverNode useSuppliedConstraints\n"); returnStatus = addAttribute(useSuppliedForce); McheckErr(returnStatus, "ERROR adding LSSolverNode useSuppliedForce\n"); returnStatus = addAttribute(forceMagnitude); McheckErr(returnStatus, "ERROR adding LSSolverNode forceMagnitude\n"); returnStatus = addAttribute(forceDirection); McheckErr(returnStatus, "ERROR adding LSSolverNode forceDirection\n"); returnStatus = addAttribute(forceApplicationTime); McheckErr(returnStatus, "ERROR adding LSSolverNode forceApplicationTime\n"); returnStatus = addAttribute(forceReleasedTime); McheckErr(returnStatus, "ERROR adding LSSolverNode forceReleasedTime\n"); returnStatus = addAttribute(forceIncrementTime); McheckErr(returnStatus, "ERROR adding LSSolverNode forceIncrementTime\n"); returnStatus = addAttribute(forceStartTime); McheckErr(returnStatus, "ERROR adding LSSolverNode forceIdleTime\n"); returnStatus = addAttribute(forceStopTime); McheckErr(returnStatus, "ERROR adding LSSolverNode forceIdleTime\n"); // returnStatus = addAttribute(inputFilePath); // McheckErr(returnStatus, "ERROR adding LSSolverNode inputFilePath\n"); returnStatus = addAttribute(integrationType); McheckErr(returnStatus, "ERROR adding LSSolverNode integrationType\n"); returnStatus = addAttribute(forceModelType); McheckErr(returnStatus, "ERROR adding LSSolverNode forceModelType\n"); returnStatus = addAttribute(contactKd); McheckErr(returnStatus, "ERROR adding LSSolverNode contactKd\n"); returnStatus = addAttribute(contactKs); McheckErr(returnStatus, "ERROR adding LSSolverNode contactKs\n"); returnStatus = attributeAffects(restShape, deformed); McheckErr(returnStatus, "ERROR in attributeAffects: restShape - deformed\n"); returnStatus = attributeAffects(time, deformed); McheckErr(returnStatus, "ERROR in attributeAffects: time - deformed\n"); return MS::kSuccess; }
MStatus latticeNoiseNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus returnStatus; float noiseAmplitude; float noiseFreq; if( plug == output ) { // Get the lattice data from the input attribute. First get the // data object, and then use the lattice data function set to extract // the actual lattice. // // Get the data handle // MDataHandle inputData = data.inputValue( input, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice data handle\n" ); // Get the data object // MObject latticeData = inputData.data(); MFnLatticeData dataFn( latticeData ); // Get the actual geometry // MObject lattice = dataFn.lattice(); MFnLattice lattFn( lattice, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice geometry\n" ); // Do the same for the output lattice // MDataHandle outputData = data.outputValue( output, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice data handle\n" ); // Get the data object // latticeData = outputData.data(); if ( latticeData.isNull() ) { // The data object for this attribute has not been created yet, so // we'll create it // latticeData = dataFn.create(); } else { // Use the data object that is already there // dataFn.setObject( latticeData ); } // Get the actual geometry // MObject outLattice = dataFn.lattice(); MFnLattice outLattFn( outLattice, &returnStatus ); McheckErr( returnStatus, "ERROR getting lattice geometry\n" ); // Get the amplitude and frequency // MDataHandle ampData = data.inputValue( amplitude, &returnStatus ); McheckErr( returnStatus, "ERROR getting amplitude\n" ); noiseAmplitude = ampData.asFloat(); MDataHandle freqData = data.inputValue( frequency, &returnStatus ); McheckErr( returnStatus, "ERROR getting frequency\n" ); noiseFreq = freqData.asFloat(); // Get the time. // MDataHandle timeData = data.inputValue( time, &returnStatus ); McheckErr( returnStatus, "ERROR getting time data handle\n" ); MTime time = timeData.asTime(); float seconds = (float)time.as( MTime::kSeconds ); // Easiest way to modify frequency is by modifying the time // seconds = seconds * noiseFreq; // We have the information we need now. We'll apply noise to the // points upon the lattice // unsigned s, t, u; lattFn.getDivisions( s, t, u ); // match up the divisions in the lattices // outLattFn.setDivisions( s, t, u ); for ( unsigned i = 0; i < s; i++ ) { for ( unsigned j = 0; j < t; j++ ) { for ( unsigned k = 0; k < u; k++ ) { MPoint & point = lattFn.point( i, j, k ); MPoint & outPoint = outLattFn.point( i, j, k ); pnt noisePnt = noise::atPointAndTime( (float)point.x, (float)point.y, (float)point.z, seconds ); // Make noise between -1 and 1 instead of 0 and 1 // noisePnt.x = ( noisePnt.x * 2.0F ) - 1.0F; noisePnt.y = ( noisePnt.y * 2.0F ) - 1.0F; noisePnt.z = ( noisePnt.z * 2.0F ) - 1.0F; outPoint.x = point.x + ( noisePnt.x * noiseAmplitude ); outPoint.y = point.y + ( noisePnt.y * noiseAmplitude ); outPoint.z = point.z + ( noisePnt.z * noiseAmplitude ); } } } outputData.set( latticeData ); data.setClean(plug); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
MStatus dynExprField::compute(const MPlug& plug, MDataBlock& block) // // Descriptions: // compute output force. // { MStatus status; if( !(plug == mOutputForce) ) return( MS::kUnknownParameter ); // get the logical index of the element this plug refers to. // int multiIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in plug.logicalIndex.\n"); // Get input data handle, use outputArrayValue since we do not // want to evaluate both inputs, only the one related to the // requested multiIndex. Evaluating both inputs at once would cause // a dependency graph loop. MArrayDataHandle hInputArray = block.outputArrayValue( mInputData, &status ); McheckErr(status,"ERROR in hInputArray = block.outputArrayValue().\n"); status = hInputArray.jumpToElement( multiIndex ); McheckErr(status, "ERROR: hInputArray.jumpToElement failed.\n"); // get children of aInputData. MDataHandle hCompond = hInputArray.inputValue( &status ); McheckErr(status, "ERROR in hCompond=hInputArray.inputValue\n"); MDataHandle hPosition = hCompond.child( mInputPositions ); MObject dPosition = hPosition.data(); MFnVectorArrayData fnPosition( dPosition ); MVectorArray points = fnPosition.array( &status ); McheckErr(status, "ERROR in fnPosition.array(), not find points.\n"); // Comment out the following since velocity, and mass are // not needed in this field. // // MDataHandle hVelocity = hCompond.child( mInputVelocities ); // MObject dVelocity = hVelocity.data(); // MFnVectorArrayData fnVelocity( dVelocity ); // MVectorArray velocities = fnVelocity.array( &status ); // McheckErr(status, "ERROR in fnVelocity.array(), not find velocities.\n"); // // MDataHandle hMass = hCompond.child( mInputMass ); // MObject dMass = hMass.data(); // MFnDoubleArrayData fnMass( dMass ); // MDoubleArray masses = fnMass.array( &status ); // McheckErr(status, "ERROR in fnMass.array(), not find masses.\n"); // The attribute mInputPPData contains the attribute in an array form // parpared by the particleShape if the particleShape has per particle // attribute fieldName_attrName. // // Suppose a field with the name dynExprField1 is connecting to // particleShape1, and the particleShape1 has per particle float attribute // dynExprField1_magnitude and vector attribute dynExprField1_direction, // then hInputPPArray will contains a MdoubleArray with the corresponding // name "magnitude" and a MvectorArray with the name "direction". This // is a mechanism to allow the field attributes being driven by dynamic // expression. MArrayDataHandle mhInputPPData = block.inputArrayValue( mInputPPData, &status ); McheckErr(status,"ERROR in mhInputPPData = block.inputArrayValue().\n"); status = mhInputPPData.jumpToElement( multiIndex ); McheckErr(status, "ERROR: mhInputPPArray.jumpToElement failed.\n"); MDataHandle hInputPPData = mhInputPPData.inputValue( &status ); McheckErr(status, "ERROR in hInputPPData = mhInputPPData.inputValue\n"); MObject dInputPPData = hInputPPData.data(); MFnArrayAttrsData inputPPArray( dInputPPData ); MDataHandle hOwnerPPData = block.inputValue( mOwnerPPData, &status ); McheckErr(status, "ERROR in hOwnerPPData = block.inputValue\n"); MObject dOwnerPPData = hOwnerPPData.data(); MFnArrayAttrsData ownerPPArray( dOwnerPPData ); const MString magString("magnitude"); MFnArrayAttrsData::Type doubleType(MFnArrayAttrsData::kDoubleArray); bool arrayExist; MDoubleArray magnitudeArray; arrayExist = inputPPArray.checkArrayExist(magString, doubleType, &status); // McheckErr(status, "ERROR in checkArrayExist(magnitude)\n"); if(arrayExist) { magnitudeArray = inputPPArray.getDoubleData(magString, &status); // McheckErr(status, "ERROR in inputPPArray.doubleArray(magnitude)\n"); } MDoubleArray magnitudeOwnerArray; arrayExist = ownerPPArray.checkArrayExist(magString, doubleType, &status); // McheckErr(status, "ERROR in checkArrayExist(magnitude)\n"); if(arrayExist) { magnitudeOwnerArray = ownerPPArray.getDoubleData(magString, &status); // McheckErr(status, "ERROR in ownerPPArray.doubleArray(magnitude)\n"); } const MString dirString("direction"); MFnArrayAttrsData::Type vectorType(MFnArrayAttrsData::kVectorArray); arrayExist = inputPPArray.checkArrayExist(dirString, vectorType, &status); MVectorArray directionArray; // McheckErr(status, "ERROR in checkArrayExist(direction)\n"); if(arrayExist) { directionArray = inputPPArray.getVectorData(dirString, &status); // McheckErr(status, "ERROR in inputPPArray.vectorArray(direction)\n"); } arrayExist = ownerPPArray.checkArrayExist(dirString, vectorType, &status); MVectorArray directionOwnerArray; // McheckErr(status, "ERROR in checkArrayExist(direction)\n"); if(arrayExist) { directionOwnerArray = ownerPPArray.getVectorData(dirString, &status); // McheckErr(status, "ERROR in ownerPPArray.vectorArray(direction)\n"); } // Compute the output force. // MVectorArray forceArray; apply( block, points.length(), magnitudeArray, magnitudeOwnerArray, directionArray, directionOwnerArray, forceArray ); // get output data handle // MArrayDataHandle hOutArray = block.outputArrayValue( mOutputForce, &status); McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n"); MArrayDataBuilder bOutArray = hOutArray.builder( &status ); McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n"); // get output force array from block. // MDataHandle hOut = bOutArray.addElement(multiIndex, &status); McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n"); MFnVectorArrayData fnOutputForce; MObject dOutputForce = fnOutputForce.create( forceArray, &status ); McheckErr(status, "ERROR in dOutputForce = fnOutputForce.create\n"); // update data block with new output force data. // hOut.set( dOutputForce ); block.setClean( plug ); return( MS::kSuccess ); }
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; }
MStatus pointOnSubd::compute( const MPlug& plug, MDataBlock& data ) // // 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 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 == aPoint) || (plug == aNormal) || (plug == aPointX) || (plug == aNormalX) || (plug == aPointY) || (plug == aNormalY) || (plug == aPointZ) || (plug == aNormalZ) ) { // Get a handle to the input attribute that we will need for the // computation. If the value is being supplied via a connection // in the dependency graph, then this call will cause all upstream // connections to be evaluated so that the correct value is supplied. // do { MDataHandle subdHandle = data.inputValue( aSubd, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get subd\n" ); break; } MDataHandle faceFirstHandle = data.inputValue( aFaceFirst, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get face first\n" ); break; } MDataHandle faceSecondHandle = data.inputValue( aFaceSecond, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get face2\n" ); break; } MDataHandle uHandle = data.inputValue( aU, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get u\n" ); break; } MDataHandle vHandle = data.inputValue( aV, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get v\n" ); break; } MDataHandle relHandle = data.inputValue( aRelativeUV, &returnStatus ); if( returnStatus != MS::kSuccess ) { MGlobal::displayError( "ERROR: cannot get relative UV\n" ); break; } // Read the input value from the handle. // MStatus stat; MObject subdValue = subdHandle.asSubdSurface(); MFnSubd subdFn( subdValue, &stat ); McheckErr(stat,"ERROR creating subd function set"); int faceFirstValue = faceFirstHandle.asLong(); int faceSecondValue = faceSecondHandle.asLong(); double uValue = uHandle.asDouble(); double vValue = vHandle.asDouble(); bool relUV = relHandle.asBool(); MPoint point; MVector normal; MUint64 polyId; stat = MFnSubdNames::fromSelectionIndices( polyId, faceFirstValue, faceSecondValue ); McheckErr(stat,"ERROR converting indices"); stat = subdFn.evaluatePositionAndNormal( polyId, uValue, vValue, relUV, point, normal ); normal.normalize(); McheckErr(stat,"ERROR evaluating the position and the normal"); // Get handles to the output attributes. This is similar to the // "inputValue" call above except that no dependency graph // computation will be done as a result of this call. // MDataHandle pointHandle = data.outputValue( aPoint ); pointHandle.set( point.x, point.y, point.z ); data.setClean(plug); MDataHandle normalHandle = data.outputValue( aNormal ); normalHandle.set( normal.x, normal.y, normal.z ); data.setClean(plug); } while( false ); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
MStatus LSystemNode::initialize() { MFnUnitAttribute unitAttr; MFnTypedAttribute typedAttr; MFnNumericAttribute angleNumAttr; MFnNumericAttribute stepNumAttr; MFnTypedAttribute grammarTypedAttr; MStatus returnStatus; LSystemNode::time = unitAttr.create( "time", "tm", MFnUnitAttribute::kTime, 0.0, &returnStatus ); McheckErr(returnStatus, "ERROR creating LSystemNode time attribute\n"); LSystemNode::outputMesh = typedAttr.create( "outputMesh", "out", MFnData::kMesh, &returnStatus ); McheckErr(returnStatus, "ERROR creating LSystemNode output attribute\n"); typedAttr.setStorable(false); LSystemNode::angle = angleNumAttr.create( "angle", "a", MFnNumericData::kDouble, 90.0 ); McheckErr(returnStatus, "ERROR creating LSystemNode angle attribute\n"); LSystemNode::steps = stepNumAttr.create( "steps", "s", MFnNumericData::kDouble, 1.0 ); McheckErr(returnStatus, "ERROR creating LSystemNode step size attribute\n"); LSystemNode::grammar = grammarTypedAttr.create( "grammar", "g", MFnData::kString, &returnStatus ); McheckErr(returnStatus, "ERROR creating LSystemNode grammar attribute\n"); grammarTypedAttr.setStorable(false); returnStatus = addAttribute(LSystemNode::time); McheckErr(returnStatus, "ERROR adding time attribute\n"); returnStatus = addAttribute(LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR adding outputMesh attribute\n"); returnStatus = addAttribute(LSystemNode::angle); McheckErr(returnStatus, "ERROR adding angle attribute\n"); returnStatus = addAttribute(LSystemNode::steps); McheckErr(returnStatus, "ERROR adding steps attribute\n"); returnStatus = addAttribute(LSystemNode::grammar); McheckErr(returnStatus, "ERROR adding grammar attribute\n"); returnStatus = attributeAffects(LSystemNode::time, LSystemNode::outputMesh); returnStatus = attributeAffects(LSystemNode::angle, LSystemNode::outputMesh); returnStatus = attributeAffects(LSystemNode::grammar, LSystemNode::outputMesh); returnStatus = attributeAffects(LSystemNode::steps, LSystemNode::outputMesh); McheckErr(returnStatus, "ERROR in attributeAffects\n"); return MS::kSuccess; }
MStatus tm_noisePerlin::initialize() { MStatus status = MS::kSuccess; MFnNumericAttribute nAttr; amplitude=nAttr.create( "amplitude", "amp", MFnNumericData::kDouble, 1.0, &status ); McheckErr(status, "Error creating amplitude attribute\n"); // nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( amplitude); frequency=nAttr.create( "frequency", "freq", MFnNumericData::kDouble, 1.0, &status ); McheckErr(status, "Error creating frequency attribute\n"); // nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( frequency); levels=nAttr.create( "levels", "lev", MFnNumericData::kShort, 2.0, &status ); McheckErr(status, "Error creating levels attribute\n"); // nAttr.setDefault(2); nAttr.setKeyable(true); addAttribute( levels); lev_Mamp=nAttr.create( "lev_Mamp", "levma", MFnNumericData::kDouble, 0.25, &status ); McheckErr(status, "Error creating lev_Mamp attribute\n"); // nAttr.setDefault(0.25); nAttr.setKeyable(true); addAttribute( lev_Mamp); lev_Mfreq=nAttr.create( "lev_Mfreq", "levmf", MFnNumericData::kDouble ); nAttr.setDefault(4.0); nAttr.setKeyable(true); addAttribute( lev_Mfreq); scale=nAttr.create( "scale", "sc", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scale); scaleAmpX=nAttr.create( "scaleAmpX", "sx", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scaleAmpX); scaleAmpY=nAttr.create( "scaleAmpY", "sy", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scaleAmpY); scaleAmpZ=nAttr.create( "scaleAmpZ", "sz", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scaleAmpZ); scaleFreqX=nAttr.create( "scaleFreqX", "sfx", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scaleFreqX); scaleFreqY=nAttr.create( "scaleFreqY", "sfy", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scaleFreqY); scaleFreqZ=nAttr.create( "scaleFreqZ", "sfz", MFnNumericData::kDouble ); nAttr.setDefault(1.0); nAttr.setKeyable(true); addAttribute( scaleFreqZ); variation=nAttr.create( "variation", "var", MFnNumericData::kDouble ); nAttr.setDefault(0.0); nAttr.setKeyable(true); addAttribute( variation); attributeAffects( tm_noisePerlin::amplitude, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::frequency, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::levels, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::lev_Mamp, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::lev_Mfreq, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scale, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scaleAmpX, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scaleAmpY, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scaleAmpZ, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scaleFreqX, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scaleFreqY, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::scaleFreqZ, tm_noisePerlin::outputGeom ); attributeAffects( tm_noisePerlin::variation, tm_noisePerlin::outputGeom ); return MS::kSuccess; }
MStatus buildRotation::compute( const MPlug& plug, MDataBlock& data ) { MStatus returnStatus; if ((plug == rotate) || (plug.parent() == rotate) || (plug == rotateMatrix)) { MDataHandle upData = data.inputValue( up, &returnStatus ); McheckErr(returnStatus,"ERROR getting up vector data"); MDataHandle forwardData = data.inputValue( forward, &returnStatus ); McheckErr(returnStatus,"ERROR getting forward vector data"); MVector up = upData.asVector(); MVector forward = forwardData.asVector(); // Make sure that the up and forward vectors are orthogonal // if ( fabs( up * forward ) > EPSILON ) { // Non-zero dot product // MVector orthoVec = up ^ forward; MVector newForward = orthoVec ^ up; if ( forward * newForward < 0.0 ) { // Reverse the vector // newForward *= -1.0; } forward = newForward; } // Calculate the rotation required to align the y-axis with the up // vector // MTransformationMatrix firstRot; MVector rotAxis = MVector::yAxis ^ up; rotAxis.normalize(); firstRot.setToRotationAxis( rotAxis, MVector::yAxis.angle( up ) ); // Calculate the second rotation required to align the forward vector // MTransformationMatrix secondRot; MVector transformedForward = firstRot.asMatrix() * forward; transformedForward.normalize(); double angle = transformedForward.angle( MVector::zAxis ); if ( transformedForward.x < 0.0 ) { // Compensate for the fact that the angle method returns // the absolute value // angle *= -1.0; } secondRot.setToRotationAxis( up, angle ); // Get the requested rotation order // MDataHandle orderHandle = data.inputValue( rotateOrder ); short order = orderHandle.asShort(); MTransformationMatrix::RotationOrder rotOrder; switch ( order ) { case ROTATE_ORDER_XYZ: rotOrder = MTransformationMatrix::kXYZ; break; case ROTATE_ORDER_YZX: rotOrder = MTransformationMatrix::kYZX; break; case ROTATE_ORDER_ZXY: rotOrder = MTransformationMatrix::kZXY; break; case ROTATE_ORDER_XZY: rotOrder = MTransformationMatrix::kXZY; break; case ROTATE_ORDER_YXZ: rotOrder = MTransformationMatrix::kYXZ; break; case ROTATE_ORDER_ZYX: rotOrder = MTransformationMatrix::kZYX; break; default: rotOrder = MTransformationMatrix::kInvalid; break; } MTransformationMatrix result = firstRot.asMatrix() * secondRot.asMatrix(); result.reorderRotation( rotOrder ); double rotation[3]; result.getRotation( rotation, rotOrder, MSpace::kTransform ); MDataHandle outputRot = data.outputValue( rotate ); outputRot.set( rotation[0], rotation[1], rotation[2] ); outputRot.setClean(); MDataHandle outputMatrix = data.outputValue( rotateMatrix ); outputMatrix.set( result.asMatrix() ); outputMatrix.setClean(); } else return MS::kUnknownParameter; return MS::kSuccess; }