MStatus SwirlDeformer::deform( MDataBlock& block, MItGeometry &iter, const MMatrix &localToWorld, unsigned int geomIndex ) { MStatus stat; MDataHandle envData = block.inputValue( envelope ); float env = envData.asFloat(); if( env == 0.0 ) // Deformer has no effect return MS::kSuccess; MDataHandle matData = block.inputValue( deformSpace ); MMatrix mat = matData.asMatrix(); MMatrix invMat = mat.inverse(); MDataHandle startDistHnd = block.inputValue( startDist ); double startDist = startDistHnd.asDouble(); MDataHandle endDistHnd = block.inputValue( endDist ); double endDist = endDistHnd.asDouble(); MPoint pt; float weight; double dist; double ang; double cosAng; double sinAng; double x; double distFactor; for( iter.reset(); !iter.isDone(); iter.next() ) { weight = weightValue( block, geomIndex, iter.index() ); if( weight == 0.0f ) continue; pt = iter.position(); pt *= invMat; dist = sqrt( pt.x * pt.x + pt.z * pt.z ); if( dist < startDist || dist > endDist ) continue; distFactor = 1 - ((dist - startDist) / (endDist - startDist)); ang = distFactor * M_PI * 2.0 * env * weight; if( ang == 0.0 ) continue; cosAng = cos( ang ); sinAng = sin( ang ); x = pt.x * cosAng - pt.z * sinAng; pt.z = pt.x * sinAng + pt.z * cosAng; pt.x = x; pt *= mat; iter.setPosition( pt ); } return stat; }
MStatus transCircle::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; bool k = ( plug == outputTranslateX ) | ( plug == outputTranslateY ) | ( plug == outputTranslateZ ) | ( plug == outputTranslate ); if (!k) return MS::kUnknownParameter; MDataHandle inputData = data.inputValue( input, &stat ); MDataHandle scaleData = data.inputValue( scale, &stat ); MDataHandle framesData = data.inputValue( frames, &stat ); MDataHandle transData = data.inputValue( inputTranslate, &stat ); double3& iTranslate = transData.asDouble3(); double currentFrame = inputData.asDouble(); double scaleFactor = scaleData.asDouble(); double framesPerCircle = framesData.asDouble(); double angle = 6.2831853 * ( currentFrame/framesPerCircle ); double3 oTranslate; oTranslate[0] = iTranslate[0] + (sin( angle ) * scaleFactor); oTranslate[1] = iTranslate[1] + 1.0; oTranslate[2] = iTranslate[2] + (cos( angle ) * scaleFactor); MDataHandle otHandle = data.outputValue( outputTranslate ); otHandle.set( oTranslate[0], oTranslate[1], oTranslate[2] ); data.setClean(plug); return MS::kSuccess; }
MStatus matrixFromPolygon::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; //MFnDependencyNode thisNode( thisMObject() ); //cout << thisNode.name() << ", start" << endl; if( plug == aOutputMatrix ) { MDataHandle hInputMesh = data.inputValue( aInputMesh, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hInputMeshMatrix = data.inputValue( aInputMeshMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hPolygonIndex = data.inputValue( aPolygonIndex, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hU = data.inputValue( aU, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hV = data.inputValue( aV, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hOutputMatrix = data.outputValue( aOutputMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MMatrix outMatrix; getMatrixByPoints( outMatrix, hPolygonIndex.asInt(), hU.asDouble(), hV.asDouble(), hInputMesh.asMesh() ); outMatrix *= hInputMeshMatrix.asMatrix(); hOutputMatrix.set( outMatrix ); data.setClean( plug ); } //cout << thisNode.name() << ", end" << endl; return MS::kSuccess; }
MStatus squash::compute( const MPlug& plug, MDataBlock& data ) { MStatus returnStatus; if( plug == output ) { MDataHandle lengthOrigHandle = data.inputValue( lengthOriginal, &returnStatus ); MDataHandle lengthModiHandle = data.inputValue( lengthModify, &returnStatus ); MDataHandle rateHandle = data.inputValue( squashRate, &returnStatus ); MDataHandle forceHandle = data.inputValue( forceValue, &returnStatus ); if( returnStatus != MS::kSuccess ) MGlobal::displayError( "Node squash cannot get value\n" ); else { double lengthOrig = lengthOrigHandle.asDouble(); double lengthModi = lengthModiHandle.asDouble(); double rate = rateHandle.asDouble(); double force = forceHandle.asDouble(); double result = pow( lengthOrig/lengthModi, 0.5*rate )*(1+force); MDataHandle outputHandle = data.outputValue( squash::output ); outputHandle.set( result ); data.setClean(plug); } } else { return MS::kUnknownParameter; } return MS::kSuccess; }
MStatus sgLockAngleMatrix::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MDataHandle hBaseMatrix = data.inputValue( aBaseMatrix ); m_baseMatrix = hBaseMatrix.asMatrix(); MDataHandle hInputMatrix = data.inputValue( aInputMatrix ); m_inputMatrix = hInputMatrix.asMatrix(); MDataHandle hAngleAxis = data.inputValue( aAngleAxis ); m_angleAxis = hAngleAxis.asUChar(); MDataHandle hInputAngle = data.inputValue( aInputAngle ); m_inputAngle = hInputAngle.asDouble(); m_mtxResult = getsgLockAngleMatrix( m_inputMatrix*m_baseMatrix.inverse(), m_angleAxis, m_inputAngle ); MDataHandle hOutputMatrix = data.outputValue( aOutputMatrix ); hOutputMatrix.set( m_mtxResult * m_baseMatrix ); data.setClean( plug ); return MS::kSuccess; }
MStatus timeControl::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MDataHandle hInTime = data.inputValue( aInTime ); MDataHandle hOffset = data.inputValue( aOffset ); MDataHandle hMult = data.inputValue( aMult ); MDataHandle hMinTime = data.inputValue( aMinTime ); MDataHandle hMaxTime = data.inputValue( aMaxTime ); MDataHandle hLimitAble = data.inputValue( aLimitAble ); MTime inTime = hInTime.asTime(); double offset = hOffset.asDouble(); double mult = hMult.asDouble(); double timeValue = inTime.value(); if( hLimitAble.asBool() ) { MTime minTime = hMinTime.asTime(); MTime maxTime = hMaxTime.asTime(); double minTimeValue = minTime.value(); double maxTimeValue = maxTime.value(); if( timeValue < minTimeValue ) timeValue = minTimeValue; if( timeValue > maxTimeValue ) timeValue = maxTimeValue; } timeValue += offset; timeValue *= mult; MTime outTime( timeValue ); MDataHandle hOutTime = data.outputValue( aOutTime ); hOutTime.set( outTime ); MDataHandle hWeight = data.inputValue( aWeight ); MDataHandle hOutWeight = data.outputValue( aOutWeight ); hOutWeight.set( hWeight.asDouble() ); data.setClean( plug ); return status; }
double dynExprField::magnitude( MDataBlock& block ) { MStatus status; MDataHandle hValue = block.inputValue( mMagnitude, &status ); double value = 0.0; if( status == MS::kSuccess ) value = hValue.asDouble(); return( value ); }
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; }
//---------------------------------------------------------------------------------------------------------------------- // This method should be overridden in user defined nodes. // Recompute the given output based on the nodes inputs. // The plug represents the data value that needs to be recomputed, and the data block holds the storage // for all of the node'_scale attributes. //---------------------------------------------------------------------------------------------------------------------- MStatus OceanNode::compute( const MPlug &_plug , MDataBlock &_data ){ MStatus status; // see if we get the output plug if( _plug == m_output){ MDataHandle dataHandle; dataHandle = _data.inputValue(m_resolution, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for resolution plug"); if (m_res != dataHandle.asInt()){ switch(dataHandle.asInt()){ case 0: m_ocean->setResolution(128); MGlobal::displayInfo("Resolution: 128"); break; case 1: m_ocean->setResolution(256); MGlobal::displayInfo("Resolution: 256"); break; case 2: m_ocean->setResolution(512); MGlobal::displayInfo("Resolution: 512"); break; case 3: m_ocean->setResolution(1024); MGlobal::displayInfo("Resolution: 1024"); break; default: break; } m_res = dataHandle.asInt(); } dataHandle = _data.inputValue( m_amplitude , &status ); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL( status , "Unable to get data handle for amplitude plug" ); // now get the value for the data handle as a double double amp = dataHandle.asDouble(); m_ocean->setAmplitude(amp); dataHandle = _data.inputValue(m_frequency, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get handle for \"frequency\" plug"); double freq = dataHandle.asDouble(); m_ocean->setFrequency(freq); dataHandle = _data.inputValue(m_windDirectionX, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for windDirectionX plug"); // now get value for data handle double wdx = dataHandle.asDouble(); dataHandle = _data.inputValue(m_windDirectionZ, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for windDirectionY plug"); // now get value for data handle double wdz = dataHandle.asDouble(); m_ocean->setWindVector(make_float2(wdx, wdz)); dataHandle = _data.inputValue(m_windSpeed, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for windSpeed plug"); // now get value for data handle double ws = dataHandle.asDouble(); m_ocean->setWindSpeed(ws); // Only create a new frequency domain if either amplitude or the wind vecotr has changed if (m_amp != amp || m_wdx != wdx || m_wdz != wdz || m_ws != ws ){ MGlobal::displayInfo("here"); m_ocean->createH0(); m_amp = amp; m_wdx = wdx; m_wdz = wdz; m_ws = ws; } dataHandle = _data.inputValue(m_choppiness, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for the choppiness plug"); double choppiness = dataHandle.asDouble(); dataHandle = _data.inputValue(m_time, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to get data handle for time plug"); MTime time = dataHandle.asTime(); MDataHandle outputData = _data.outputValue(m_output, &status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL( status , "Unable to get data handle for output plug" ); MFnMeshData mesh; MObject outputObject = mesh.create(&status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to create output mesh"); // Find the current frame number we're on and create the grid based on this MAnimControl anim; anim.setMinTime(time); createGrid((int)pow(2.0, m_res+7), anim.currentTime().value()/24, choppiness, outputObject, status); CHECK_STATUS_AND_RETURN_MSTATUS_IF_FAIL(status, "Unable to to create grid"); outputData.set(outputObject); // clean the output plug, ie unset it from dirty so that maya does not re-evaluate it _data.setClean( _plug ); return MStatus::kSuccess; } return MStatus::kUnknownParameter; }
MStatus proWater::compute(const MPlug& plug, MDataBlock& dataBlock) { MStatus status = MStatus::kUnknownParameter; if (plug.attribute() == outputGeom) { // get the input corresponding to this output // unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = dataBlock.inputValue(inPlug); // get the input geometry and input groupId // MDataHandle hGeom = hInput.child(inputGeom); MDataHandle hGroup = hInput.child(groupId); unsigned int groupId = hGroup.asLong(); MDataHandle hOutput = dataBlock.outputValue(plug); hOutput.copy(hGeom); MStatus returnStatus; MDataHandle envData = dataBlock.inputValue(envelope, &returnStatus); if (MS::kSuccess != returnStatus) return returnStatus; float env = envData.asFloat(); MDataHandle timeData = dataBlock.inputValue(time, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double t = timeData.asDouble(); MDataHandle dirData = dataBlock.inputValue(dir, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double dirDeg = dirData.asDouble(); MDataHandle bigData = dataBlock.inputValue(bigFreq, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double bigFreqAmp = bigData.asDouble(); MDataHandle ampData = dataBlock.inputValue(amplitude1, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double amp1 = ampData.asDouble(); MDataHandle freqData = dataBlock.inputValue(frequency1, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double freq1 = freqData.asDouble(); MDataHandle ampData2 = dataBlock.inputValue(amplitude2, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double amp2 = ampData2.asDouble(); MDataHandle freqData2 = dataBlock.inputValue(frequency2, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double freq2 = freqData2.asDouble(); // Get the MFnMesh MStatus stat; MObject inputObj = hOutput.data(); MFnMesh * meshFn = new MFnMesh(inputObj, &stat); // do the deformation // MItGeometry iter(hOutput,groupId,false); for ( ; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); //float2 uvPoint; //float u,v; //uvPoint[0] = u; //uvPoint[1] = v; //meshFn->getUVAtPoint(pt, uvPoint, MSpace::kObject); float u = pt.x; //uvPoint[0]*100; float v = pt.z; //uvPoint[1]*100; float degDir = dirDeg; float dir = degDir* M_PI/180; float dirX = cos(dir); float dirY = sin(dir); float bigFreq = 0.01; float bigWaves = scaled_raw_noise_3d(0, 1, (u + 3*t*dirX)*bigFreq*dirX, (v + 3*t*dirY)*bigFreq*dirY*2, t*0.01); float frequency1 = freq1/10;//0.2; float amplitude1 = amp1;//1.3; float firstOctave = -(std::abs(scaled_raw_noise_3d(-amplitude1, amplitude1, (float)(u + 0.7*t*dirX)*frequency1*0.4, (float)(v + 0.7*t*dirY)*frequency1*0.6, 0.05*t))-amplitude1); float frequency2 = freq2/10; float amplitude2 = amp2; float secondOctave = - (std::abs(scaled_raw_noise_3d(-amplitude2, amplitude2, (float)(u + 0.7*t*dirX)*frequency2*0.35, (float)(v + 0.7*t*dirY)*frequency2*0.65, 0.005*t))-amplitude2); float frequency3 = freq1/10; float amplitude3 = amp1/1.5; float thirdOctave = - (std::abs(scaled_raw_noise_3d(-amplitude3, amplitude3, (float)(u + t*0.5*dirX)*frequency3*0.4, (float)(v + t*0.5*dirY)*frequency3*0.6, 30))-amplitude3); float frequency4 = freq2/10; float amplitude4 = amp2/1.5; float fourthOctave = scaled_raw_noise_3d(-amplitude4, amplitude4, (float)(u + t*0.5*dirX)*frequency4*0.4, (float)(v + t*0.5*dirY)*frequency4*0.6, 50); float frequency5 = freq2; float amplitude5 = amp2/2; float fifthOctave = scaled_raw_noise_3d(-amplitude5, amplitude5, (float)(u + t*0.5*dirX)*frequency5*0.15, (float)(v + t*0.5*dirY)*frequency5*0.85, 0.001*t); float disp = bigFreqAmp*bigWaves + 7*(bigWaves)*firstOctave + secondOctave + thirdOctave*thirdOctave + fourthOctave + std::abs(bigWaves-1)*fifthOctave; pt = pt + iter.normal()*disp; iter.setPosition(pt); } delete meshFn; status = MStatus::kSuccess; } return status; }
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 BPT_InsertVtx::doCompleteCompute( MDataBlock& data ) //---------------------------------------------------------------------------- { SPEED("Berechne EdgeSplit neu: "); MStatus status; MPRINT("MACHE KOMPLETTE BERECHNUNG") MDataHandle inMeshHandle = data.inputValue(IVinMesh); MDataHandle outMeshHandle = data.outputValue(IVoutMesh); //splitCount setzen MDataHandle countHandle = data.inputValue(IVcount); fIVfty.setCount(countHandle.asInt()); MDataHandle spinHandle = data.inputValue(IVspin); fIVfty.setSpin(spinHandle.asInt()); int initialVtxCount; //wird spueueter benueuetigt, um das ValidIndicesArray gleich in der rictigen grueueueuee zu erstellen und zu schreiben //gleich zu beginn muss der MeshPath initialisiert werden, damit der MeshPath an die fty ueuebergeben werden kann // Dies geschieht besser durch die STE - sie ist darauf ausgelegt softTransformationEngine::gatherAttributeObjects(thisMObject()); softTransformationEngine::saveMeshPathes(); fIVfty.setMeshPath(meshPath); MDataHandle rHandle = data.inputValue(IVslideRelative); fIVfty.setRelative(rHandle.asInt()); MDataHandle nRelativeHandle = data.inputValue(IVnormalRelative); fIVfty.setNormalRelative(nRelativeHandle.asInt()); //selection setzen MFnIntArrayData intDataArray; MDataHandle arrayHandle = data.inputValue(IVselEdgeIDs); intDataArray.setObject(arrayHandle.data()); fIVfty.setEdgeIDs( intDataArray.array() ); arrayHandle = data.inputValue(IVselVertIDs); intDataArray.setObject(arrayHandle.data()); fIVfty.setVertIDs(intDataArray.array()); // optionen holen arrayHandle = data.inputValue(IVoptions); intDataArray.setObject(arrayHandle.data()); MIntArray optionsArray(intDataArray.array()); fIVfty.setOptions(optionsArray); MDataHandle slideHandle = data.inputValue(IVslide); fIVfty.setSlide(slideHandle.asDouble()); //whichSide attribute wird nur fueuer SLide selbst verwendet und kann nicht bereits beim command gestetzt werden MObject inMeshRef = inMeshHandle.asMesh(); fIVfty.setMesh(inMeshRef); MFnMesh meshFn(inMeshHandle.asMesh()); initialVtxCount = meshFn.numVertices(); //ACTION try { status = fIVfty.doIt(); } catch(...) { MGlobal::displayError(" An unknown, severe, error occoured.\nIf it happens again in this situation, please write a bug report.\nPlease undo the operation and save your work!"); return MS::kUnknownParameter; } MObject newOutMesh = fIVfty.getMesh(); outMeshHandle.set(newOutMesh); // --------------------- // SOFT TRANSFORMATION // --------------------- // VtxSet setzen - hier reicht es, wenn er einfach die neuen Vtx nimmt softTransformationEngine::setVtxSet(data); //------------SELECTION ROUTINE---------------------- //nur wenn sich spin nicht verueuendert hat, darf ne neue selection gemacht werden - dies wird auch von der IV berueuecksichtigt //die selection wird nur noch einmal ausgefueuehrt, weshalb scriptJobInitiated nicht mehr gesetzt wird vom scriptjob if( optionsArray[6] && !scriptJobInitated && !(meshPath.apiType() == MFn::kInvalid) ) { //auf jeden Fall erstmal die neuen Vertizen holen, damit die anderen prozeduren auch darauf arbeiten kueuennen //alles neuen Vertces sollen gewueuehlt werden, also einfach alle Indices eintragen vom initialVtxCount //bis zum jetzigen VtxCount MIntArray validEdges, validFaces; componentConverter CC(newOutMesh); int i = 0; meshFn.setObject(newOutMesh); int newCount = meshFn.numVertices(); validIndices.clear(); validIndices.setLength(newCount - initialVtxCount); for(; initialVtxCount < newCount; initialVtxCount++) validIndices[i++] = initialVtxCount; if(optionsArray[6] == 1 || optionsArray[6] == 2) //select edges { CC.getContainedEdges(validIndices,validEdges); } BPT_Helpers helper; if(optionsArray[6] == 2) //select Faces { CC.getConnectedFaces(validEdges,validFaces); //jetzt kann gleich alles beendet werden, da hiernach keine componente mehr kommt, in die man faces umwandeln mueuesste validIndices.clear(); validIndices.append(2); helper.addIntArrayToLHS(validIndices,validFaces); } if(optionsArray[6] == 1) {//edges fertigmachen validIndices.clear(); validIndices.append(1); helper.addIntArrayToLHS(validIndices,validEdges); } else if(optionsArray[6] == 5) validIndices.insert(3,0); //component Mode umschalten bei bedarf if(optionsArray[5]) { MSelectionMask::SelectionType type = MSelectionMask::kSelectMeshVerts; if(optionsArray[6] == 5) { type = MSelectionMask::kSelectMeshVerts; } else if(optionsArray[6] == 2) { type = MSelectionMask::kSelectMeshFaces; } else if(optionsArray[6] == 1) { type = MSelectionMask::kSelectMeshEdges; } MSelectionMask mask(type); MGlobal:: setComponentSelectionMask(mask); } eID = MEventMessage::addEventCallback("idle",IV_makeSelection,this); scriptJobInitated = true; } else {//ansonsten muss die SelectionList neu aufgebaut werden, allerdings ohne komponenten //diese Aktion solte auch nur einmal ausgefueuehrt werden //gegenwueuertige selection holen MSelectionList currentList; MSelectionList newList; MGlobal::getActiveSelectionList(currentList); //durch die Liste iterieren und Komponenten Filtern MItSelectionList selIter(currentList); MObject currentObj; for( ; !selIter.isDone();selIter.next() ) { selIter.getDependNode(currentObj); newList.add(currentObj); } MGlobal::setActiveSelectionList(newList, MGlobal::kAddToList); } return status; }
//--------------------------------------------------------------------------------------------------- bool BPT_InsertVtx::setInternalValue ( const MPlug & plug, const MDataHandle & dataHandle) //--------------------------------------------------------------------------------------------------- { // cout<<"War hier, plug war "<<plug.info()<<endl; if(plug == IVslide) { int isLimited; MFnDependencyNode depFn(plug.node()); depFn.findPlug( "sll" ).getValue( isLimited ); if( isLimited ) {//limits setzen, wenn gewueuenscht double value = dataHandle.asDouble(); // cout<<value<<endl; if(value > 1.0) value = 1.0; if(value < 0.0) value = 0.0; //Das muss hier einfach sein, um limits dynamisch zu setzen je nach userwunsch const_cast<MDataHandle&>(dataHandle).set(value); } } else if( plug == IVcount ) { int value = dataHandle.asInt(); if(value != lastCount) {//count hat sich nicht verueuendert, also outHandle sueueubern und raus hier meshDirty = true; lastCount = value; } } else if( plug == IVspin ) { int value = dataHandle.asInt(); /* MFnIntArrayData arrayData; MPlug optionPlug(thisMObject(), options); //dieser wert kann gefahrlos geholt werden, da er das outmesh nicht beeinflusst MObject data; optionsPlug.getValue(data); arrayData.setObject(data); if(!(arrayData.array())[9]) {//wenn civ nicht gesetzt ist, dann macht dieser Wert keinen sinn } */ if(value != lastSpin) { meshDirty = true; lastSpin = value; } } // Sich jetzt um die STE internals kuemmern // // STE_CHECK_INTERNALS( IV,dataHandle ); if(plug==IVinMesh) meshDirty = true; return MPxNode::setInternalValue (plug, dataHandle); }
MStatus closestPointOnCurveNode::compute(const MPlug &plug, MDataBlock &data) { // DO THE COMPUTE ONLY FOR THE *OUTPUT* PLUGS THAT ARE DIRTIED: if ((plug == aPosition) || (plug == aPositionX) || (plug == aPositionY) || (plug == aPositionZ) || (plug == aNormal) || (plug == aNormalX) || (plug == aNormalY) || (plug == aNormalZ) || (plug == aTangent) || (plug == aTangentX) || (plug == aTangentY) || (plug == aTangentZ) || (plug == aParamU) || (plug == aDistance)) { // READ IN ".inCurve" DATA: MDataHandle inCurveDataHandle = data.inputValue(aInCurve); MObject inCurve = inCurveDataHandle.asNurbsCurve(); // READ IN ".inPositionX" DATA: MDataHandle inPositionXDataHandle = data.inputValue(aInPositionX); double inPositionX = inPositionXDataHandle.asDouble(); // READ IN ".inPositionY" DATA: MDataHandle inPositionYDataHandle = data.inputValue(aInPositionY); double inPositionY = inPositionYDataHandle.asDouble(); // READ IN ".inPositionZ" DATA: MDataHandle inPositionZDataHandle = data.inputValue(aInPositionZ); double inPositionZ = inPositionZDataHandle.asDouble(); // GET THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE: MPoint inPosition(inPositionX, inPositionY, inPositionZ), position; MVector normal, tangent; double paramU, distance; MDagPath dummyDagPath; closestTangentUAndDistance(dummyDagPath, inPosition, position, normal, tangent, paramU, distance, inCurve); // WRITE OUT ".position" DATA: MDataHandle positionDataHandle = data.outputValue(aPosition); positionDataHandle.set(position.x, position.y, position.z); data.setClean(plug); // WRITE OUT ".normal" DATA: MDataHandle normalDataHandle = data.outputValue(aNormal); normalDataHandle.set(normal.x, normal.y, normal.z); data.setClean(plug); // WRITE OUT ".tangent" DATA: MDataHandle tangentDataHandle = data.outputValue(aTangent); tangentDataHandle.set(tangent.x, tangent.y, tangent.z); data.setClean(plug); // WRITE OUT ".paramU" DATA: MDataHandle paramUDataHandle = data.outputValue(aParamU); paramUDataHandle.set(paramU); data.setClean(plug); // WRITE OUT ".distance" DATA: MDataHandle distanceDataHandle = data.outputValue(aDistance); distanceDataHandle.set(distance); data.setClean(plug); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
MStatus sgIkSmoothStretch::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if ( plug == aOutputDistance ) { MArrayDataHandle hArrInputDistance = data.inputArrayValue( aInputDistance ); MDataHandle hStretchAble = data.inputValue( aStretchAble ); MDataHandle hSmoothArea = data.inputValue( aSmoothArea ); float stretchAble = hStretchAble.asFloat(); double allDistance = 0.0; int arrayCount = hArrInputDistance.elementCount(); double* outputDistances = new double[arrayCount]; int multMinus = 1; for( int i=0; i<arrayCount; i++ ) { MDataHandle hInputDistance = hArrInputDistance.inputValue(); double inputDistance = hInputDistance.asDouble(); if( inputDistance < 0 ) { multMinus = -1; outputDistances[i] = -inputDistance; } else { outputDistances[i] = inputDistance; } allDistance += outputDistances[i]; hArrInputDistance.next(); } MDataHandle hInPosition = data.inputValue( aInPosition ); MDataHandle hInPositionX = hInPosition.child( aInPositionX ); MDataHandle hInPositionY = hInPosition.child( aInPositionY ); MDataHandle hInPositionZ = hInPosition.child( aInPositionZ ); double smoothArea = hSmoothArea.asDouble()*0.1; double poseDistance = sqrt( pow( hInPositionX.asDouble(), 2 )+pow( hInPositionY.asDouble(), 2 )+pow( hInPositionZ.asDouble(), 2 ) ) ; allDistance = fabs( allDistance ); double stretchRate = getSmoothStretchRate( outputDistances[0], outputDistances[1], poseDistance, smoothArea ); double smoothRate = getSmoothRate( outputDistances[0], outputDistances[1], poseDistance, smoothArea ); double currentRate = ( 1-stretchAble )*smoothRate + stretchAble*stretchRate; outputDistances[0] *= currentRate*multMinus; outputDistances[1] *= currentRate*multMinus; MArrayDataHandle hArrOutputDistance = data.outputArrayValue( aOutputDistance ); MArrayDataBuilder bArrOutputDistance( aOutputDistance, arrayCount, &stat ); for( int i=0; i<arrayCount; i++ ) { MDataHandle hOutputDistance = bArrOutputDistance.addElement( i ); hOutputDistance.set( outputDistances[i] ); } hArrOutputDistance.set( bArrOutputDistance ); hArrOutputDistance.setAllClean(); data.setClean( plug ); } return MS::kSuccess; }
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 AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock) { MStatus status; // update the frame number to be imported MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status); double speed = speedHandle.asDouble(); MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status); double offset = offsetHandle.asDouble(); MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status); MTime t = timeHandle.asTime(); double inputTime = t.as(MTime::kSeconds); double fps = getFPS(); // scale and offset inputTime. inputTime = computeAdjustedTime(inputTime, speed, offset/fps); // this should be done only once per file if (mFileInitialized == false) { mFileInitialized = true; MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr); MFileObject fileObject; fileObject.setRawFullName(dataHandle.asString()); MString fileName = fileObject.resolvedFullName(); // TODO, make sure the file name, or list of files create a valid // Alembic IArchive // initialize some flags for plug update mSubDInitialized = false; mPolyInitialized = false; // When an alembic cache will be imported at the first time using // AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be // mIncludeFilterString for later use. When we save a maya scene(.ma) // mIncludeFilterAttr will be saved. Then when we load the saved // .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr. MDataHandle includeFilterHandle = dataBlock.inputValue(mIncludeFilterAttr, &status); MString& includeFilterString = includeFilterHandle.asString(); if (mIncludeFilterString.length() > 0) { includeFilterHandle.set(mIncludeFilterString); dataBlock.setClean(mIncludeFilterAttr); } else if (includeFilterString.length() > 0) { mIncludeFilterString = includeFilterString; } MDataHandle excludeFilterHandle = dataBlock.inputValue(mExcludeFilterAttr, &status); MString& excludeFilterString = excludeFilterHandle.asString(); if (mExcludeFilterString.length() > 0) { excludeFilterHandle.set(mExcludeFilterString); dataBlock.setClean(mExcludeFilterAttr); } else if (excludeFilterString.length() > 0) { mExcludeFilterString = excludeFilterString; } MFnDependencyNode dep(thisMObject()); MPlug allSetsPlug = dep.findPlug("allColorSets"); CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(), MObject::kNullObj, CreateSceneVisitor::NONE, "", mIncludeFilterString, mExcludeFilterString); { mData.getFrameRange(mSequenceStartTime, mSequenceEndTime); MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr, &status); startFrameHandle.set(mSequenceStartTime*fps); MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr, &status); endFrameHandle.set(mSequenceEndTime*fps); } } // Retime MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status); short playType = cycleHandle.asShort(); inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime, playType); clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime); // update only when the time lapse is big enough if (fabs(inputTime - mCurTime) > 0.00001) { mOutRead = std::vector<bool>(mOutRead.size(), false); mCurTime = inputTime; } if (plug == mOutPropArrayAttr) { if (mOutRead[0]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[0] = true; unsigned int propSize = static_cast<unsigned int>(mData.mPropList.size()); if (propSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutPropArrayAttr, &status); unsigned int outHandleIndex = 0; MDataHandle outHandle; // for all of the nodes with sampled attributes for (unsigned int i = 0; i < propSize; i++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(); } else { continue; } if (mData.mPropList[i].mArray.valid()) { readProp(mCurTime, mData.mPropList[i].mArray, outHandle); } else if (mData.mPropList[i].mScalar.valid()) { // for visibility only if (mData.mPropList[i].mScalar.getName() == Alembic::AbcGeom::kVisibilityPropertyName) { Alembic::Util::int8_t visVal = 1; mData.mPropList[i].mScalar.get(&visVal, Alembic::Abc::ISampleSelector(mCurTime, Alembic::Abc::ISampleSelector::kNearIndex )); outHandle.setGenericBool(visVal != 0, false); } else { // for all scalar props readProp(mCurTime, mData.mPropList[i].mScalar, outHandle); } } outArrayHandle.next(); } outArrayHandle.setAllClean(); } } else if (plug == mOutTransOpArrayAttr ) { if (mOutRead[1]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[1] = true; unsigned int xformSize = static_cast<unsigned int>(mData.mXformList.size()); if (xformSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutTransOpArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr); MDataHandle outHandle; unsigned int outHandleIndex = 0; for (unsigned int i = 0; i < xformSize; i++) { std::vector<double> sampleList; if (mData.mIsComplexXform[i]) { readComplex(mCurTime, mData.mXformList[i], sampleList); } else { Alembic::AbcGeom::XformSample samp; read(mCurTime, mData.mXformList[i], sampleList, samp); } unsigned int sampleSize = (unsigned int)sampleList.size(); for (unsigned int j = 0; j < sampleSize; j++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(&status); } else continue; outArrayHandle.next(); outHandle.set(sampleList[j]); } } outArrayHandle.setAllClean(); } } else if (plug == mOutLocatorPosScaleArrayAttr ) { if (mOutRead[8]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[8] = true; unsigned int locSize = static_cast<unsigned int>(mData.mLocList.size()); if (locSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr); MDataHandle outHandle; unsigned int outHandleIndex = 0; for (unsigned int i = 0; i < locSize; i++) { std::vector< double > sampleList; read(mCurTime, mData.mLocList[i], sampleList); unsigned int sampleSize = (unsigned int)sampleList.size(); for (unsigned int j = 0; j < sampleSize; j++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(&status); } else continue; outArrayHandle.next(); outHandle.set(sampleList[j]); } } outArrayHandle.setAllClean(); } } else if (plug == mOutSubDArrayAttr) { if (mOutRead[2]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutSubDArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[2] = true; unsigned int subDSize = static_cast<unsigned int>(mData.mSubDList.size()); if (subDSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutSubDArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < subDSize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFnMesh fnMesh(obj); readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j], mSubDInitialized); outHandle.set(obj); } } mSubDInitialized = true; outArrayHandle.setAllClean(); } // for the case where we don't have any nodes, we want to make sure // to push out empty meshes on our connections, this can happen if // the input file was offlined, currently we only need to do this for // meshes as Nurbs, curves, and the other channels don't crash Maya else { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutSubDArrayAttr, &status); if (outArrayHandle.elementCount() > 0) { do { MDataHandle outHandle = outArrayHandle.outputValue(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFloatPointArray emptyVerts; MIntArray emptyCounts; MIntArray emptyConnects; MFnMesh emptyMesh; emptyMesh.create(0, 0, emptyVerts, emptyCounts, emptyConnects, obj); outHandle.set(obj); } } while (outArrayHandle.next() == MS::kSuccess); } mSubDInitialized = true; outArrayHandle.setAllClean(); } } else if (plug == mOutPolyArrayAttr) { if (mOutRead[3]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutPolyArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[3] = true; unsigned int polySize = static_cast<unsigned int>(mData.mPolyMeshList.size()); if (polySize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutPolyArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < polySize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFnMesh fnMesh(obj); readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j], mPolyInitialized); outHandle.set(obj); } } mPolyInitialized = true; outArrayHandle.setAllClean(); } // for the case where we don't have any nodes, we want to make sure // to push out empty meshes on our connections, this can happen if // the input file was offlined, currently we only need to do this for // meshes as Nurbs, curves, and the other channels don't crash Maya else { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutPolyArrayAttr, &status); if (outArrayHandle.elementCount() > 0) { do { MDataHandle outHandle = outArrayHandle.outputValue(&status); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFloatPointArray emptyVerts; MIntArray emptyCounts; MIntArray emptyConnects; MFnMesh emptyMesh; emptyMesh.create(0, 0, emptyVerts, emptyCounts, emptyConnects, obj); outHandle.set(obj); } } while (outArrayHandle.next() == MS::kSuccess); } mPolyInitialized = true; outArrayHandle.setAllClean(); } } else if (plug == mOutCameraArrayAttr) { if (mOutRead[4]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[4] = true; unsigned int cameraSize = static_cast<unsigned int>(mData.mCameraList.size()); if (cameraSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutCameraArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr); double angleConversion = 1.0; switch (MAngle::uiUnit()) { case MAngle::kRadians: angleConversion = 0.017453292519943295; break; case MAngle::kAngMinutes: angleConversion = 60.0; break; case MAngle::kAngSeconds: angleConversion = 3600.0; break; default: break; } MDataHandle outHandle; unsigned int index = 0; for (unsigned int cameraIndex = 0; cameraIndex < cameraSize; cameraIndex++) { Alembic::AbcGeom::ICamera & cam = mData.mCameraList[cameraIndex]; std::vector<double> array; read(mCurTime, cam, array); for (unsigned int dataIndex = 0; dataIndex < array.size(); dataIndex++, index++) { // skip over sparse elements if (index != outArrayHandle.elementIndex()) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); // not shutter angle index, so not an angle if (dataIndex != 11) { outHandle.set(array[dataIndex]); } else { outHandle.set(array[dataIndex] * angleConversion); } } // for the per camera data handles } // for each camera outArrayHandle.setAllClean(); } } else if (plug == mOutNurbsSurfaceArrayAttr) { if (mOutRead[5]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[5] = true; unsigned int nSurfaceSize = static_cast<unsigned int>(mData.mNurbsList.size()); if (nSurfaceSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < nSurfaceSize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) continue; outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kNurbsSurface)) { readNurbs(mCurTime, mData.mNurbsList[j], obj); outHandle.set(obj); } } outArrayHandle.setAllClean(); } } else if (plug == mOutNurbsCurveGrpArrayAttr) { if (mOutRead[6]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[6] = true; unsigned int nCurveGrpSize = static_cast<unsigned int>(mData.mCurvesList.size()); if (nCurveGrpSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status); MDataHandle outHandle; std::vector<MObject> curvesObj; for (unsigned int i = 0; i < nCurveGrpSize; ++i) { readCurves(mCurTime, mData.mCurvesList[i], mData.mNumCurves[i], curvesObj); } std::size_t numChild = curvesObj.size(); // not the best way to do this // only reading bunches of curves based on the connections would be // more efficient when there is a bunch of broken connections for (unsigned int i = 0; i < numChild; i++) { if (outArrayHandle.elementIndex() != i) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); status = outHandle.set(curvesObj[i]); } outArrayHandle.setAllClean(); } } else { return MS::kUnknownParameter; } dataBlock.setClean(plug); return status; }
MStatus MocapMesh::compute( const MPlug &plug, MDataBlock &data ) { MStatus stat; MDataHandle indata_inMesh = data.inputValue(in_inMesh, &stat); if(stat != MS::kSuccess) return stat; MDataHandle hMessage = data.outputValue( out_message, &stat ); if(stat != MS::kSuccess) return stat; double &v = hMessage.asDouble(); value += 0.001; v = value; MObject oMesh = indata_inMesh.asMesh(); MFnMesh fnMesh( oMesh ); MPointArray points; fnMesh.getPoints( points ); MIntArray vertCount, vertList; fnMesh.getTriangles( vertCount, vertList ); if (hPipe) { size_t pointLen = points.length() * sizeof(float) * 3; size_t vertLen = vertList.length() * sizeof(int); size_t headLen = 3 * sizeof(int); size_t packetLen = pointLen + vertLen + headLen; char *data = (char*) malloc(packetLen); unsigned int * header = (unsigned int*)data; header[0] = 0x3223; header[1] = pointLen; header[2] = vertLen; float *fptr = (float*) (data + headLen); for (int i = 0; i < points.length(); i++) { *fptr = (float)points[i].x; fptr++; *fptr = (float)points[i].y; fptr++; *fptr = (float)points[i].z; fptr++; } int *iptr = (int*) ( data + headLen + pointLen ); for (int i = 0; i < vertList.length(); i++) { *iptr = vertList[i]; iptr++; } DWORD written; if (!WriteFile(hPipe, data, packetLen, &written, NULL)) { TCHAR buf[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buf, 1024 * sizeof(TCHAR), 0); printf("Error Writing to pipe: %s", buf); } free(data); } MDataHandle outdata_message = data.outputValue(out_message, &stat); if(stat != MS::kSuccess) return stat; 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; }
// // A very simple implementation of validAndSetValue(). No lock // or limit checking on the rocking attribute is done in this method. // If you wish to apply locks and limits to the rocking attribute, you // would follow the approach taken in the rockingTransformCheck example. // Meaning you would implement methods similar to: // * applyRotationLocks(); // * applyRotationLimits(); // * checkAndSetRotation(); // but for the rocking attribute. The method checkAndSetRotation() // would be called below rather than updating the rocking attribute // directly. // MStatus rockingTransformNode::validateAndSetValue(const MPlug& plug, const MDataHandle& handle, const MDGContext& context) { MStatus status = MS::kSuccess; // Make sure that there is something interesting to process. // if (plug.isNull()) return MS::kFailure; MDataBlock block = forceCache(*(MDGContext *)&context); MDataHandle blockHandle = block.outputValue(plug, &status); ReturnOnError(status); MString cachename = block.inputValue( acachename ).asString(); MString meshname = block.inputValue( ameshname ).asString(); /* if ( plug == aRockInX ) { // Update our new rock in x value double rockInX = handle.asDouble(); blockHandle.set(rockInX); rockXValue = rockInX; // Update the custom transformation matrix to the // right rock value. rockingTransformMatrix *ltm = getRockingTransformMatrix(); if (ltm) ltm->setRockInX(rockXValue); else MGlobal::displayError("Failed to get rock transform matrix"); blockHandle.setClean(); // Mark the matrix as dirty so that DG information // will update. dirtyMatrix(); } */ if ( plug == aframe ) { // Update our new rock in x value double rockInX = handle.asDouble(); blockHandle.set(rockInX); rockXValue = rockInX; // Update the custom transformation matrix to the // right rock value. rockingTransformMatrix *ltm = getRockingTransformMatrix(); if (ltm) ltm->setRockInX(rockXValue, cachename, meshname); else MGlobal::displayError("Failed to get rock transform matrix"); blockHandle.setClean(); // Mark the matrix as dirty so that DG information // will update. dirtyMatrix(); } // Allow processing for other attributes return ParentClass::validateAndSetValue(plug, handle, context); }
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 sgHair_controlJoint::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MDataHandle hStaticRotation = data.inputValue( aStaticRotation ); m_bStaticRotation = hStaticRotation.asBool(); if( m_isDirtyMatrix ) { MDataHandle hInputBaseCurveMatrix = data.inputValue( aInputBaseCurveMatrix ); m_mtxBaseCurve = hInputBaseCurveMatrix.asMatrix(); } if( m_isDirtyParentMatrixBase ) { MDataHandle hJointParenBasetMatrix = data.inputValue( aJointParentBaseMatrix ); m_mtxJointParentBase = hJointParenBasetMatrix.asMatrix(); } if( m_isDirtyCurve || m_isDirtyParentMatrixBase ) { MDataHandle hInputBaseCurve = data.inputValue( aInputBaseCurve ); MFnNurbsCurve fnCurve = hInputBaseCurve.asNurbsCurve(); fnCurve.getCVs( m_cvs ); getJointPositionBaseWorld(); } if( m_isDirtyGravityOption || m_isDirtyCurve || m_isDirtyParentMatrixBase ) { MDataHandle hGravityParam = data.inputValue( aGravityParam ); MDataHandle hGravityRange = data.inputValue( aGravityRange ); MDataHandle hGravityWeight = data.inputValue( aGravityWeight ); MDataHandle hGravityOffsetMatrix = data.inputValue( aGravityOffsetMatrix ); m_paramGravity = hGravityParam.asDouble(); m_rangeGravity = hGravityRange.asDouble(); m_weightGravity = hGravityWeight.asDouble(); m_mtxGravityOffset = hGravityOffsetMatrix.asMatrix(); m_mtxGravityOffset( 3,0 ) = 0.0; m_mtxGravityOffset( 3,1 ) = 0.0; m_mtxGravityOffset( 3,2 ) = 0.0; setGravityJointPositionWorld(); } setOutput(); MArrayDataHandle hArrOutput = data.outputValue( aOutput ); MArrayDataBuilder builderOutput( aOutput, m_cvs.length() ); for( int i=0; i< m_cvs.length(); i++ ) { MDataHandle hOutput = builderOutput.addElement( i ); MDataHandle hOutTrans = hOutput.child( aOutTrans ); MDataHandle hOutOrient = hOutput.child( aOutOrient ); hOutTrans.set( m_vectorArrTransJoint[i] ); hOutOrient.set( m_vectorArrRotateJoint[i] ); } hArrOutput.set( builderOutput ); hArrOutput.setAllClean(); data.setClean( plug ); m_isDirtyMatrix = false; m_isDirtyCurve = false; m_isDirtyGravityOption = false; m_isDirtyParentMatrixBase = false; return MS::kSuccess; }
MStatus retargetLocator::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MDataHandle hDiscMatrix = data.inputValue( aDiscMatrix ); MDataHandle hDiscAxis = data.inputValue( aDiscAxis ); MDataHandle hDiscAngle = data.inputValue( aDiscAngle ); MDataHandle hDiscDivision = data.inputValue( aDiscDivision ); MDataHandle hDiscOffset = data.inputValue( aDiscOffset ); MDataHandle hDiscSize = data.inputValue( aDiscSize ); MDataHandle hDiscActiveColor = data.inputValue( aDiscActiveColor ); MDataHandle hDiscLeadColor = data.inputValue( aDiscLeadColor ); MDataHandle hDiscDefaultColor = data.inputValue( aDiscDefaultColor ); MDataHandle hDiscFillAlpha = data.inputValue( aDiscFillAlpha ); MDataHandle hDiscLineAlpha = data.inputValue( aDiscLineAlpha ); discAxis = hDiscAxis.asInt(); discDivision = hDiscDivision.asInt(); discAngle = hDiscAngle.asDouble(); discSize = hDiscSize.asVector(); discOffset = hDiscOffset.asVector(); discActiveColor = hDiscActiveColor.asFloat3(); discLeadColor = hDiscLeadColor.asFloat3(); discDefaultColor = hDiscDefaultColor.asFloat3(); discFillAlpha = hDiscFillAlpha.asFloat(); discLineAlpha = hDiscLineAlpha.asFloat(); MArrayDataHandle hArrArrow = data.inputArrayValue( aArrow ); arrowNum = hArrArrow.elementCount(); inheritMatrix.setLength( arrowNum ); aimMatrix.setLength( arrowNum ); inputMeshObj.setLength( arrowNum ); startSize.setLength( arrowNum ); size.setLength( arrowNum ); activeColor.setLength( arrowNum ); leadColor.setLength( arrowNum ); defaultColor.setLength( arrowNum ); fillAlpha.setLength( arrowNum ); lineAlpha.setLength( arrowNum ); offset.setLength( arrowNum ); for( int i =0; i < arrowNum; i++ ) { MDataHandle hArrow = hArrArrow.inputValue(); MDataHandle hInheritMatrix = hArrow.child( aInheritMatrix ); MDataHandle hAimMatrix = hArrow.child( aAimMatrix ); MDataHandle hInputMesh = hArrow.child( aInputMesh ); MDataHandle hStartSize = hArrow.child( aStartSize ); MDataHandle hSize = hArrow.child( aSize ); MDataHandle hActiveColor = hArrow.child( aActiveColor ); MDataHandle hLeadColor = hArrow.child( aLeadColor ); MDataHandle hDefaultColor = hArrow.child( aDefaultColor ); MDataHandle hFillAlpha = hArrow.child( aFillAlpha ); MDataHandle hLineAlpha = hArrow.child( aLineAlpha ); MDataHandle hOffset = hArrow.child( aOffset ); inheritMatrix[i] = hInheritMatrix.asBool(); aimMatrix[i] = hAimMatrix.asMatrix()*hDiscMatrix.asMatrix().inverse(); inputMeshObj[i] = hInputMesh.asMesh(); startSize[i] = hStartSize.asFloat(); size[i] = hSize.asFloat(); activeColor[i] = hActiveColor.asFloat3(); leadColor[i] = hLeadColor.asFloat3(); defaultColor[i] = hDefaultColor.asFloat3(); fillAlpha[i] = hFillAlpha.asFloat(); lineAlpha[i] = hLineAlpha.asFloat(); offset[i] = hOffset.asVector(); hArrArrow.next(); } MDataHandle hOutput = data.outputValue( aOutput ); hOutput.set( 1.0 ); data.setClean( plug ); 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 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; }
MStatus stringFormat::compute (const MPlug& plug, MDataBlock& data) { MStatus status; // Check that the requested recompute is one of the output values // if (plug == attrOutput) { // Read the input values // MDataHandle inputData = data.inputValue (attrFormat, &status); CHECK_MSTATUS( status ); MString format = inputData.asString(); // Get input data handle, use outputArrayValue since we do not // want to evaluate all inputs, only the ones related to the // requested multiIndex. This is for efficiency reasons. // MArrayDataHandle vals = data.outputArrayValue(attrValues, &status); CHECK_MSTATUS( status ); int indx = 0; int param; char letter; while ((indx = findNextMatch(format, indx, param, letter)) > 0) { double val = 0.; status = vals.jumpToElement(param); if (status == MStatus::kSuccess) { MDataHandle thisVal = vals.inputValue( &status ); if (status == MStatus::kSuccess) { val = thisVal.asDouble(); } } MString replace; bool valid = false; switch (letter) { case 'd': // Integer val = floor(val+.5); // No break here case 'f': // Float replace.set(val); valid = true; break; case 't': // Timecode { const char * sign = ""; if (val<0) { sign = "-"; val = -val; } int valInt = (int)(val+.5); int sec = valInt / 24; int frame = valInt - sec * 24; int min = sec / 60; sec -= min * 60; int hour = min / 60; min -= hour * 60; char buffer[90]; if (hour>0) sprintf(buffer, "%s%d:%02d:%02d.%02d", sign, hour, min, sec, frame); else sprintf(buffer, "%s%02d:%02d.%02d", sign, min, sec, frame); replace = buffer; } valid = true; break; } if (valid) { format = format.substring(0, indx-2) + replace + format.substring(indx+2, format.length()-1); indx += replace.length() - 3; } } // Store the result // MDataHandle output = data.outputValue(attrOutput, &status ); CHECK_MSTATUS( status ); output.set( format ); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
MStatus multiCurve::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if ( plug == outputCurves ) { MDataHandle numCurvesHandle = data.inputValue(numCurves, &stat); PERRORfail(stat, "multiCurve::compute getting numCurves"); int num = numCurvesHandle.asLong(); MDataHandle curveOffsetHandle = data.inputValue(curveOffset, &stat); PERRORfail(stat, "multiCurve::compute getting curveOffset"); double baseOffset = curveOffsetHandle.asDouble(); MDataHandle inputCurveHandle = data.inputValue(inputCurve, &stat); PERRORfail(stat, "multiCurve::compute getting inputCurve"); MObject inputCurveObject ( inputCurveHandle.asNurbsCurveTransformed() ); MFnNurbsCurve inCurveFS ( inputCurveObject ); MArrayDataHandle outputArray = data.outputArrayValue(outputCurves, &stat); PERRORfail(stat, "multiCurve::compute getting output data handle"); // Create an array data build that is preallocated to hold just // the number of curves we plan on creating. When this builder // is set in to the MArrayDataHandle at the end of the compute // method, the new array will replace the existing array in the // scene. // // If the number of elements of the multi does not change between // compute cycles, then one can reuse the space allocated on a // previous cycle by extracting the existing builder from the // MArrayDataHandle: // MArrayDataBuilder builder( outputArray.builder(&stat) ); // this later form of the builder will allow you to rewrite elements // of the array, and to grow it, but the array can only be shrunk by // explicitly removing elements with the method // MArrayDataBuilder::removeElement(unsigned index); // MArrayDataBuilder builder(outputCurves, num, &stat); PERRORfail(stat, "multiCurve::compute creating builder"); for (int curveNum = 0; curveNum < num; curveNum++) { MDataHandle outHandle = builder.addElement(curveNum); MFnNurbsCurveData dataCreator; MObject outCurveData = dataCreator.create(); MObject outputCurve = inCurveFS.copy(inputCurveObject, outCurveData, &stat); PERRORfail(stat, "multiCurve::compute copying curve"); MFnNurbsCurve outCurveFS ( outputCurve ); MPointArray cvs; double offset = baseOffset * (curveNum+1); outCurveFS.getCVs ( cvs, MSpace::kWorld ); int numCVs = cvs.length(); for (int i = 0; i < numCVs; i++) { cvs[i].x += offset; } outCurveFS.setCVs ( cvs ); outHandle.set(outCurveData); } // Set the builder back into the output array. This statement // is always required, no matter what constructor was used to // create the builder. stat = outputArray.set(builder); PERRORfail(stat, "multiCurve::compute setting the builder"); // Since we compute all the elements of the array, instead of // just marking the plug we were asked to compute as clean, mark // every element of the array as clean to prevent further calls // to this compute method during this DG evaluation cycle. stat = outputArray.setAllClean(); PERRORfail(stat, "multiCurve::compute cleaning outputCurves"); } else { return MS::kUnknownParameter; } return stat; }