bool OpenSubdivShader::setInternalValueInContext(const MPlug &plug, const MDataHandle &handle, MDGContext &) { if (plug == aLevel) { _hbrMeshDirty = true; _level = handle.asLong(); } else if (plug == aTessFactor) { _tessFactor = handle.asLong(); } else if (plug == aScheme) { _hbrMeshDirty = true; _scheme = (OsdMeshData::SchemeType)handle.asShort(); } else if (plug == aKernel) { _hbrMeshDirty = true; _kernel = (OsdMeshData::KernelType)handle.asShort(); } else if (plug == aInterpolateBoundary) { _hbrMeshDirty = true; _interpolateBoundary = (OsdMeshData::InterpolateBoundaryType)handle.asShort(); } else if (plug == aAdaptive) { _hbrMeshDirty = true; _adaptiveDirty = true; _adaptive = handle.asBool(); } else if (plug == aDiffuseMapFile) { _diffuseMapDirty = true; _diffuseMapFile = handle.asString(); } else if (plug == aUVSet) { _hbrMeshDirty = true; _uvSet = handle.asString(); } else if (plug == aInterpolateUVBoundary) { _hbrMeshDirty = true; _interpolateUVBoundary = (OsdMeshData::InterpolateBoundaryType)handle.asShort(); } else if (plug == aShaderSource) { _shaderSourceFilename = handle.asString(); std::ifstream ifs; ifs.open(_shaderSourceFilename.asChar()); if (ifs.fail()) { printf("Using default shader\n"); _shaderSource.clear(); _shaderSourceFilename.clear(); } else { printf("Using %s shader\n", _shaderSourceFilename.asChar()); std::stringstream buffer; buffer << ifs.rdbuf(); _shaderSource = buffer.str(); } ifs.close(); _shaderSourceDirty = true; } return false; }
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; }
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 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; }
MStatus clusterControledCurve::compute( const MPlug& plug, MDataBlock& data ) { //MFnDependencyNode thisNode( thisMObject() ); //cout << thisNode.name() << ", start" << endl; MStatus status; MDataHandle hInputCurve = data.inputValue( aInputCurve, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hInputCurveMatrix = data.inputValue( aInputCurveMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hOutputCurve = data.outputValue( aOutputCurve, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MArrayDataHandle hArrBindPreMatrix = data.inputArrayValue( aBindPreMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MArrayDataHandle hArrMatrix = data.inputArrayValue( aMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MArrayDataHandle hArrWeightList = data.inputArrayValue( aWeightList, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hUpdate = data.inputValue( aUpdate, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MObject oInputCurve = hInputCurve.asNurbsCurve(); int bindPreMatrixLength = hArrBindPreMatrix.elementCount(); int matrixLength = hArrMatrix.elementCount(); MFnNurbsCurve fnInputCurve = oInputCurve; int numCVs = fnInputCurve.numCVs(); int weightListLength = hArrWeightList.elementCount(); if( weightListLength > 100 ) { cout << "WeightList Count Error : " << weightListLength << endl; return MS::kFailure; } MPointArray inputCvPoints; MPointArray outputCvPoints; fnInputCurve.getCVs( inputCvPoints ); outputCvPoints.setLength( numCVs ); MMatrix matrix; MMatrix inputCurveMatrix = hInputCurveMatrix.asMatrix(); MMatrix inputCurveMatrixInverse = inputCurveMatrix.inverse(); if( requireUpdate ) CHECK_MSTATUS_AND_RETURN_IT( updateBindPreMatrix( oInputCurve, inputCurveMatrixInverse, hArrMatrix, hArrBindPreMatrix, hUpdate.asBool() ) ); for( int i=0; i< numCVs; i++ ) { inputCvPoints[i] *= inputCurveMatrix; } for( int i=0; i< numCVs; i++ ) { outputCvPoints[i] = MPoint( 0,0,0 ); double weight; for( int j=0; j< matrixLength; j++ ) { weight = setWeights[i][j]; hArrMatrix.jumpToElement( j ); matrix = hArrMatrix.inputValue().asMatrix(); outputCvPoints[i] += inputCvPoints[i]*bindPreMatrix[j]*matrix*weight; } } for( int i=0; i< numCVs; i++ ) { outputCvPoints[i] *= inputCurveMatrixInverse; } MFnNurbsCurveData outputCurveData; MObject oOutputCurve = outputCurveData.create(); fnInputCurve.copy( oInputCurve, oOutputCurve ); MFnNurbsCurve fnOutputCurve( oOutputCurve, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); fnOutputCurve.setCVs( outputCvPoints ); hOutputCurve.set( oOutputCurve ); data.setClean( plug ); //cout << thisNode.name() << ", end" << endl; return status; }
MStatus finalproject::compute(const MPlug& plug, MDataBlock& data) { // do this if we are using an OpenMP implementation that is not the same as Maya's. // Even if it is the same, it does no harm to make this call. MThreadUtils::syncNumOpenMPThreads(); MStatus status = MStatus::kUnknownParameter; if (plug.attribute() != outputGeom) { return status; } unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); // get input value MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = data.inputValue(inPlug, &status); MCheckStatus(status, "ERROR getting input mesh\n"); // get the input geometry MDataHandle inputData = hInput.child(inputGeom); if (inputData.type() != MFnData::kMesh) { printf("Incorrect input geometry type\n"); return MStatus::kFailure; } // get the input groupId - ignored for now... MDataHandle hGroup = inputData.child(groupId); unsigned int groupId = hGroup.asLong(); // get deforming mesh MDataHandle deformData = data.inputValue(deformingMesh, &status); MCheckStatus(status, "ERROR getting deforming mesh\n"); if (deformData.type() != MFnData::kMesh) { printf("Incorrect deformer geometry type %d\n", deformData.type()); return MStatus::kFailure; } MDataHandle offloadData = data.inputValue(offload, &status); //gathers world space positions of the object and the magnet MObject dSurf = deformData.asMeshTransformed(); MObject iSurf = inputData.asMeshTransformed(); MFnMesh fnDeformingMesh, fnInputMesh; fnDeformingMesh.setObject( dSurf ) ; fnInputMesh.setObject( iSurf ) ; MDataHandle outputData = data.outputValue(plug); outputData.copy(inputData); if (outputData.type() != MFnData::kMesh) { printf("Incorrect output mesh type\n"); return MStatus::kFailure; } MItGeometry iter(outputData, groupId, false); // get all points at once. Faster to query, and also better for // threading than using iterator MPointArray objVerts; iter.allPositions(objVerts); int objNumPoints = objVerts.length(); MPointArray magVerts, tempverts; fnDeformingMesh.getPoints(magVerts); fnInputMesh.getPoints(tempverts); int magNumPoints = magVerts.length(); double min = DBL_MAX, max = -DBL_MAX; //finds min and max z-coordinate values to determine middle point (choice of z-axis was ours) for (int i = 0; i < magNumPoints; i++) { min = magVerts[i].z < min ? magVerts[i].z : min; max = magVerts[i].z > max ? magVerts[i].z : max; } double middle = (min + max) / 2; double polarity[magNumPoints]; //assigns polarity based on middle point of mesh for (int i = 0; i < magNumPoints; i++) { polarity[i] = magVerts[i].z > middle ? max / magVerts[i].z : -min / magVerts[i].z; } double* objdVerts = (double *)malloc(sizeof(double) * objNumPoints * 3); double* magdVerts = (double *)malloc(sizeof(double) * magNumPoints * 3); //creates handles to use attribute data MDataHandle vecX = data.inputValue(transX, &status); MDataHandle vecY = data.inputValue(transY, &status); MDataHandle vecZ = data.inputValue(transZ, &status); //gathers previously stored coordinates of the center of the object double moveX = vecX.asFloat(); double moveY = vecY.asFloat(); double moveZ = vecZ.asFloat(); //translates object based on the position stored in the attribute values for (int i=0; i<objNumPoints; i++) { objdVerts[i * 3] = tempverts[i].x + moveX; objdVerts[i * 3 + 1] = tempverts[i].y + moveY; objdVerts[i * 3 + 2] = tempverts[i].z + moveZ; } for (int i=0; i<magNumPoints; i++) { magdVerts[i * 3] = magVerts[i].x; magdVerts[i * 3 + 1] = magVerts[i].y; magdVerts[i * 3 + 2] = magVerts[i].z; } double teslaData = data.inputValue(tesla, &status).asDouble(); MDataHandle posiData = data.inputValue(positivelycharged, &status); double pivot[6] = {DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX}; //finds the pivot point of the object in world space prior to being affected by the magnet for (int i = 0; i < tempverts.length(); i++) { pivot[0] = tempverts[i].x < pivot[0] ? tempverts[i].x : pivot[0]; pivot[1] = tempverts[i].x > pivot[1] ? tempverts[i].x : pivot[1]; pivot[2] = tempverts[i].y < pivot[2] ? tempverts[i].y : pivot[2]; pivot[3] = tempverts[i].y > pivot[3] ? tempverts[i].y : pivot[3]; pivot[4] = tempverts[i].z < pivot[4] ? tempverts[i].z : pivot[4]; pivot[5] = tempverts[i].z > pivot[5] ? tempverts[i].z : pivot[5]; } MTimer timer; timer.beginTimer(); //main function call magnetForce(magNumPoints, objNumPoints, teslaData, magdVerts, objdVerts, polarity, posiData.asBool(), offloadData.asBool()); timer.endTimer(); printf("Runtime for threaded loop %f\n", timer.elapsedTime()); for (int i=0; i<objNumPoints; i++) { objVerts[i].x = objdVerts[i * 3 + 0]; objVerts[i].y = objdVerts[i * 3 + 1]; objVerts[i].z = objdVerts[i * 3 + 2]; } //finds the pivot point of object in world space after being affected by the magnet double objCenter[6] = {DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX}; for (int i = 0; i < tempverts.length(); i++) { objCenter[0] = objVerts[i].x < objCenter[0] ? objVerts[i].x : objCenter[0]; objCenter[1] = objVerts[i].x > objCenter[1] ? objVerts[i].x : objCenter[1]; objCenter[2] = objVerts[i].y < objCenter[2] ? objVerts[i].y : objCenter[2]; objCenter[3] = objVerts[i].y > objCenter[3] ? objVerts[i].y : objCenter[3]; objCenter[4] = objVerts[i].z < objCenter[4] ? objVerts[i].z : objCenter[4]; objCenter[5] = objVerts[i].z > objCenter[5] ? objVerts[i].z : objCenter[5]; } //creates vector based on the two calculated pivot points moveX = (objCenter[0] + objCenter[1]) / 2 - (pivot[0] + pivot[1]) / 2; moveY = (objCenter[2] + objCenter[3]) / 2 - (pivot[2] + pivot[3]) / 2; moveZ = (objCenter[4] + objCenter[5]) / 2 - (pivot[4] + pivot[5]) / 2; //stores pivot vector for next computation if (teslaData) { vecX.setFloat(moveX); vecY.setFloat(moveY); vecZ.setFloat(moveZ); } // write values back onto output using fast set method on iterator iter.setAllPositions(objVerts, MSpace::kWorld); free(objdVerts); free(magdVerts); return status; }
bool OpenSubdivPtexShader::setInternalValueInContext(const MPlug &plug, const MDataHandle &handle, MDGContext &) { if (plug == aLevel) { _hbrMeshDirty = true; _level = handle.asLong(); } else if (plug == aTessFactor) { _tessFactor = handle.asLong(); } else if (plug == aScheme) { _hbrMeshDirty = true; _scheme = (OsdPtexMeshData::SchemeType)handle.asShort(); } else if (plug == aKernel) { _hbrMeshDirty = true; _kernel = (OsdPtexMeshData::KernelType)handle.asShort(); } else if (plug == aInterpolateBoundary) { _hbrMeshDirty = true; _interpolateBoundary = (OsdPtexMeshData::InterpolateBoundaryType)handle.asShort(); } else if (plug == aAdaptive) { _hbrMeshDirty = true; _adaptiveDirty = true; _adaptive = handle.asBool(); } else if (plug == aShaderSource) { _shaderSourceFilename = handle.asString(); std::ifstream ifs; ifs.open(_shaderSourceFilename.asChar()); if (ifs.fail()) { printf("Using default shader\n"); _shaderSource.clear(); _shaderSourceFilename.clear(); } else { printf("Using %s shader\n", _shaderSourceFilename.asChar()); std::stringstream buffer; buffer << ifs.rdbuf(); _shaderSource = buffer.str(); } ifs.close(); _shaderSourceDirty = true; } else if (plug == aDiffuseEnvironmentMapFile) { _diffEnvMapDirty = true; _diffEnvMapFile = handle.asString(); } else if (plug == aSpecularEnvironmentMapFile) { _specEnvMapDirty = true; _specEnvMapFile = handle.asString(); } else if (plug == aColorFile) { _ptexColorDirty = true; _colorFile = handle.asString(); } else if (plug == aDisplacementFile) { _ptexDisplacementDirty = true; _displacementFile = handle.asString(); } else if (plug == aOcclusionFile) { _ptexOcclusionDirty = true; _occlusionFile = handle.asString(); } else if (plug == aEnableColor) { _enableColor = handle.asBool(); } else if (plug == aEnableDisplacement) { _enableDisplacement = handle.asBool(); } else if (plug == aEnableOcclusion) { _enableOcclusion = handle.asBool(); } else if (plug == aEnableNormal) { _enableNormal = handle.asBool(); } return false; }
MStatus MG_nurbsRivet::compute(const MPlug& plug,MDataBlock& dataBlock) { //Get recompute value MDataHandle recomputeH = dataBlock.inputValue(recompute); bool recomputeV = recomputeH.asBool(); //input mesh MDataHandle inputNurbsH = dataBlock.inputValue(inputNurbSurface); MObject inputNurb = inputNurbsH.asNurbsSurfaceTransformed(); MMatrix offsetMatrixV = dataBlock.inputValue(offsetMatrix).asMatrix(); double U,V; MFnNurbsSurface nurbsFn ; nurbsFn.setObject(inputNurb); MStatus stat; if (recomputeV == true) { //input point MDataHandle inputPointH = dataBlock.inputValue(inputPoint); MPoint inputP = inputPointH.asVector(); MPoint closestP = nurbsFn.closestPoint(inputP,NULL,NULL,false,1e+99,MSpace::kObject); stat = nurbsFn.getParamAtPoint(closestP,U,V,MSpace::kObject); //Handle to U and V MDataHandle uValueH =dataBlock.outputValue(uValue); MDataHandle vValueH =dataBlock.outputValue(vValue); uValueH.set(float(U)); vValueH.set(float(V)); uValueH.setClean(); vValueH.setClean(); MDataHandle recomputeOutH = dataBlock.outputValue(recompute); } MDataHandle uH = dataBlock.inputValue(uValue); MDataHandle vH = dataBlock.inputValue(vValue); U = uH.asFloat(); V = vH.asFloat(); MPoint outPoint ; MVector uVec ; MVector vVec; MVector normal; //Get point stat = nurbsFn.getPointAtParam(U,V,outPoint,MSpace::kObject); //Since if getting both the U and V tangent was leading to some little rotation snapping //of the rivet I only used the U tangent and calculated the next one by dot product //of the normal and U tangent leading to a 100% stable rivet nurbsFn.getTangents(U,V,uVec,vVec,MSpace::kObject); uVec.normalize(); vVec.normalize(); MVector vVecCross; //Get normal normal = nurbsFn.normal(U,V,MSpace::kObject); normal.normalize(); vVecCross =(uVec^normal); //Build the maya matrix double myMatrix[4][4]={ { uVec.x, uVec.y , uVec.z, 0}, { normal[0], normal[1] , normal[2], 0}, {vVecCross.x, vVecCross.y , vVecCross.z, 0}, { outPoint[0], outPoint[1] , outPoint[2], 1}}; MMatrix rotMatrix (myMatrix); MMatrix offsetMatrixV2 = offsetMatrixV*rotMatrix; MTransformationMatrix matrixFn(offsetMatrixV2); double angles[3]; MTransformationMatrix::RotationOrder rotOrder; rotOrder =MTransformationMatrix::kXYZ; matrixFn.getRotation(angles,rotOrder,MSpace::kObject ); //get back radians value double radX,radY,radZ; radX=angles[0]; radY=angles[1]; radZ=angles[2]; //convert to degree double rotX,rotY,rotZ; rotX = radX*toDeg; rotY = radY*toDeg; rotZ = radZ*toDeg; MDataHandle outputRotateH = dataBlock.outputValue(outputRotate); outputRotateH.set3Double(rotX,rotY,rotZ); outputRotateH.setClean(); //let set the output matrix too MDataHandle outMH= dataBlock.outputValue(outputMatrix); outMH.set(rotMatrix); outMH.setClean(); MDataHandle outputH = dataBlock.outputValue(output); outputH.set(offsetMatrixV2[3][0],offsetMatrixV2[3][1],offsetMatrixV2[3][2]); outputH.setClean(); return MS::kSuccess; }
MStatus puttyNode::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& worldMatrix, unsigned int multiIndex) { // MGlobal::displayInfo("deform"); MStatus status = MS::kSuccess; ///////////////////////////////////////////////////////////////////////////////////////////////// // // get inputs // // get the node ready flag MDataHandle dh = block.inputValue(aScriptSourced,&status); SYS_ERROR_CHECK(status, "Error getting aScriptSourced data handle\n"); bool scriptSourced = dh.asBool(); if (!scriptSourced) return MS::kSuccess; dh = block.inputValue(aNodeReady,&status); SYS_ERROR_CHECK(status, "Error getting node ready data handle\n"); bool nodeReady = dh.asBool(); // if it's not ready, don't do anything if (!nodeReady) return MS::kSuccess; dh = block.inputValue(aDefSpace,&status); SYS_ERROR_CHECK(status, "Error getting defSpace data handle\n"); short defSpace = dh.asShort(); dh = block.inputValue(aDefWeights,&status); SYS_ERROR_CHECK(status, "Error getting defWeights data handle\n"); short defWeights = dh.asShort(); dh = block.inputValue(aDefEnvelope,&status); SYS_ERROR_CHECK(status, "Error getting defEnvelope data handle\n"); short defEnvelope = dh.asShort(); // get the command dh = block.inputValue(aCmdBaseName,&status); SYS_ERROR_CHECK(status, "Error getting aCmdBaseName handle\n"); MString script = dh.asString(); /* if (script == "") { status = MS::kFailure; USER_ERROR_CHECK(status, "no script provided!\n"); } */ ///////////////////////////////////////////////////////////////////////////////////////////////// // // build mel cmd string // // check if it's a valid cmd // get the envelope // double env = 1; if (defEnvelope == MSD_ENVELOPE_AUTO) { dh = block.inputValue(envelope,&status); SYS_ERROR_CHECK(status, "Error getting envelope data handle\n"); env = double(dh.asFloat()); // early stop 'cause there is nothing more to do if (env == 0.0) return MS::kSuccess; } // get the points, transform them into the right space if needed // int count = iter.count(); MVectorArray points(count); for ( ; !iter.isDone(); iter.next()) points[iter.index()] = iter.position(); if ( defSpace == MSD_SPACE_WORLD ) { for (int i = 0;i<count;i++) points[i] = MPoint(points[i]) * worldMatrix; } // get the weights // MDoubleArray weights; if ( defWeights == MSD_WEIGHTS_AUTO) { weights.setLength(count); for (int i = 0;i<count;i++) weights[i] = weightValue(block,multiIndex,i); } // get the object name and type // get the input geometry, traverse through the data handles MArrayDataHandle adh = block.outputArrayValue( input, &status ); SYS_ERROR_CHECK(status,"error getting input array data handle.\n"); status = adh.jumpToElement( multiIndex ); SYS_ERROR_CHECK(status, "input jumpToElement failed.\n"); // compound data MDataHandle cdh = adh.inputValue( &status ); SYS_ERROR_CHECK(status, "error getting input inputValue\n"); // input geometry child dh = cdh.child( inputGeom ); MObject dInputGeometry = dh.data(); // get the type MString geometryType = dInputGeometry.apiTypeStr(); // get the name // MFnDagNode dagFn( dInputGeometry, &status); // SYS_ERROR_CHECK(status, "error converting geometry obj to dag node\n"); // MString geometryName = dagFn.fullPathName(&status); // SYS_ERROR_CHECK(status, "error getting full path name \n"); // MString geometryType = ""; // MString geometryName = ""; ///////////////////////////////////////////////////////////////////////////////////////////////// // // set the current values on the temp plugs for the script to be picked up // // the position MObject thisNode = thisMObject(); MPlug currPlug(thisNode,aCurrPosition); MFnVectorArrayData vecD; MObject currObj = vecD.create(points,&status); currPlug.setValue(currObj); SYS_ERROR_CHECK(status, "error setting currPosPlug value\n"); // the weights currPlug =MPlug(thisNode,aCurrWeight); MFnDoubleArrayData dblD; currObj = dblD.create(weights,&status); currPlug.setValue(currObj); SYS_ERROR_CHECK(status, "error setting currWeightsPlug value\n"); // world matrix currPlug =MPlug(thisNode,aCurrWorldMatrix); MFnMatrixData matD; currObj = matD.create(worldMatrix,&status); currPlug.setValue(currObj); SYS_ERROR_CHECK(status, "error setting currWorldMatrixPlug value\n"); // the multi index currPlug =MPlug(thisNode,aCurrMultiIndex); currPlug.setValue(int(multiIndex)); SYS_ERROR_CHECK(status, "error setting currMultiIndexPlug value\n"); // geometry name/type // currPlug =MPlug(thisNode,aCurrGeometryName); // currPlug.setValue(geometryName); // SYS_ERROR_CHECK(status, "error setting aCurrGeometryName value\n"); currPlug =MPlug(thisNode,aCurrGeometryType); currPlug.setValue(geometryType); SYS_ERROR_CHECK(status, "error setting aCurrGeometryType value\n"); ///////////////////////////////////////////////////////////////////////////////////////////////// // // execute the mel script // MString melCmd = script+"(\"" +name()+"\","+count+")"; MCommandResult melResult; status = MGlobal::executeCommand(melCmd,melResult); // if the command did not work, then try to resource the script // (might have been that we were in a fresh scene and nothing was ready yet if (status != MS::kSuccess) { dh = block.inputValue(aScript,&status); SYS_ERROR_CHECK(status, "Error getting aCmdBaseName handle\n"); MString scriptFile = dh.asString(); // try to source the script MString cmd = "source \"" + scriptFile+"\""; MCommandResult melResult; status = MGlobal::executeCommand(cmd,melResult); // if successfull, retry the command if (!status.error()) { status = MGlobal::executeCommand(melCmd,melResult); } } USER_ERROR_CHECK(status, "Error executing mel command, please check the function you provided is valid, error free and has the appropriate parameters!"); // check the result type if ((melResult.resultType()) != (MCommandResult::kDoubleArray)) { USER_ERROR_CHECK(MS::kFailure, "result of mel command has wrong type, should be doubleArray (which will be interpreted as vectorArray)!"); } // get the result as a double array MDoubleArray newP; status = melResult.getResult(newP); USER_ERROR_CHECK(status, "Error getting result of mel command!"); int newCount = newP.length()/3; // size check if (newCount != count) { USER_ERROR_CHECK(MS::kFailure, "the size of the result does not match the size of the input!"); } // convert the double array into a vector array MPointArray newPoints(newCount); for(int i=0;i<newCount;i++) newPoints[i]=MPoint(newP[i*3],newP[i*3+1],newP[i*3+2]); ///////////////////////////////////////////////////////////////////////////////////////////////// // // interprete and apply the result // // do the envelope and weights if ((defEnvelope == MSD_ENVELOPE_AUTO)||((defWeights == MSD_WEIGHTS_AUTO))) { MDoubleArray envPP(count, env); if (defWeights == MSD_WEIGHTS_AUTO) { for (int i = 0;i<count;i++) envPP[i] *= weights[i]; } // linear interpolation between old and new points for (int i = 0;i<count;i++) newPoints[i] = (points[i] * (1-envPP[i])) + (newPoints[i] * envPP[i]); } // retransform the result if it was in world space if ( defSpace == MSD_SPACE_WORLD ) { MMatrix worldMatrixInv = worldMatrix.inverse(); for (int i = 0;i<count;i++) newPoints[i] *= worldMatrixInv; } // set the points iter.reset(); for ( ; !iter.isDone(); iter.next()) iter.setPosition(newPoints[iter.index()]); return status; }
MStatus puttyNode::compute( const MPlug& plug, MDataBlock& block ) { MStatus status; if ( plug == aNodeReady ) { // MGlobal::displayInfo("compute"); bool result =false; MString cmdBaseName; // get the source flag MDataHandle dh = block.inputValue(aSource,&status); SYS_ERROR_CHECK(status, "Error getting source data handle\n"); bool source = dh.asBool(); // get the command dh = block.inputValue(aScript,&status); SYS_ERROR_CHECK(status, "Error getting reload script handle\n"); MString script = dh.asString(); if (script == "") { MGlobal::displayError("no script provided!\n"); } else { // chech if script is sourced dh = block.inputValue(aScriptSourced,&status); SYS_ERROR_CHECK(status, "Error getting aScriptSourced data handle\n"); bool scriptSourced = dh.asBool(); // if it's not ready, don't do anything if (!scriptSourced) return MS::kSuccess; else { MCommandResult melResult; // now get the real name of the function and store it in a separate attribute MString cmd="basenameEx \"" + script+"\""; status = MGlobal::executeCommand(cmd,melResult); melResult.getResult(cmdBaseName); result = true; MDataHandle dhCBN = block.outputValue(aCmdBaseName,&status); SYS_ERROR_CHECK(status, "Error getting aCmdBaseName data handle\n"); dhCBN.set(cmdBaseName); dhCBN.setClean(); // see if an interface function is present, if yes, execute it cmd= "if(exists(\"" + cmdBaseName +".interface\")) {"; cmd+= "string $attr[] = `deleteAttr -q " +name()+"`; string $a;"; cmd+="for($a in $attr) deleteAttr (\""+name()+".\"+$a);"; cmd+= cmdBaseName +".interface(\"" +name()+"\");}"; status = MGlobal::executeCommand(cmd); } } // check the current status // set the result MDataHandle dhNodeReady = block.outputValue(aNodeReady,&status); SYS_ERROR_CHECK(status, "Error getting reload data handle\n"); dhNodeReady.set(result); dhNodeReady.setClean(); return MS::kSuccess; } else if (plug==aScriptSourced) { // this part of the function sources the script // try to source the script // cerr << "\nsource"; MStatus status; bool result = true; // get the source flag MDataHandle dh = block.inputValue(aSource,&status); SYS_ERROR_CHECK(status, "Error getting source data handle\n"); bool source = dh.asBool(); // get the script dh = block.inputValue(aScript,&status); SYS_ERROR_CHECK(status, "Error getting reload script handle\n"); MString script = dh.asString(); MString cmd = "source \"" + script+"\""; MCommandResult melResult; status = MGlobal::executeCommand(cmd,melResult); if (status.error()) { MGlobal::displayError( "Error sourcing mel script, please check the function you provided is valid!"); result = false; } // set the result MDataHandle dhScriptSourced = block.outputValue(aScriptSourced,&status); SYS_ERROR_CHECK(status, "Error getting ScriptSourced data handle\n"); dhScriptSourced.set(result); dhScriptSourced.setClean(); return MS::kSuccess; } return MS::kUnknownParameter; }
/* This function gets called by Maya to evaluate the texture. */ MStatus shiftNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if ((plug != aOutColor) && (plug.parent() != aOutColor)) return MS::kUnknownParameter; MDataHandle colorH; MFloatVector color; MDataHandle shiftH = data.inputValue( aShift, &stat); PERRORfail(stat, "compute getting shift attr"); bool shiftIt = shiftH.asBool(); MDataHandle distH = data.inputValue( aDist, &stat); PERRORfail(stat, "compute getting distance attr"); float distance = distH.asFloat(); MFloatVector clr; if ( shiftIt && distance != 0.0 ) { // first evaluate color at default sample posiiton clr = data.inputValue( aColor ).asFloatVector(); // uv is used by 2d textures // refPointCamera is used by 3d textures MDataHandle refPointCamH = data.inputValue( aRefPointCamera, &stat); PERRORfail(stat, "compute getting refPointCamera attr"); MFloatVector refPC = refPointCamH.asFloatVector(); // get current UV const float2 & oldUV = data.inputValue(aUv).asFloat2(); // shift and set the uv/refPointCamera values so // we can sample around the current uv/refPointCamera MDataHandle outUV = data.outputValue( aUv ); MDataHandle outPC = data.outputValue( aRefPointCamera ); outUV.set( oldUV[0]-distance, oldUV[1] ); outPC.set( refPC.x + distance, refPC.y + distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; outUV.set( oldUV[0]+distance, oldUV[1] ); outPC.set( refPC.x - distance, refPC.y + distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; outUV.set( oldUV[0], oldUV[1]-distance ); outPC.set( refPC.x + distance, refPC.y - distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; outUV.set( oldUV[0], oldUV[1]+distance ); outPC.set( refPC.x - distance, refPC.y - distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; clr /= 5.0; // average the colors from all locations // set sample data back to original values outUV.set( oldUV[0], oldUV[1] ); outPC.set( refPC.x, refPC.y, refPC.z ); } else { colorH = data.inputValue( aColor, &stat); clr = colorH.asFloatVector(); } MDataHandle outColorHandle = data.outputValue( aOutColor ); MFloatVector& oclr = outColorHandle.asFloatVector(); oclr = clr; outColorHandle.setClean(); return MS::kSuccess; }
MStatus MG_dotProduct::compute(const MPlug& plug,MDataBlock& dataBlock) { MStatus returnStatus; if ((plug==dotProductA)|| (plug==dotProductMax)|| (plug==proj1on2)|| (plug==proj2on1)|| (plug==angleInBetweenAttr)|| (plug==angleX)|| (plug==angleY)|| (plug==angleZ)) /*get time */ { //creating handles to the input values MDataHandle vector1DataH = dataBlock.inputValue(vector1); MFloatPoint vector1V = vector1DataH.asFloatVector(); MDataHandle vector2DataH = dataBlock.inputValue(vector2); MFloatPoint vector2V = vector2DataH.asFloatVector(); MDataHandle xAxisH = dataBlock.inputValue(projAxisX); MFloatPoint xAxisData = xAxisH.asFloatVector(); MDataHandle yAxisH = dataBlock.inputValue(projAxisY); MFloatPoint yAxisData = yAxisH.asFloatVector(); MDataHandle zAxisH = dataBlock.inputValue(projAxisZ); MFloatPoint zAxisData = zAxisH.asFloatVector(); MDataHandle normData = dataBlock.inputValue(normalize); bool norm =normData.asBool(); //Creating some neededs variables float dotResult; // variable that will hold the dot product result float maxValue; //variable that will hold the dot product max value float distance1; // variable that will hold the vector 1 lenght float distance2; //variable that will hold the vector 2 lenght float angleDeg; //variable that will hold the angle inbetween the two vectors //float cosRad ; //variable that will hold the cosine value in radiants //Dot product math float vec1Array[3] = {vector1V[0],vector1V[1],vector1V[2]}; vector <float> vec1 = makeVector(vec1Array) ; float vec2Array[3] = {vector2V[0],vector2V[1],vector2V[2]}; vector <float> vec2 = makeVector(vec2Array) ; dotResult = vecDotProduct(vec1,vec2); distance1 = vectorLength(vec1); distance2 = vectorLength(vec2); maxValue = distance1*distance2; if (norm == 1) { if (maxValue ==0) { dotResult=0; }else{ dotResult = dotResult/maxValue; } } //Projection v2 on v1 float projV2=0; //variable that will hold the value projection of v2 projected on v1 vector <float> v1Norm; // variable that will hold the normalized v1 vector vector<float> v2Vec; // variable that will hold the projected vector if (distance1 != 0) { projV2 = projVector(vec2,vec1); v1Norm = normVector(vec1); v2Vec = scalarVector(v1Norm,projV2); }else{ //initialize the vector as 0 0 0 float zeroVec2[3]= {0,0,0}; v2Vec=makeVector(zeroVec2); } //Projection v1 on v2 float projV1=0; //variable that will hold the value projection of v1 projected on v2 vector <float> v2Norm;// variable that will hold the normalized v2 vector vector <float> v1Vec;// variable that will hold the projected vector if (distance2 != 0) { projV1 = projVector(vec1,vec2); v2Norm = normVector(vec2); v1Vec = scalarVector(v2Norm,projV1); }else{ //initialize the vector as 0 0 0 float zeroVec1[3]= {0,0,0}; v1Vec=makeVector(zeroVec1); } //Angle in between if ((distance2*distance1)!=0) { angleDeg=angleInbetweenVector(vec1,vec2); }else{ angleDeg=0; } //Angle inbetween splitted into X,Y,Z world rotation //float dotResultV1X; // splitting inbetween angle into X Y Z rotation //converting axis from node into vector class float xAxisArray[3] = {xAxisData[0],xAxisData[1],xAxisData[2]}; vector<float> xAxisVec = makeVector(xAxisArray) ; float yAxisArray[3] = {yAxisData[0],yAxisData[1],yAxisData[2]}; vector<float> yAxisVec = makeVector(yAxisArray) ; float zAxisArray[3] = {zAxisData[0],zAxisData[1],zAxisData[2]}; vector<float> zAxisVec = makeVector(zAxisArray) ; float angleProjXYDeg=0 ; float angleProjYZDeg=0 ; float angleProjXZDeg=0 ; // angle Z vector<float> projectedV1; vector<float> projectedV2; projectedV1= projectVectorOnPlane(vec1,xAxisVec,yAxisVec); projectedV2= projectVectorOnPlane(vec2,xAxisVec,yAxisVec); angleProjXYDeg=angleInbetweenVector(projectedV1,projectedV2); // angle X projectedV1= projectVectorOnPlane(vec1,zAxisVec,yAxisVec); projectedV2= projectVectorOnPlane(vec2,zAxisVec,yAxisVec); angleProjYZDeg=angleInbetweenVector(projectedV1,projectedV2); // angle Y projectedV1= projectVectorOnPlane(vec1,zAxisVec,xAxisVec); projectedV2= projectVectorOnPlane(vec2,zAxisVec,xAxisVec); angleProjXZDeg=angleInbetweenVector(projectedV1,projectedV2); //Setting output values MDataHandle output = dataBlock.outputValue(dotProductA); MDataHandle outputMax = dataBlock.outputValue(dotProductMax); MDataHandle projV1Output = dataBlock.outputValue(proj1on2); MDataHandle projV2Output = dataBlock.outputValue(proj2on1); MDataHandle angleInBetweenOutput = dataBlock.outputValue(angleInBetweenAttr); MDataHandle angleXout = dataBlock.outputValue(angleX); MDataHandle angleYout = dataBlock.outputValue(angleY); MDataHandle angleZout = dataBlock.outputValue(angleZ); output.set(dotResult); outputMax.set(maxValue); projV1Output.set(v1Vec[0],v1Vec[1],v1Vec[2]); projV2Output.set(v2Vec[0],v2Vec[1],v2Vec[2]); angleInBetweenOutput.set(angleDeg); angleXout.set(angleProjYZDeg); angleYout.set(angleProjXZDeg); angleZout.set(angleProjXYDeg); //SetClean tells maya attribute is update outputMax.setClean(); output.setClean(); projV1Output.setClean(); projV2Output.setClean(); angleInBetweenOutput.setClean(); angleXout.setClean(); angleYout.setClean(); angleZout.setClean(); } return MS::kSuccess; }
/*! Compute function, gets the input surface, determines what type it is and calls the appropriate conversion function Encapsulates an cowpointer to the body into the naiadBodyData type and outputs it */ MStatus NBuddySurfaceToBodyNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; if (plug == _outBody) { //Get the body name MDataHandle bodyNameHndl = data.inputValue( _bodyName, &status ); MString bodyName = bodyNameHndl.asString(); //Create the MFnPluginData for the naiadBody MFnPluginData dataFn; dataFn.create( MTypeId( naiadBodyData::id ), &status); NM_CheckMStatus( status, "Failed to create naiadBodyData in MFnPluginData"); //Get subdivision info from plugs so better approximations of meshes can be done int divisions = data.inputValue( _subDivide, &status ).asBool(); //Getting genericAttribute handle containing the surface and pick the correct conversion function MObject meshObj; MDataHandle inSurfaceHdl = data.inputValue( _inSurface, &status ); if (inSurfaceHdl.type() == MFnData::kNurbsSurface) { MFnNurbsSurface nurbsFn(inSurfaceHdl.asNurbsSurface()); // Create the data holder for the tesselated mesh MFnMeshData dataCreator; MObject newOutputData = dataCreator.create(&status); //Setup the tesselation parameters MTesselationParams tParams; tParams.setOutputType( MTesselationParams::kTriangles ); tParams.setFormatType( MTesselationParams::kGeneralFormat ); tParams.setUIsoparmType( MTesselationParams::kSpanEquiSpaced ); tParams.setVIsoparmType( MTesselationParams::kSpanEquiSpaced ); tParams.setUNumber( divisions+1 ); tParams.setVNumber( divisions+1 ); // Tesselate and get the returned mesh meshObj = nurbsFn.tesselate( tParams, newOutputData, &status ); NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate nurbs surface to poly"); } else if (inSurfaceHdl.type() == MFnData::kMesh) { meshObj = inSurfaceHdl.asMesh(); if ( divisions > 0 ) { MFnMeshData dataCreator; MObject newOutputData = dataCreator.create(&status); MFnMesh meshFn(meshObj); MIntArray faceIds; for ( unsigned int i(0); i < meshFn.numPolygons(); ++i ) faceIds.append(i); meshFn.subdivideFaces( faceIds , divisions ); } } else if (inSurfaceHdl.type() == MFnData::kSubdSurface) { // Create the subd function set so we can tesselate MFnSubd subDfn(inSurfaceHdl.asSubdSurface()); // Create the data holder for the tesselated mesh MFnMeshData dataCreator; MObject newOutputData = dataCreator.create(&status); // Tesselate the subD surface meshObj = subDfn.tesselate(true, 1 , divisions , newOutputData, &status ); NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate SubD surface to poly"); } else return status ; //Get the handle for the input transform MDataHandle inTransformHdl = data.inputValue( _inTransform, &status ); NM_CheckMStatus( status, "Failed to get inTransform handle"); MDataHandle useTransformHdl = data.inputValue( _useTransform, &status); NM_CheckMStatus( status, "Failed to get worldSpaceHdl "); bool useTransform = useTransformHdl.asBool(); //Get a new naiadBodyData naiadBodyData * newBodyData = (naiadBodyData*)dataFn.data( &status ); NM_CheckMStatus( status, "Failed to get naiadBodyData handle from MFnPluginData"); try { newBodyData->nBody = mayaMeshToNaiadBody( meshObj, std::string(bodyName.asChar()), useTransform, inTransformHdl.asMatrix() ); } catch(std::exception& ex) { NM_ExceptionPlugDisplayError("NBuddySurfaceToBodyNode::compute ", plug, ex ); } //Give the data to the output handle and set it clean MDataHandle bodyDataHnd = data.outputValue( _outBody, &status ); NM_CheckMStatus( status, "Failed to get outputData handle for outBody"); bodyDataHnd.set( newBodyData ); data.setClean( plug ); } return status; }
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; }
bool pnTriangles::setInternalValue( const MPlug &plug, const MDataHandle &dh ) // // Description: // Set internally cached values when attribute changes // { if( plug == pnTriangles::attrSubdivisions ) { fSubdivisions = dh.asInt(); // Make sure we don't go above the maximum allowed by // the extension if (fSubdivisions > fMaxTessellationLevel) fSubdivisions = fMaxTessellationLevel; return true; } else if ( plug == pnTriangles::attrColored) { if (dh.asBool() == true) fNumColors = 1; else fNumColors = 0; return true; } else if ( plug == pnTriangles::attrWireframe) { if (dh.asBool() == true) fWireframe = 1; else fWireframe = 0; return true; } else if ( plug == pnTriangles::attrTextured) { if (dh.asBool() == true) fNumTextureCoords = 1; else fNumTextureCoords = 0; return true; } else if ( plug == pnTriangles::attrNormalMode ) { if (dh.asInt() == 0) fNormalMode = kNormalLinear; else fNormalMode = kNormalQuadratic; return true; } else if ( plug == pnTriangles::attrPointMode ) { if (dh.asInt() == 0) fPointMode = kPointLinear; else fPointMode = kPointCubic; return true; } else if ( plug == pnTriangles::attrEnableVertexProgram ) { if (dh.asBool() == true) { if (fExtensionSupported[kVertexShaderEXT]) fTestVertexProgram = 1; else fTestVertexProgram = 0; } else fTestVertexProgram = 0; return true; } else if ( plug == pnTriangles::attrEnablePixelProgram ) { #ifdef _FRAGMENT_PROGRAM_READY_ if (dh.asBool() == true) if (fExtensionSupported[kFragmentShaderEXT]) fTestFragmentProgram = 1; else fTestFragmentProgram = 0; else fTestFragmentProgram = 0; #else fTestFragmentProgram = 0; #endif return true; } return false; }
MStatus sseDeformer::compute(const MPlug& plug, MDataBlock& data) { MStatus status; if (plug.attribute() != outputGeom) { printf("Ignoring requested plug\n"); return status; } unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); // get input value MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = data.inputValue(inPlug, &status); MCheckStatus(status, "ERROR getting input mesh\n"); // get the input geometry MDataHandle inputData = hInput.child(inputGeom); if (inputData.type() != MFnData::kMesh) { printf("Incorrect input geometry type\n"); return MStatus::kFailure; } MObject iSurf = inputData.asMesh() ; MFnMesh inMesh; inMesh.setObject( iSurf ) ; MDataHandle outputData = data.outputValue(plug); outputData.copy(inputData); if (outputData.type() != MFnData::kMesh) { printf("Incorrect output mesh type\n"); return MStatus::kFailure; } MObject oSurf = outputData.asMesh() ; if(oSurf.isNull()) { printf("Output surface is NULL\n"); return MStatus::kFailure; } MFnMesh outMesh; outMesh.setObject( oSurf ) ; MCheckStatus(status, "ERROR setting points\n"); // get all points at once for demo purposes. Really should get points from the current group using iterator MFloatPointArray pts; outMesh.getPoints(pts); int nPoints = pts.length(); MDataHandle envData = data.inputValue(envelope, &status); float env = envData.asFloat(); MDataHandle sseData = data.inputValue(sseEnabled, &status); bool sseEnabled = (bool) sseData.asBool(); // NOTE: Using MTimer and possibly other classes disables // autovectorization with Intel <=10.1 compiler on OSX and Linux!! // Must compile this function with -fno-exceptions on OSX and // Linux to guarantee autovectorization is done. Use -fvec_report2 // to check for vectorization status messages with Intel compiler. MTimer timer; timer.beginTimer(); if(sseEnabled) { // Innter loop will autovectorize. Around 3x faster than the // loop below it. It would be faster if first element was // guaranteed to be aligned on 16 byte boundary. for(int i=0; i<nPoints; i++) { float* ptPtr = &pts[i].x; for(int j=0; j<4; j++) { ptPtr[j] = env * (cosf(ptPtr[j]) * sinf(ptPtr[j]) * tanf(ptPtr[j])); } } } else { // This inner loop will not autovectorize. for(int i=0; i<nPoints; i++) { MFloatPoint& pt = pts[i]; for(int j=0; j<3; j++) { pt[j] = env * (cosf(pt[j]) * sinf(pt[j]) * tanf(pt[j])); } } } timer.endTimer(); if(sseEnabled) { printf("SSE enabled, runtime %f\n", timer.elapsedTime()); } else { printf("SSE disabled, runtime %f\n", timer.elapsedTime()); } outMesh.setPoints(pts); return status; }
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; }
/* virtual */ MStatus cgfxVector::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MFnData::Type dataType = MFnData::kInvalid; if( plug == sWorldVector || plug == sWorldVectorX || plug == sWorldVectorY || plug == sWorldVectorZ || plug == sWorldVectorW) { // We do isDirection first simply because if there is an // error, the isDirection error is more legible than the // vector or matrix error. // MDataHandle dhIsDirection = data.inputValue(sIsDirection, &status); if (!status) { status.perror("cgfxVector: isDirection handle"); return status; } dataType = dhIsDirection.type(); MDataHandle dhVector = data.inputValue(sVector, &status); if (!status) { status.perror("cgfxVector: vector handle"); return status; } dataType = dhVector.type(); MMatrix matrix; MPlug matrixPlug(thisMObject(), sMatrix); if (matrixPlug.isNull()) { OutputDebugString("matrixPlug is NULL!\n"); } // TODO: Fix this kludge. // // We should not have to do this but for some reason, // using data.inputValue() fails for the sMatrix attribute. // Instead, we get a plug to the attribute and then get // the value directly. // MObject oMatrix; matrixPlug.getValue(oMatrix); MFnMatrixData fndMatrix(oMatrix, &status); if (!status) { status.perror("cgfxVector: matrix data"); } matrix= fndMatrix.matrix(&status); if (!status) { status.perror("cgfxVector: get matrix"); } #if 0 // TODO: This is how we are supposed to do it. (I think). // MDataHandle dhMatrix = data.inputValue(sMatrix, &status); if (!status) { status.perror("cgfxVector: matrix handle"); } dataType = dhMatrix.type(); oMatrix = dhMatrix.data(); MFnMatrixData fnMatrix(oMatrix, &status); if (!status) { status.perror("cgfxVector: matrix function set"); } matrix = fnMatrix.matrix(); #endif /* 0 */ bool isDirection = dhIsDirection.asBool(); double3& vector = dhVector.asDouble3(); double mat[4][4]; matrix.get(mat); double ix, iy, iz, iw; // Input vector float ox, oy, oz, ow; // Output vector ix = vector[0]; iy = vector[1]; iz = vector[2]; iw = isDirection ? 0.0 : 1.0; ox = (float)(mat[0][0] * ix + mat[1][0] * iy + mat[2][0] * iz + mat[3][0] * iw); oy = (float)(mat[0][1] * ix + mat[1][1] * iy + mat[2][1] * iz + mat[3][1] * iw); oz = (float)(mat[0][2] * ix + mat[1][2] * iy + mat[2][2] * iz + mat[3][2] * iw); ow = (float)(mat[0][3] * ix + mat[1][3] * iy + mat[2][3] * iz + mat[3][3] * iw); MDataHandle dhWVector = data.outputValue(sWorldVector, &status); if (!status) { status.perror("cgfxVector: worldVector handle"); return status; } MDataHandle dhWVectorW = data.outputValue(sWorldVectorW, &status); if (!status) { status.perror("cgfxVector: worldVectorW handle"); return status; } dhWVector.set(ox, oy, oz); dhWVectorW.set(ow); data.setClean(sWorldVector); data.setClean(sWorldVectorW); } else { return MS::kUnknownParameter; } return MS::kSuccess; }
MStatus inverseSkinCluster::deform(MDataBlock& data, MItGeometry& itGeo, const MMatrix& localToWorldMatrix, unsigned int geomIndex) { MStatus status; MMatrix geomMatrix; bool updateSkinInfo; MDataHandle hInMesh = data.inputValue( aInMesh, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MObject oInMesh = hInMesh.asMesh(); if( oInMesh.isNull() ) return MS::kFailure; MFnMesh inMesh = oInMesh; inMesh.getPoints( m_meshPoints ); if( originalMeshUpdated ) { itGeo.allPositions( pTaskData->basePoints ); originalMeshUpdated = false; } MDataHandle hGeomMatrix = data.inputValue( aGeomMatrix ); geomMatrix = hGeomMatrix.asMatrix(); MDataHandle hUpdateWeightList = data.inputValue( aUpdateWeightList ); updateSkinInfo = hUpdateWeightList.asBool(); MDataHandle hEnvelop = data.inputValue( envelope ); envelopValue = hEnvelop.asFloat(); pTaskData->envelop = envelopValue; pTaskData->invEnv = 1.0f - envelopValue; pTaskData->beforePoints = m_meshPoints; if( updateSkinInfo ) { MDataHandle hUpdateSkinInfoOutput = data.outputValue( aUpdateWeightList ); hUpdateSkinInfoOutput.set( false ); weightListUpdated = false; } if( logicalIndexArray.length() == 0 ) updateLogicalIndexArray(); MDataHandle hUpdateMatrix = data.inputValue( aUpdateMatrix ); if( hUpdateMatrix.asBool() ) { matrixAttrUpdated = false; matrixInfoUpdated = false; } MArrayDataHandle hArrMatrix = data.inputArrayValue( aMatrix ); MArrayDataHandle hArrBindPreMatrix = data.inputArrayValue( aBindPreMatrix ); updateMatrixAttribute( hArrMatrix, hArrBindPreMatrix ); if( !matrixInfoUpdated ) { updateMatrixInfo( hArrMatrix, hArrBindPreMatrix ); } if( !weightListUpdated ) { pTaskData->afterPoints.setLength( m_meshPoints.length() ); pTaskData->envPoints.setLength( m_meshPoints.length() ); updateWeightList(); } if( !matrixInfoUpdated || !weightListUpdated ) { if( pSkinInfo->weightsArray.size() > 0 ) getWeightedMatrices( geomMatrix ); else return MS::kFailure; matrixInfoUpdated = true; weightListUpdated = true; } if( envelopValue ) { setThread(); MThreadPool::newParallelRegion( parallelCompute, pThread ); endThread(); itGeo.setAllPositions( pTaskData->envPoints ); } else { itGeo.setAllPositions( pTaskData->basePoints ); } return MS::kSuccess; }