コード例 #1
0
ファイル: splatDeformer.cpp プロジェクト: BigRoy/Maya-devkit
MStatus splatDeformer::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;
	}

  	MObject dSurf = deformData.asMeshTransformed();
 	MFnMesh fnDeformingMesh;
 	fnDeformingMesh.setObject( dSurf ) ;

	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);

	// create fast intersector structure
	MMeshIntersector intersector;
	intersector.create(dSurf);

	// get all points at once. Faster to query, and also better for
	// threading than using iterator
	MPointArray verts;
	iter.allPositions(verts);
	int nPoints = verts.length();

	// use bool variable as lightweight object for failure check in loop below
	bool failed = false;

 	MTimer timer; timer.beginTimer();

#ifdef _OPENMP
#pragma omp parallel for
#endif
 	for(int i=0; i<nPoints; i++) {

		// Cannot break out of an OpenMP loop, so if one of the
		// intersections failed, skip the rest
		if(failed) continue;

		// mesh point object must be in loop-local scope to avoid race conditions
		MPointOnMesh meshPoint;

		// Do intersection. Need to use per-thread status value as
		// MStatus has internal state and may trigger race conditions
		// if set from multiple threads. Probably benign in this case,
		// but worth being careful.
		MStatus localStatus = intersector.getClosestPoint(verts[i], meshPoint);
		if(localStatus != MStatus::kSuccess) {
			// NOTE - we cannot break out of an OpenMP region, so set
			// bad status and skip remaining iterations
			failed = true;
			continue;
		}

		// default OpenMP scheduling breaks traversal into large
		// chunks, so low risk of false sharing here in array write.
		verts[i] = meshPoint.getPoint();
 	}

 	timer.endTimer(); printf("Runtime for threaded loop %f\n", timer.elapsedTime());

	// write values back onto output using fast set method on iterator
	iter.setAllPositions(verts);

	if(failed) {
		printf("Closest point failed\n");
		return MStatus::kFailure;
	}

	return status;
}
コード例 #2
0
MStatus AlembicCurvesLocatorNode::compute(const MPlug &plug,
                                          MDataBlock &dataBlock)
{
  ESS_PROFILE_SCOPE("AlembicCurvesLocatorNode::compute");
  MStatus status;

  // update the frame number to be imported
  double inputTime =
      dataBlock.inputValue(mTimeAttr).asTime().as(MTime::kSeconds);
  MString &fileName = dataBlock.inputValue(mFileNameAttr).asString();
  MString &identifier = dataBlock.inputValue(mIdentifierAttr).asString();

  AbcG::ICurves obj;

  // check if we have the file
  if (fileName != mFileName || identifier != mIdentifier) {
    mSchema.reset();
    if (fileName != mFileName) {
      delRefArchive(mFileName);
      mFileName = fileName;
      addRefArchive(mFileName);
    }
    mIdentifier = identifier;

    // get the object from the archive
    Abc::IObject iObj = getObjectFromArchive(mFileName, identifier);
    if (!iObj.valid()) {
      MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier +
                              "' not found in archive '" + mFileName + "'.");
      return MStatus::kFailure;
    }
    obj = AbcG::ICurves(iObj, Abc::kWrapExisting);
    if (!obj.valid()) {
      MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier +
                              "' in archive '" + mFileName +
                              "' is not a Curves.");
      return MStatus::kFailure;
    }
    mSchema = obj.getSchema();
  }

  if (!mSchema.valid()) {
    return MStatus::kFailure;
  }

  // get the sample
  SampleInfo sampleInfo = getSampleInfo(inputTime, mSchema.getTimeSampling(),
                                        mSchema.getNumSamples());

  // check if we have to do this at all
  if (mNbCurves == 0 || mLastSampleInfo.floorIndex != sampleInfo.floorIndex ||
      mLastSampleInfo.ceilIndex != sampleInfo.ceilIndex) {
    AbcG::ICurvesSchema::Sample sample;
    AbcG::ICurvesSchema::Sample sample2;
    mSchema.get(sample, sampleInfo.floorIndex);
    if (sampleInfo.alpha != 0.0) {
      mSchema.get(sample2, sampleInfo.ceilIndex);
    }

    // update the indices
    Abc::P3fArraySamplePtr samplePos = sample.getPositions();
    if (mNbCurves != sample.getNumCurves() ||
        mNbVertices != samplePos->size()) {
      mNbCurves = (unsigned int)sample.getNumCurves();
      mNbVertices = (unsigned int)samplePos->size();

      Abc::Int32ArraySamplePtr nbVertices = sample.getCurvesNumVertices();
      mIndices.clear();
      unsigned int offset = 0;
      for (unsigned int i = 0; i < mNbCurves; i++) {
        unsigned int verticesPerCurve = nbVertices->get()[i];
        for (unsigned j = 0; j < verticesPerCurve - 1; j++) {
          mIndices.push_back(offset);
          offset++;
          mIndices.push_back(offset);
        }
        offset++;
      }
    }

    if (mPositions.size() != samplePos->size()) {
      mPositions.resize(samplePos->size());
    }

    // check if we need to interpolate
    bool done = false;
    mBoundingBox.clear();
    if (sampleInfo.alpha != 0.0) {
      Abc::P3fArraySamplePtr samplePos2 = sample2.getPositions();
      if (samplePos->size() == samplePos2->size()) {
        float alpha = float(sampleInfo.alpha);
        float ialpha = 1.0f - alpha;
        for (unsigned int i = 0; i < samplePos->size(); i++) {
          mPositions[i].x =
              ialpha * samplePos->get()[i].x + alpha * samplePos2->get()[i].x;
          mPositions[i].y =
              ialpha * samplePos->get()[i].y + alpha * samplePos2->get()[i].y;
          mPositions[i].z =
              ialpha * samplePos->get()[i].z + alpha * samplePos2->get()[i].z;
          mBoundingBox.expand(
              MPoint(mPositions[i].x, mPositions[i].y, mPositions[i].z));
        }
        done = true;
      }
    }

    if (!done) {
      for (unsigned int i = 0; i < samplePos->size(); i++) {
        mPositions[i].x = samplePos->get()[i].x;
        mPositions[i].y = samplePos->get()[i].y;
        mPositions[i].z = samplePos->get()[i].z;
        mBoundingBox.expand(
            MPoint(mPositions[i].x, mPositions[i].y, mPositions[i].z));
      }
    }

    // get the colors
    // mColors.clear();

    Abc::IC4fArrayProperty propColor;
    if (getArbGeomParamPropertyAlembic(obj, "color", propColor)) {
      mColors.clear();
      SampleInfo colorSampleInfo = getSampleInfo(
          inputTime, propColor.getTimeSampling(), propColor.getNumSamples());
      Abc::C4fArraySamplePtr sampleColor =
          propColor.getValue(colorSampleInfo.floorIndex);
      mColors.resize(mPositions.size());
      if (sampleColor->size() == 1) {
        for (unsigned int i = 0; i < (unsigned int)mColors.size(); i++) {
          mColors[i].r = sampleColor->get()[0].r;
          mColors[i].g = sampleColor->get()[0].g;
          mColors[i].b = sampleColor->get()[0].b;
          mColors[i].a = sampleColor->get()[0].a;
        }
      }
      else if (sampleColor->size() == mPositions.size()) {
        for (unsigned int i = 0; i < sampleColor->size(); i++) {
          mColors[i].r = sampleColor->get()[i].r;
          mColors[i].g = sampleColor->get()[i].g;
          mColors[i].b = sampleColor->get()[i].b;
          mColors[i].a = sampleColor->get()[i].a;
        }
      }
      else if (sampleColor->size() == mNbCurves) {
        Abc::Int32ArraySamplePtr nbVertices = sample.getCurvesNumVertices();
        unsigned int offset = 0;
        for (unsigned int i = 0; i < nbVertices->size(); i++) {
          for (unsigned j = 0; j < (unsigned int)nbVertices->get()[i]; j++) {
            mColors[offset].r = sampleColor->get()[i].r;
            mColors[offset].g = sampleColor->get()[i].g;
            mColors[offset].b = sampleColor->get()[i].b;
            mColors[offset].a = sampleColor->get()[i].a;
            offset++;
          }
        }
      }
    }
  }

  mLastSampleInfo = sampleInfo;

  MDataHandle outSent = dataBlock.outputValue(mSentinelAttr);
  // increment, this tells the draw routine that the display list needs to be
  // regenerated
  outSent.set((mSent + 1 % 10));
  dataBlock.setClean(mSentinelAttr);

  return MStatus::kSuccess;
}
コード例 #3
0
ファイル: MG_nurbsRivet.cpp プロジェクト: bungnoid/MG_Tools
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;
	}
コード例 #4
0
void connectingNode::turnOffTrigger(MDataBlock &data){
	MStatus status=MStatus::kSuccess;
	MDataHandle triggerHandle=data.outputValue(trigger,&status);
	triggerHandle.setBool(false);
}
コード例 #5
0
MStatus AlembicCurvesNode::compute(const MPlug &plug, MDataBlock &dataBlock)
{
  ESS_PROFILE_SCOPE("AlembicCurvesNode::compute");
  MStatus status;

  // update the frame number to be imported
  const double inputTime =
      dataBlock.inputValue(mTimeAttr).asTime().as(MTime::kSeconds);
  MString &fileName = dataBlock.inputValue(mFileNameAttr).asString();
  MString &identifier = dataBlock.inputValue(mIdentifierAttr).asString();

  // check if we have the file
  if (fileName != mFileName || identifier != mIdentifier) {
    mSchema.reset();
    if (fileName != mFileName) {
      delRefArchive(mFileName);
      mFileName = fileName;
      addRefArchive(mFileName);
    }
    mIdentifier = identifier;

    // get the object from the archive
    Abc::IObject iObj = getObjectFromArchive(mFileName, identifier);
    if (!iObj.valid()) {
      MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier +
                              "' not found in archive '" + mFileName + "'.");
      return MStatus::kFailure;
    }
    AbcG::ICurves obj(iObj, Abc::kWrapExisting);
    if (!obj.valid()) {
      MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier +
                              "' in archive '" + mFileName +
                              "' is not a Curves.");
      return MStatus::kFailure;
    }
    mObj = obj;
    mSchema = obj.getSchema();
    mCurvesData = MObject::kNullObj;
  }

  if (!mSchema.valid()) {
    return MStatus::kFailure;
  }

  {
    ESS_PROFILE_SCOPE("AlembicCurvesNode::compute readProps");
    Alembic::Abc::ICompoundProperty arbProp = mSchema.getArbGeomParams();
    Alembic::Abc::ICompoundProperty userProp = mSchema.getUserProperties();
    readProps(inputTime, arbProp, dataBlock, thisMObject());
    readProps(inputTime, userProp, dataBlock, thisMObject());

    // Set all plugs as clean
    // Even if one of them failed to get set,
    // trying again in this frame isn't going to help
    for (unsigned int i = 0; i < mGeomParamPlugs.length(); i++) {
      dataBlock.outputValue(mGeomParamPlugs[i]).setClean();
    }

    for (unsigned int i = 0; i < mUserAttrPlugs.length(); i++) {
      dataBlock.outputValue(mUserAttrPlugs[i]).setClean();
    }
  }

  // get the sample
  SampleInfo sampleInfo = getSampleInfo(inputTime, mSchema.getTimeSampling(),
                                        mSchema.getNumSamples());

  // check if we have to do this at all
  if (!mCurvesData.isNull() &&
      mLastSampleInfo.floorIndex == sampleInfo.floorIndex &&
      mLastSampleInfo.ceilIndex == sampleInfo.ceilIndex) {
    return MStatus::kSuccess;
  }

  mLastSampleInfo = sampleInfo;
  const float blend = (float)sampleInfo.alpha;

  // access the camera values
  AbcG::ICurvesSchema::Sample sample;
  AbcG::ICurvesSchema::Sample sample2;
  mSchema.get(sample, sampleInfo.floorIndex);
  if (blend != 0.0f) {
    mSchema.get(sample2, sampleInfo.ceilIndex);
  }

  Abc::P3fArraySamplePtr samplePos = sample.getPositions();
  Abc::P3fArraySamplePtr samplePos2 = sample2.getPositions();
  Abc::Int32ArraySamplePtr nbVertices = sample.getCurvesNumVertices();
  const bool applyBlending =
      (blend == 0.0f) ? false : (samplePos->size() == samplePos2->size());

  Abc::FloatArraySamplePtr pKnotVec = getKnotVector(mObj);
  Abc::UInt16ArraySamplePtr pOrders = getCurveOrders(mObj);

  MArrayDataHandle arrh = dataBlock.outputArrayValue(mOutGeometryAttr);
  MArrayDataBuilder builder = arrh.builder();

  // reference:
  // http://download.autodesk.com/us/maya/2010help/API/multi_curve_node_8cpp-example.html

  const int degree = (sample.getType() == AbcG::kCubic) ? 3 : 1;
  const bool closed = (sample.getWrap() == AbcG::kPeriodic);
  unsigned int pointOffset = 0;
  unsigned int knotOffset = 0;
  for (int ii = 0; ii < nbVertices->size(); ++ii) {
    const unsigned int nbCVs = (unsigned int)nbVertices->get()[ii];
    const int ldegree = (pOrders) ? pOrders->get()[ii] : degree;
    const int nbSpans = (int)nbCVs - ldegree;

    MDoubleArray knots;
    if (pKnotVec) {
      const unsigned int nb_knot = nbCVs + ldegree - 1;
      for (unsigned int i = 0; i < nb_knot; ++i) {
        knots.append(pKnotVec->get()[knotOffset + i]);
      }
      knotOffset += nb_knot;
    }
    else {
      for (int span = 0; span <= nbSpans; ++span) {
        knots.append(double(span));
        if (span == 0 || span == nbSpans) {
          for (int m = 1; m < degree; ++m) {
            knots.append(double(span));
          }
        }
      }
    }

    MPointArray points;
    if (samplePos->size() > 0) {
      points.setLength((unsigned int)nbCVs);
      if (applyBlending) {
        for (unsigned int i = 0; i < nbCVs; ++i) {
          const Abc::P3fArraySample::value_type &vals1 =
              samplePos->get()[pointOffset + i];
          const Abc::P3fArraySample::value_type &vals2 =
              samplePos2->get()[pointOffset + i];
          MPoint &pt = points[i];

          pt.x = vals1.x + (vals2.x - vals1.x) * blend;
          pt.y = vals1.y + (vals2.y - vals1.y) * blend;
          pt.z = vals1.z + (vals2.z - vals1.z) * blend;
        }
      }
      else {
        for (unsigned int i = 0; i < nbCVs; ++i) {
          const Abc::P3fArraySample::value_type &vals =
              samplePos->get()[pointOffset + i];
          MPoint &pt = points[i];
          pt.x = vals.x;
          pt.y = vals.y;
          pt.z = vals.z;
        }
      }
      pointOffset += nbCVs;
    }

    // create a subd either with or without uvs
    MObject mmCurvesData = MFnNurbsCurveData().create();
    if (ldegree == 1 || ldegree == 3)
      mCurves.create(points, knots, ldegree,
                     closed ? MFnNurbsCurve::kClosed : MFnNurbsCurve::kOpen,
                     false, false, mmCurvesData);
    builder.addElement(ii).set(mmCurvesData);
  }
  arrh.set(builder);
  arrh.setAllClean();
  return MStatus::kSuccess;
}
コード例 #6
0
ファイル: shiftNode.cpp プロジェクト: BigRoy/Maya-devkit
/*

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;
}
コード例 #7
0
ファイル: puttyNode.cpp プロジェクト: Leopardob/puttynodes
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;
}
コード例 #8
0
ファイル: MG_dotProduct.cpp プロジェクト: bungnoid/MG_Tools
		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;


		}
コード例 #9
0
MStatus liqSurfaceNode::compute( const MPlug& plug, MDataBlock& block )
{
  // outColor or individual R, G, B channel
  if( (plug == aOutColor) || (plug.parent() == aOutColor) ||
	  (plug == aOutTransparency) || (plug.parent() == aOutTransparency)
  	) {

    //cout <<"compute... "<<endl;

    // init shader
    MStatus status;
    MFloatVector theColor( 0.0f, 0.0f, 0.0f );
    MFloatVector& cColor  = block.inputValue(aColor).asFloatVector();
    MFloatVector& cTrans  = block.inputValue(aOpacity).asFloatVector();
    MFloatVector& ctex    = block.inputValue(aGLPreviewTexture).asFloatVector();

    // exploit maya's free openGL preview
    if ( ctex != MFloatVector( -1.0, -1.0, -1.0 ) ) theColor = ctex;
    else theColor = cColor;

    MFloatVector resultColor( 0.0, 0.0, 0.0 );
    MFloatVector resultTrans( cTrans );



    // lambert calc -------------------
    bool&  ignoreLights = block.inputValue( aMayaIgnoreLights, &status ).asBool();
    float& Ka = block.inputValue( aMayaKa, &status ).asFloat();
    float& Kd = block.inputValue( aMayaKd, &status ).asFloat();

    // get surface normal
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera, &status ).asFloatVector();
    CHECK_MSTATUS( status );

    if ( ignoreLights ) {

      MFloatVector cam( 0.0, 0.0, 1.0 );
      float cosln = cam * surfaceNormal;
      if ( cosln > 0.0f ) {
        float diff = cosln * cosln * Kd + Ka;
        resultColor = diff * theColor;
      }

    } else {

      // Get light list
      MArrayDataHandle lightData = block.inputArrayValue( aLightData, &status );
      CHECK_MSTATUS( status );
      int numLights = lightData.elementCount( &status );
      CHECK_MSTATUS( status );

      // Iterate through light list and get ambient/diffuse values
      for( int count=1; count <= numLights; count++ )
      {
        // Get the current light out of the array
        MDataHandle currentLight = lightData.inputValue( &status );
        CHECK_MSTATUS( status );

        // Get the intensity of that light
        MFloatVector& lightIntensity = currentLight.child( aLightIntensity ).asFloatVector();

        // Find ambient component
        if ( currentLight.child( aLightAmbient ).asBool() ) {
          resultColor += lightIntensity;
        }

        // Find diffuse component
        if ( currentLight.child( aLightDiffuse ).asBool() ) {
          MFloatVector& lightDirection = currentLight.child( aLightDirection ).asFloatVector();
          float cosln = lightDirection * surfaceNormal;
          if ( cosln > 0.0f )  resultColor += lightIntensity * cosln * Kd ;
        }

        // Advance to the next light.
        if ( count < numLights ) {
          status = lightData.next();
          CHECK_MSTATUS( status );
        }
      }

      resultColor[0] *= theColor[0];
      resultColor[1] *= theColor[1];
      resultColor[2] *= theColor[2];

    }

    resultTrans[0] = ( 1 - resultTrans[0] );
    resultTrans[1] = ( 1 - resultTrans[1] );
    resultTrans[2] = ( 1 - resultTrans[2] );


    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();

    MDataHandle outTransHandle = block.outputValue( aOutTransparency );
    MFloatVector& outTrans = outTransHandle.asFloatVector();
    outTrans = resultTrans;
    outTransHandle.setClean();

  } else return MS::kUnknownParameter;


  return MS::kSuccess;
}
コード例 #10
0
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;
}
コード例 #11
0
ファイル: splitUVNode.cpp プロジェクト: DimondTheCat/xray
MStatus splitUVNode::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 status = MS::kSuccess;
 
	MDataHandle stateData = data.outputValue( state, &status );
	MCheckStatus( status, "ERROR getting state" );

	// Check for the HasNoEffect/PassThrough flag on the node.
	//
	// (stateData is an enumeration standard in all depend nodes - stored as short)
	// 
	// (0 = Normal)
	// (1 = HasNoEffect/PassThrough)
	// (2 = Blocking)
	// ...
	//
	if( stateData.asShort() == 1 )
	{
		MDataHandle inputData = data.inputValue( inMesh, &status );
		MCheckStatus(status,"ERROR getting inMesh");

		MDataHandle outputData = data.outputValue( outMesh, &status );
		MCheckStatus(status,"ERROR getting outMesh");

		// Simply redirect the inMesh to the outMesh for the PassThrough effect
		//
		outputData.set(inputData.asMesh());
	}
	else
	{
		// 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 == outMesh)
		{
			MDataHandle inputData = data.inputValue( inMesh, &status );
			MCheckStatus(status,"ERROR getting inMesh");

			MDataHandle outputData = data.outputValue( outMesh, &status );
			MCheckStatus(status,"ERROR getting outMesh"); 

			// Now, we get the value of the uvList and use it to perform
			// the operation on this mesh
			//
			MDataHandle inputUVs = data.inputValue( uvList, &status);
			MCheckStatus(status,"ERROR getting uvList"); 
			
			// Copy the inMesh to the outMesh, and now you can
			// perform operations in-place on the outMesh
			//
			outputData.set(inputData.asMesh());
			MObject mesh = outputData.asMesh();

			// Retrieve the UV list from the component list.
			//
			// Note, we use a component list to store the components
			// because it is more compact memory wise. (ie. comp[81:85]
			// is smaller than comp[81], comp[82],...,comp[85])
			//
			MObject compList = inputUVs.data();
			MFnComponentListData compListFn( compList );

			unsigned i;
			int j;
			MIntArray uvIds;

			for( i = 0; i < compListFn.length(); i++ )
			{
				MObject comp = compListFn[i];
				if( comp.apiType() == MFn::kMeshMapComponent )
				{
					MFnSingleIndexedComponent uvComp( comp );
					for( j = 0; j < uvComp.elementCount(); j++ )
					{
						int uvId = uvComp.element(j);
						uvIds.append( uvId );
					}
				}
			}

			// Set the mesh object and uvList on the factory
			//
			fSplitUVFactory.setMesh( mesh );
			fSplitUVFactory.setUVIds( uvIds );

			// Now, perform the splitUV
			//
			status = fSplitUVFactory.doIt();

			// Mark the output mesh as clean
			//
			outputData.setClean();
		}
		else
		{
			status = MS::kUnknownParameter;
		}
	}

	return status;
}
コード例 #12
0
MStatus VmIslandNode::compute( const MPlug& i_plug, MDataBlock& io_dataBlock )
{
    MStatus status;
    
    fprintf( stderr, "VmIslandNode::compute()...\n" );
    
    //Check plugs
    if( i_plug == oa_update )
    {
        //Make sure all internal structures are up to date with attributes
        fprintf( stderr, "VmIslandNode::compute(oa_update)\n" );
        
        MDataHandle seedHandle = io_dataBlock.inputValue( ia_seed, & status);
        const long seed = seedHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle roughnessHandle = io_dataBlock.inputValue( ia_roughness, & status);
        const float roughness = roughnessHandle.asFloat();
        CHECK_MSTATUS( status );
        
        MDataHandle planeHeightHandle = io_dataBlock.inputValue( ia_planeHeight, & status);
        const long planeHeight = planeHeightHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle smoothHandle = io_dataBlock.inputValue( ia_smooth, & status);
        const long smooth = smoothHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle resolutionHandle = io_dataBlock.inputValue( ia_resolution, & status);
        const long resolution = resolutionHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle planeSizeHandle = io_dataBlock.inputValue( ia_planeSize, & status);
        const long planeSize = planeSizeHandle.asLong();
        CHECK_MSTATUS( status );


        
        MDataHandle gridSizeHandle = io_dataBlock.inputValue( ia_gridSize, & status);
        const long gridSize = gridSizeHandle.asLong();
        m_gridSize = (int) gridSize;
        CHECK_MSTATUS( status );


        //Grass
        //--------------
        MDataHandle baseWidthHandle = io_dataBlock.inputValue( ia_baseWidth, & status);
        const float baseWidth = baseWidthHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle grassMultiplierHandle = io_dataBlock.inputValue( ia_grassMultiplier, & status);
        const long grassMultiplier = grassMultiplierHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle grassSegmentLengthHandle = io_dataBlock.inputValue( ia_grassSegmentLength, & status);
        const float grassSegmentLength = grassSegmentLengthHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle grassNumSegmentsHandle = io_dataBlock.inputValue( ia_grassNumSegments, & status);
        const long grassNumSegments = grassNumSegmentsHandle.asLong();
        CHECK_MSTATUS( status );

        //MDataHandle windDirectionHandle = io_dataBlock.inputValue( ia_windDirection, & status);
        MFloatVector& windDirVec = io_dataBlock.inputValue( ia_windDirection, & status).asFloatVector();
        const Vcore::Vec3 windDirection = Vec3(windDirVec.x, windDirVec.y, windDirVec.z);
        CHECK_MSTATUS( status );

        MDataHandle grassBendAmountHandle = io_dataBlock.inputValue( ia_grassBendAmount, & status);
        const float grassBendAmount = grassBendAmountHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle windSpreadHandle = io_dataBlock.inputValue( ia_windSpread, & status);
        const float windSpread = windSpreadHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle clockHandle = io_dataBlock.inputValue( ia_clock, & status);
        const float clock = clockHandle.asLong();
        CHECK_MSTATUS( status );

        //Colours
        //-----------------
        MFloatVector& grassBaseColour1Vec = io_dataBlock.inputValue( ia_grassBaseColour1, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour1 = Vec3(grassBaseColour1Vec.x, grassBaseColour1Vec.y, grassBaseColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour1Vec = io_dataBlock.inputValue( ia_grassTipColour1, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour1 = Vec3(grassTipColour1Vec.x, grassTipColour1Vec.y, grassTipColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassBaseColour2Vec = io_dataBlock.inputValue( ia_grassBaseColour2, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour2 = Vec3(grassBaseColour2Vec.x, grassBaseColour2Vec.y, grassBaseColour2Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour2Vec = io_dataBlock.inputValue( ia_grassTipColour2, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour2 = Vec3(grassTipColour2Vec.x, grassTipColour2Vec.y, grassTipColour2Vec.z);
        CHECK_MSTATUS( status );


        //Update paramters of external lib system and rebuild
        m_island.setPlaneParameters( 
            planeSize, 
            planeHeight, 
            seed, 
            roughness, 
            resolution, 
            gridSize, 
            grassMultiplier, 
            baseWidth,
            grassSegmentLength, 
            grassNumSegments, 
            windDirection, 
            grassBendAmount, 
            windSpread, 
            clock, 
            smooth,
            grassBaseColour1,
            grassTipColour1,
            grassBaseColour2,
            grassTipColour2
        );
        
        //Rebuild object and check for success
        const bool updateOK = m_island.build();

        m_cachedVertices = m_island.getComponents( Vcore::Visland::VERTICES );
        m_cachedColours = m_island.getComponents( Vcore::Visland::COLOURS );
        m_cachedNormals = m_island.getComponents( Vcore::Visland::NORMALS );
        m_cachedIndices = m_island.getAllIndices();
        m_geomInstances = m_island.getAllGeometryInstances();
        
        // We must set a value for the plug we have been asked to evaluate,
        // even if we are not going to use it. We set it in the data-block,
        // and to set it we use outputValue().
        //
        // Here we usually set the result to true. The caller who triggered the
        // computation for this attribute might not look at the value that
        // we are setting this plug to. But they do ask for the value of this plug,
        // only to trigger an update of the internal structures. See the draw()
        // and boundingBox() methods to see how this is done.
        
        MDataHandle updateHandle = io_dataBlock.outputValue( i_plug );
        updateHandle.set( updateOK );
        
        //Need to set plug to clean to refresh it
        io_dataBlock.setClean( i_plug );
    }
    
    else if( i_plug == oa_rib ) {
        //Set up rib system to ready renderman values
        
        fprintf( stderr, "VmIslandNode::compute(oa_rib)\n" );
        
        MDataHandle seedHandle = io_dataBlock.inputValue( ia_seed, & status);
        const long seed = seedHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle smoothHandle = io_dataBlock.inputValue( ia_smooth, & status);
        const float smooth = smoothHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle roughnessHandle = io_dataBlock.inputValue( ia_roughness, & status);
        const float roughness = roughnessHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle rmanResolutionHandle = io_dataBlock.inputValue( ia_rmanResolution, & status);
        const long rmanResolution = rmanResolutionHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle planeHeightHandle = io_dataBlock.inputValue( ia_planeHeight, & status);
        const long planeHeight = planeHeightHandle.asLong();
        CHECK_MSTATUS( status );
        
        MDataHandle planeSizeHandle = io_dataBlock.inputValue( ia_planeSize, & status);
        const long planeSize = planeSizeHandle.asLong();
        CHECK_MSTATUS( status );


        //Grass
        //----------------

        MDataHandle gridSizeHandle = io_dataBlock.inputValue( ia_gridSize, & status);
        const long gridSize = gridSizeHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle grassMultiplierHandle = io_dataBlock.inputValue( ia_grassMultiplier, & status);
        const long grassMultiplier = grassMultiplierHandle.asLong();
        CHECK_MSTATUS( status );

        MDataHandle baseWidthHandle = io_dataBlock.inputValue( ia_baseWidth, & status);
        const float baseWidth = baseWidthHandle.asFloat();
        m_gridSize = (int) baseWidth;
        CHECK_MSTATUS( status );

        MDataHandle grassSegmentLengthHandle = io_dataBlock.inputValue( ia_grassSegmentLength, & status);
        const float grassSegmentLength = grassSegmentLengthHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle grassNumSegmentsHandle = io_dataBlock.inputValue( ia_grassNumSegments, & status);
        const long grassNumSegments = grassNumSegmentsHandle.asLong();
        CHECK_MSTATUS( status );

        MFloatVector& windDirVec = io_dataBlock.inputValue( ia_windDirection, & status).asFloatVector();
        const Vcore::Vec3 windDirection = Vec3(windDirVec.x, windDirVec.y, windDirVec.z);
        CHECK_MSTATUS( status );

        MDataHandle grassBendAmountHandle = io_dataBlock.inputValue( ia_grassBendAmount, & status);
        const float grassBendAmount = grassBendAmountHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle windSpreadHandle = io_dataBlock.inputValue( ia_windSpread, & status);
        const float windSpread = windSpreadHandle.asFloat();
        CHECK_MSTATUS( status );

        MDataHandle clockHandle = io_dataBlock.inputValue( ia_clock, & status);
        const float clock = clockHandle.asLong();
        CHECK_MSTATUS( status );

        //Colours
        //-------------------
        MFloatVector& grassBaseColour1Vec = io_dataBlock.inputValue( ia_grassBaseColour1, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour1 = Vec3(grassBaseColour1Vec.x, grassBaseColour1Vec.y, grassBaseColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour1Vec = io_dataBlock.inputValue( ia_grassTipColour1, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour1 = Vec3(grassTipColour1Vec.x, grassTipColour1Vec.y, grassTipColour1Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassBaseColour2Vec = io_dataBlock.inputValue( ia_grassBaseColour2, & status).asFloatVector();
        const Vcore::Vec3 grassBaseColour2 = Vec3(grassBaseColour2Vec.x, grassBaseColour2Vec.y, grassBaseColour2Vec.z);
        CHECK_MSTATUS( status );

        MFloatVector& grassTipColour2Vec = io_dataBlock.inputValue( ia_grassTipColour2, & status).asFloatVector();
        const Vcore::Vec3 grassTipColour2 = Vec3(grassTipColour2Vec.x, grassTipColour2Vec.y, grassTipColour2Vec.z);
        CHECK_MSTATUS( status );

        char rib[4096];
        sprintf( rib, "seed=%d;roughness=%f;planeHeight=%d;planeSize=%d;resolution=%d;gridSize=%d;grassMultiplier=%d;baseWidth=%f;grassSegmentLength=%f;grassNumSegments=%d;windDirectionX=%f;windDirectionY=%f;windDirectionZ=%f;grassBendAmount=%f;windSpread=%f;clock=%d;smooth=%d;grassBaseColour1X=%f;grassBaseColour1Y=%f;grassBaseColour1Z=%f;grassTipColour1X=%f;grassTipColour1Y=%f;grassTipColour1Z=%f;grassBaseColour2X=%f;grassBaseColour2Y=%f;grassBaseColour2Z=%f;grassTipColour2X=%f;grassTipColour2Y=%f;grassTipColour2Z=%f;",
            (int) seed, 
            (float) roughness, 
            (int) planeHeight, 
            (int) planeSize, 
            (int) rmanResolution , 
            (int) gridSize, 
            (int) grassMultiplier, 
            (float) baseWidth,
            (float) grassSegmentLength, 
            (int) grassNumSegments, 
            (float) windDirection.x, 
            (float) windDirection.y,
            (float) windDirection.z,
            (float) grassBendAmount, 
            (float) windSpread,
            (int) clock,
            (int) smooth,
            (float) grassBaseColour1.x,
            (float) grassBaseColour1.y,
            (float) grassBaseColour1.z,
            (float) grassTipColour1.x,
            (float) grassTipColour1.y,
            (float) grassTipColour1.z,
            (float) grassBaseColour2.x,
            (float) grassBaseColour2.y,
            (float) grassBaseColour2.z,
            (float) grassTipColour2.x,
            (float) grassTipColour2.y,
            (float) grassTipColour2.z
        );        
        
        // We must set a value for the plug we have been asked to evaluate,
        // even if we are not going to use it. We set it in the data-block,
        // and to set it we use outputValue().
        //
        // Here we are calculating a string value, and that value will 
        // be used by the caller in a "rib-gen" operation - a process in 
        // which a RIB file is generated for Renderman.
        //
        // Notice also that strings in Maya or more complicated than numbers.
        // We need to make a data object for the string data.
        
        MFnStringData stringDataFn;
        MObject stringDataObj = stringDataFn.create( rib, & status );
        CHECK_MSTATUS( status );
        
        MDataHandle ribHandle = io_dataBlock.outputValue( i_plug );
        ribHandle.set( stringDataObj );
        io_dataBlock.setClean( i_plug );
    }
    
    else {
        //Shouldn't be here.
        return MStatus::kSuccess;
    }
}
コード例 #13
0
ファイル: meshOpNode.cpp プロジェクト: BigRoy/Maya-devkit
MStatus meshOpNode::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 status = MS::kSuccess;
 
	MDataHandle stateData = data.outputValue( state, &status );
	MCheckStatus( status, "ERROR getting state" );

	// Check for the HasNoEffect/PassThrough flag on the node.
	//
	// (stateData is an enumeration standard in all depend nodes)
	// 
	// (0 = Normal)
	// (1 = HasNoEffect/PassThrough)
	// (2 = Blocking)
	// ...
	//
	if( stateData.asShort() == 1 )
	{
		MDataHandle inputData = data.inputValue( inMesh, &status );
		MCheckStatus(status,"ERROR getting inMesh");

		MDataHandle outputData = data.outputValue( outMesh, &status );
		MCheckStatus(status,"ERROR getting outMesh");

		// Simply redirect the inMesh to the outMesh for the PassThrough effect
		//
		outputData.set(inputData.asMesh());
	}
	else
	{
		// 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 == outMesh)
		{
			MDataHandle inputData = data.inputValue( inMesh, &status );
			MCheckStatus(status,"ERROR getting inMesh");

			MDataHandle outputData = data.outputValue( outMesh, &status );
			MCheckStatus(status,"ERROR getting outMesh"); 

			// Now, we get the value of the component list and the operation
			// type and use it to perform the mesh operation on this mesh
			//
			MDataHandle inputIDs = data.inputValue( cpList, &status);
			MCheckStatus(status,"ERROR getting componentList"); 
			
			MDataHandle opTypeData = data.inputValue( opType, &status);
			MCheckStatus(status,"ERROR getting opType"); 

			// Copy the inMesh to the outMesh, so you can
			// perform operations directly on outMesh
			//
			outputData.set(inputData.asMesh());
			MObject mesh = outputData.asMesh();

			// Retrieve the ID list from the component list.
			//
			// Note, we use a component list to store the components
			// because it is more compact memory wise. (ie. comp[81:85]
			// is smaller than comp[81], comp[82],...,comp[85])
			//
			MObject compList = inputIDs.data();
			MFnComponentListData compListFn( compList );

			// Get what operation is requested and 
			// what type of component is expected for this operation.
			MeshOperation operationType = (MeshOperation) opTypeData.asShort();
			MFn::Type componentType =
				meshOpFty::getExpectedComponentType(operationType);

			unsigned i;
			int j;
			MIntArray cpIds;

			for( i = 0; i < compListFn.length(); i++ )
			{
				MObject comp = compListFn[i];
				if( comp.apiType() == componentType )
				{
					MFnSingleIndexedComponent siComp( comp );
					for( j = 0; j < siComp.elementCount(); j++ )
						cpIds.append( siComp.element(j) );
				}
			}

			// Set the mesh object and component List on the factory
			//
			fmeshOpFactory.setMesh( mesh );
			fmeshOpFactory.setComponentList( compList );
			fmeshOpFactory.setComponentIDs( cpIds );
			fmeshOpFactory.setMeshOperation( operationType );

			// Now, perform the meshOp
			//
			status = fmeshOpFactory.doIt();

			// Mark the output mesh as clean
			//
			outputData.setClean();
		}
		else
		{
			status = MS::kUnknownParameter;
		}
	}

	return status;
}
コード例 #14
0
MStatus resetVtxRemapNode::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 status = MS::kSuccess;
 
	MDataHandle stateData = data.outputValue( state, &status );
	MCheckStatus( status, "ERROR getting state" );

	// Check for the HasNoEffect/PassThrough flag on the node.
	//
	// (stateData is an enumeration standard in all depend nodes - stored as short)
	// 
	// (0 = Normal)
	// (1 = HasNoEffect/PassThrough)
	// (2 = Blocking)
	// ...
	//
	if( stateData.asShort() == 1 )
	{
		MDataHandle inputData = data.inputValue( inMesh, &status );
		MCheckStatus(status,"ERROR getting inMesh");

		MDataHandle outputData = data.outputValue( outMesh, &status );
		MCheckStatus(status,"ERROR getting outMesh");

		// Simply redirect the inMesh to the outMesh for the PassThrough effect
		//
		outputData.set(inputData.asMesh());
	}
	else
	{
		// 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 == outMesh)
		{
			MDataHandle inputData = data.inputValue( inMesh, &status );
			MCheckStatus(status,"ERROR getting inMesh");

			MDataHandle outputData = data.outputValue( outMesh, &status );
			MCheckStatus(status,"ERROR getting outMesh"); 

			// Copy the inMesh to the outMesh, and now you can
			// perform operations in-place on the outMesh
			//
			outputData.set(inputData.asMesh());
			MObject mesh = outputData.asMesh();

			fresetVtxRemapFactory.setMesh( mesh );

			status = fresetVtxRemapFactory.doIt();

			outputData.setClean();
		}
		else
		{
			status = MS::kUnknownParameter;
		}
	}

	return status;
}
コード例 #15
0
MStatus vixo_visImport::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus stat=MS::kSuccess;	
	if(plug.array()!=vis)
		return MS::kSuccess;

	//cout<<plug.info().asChar()<<endl;

	int objIdx=plug.logicalIndex();

	MDataHandle file_handle=data.inputValue(file);
	MString filename=file_handle.asString();

	MDataHandle timeHandle=data.inputValue(time);
	int t=timeHandle.asTime().as(MTime::Unit::kFilm);

	if(mapObjName.count(objIdx)<=0)
		return MS::kSuccess;

	//cout<<"test"<<endl;

	MString objNameValue(mapObjName.find(objIdx)->second.c_str());
	bool res=true;
	ifstream fin(filename.asChar(),ios_base::in|ios_base::binary);
	if(fin.fail())
	{
		MDataHandle eleHandle=data.outputValue(plug);
		eleHandle.set(res);
		data.setClean(plug);
		return MS::kSuccess;
	}

	int objNum=0;
	fin.read((char*)&objNum,sizeof(int));
	vector<struct_visBasicInfo> objIndexes(objNum);
	fin.read((char*)&objIndexes[0],sizeof(struct_visBasicInfo)*objNum);

	int fileObjIndex=-1;
	for(int i=0;i<objNum;i++)
	{
		MStringArray tempArr;
		MString tempStr(objIndexes[i].objName);
		tempStr.split(':',tempArr);
		if(tempArr[tempArr.length()-1]==objNameValue)
		{
			fileObjIndex=i;
			break;
		}
	}

	if(fileObjIndex==-1)
	{
		MDataHandle eleHandle=data.outputValue(plug);
		eleHandle.set(res);
		data.setClean(plug);
		fin.close();
		return MS::kSuccess;
	}
	//cout<<"test1"<<endl;
	if(t<objIndexes[fileObjIndex].startFrame||t>objIndexes[fileObjIndex].endFrame)
	{
		fin.close();
		MDataHandle eleHandle=data.outputValue(plug);
		eleHandle.set(res);
		data.setClean(plug);
		return MS::kSuccess;
	}
	//cout<<"test2"<<endl;
	fin.seekg(objIndexes[fileObjIndex].visBegin.operator+(sizeof(char)*(t-objIndexes[fileObjIndex].startFrame)));
	char value;
	fin.read((char *)&value,sizeof(char));
	fin.close();

	//cout<<t<<" "<<(int)value<<endl;
	
	if(value==0)
		res=0;
	MDataHandle eleHandle=data.outputValue(plug);
	eleHandle.set(res);
	data.setClean(plug);

	return MS::kSuccess;
}
コード例 #16
0
ファイル: percentageToU.cpp プロジェクト: kattkieru/mgear
// COMPUTE ======================================
MStatus gear_percentageToU::compute(const MPlug& plug, MDataBlock& data)
{
	MStatus returnStatus;
	// Error check
    if (plug != percentage)
        return MS::kUnknownParameter;
	
	// Curve
	MFnNurbsCurve crv( data.inputValue( curve ).asNurbsCurve() );

	// Sliders
	bool in_normU = data.inputValue( normalizedU ).asBool();
	double in_percentage = (double)data.inputValue( percentage ).asFloat() * .01;
	const unsigned in_steps = data.inputValue( steps ).asShort();

	// Process
	// Get length
	MVectorArray u_subpos(in_steps);
	MPoint pt;
	MDoubleArray u_list(in_steps);
	for(unsigned i = 0 ; i < in_steps ; i++ ){
		u_list[i] = normalizedUToU(i /(in_steps - 1.0), crv.numCVs());

		crv.getPointAtParam(u_list[i], pt, MSpace::kWorld);
		u_subpos[i] = MVector(pt);
	}
	
	
	double t_length = 0;
	MDoubleArray dist(in_steps);
	MVector v;
	for (unsigned i = 0; i < in_steps ; i++){
		if (i>0){
			v = u_subpos[i] - u_subpos[i-1];
			t_length += v.length();
			dist[i] = t_length;
		}
	}

	MDoubleArray u_perc(in_steps);
	for (unsigned i = 0; i < in_steps ; i++){
		u_perc[i] = dist[i] / t_length;
	}

	
    // Get closest indices
    unsigned index = findClosestInArray(in_percentage, u_perc);
	unsigned indexA, indexB;
    if (in_percentage <= u_perc[index]){
        indexA = abs(int(index));
        indexB = index;
		if ( indexA > indexB){
			indexA = indexB;
			indexB = indexA+1;
		}
	}
    else {
        indexA = index;
        indexB = index + 1;
	}
	
    // blend value
    double blend = set01range(in_percentage, u_perc[indexA], u_perc[indexB]);
            
    double out_u = linearInterpolate(u_list[indexA], u_list[indexB], blend);
        
    if (in_normU)
        out_u = uToNormalizedU(out_u, crv.numCVs());
	
	// Ouput
	MDataHandle h = data.outputValue( u );
    h.setDouble( out_u );
    data.setClean( plug );

	return MS::kSuccess;
}
コード例 #17
0
ファイル: MG_poseReader.cpp プロジェクト: bungnoid/MG_Tools
MStatus MG_poseReader::compute(const MPlug& plug,MDataBlock& dataBlock)
	{
		
	      
		MMatrix poseM = dataBlock.inputValue(poseMatrix).asMatrix();
		MMatrix readerM = dataBlock.inputValue(readerMatrix).asMatrix();

		// aim axis value 
		//0 =x
		//1 =y
		//2 =z
		int axis = dataBlock.inputValue(aimAxis).asInt();


		MVector poseAimV;
		if (axis==0)
		{
			
			poseAimV.x=poseM[0][0];
			poseAimV.y=poseM[0][1];
			poseAimV.z=poseM[0][2];
		}
		else if (axis==1)
		{
			
			poseAimV.x=poseM[1][0];
			poseAimV.y=poseM[1][1];
			poseAimV.z=poseM[1][2];

		}else
		{
			
			poseAimV.x=poseM[2][0];
			poseAimV.y=poseM[2][1];
			poseAimV.z=poseM[2][2];
		}
	
		MVector x (readerM[0][0],readerM[0][1],readerM[0][2]);
		MVector y (readerM[1][0],readerM[1][1],readerM[1][2]);
		MVector z (readerM[2][0],readerM[2][1],readerM[2][2]);
		double porjX =projVector (poseAimV,x);
		double porjXNeg =projVector (poseAimV,x*-1);
		double porjY =projVector (poseAimV,y);
		double porjYNeg =projVector (poseAimV,y*-1);
		double porjZ =projVector (poseAimV,z);
		double porjZNeg =projVector (poseAimV,z*-1);

		dataBlock.outputValue(xPositive).set(porjX);
		dataBlock.outputValue(xPositive).setClean();

		dataBlock.outputValue(xNegative).set(porjXNeg);
		dataBlock.outputValue(xNegative).setClean();


		dataBlock.outputValue(yPositive).set(porjY);
		dataBlock.outputValue(yPositive).setClean();

		dataBlock.outputValue(yNegative).set(porjYNeg);
		dataBlock.outputValue(yNegative).setClean();

		dataBlock.outputValue(zPositive).set(porjZ);
		dataBlock.outputValue(zPositive).setClean();

		dataBlock.outputValue(zNegative).set(porjZNeg);
		dataBlock.outputValue(zNegative).setClean();

		return MS::kSuccess;
	}
コード例 #18
0
ファイル: rigidBodyNode.cpp プロジェクト: benelot/dynamica
void rigidBodyNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
{
	if (!m_rigid_body)
		return;

  //  std::cout << "rigidBodyNode::computeWorldMatrix" << std::endl;
    MObject thisObject(thisMObject());
    MFnDagNode fnDagNode(thisObject);

    MObject update;
    MPlug(thisObject, ca_rigidBody).getValue(update);
    MPlug(thisObject, ca_rigidBodyParam).getValue(update);
    
    vec3f pos;
    quatf rot;

    MStatus status;

    MFnTransform fnParentTransform(fnDagNode.parent(0, &status));

	double mscale[3];
    fnParentTransform.getScale(mscale);
	m_rigid_body->get_transform(pos, rot);
	
	
	if(dSolverNode::isStartTime)
	{ // allow to edit ptranslation and rotation
		MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status);
		MQuaternion mrotation;
		fnParentTransform.getRotation(mrotation, MSpace::kTransform);

		float deltaPX = (float)mtranslation.x - pos[0];
		float deltaPY = (float)mtranslation.y - pos[1];
		float deltaPZ = (float)mtranslation.z - pos[2];
		float deltaRX = (float)mrotation.x - rot[1];
		float deltaRY = (float)mrotation.y - rot[2];
		float deltaRZ = (float)mrotation.z - rot[3];
		float deltaRW = (float)mrotation.w - rot[0];
		float deltaSq = deltaPX * deltaPX + deltaPY * deltaPY  + deltaPZ * deltaPZ 
						+ deltaRX * deltaRX + deltaRY * deltaRY + deltaRZ * deltaRZ + deltaRW * deltaRW;
		if(deltaSq > FLT_EPSILON)
		{
			m_rigid_body->set_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z),
										quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z));
			m_rigid_body->set_interpolation_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z),
														quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z));
			m_rigid_body->update_constraint();
				MDataHandle hInitPos = data.outputValue(ia_initialPosition);
				float3 &ihpos = hInitPos.asFloat3();
				ihpos[0] = (float)mtranslation.x;
				ihpos[1] = (float)mtranslation.y;
				ihpos[2] = (float)mtranslation.z;
				MDataHandle hInitRot = data.outputValue(ia_initialRotation);
				float3 &ihrot = hInitRot.asFloat3();
				MEulerRotation newrot(mrotation.asEulerRotation());
				ihrot[0] = rad2deg((float)newrot.x);
				ihrot[1] = rad2deg((float)newrot.y);
				ihrot[2] = rad2deg((float)newrot.z);
		}
	}
	else
	{ // if not start time, lock position and rotation for active rigid bodies
        float mass = 0.f;
		MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass);
        if(mass > 0.f) 
		{
			fnParentTransform.setTranslation(MVector(pos[0], pos[1], pos[2]), MSpace::kTransform);
			fnParentTransform.setRotation(MQuaternion(rot[1], rot[2], rot[3], rot[0])); 
		}
	}

	float mass = 0.f;
	MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass);

	float curMass = m_rigid_body->get_mass();
	bool changedMassStatus= false;
	if ((curMass > 0.f) != (mass > 0.f))
	{
		changedMassStatus = true;
	}
	if (changedMassStatus)
		solver_t::remove_rigid_body(m_rigid_body);
	
	m_rigid_body->set_mass(mass);
	m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia());

	if (changedMassStatus)
		solver_t::remove_rigid_body(m_rigid_body);

	float restitution = 0.f;
	 MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution);
	 m_rigid_body->set_restitution(restitution);
	 float friction = 0.5f;
	  MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction);
    m_rigid_body->set_friction(friction);
    float linDamp = 0.f;
	  MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp);
	m_rigid_body->set_linear_damping(linDamp);
    float angDamp = 0.f;
	  MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp);
	m_rigid_body->set_angular_damping(angDamp);

    data.setClean(plug);
    //set the scale to the collision shape
    m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2]));
}
コード例 #19
0
ファイル: sseDeformer.cpp プロジェクト: BigRoy/Maya-devkit
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;
}
コード例 #20
0
//
//	Calls applyRotationLocks && applyRotationLimits
//	This method verifies that the passed value can be set on the 
//	rotate plugs. In the base class, limits as well as locking are
//	checked by this method.
//
//	The compute, validateAndSetValue, and rotateTo functions
//	all use this method.
//
MStatus rockingTransformCheckNode::checkAndSetRotation(MDataBlock &block,
									const MPlug& plug,
									const MEulerRotation& newRotation, 
									MSpace::Space space )
{
	const MDGContext context = block.context();
	updateMatrixAttrs(context);

	MStatus status = MS::kSuccess;
	MEulerRotation outRotation = newRotation;
	if (context.isNormal()) {
		//	For easy reading.
		//
		MPxTransformationMatrix *xformMat = baseTransformationMatrix;

		//	Get the current translation in transform space for 
		//	clamping and locking.
		//
		MEulerRotation savedRotation = 
			xformMat->eulerRotation(MSpace::kTransform, &status);
		ReturnOnError(status);

		//	Translate to transform space, since the limit test needs the
		//	values in transform space. The locking test needs the values
		//	in the same space as the savedR value - which is transform 
		//	space as well.
		//
		status = baseTransformationMatrix->rotateTo(newRotation, space);
		ReturnOnError(status);

		outRotation = xformMat->eulerRotation(MSpace::kTransform, &status);
		ReturnOnError(status);

		//	Now that everything is in the same space, apply limits 
		//	and change the value to adhere to plug locking.
		//
		outRotation = applyRotationLimits(outRotation, block, &status);
		ReturnOnError(status);

		outRotation = applyRotationLocks(outRotation, savedRotation, &status);
		ReturnOnError(status);

		//	The value that remain is in transform space.
		//
		status = xformMat->rotateTo(outRotation, MSpace::kTransform);
		ReturnOnError(status);

		//	Get the value that was just set. It needs to be in transform
		//	space since it is used to set the datablock values at the
		//	end of this method. Getting the vaolue right before setting
		//	ensures that the transformation matrix and data block will
		//	be synchronized.
		//
		outRotation = xformMat->eulerRotation(MSpace::kTransform, &status);
		ReturnOnError(status);
	} else {
		//	Get the rotation for clamping and locking. This will get the
		//	rotate value in transform space.
		//
		double3 &s3 = block.inputValue(rotate).asDouble3();
		MEulerRotation savedRotation(s3[0], s3[1], s3[2]);

		//	Create a local transformation matrix for non-normal context
		//	calculations.
		//
		MPxTransformationMatrix *local = createTransformationMatrix();
		if (NULL == local) {
			MGlobal::displayError("rockingTransformCheck::checkAndSetRotation internal error");
			return status;
		}

		//	Fill the newly created transformation matrix.
		//
		status = computeLocalTransformation(local, block);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		//	Translate the values to transform space. This will allow the 
		//	limit and locking tests to work properly.
		//
		status = local->rotateTo(newRotation, space);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		outRotation = local->eulerRotation(MSpace::kTransform, &status);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		//	Apply limits
		//
		outRotation = applyRotationLimits(outRotation, block, &status);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		outRotation = applyRotationLocks(outRotation, savedRotation, &status);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		status = local->rotateTo(outRotation, MSpace::kTransform);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		//	Get the rotate value in transform space for placement in the
		//	datablock.
		//
		outRotation = local->eulerRotation(MSpace::kTransform, &status);
		if ( MS::kSuccess != status)
		{
			delete local;
			return status;
		}

		delete local;
	}

	MDataHandle handle = block.outputValue(plug, &status);
	if ( MS::kSuccess != status)
	{
		return status;
	}

	if (plug == rotate) {
		handle.set(outRotation.x, outRotation.y, outRotation.z);
	} else if (plug == rotateX) {
		handle.set(outRotation.x);
	} else if (plug == rotateY) {
		handle.set(outRotation.y);
	} else {
		handle.set(outRotation.z);
	}

	return status;
}
コード例 #21
0
MStatus testNpassiveNode::compute(const MPlug &plug, MDataBlock &data)
{
    MStatus stat;
    if ( plug == currentState )
    { 
      // get old positions and numVerts
      // if num verts is different, reset topo and zero velocity
      // if num verts is the same, compute new velocity
        int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
                
        MFnMesh inputMesh(inMeshObj);       
        unsigned int numVerts = 0;
        numVerts = inputMesh.numVertices();
        unsigned int prevNumVerts;
        fNObject.getNumVertices(prevNumVerts);
        if(numVerts != prevNumVerts) {
                int numPolygons = inputMesh.numPolygons();
                int * faceVertCounts = new int[numPolygons];
                
        
                int facesArrayLength = 0;
                for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                faceVertCounts[ii] = verts.length();
                facesArrayLength += verts.length();
                }
                int * faces = new int[facesArrayLength];
                int currIndex = 0;
                for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                for(jj=0;jj<(int)verts.length();jj++) {
                    faces[currIndex++] = verts[jj];
                }
            }
                int numEdges = inputMesh.numEdges();
                int * edges = new int[2*numEdges];
                currIndex = 0;
                for(ii=0;ii<numEdges;ii++) {
                int2 edge;
                inputMesh.getEdgeVertices(ii,edge);
                edges[currIndex++] = edge[0];
                edges[currIndex++] = edge[1];
                }
                // When you are doing the initialization, the first call must to be setTopology().  All other
                // calls must come after this.
            fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
                delete[] faceVertCounts;
                delete[] faces;
                delete[] edges;        
                MFloatPointArray vertexArray;
                inputMesh.getPoints(vertexArray, MSpace::kWorld);
                fNObject.setPositions(vertexArray,true);
                MFloatPointArray velocitiesArray;
                velocitiesArray.setLength(numVerts);
                for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = 0.0f;
                velocitiesArray[ii].y = 0.0f;
                velocitiesArray[ii].z = 0.0f;
                velocitiesArray[ii].w = 0.0f;
            }
            fNObject.setVelocities(velocitiesArray);
        } else {
                MFloatPointArray vertexArray;
                MFloatPointArray prevVertexArray;
                inputMesh.getPoints(vertexArray, MSpace::kWorld);
                fNObject.getPositions(prevVertexArray);
            // you may want to get the playback rate for the dt
            // double dt = MAnimControl::playbackBy() \ 24.0;
            // or get the real dt by caching the last eval time
            double dt = 1.0/24.0;
                MFloatPointArray velocitiesArray;
                velocitiesArray.setLength(numVerts);
                for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = (float)( (vertexArray[ii].x - prevVertexArray[ii].x)/dt);
                velocitiesArray[ii].y = (float)( (vertexArray[ii].y - prevVertexArray[ii].y)/dt);
                velocitiesArray[ii].z = (float)( (vertexArray[ii].x - prevVertexArray[ii].z)/dt);
                velocitiesArray[ii].w = 0.0f;
            }
            fNObject.setVelocities(velocitiesArray);
            fNObject.setPositions(vertexArray,true);
        }
        // in real life, you'd get these attribute values each frame and set them
        fNObject.setThickness(0.1f);
        fNObject.setBounce(0.0f);
        fNObject.setFriction(0.1f);
        fNObject.setCollisionFlags(true, true, true);               
        MFnNObjectData outputData;
        MObject mayaNObjectData = outputData.create();
        outputData.setObject(mayaNObjectData);
        
        outputData.setObjectPtr(&fNObject);        
        outputData.setCached(false);
        MDataHandle currStateOutputHandle = data.outputValue(currentState);
        currStateOutputHandle.set(outputData.object());
      
    }
    if ( plug == startState )
    {
        int ii,jj;
        // initialize MnCloth
        MObject inMeshObj = data.inputValue(inputGeom).asMesh();
                
        MFnMesh inputMesh(inMeshObj);       
        int numPolygons = inputMesh.numPolygons();
            int * faceVertCounts = new int[numPolygons];
                
        
            int facesArrayLength = 0;
            for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                faceVertCounts[ii] = verts.length();
                facesArrayLength += verts.length();
            }
            int * faces = new int[facesArrayLength];
            int currIndex = 0;
            for(ii=0;ii<numPolygons;ii++) {
                MIntArray verts;
                inputMesh.getPolygonVertices(ii,verts);
                for(jj=0;jj<(int)verts.length();jj++) {
                    faces[currIndex++] = verts[jj];
               }
           }
            int numEdges = inputMesh.numEdges();
            int * edges = new int[2*numEdges];
            currIndex = 0;
            for(ii=0;ii<numEdges;ii++) {
                int2 edge;
                inputMesh.getEdgeVertices(ii,edge);
                edges[currIndex++] = edge[0];
                edges[currIndex++] = edge[1];
            }
            // When you are doing the initialization, the first call must to be setTopology().  All other
            // calls must come after this.
            fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
            delete[] faceVertCounts;
            delete[] faces;
            delete[] edges;        
            unsigned int numVerts = 0;
            numVerts = inputMesh.numVertices();        
            MFloatPointArray vertexArray;
            inputMesh.getPoints(vertexArray, MSpace::kWorld);
            fNObject.setPositions(vertexArray,true);
            MFloatPointArray velocitiesArray;
            velocitiesArray.setLength(numVerts);
            for(ii=0;ii<(int)numVerts;ii++) {
                velocitiesArray[ii].x = 0.0f;
                velocitiesArray[ii].y = 0.0f;
                velocitiesArray[ii].z = 0.0f;
                velocitiesArray[ii].w = 0.0f;
           }
           fNObject.setVelocities(velocitiesArray);
           fNObject.setThickness(0.1f);
            fNObject.setBounce(0.0f);
            fNObject.setFriction(0.1f);
            fNObject.setCollisionFlags(true, true, true);               
        
            MFnNObjectData outputData;
            MObject mayaNObjectData = outputData.create();
            outputData.setObject(mayaNObjectData);
        
            outputData.setObjectPtr(&fNObject);        
            outputData.setCached(false);
            MDataHandle startStateOutputHandle = data.outputValue(startState);
            startStateOutputHandle.set(outputData.object());
    }
    else {
        stat = MS::kUnknownParameter;
    }
    return stat;
}
コード例 #22
0
ファイル: phongShader.cpp プロジェクト: DimondTheCat/xray
//
// DESCRIPTION:
///////////////////////////////////////////////////////
MStatus PhongNode::compute(
const MPlug&      plug,
      MDataBlock& block ) 
{ 
    if ((plug != aOutColor) && (plug.parent() != aOutColor))
		return MS::kUnknownParameter;

    MFloatVector resultColor(0.0,0.0,0.0);

    // get sample surface shading parameters
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    MFloatVector& cameraPosition = block.inputValue( aPointCamera ).asFloatVector();

	// use for raytracing api enhancement below
	MFloatVector point = cameraPosition;
	MFloatVector normal = surfaceNormal;

    MFloatVector& surfaceColor  = block.inputValue( aColor ).asFloatVector();
    MFloatVector& incandescence = block.inputValue( aIncandescence ).asFloatVector();
    float diffuseReflectivity = block.inputValue( aDiffuseReflectivity ).asFloat();
    // float translucenceCoeff   = block.inputValue( aTranslucenceCoeff ).asFloat();
	// User-defined Reflection Color Gain
	float reflectGain = block.inputValue( aReflectGain ).asFloat();
  
    // Phong shading attributes
    float power = block.inputValue( aPower ).asFloat();
    float spec = block.inputValue( aSpecularity ).asFloat();

    float specularR, specularG, specularB;
    float diffuseR, diffuseG, diffuseB;
    diffuseR = diffuseG = diffuseB = specularR = specularG = specularB = 0.0;

    // get light list
    MArrayDataHandle lightData = block.inputArrayValue( aLightData );
    int numLights = lightData.elementCount();
    
    // iterate through light list and get ambient/diffuse values
    for( int count=1; count <= numLights; count++ )
    {
        MDataHandle currentLight = lightData.inputValue();
        MFloatVector& lightIntensity = currentLight.child(aLightIntensity).asFloatVector();
        
        // Find the blind data
        void*& blindData = currentLight.child( aLightBlindData ).asAddr();
     
        // find ambient component
        if( currentLight.child(aLightAmbient).asBool() ) {
            diffuseR += lightIntensity[0];
            diffuseG += lightIntensity[1];
            diffuseB += lightIntensity[2];
        }

        MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector();
        
        if ( blindData == NULL )
        {
			// find diffuse and specular component
			if( currentLight.child(aLightDiffuse).asBool() )
			{			
			    float cosln = lightDirection * surfaceNormal;;				
			    if( cosln > 0.0f )  // calculate only if facing light
			    {
			         diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity );
			         diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity );
			         diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity );
			    }

			    CHECK_MSTATUS( cameraPosition.normalize() );
			    			
				if( cosln > 0.0f ) // calculate only if facing light
				{				
				    float RV = ( ( (2*surfaceNormal) * cosln ) - lightDirection ) * cameraPosition;
				    if( RV > 0.0 ) RV = 0.0;
				    if( RV < 0.0 ) RV = -RV;

				    if ( power < 0 ) power = -power;

				    float s = spec * powf( RV, power );

				    specularR += lightIntensity[0] * s; 
				    specularG += lightIntensity[1] * s; 
				    specularB += lightIntensity[2] * s; 
				}
			}    
        }
        else
        {
			float cosln = MRenderUtil::diffuseReflectance( blindData, lightDirection, point, surfaceNormal, true );
			if( cosln > 0.0f )  // calculate only if facing light
			{
			     diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity );
			     diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity );
			     diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity );
			}

			CHECK_MSTATUS ( cameraPosition.normalize() );
			
			if ( currentLight.child(aLightSpecular).asBool() )
			{
				MFloatVector specLightDirection = lightDirection;
				MDataHandle directionH = block.inputValue( aRayDirection );
				MFloatVector direction = directionH.asFloatVector();
				float lightAttenuation = 1.0;
						
				specLightDirection = MRenderUtil::maximumSpecularReflection( blindData,
										lightDirection, point, surfaceNormal, direction );
				lightAttenuation = MRenderUtil::lightAttenuation( blindData, point, surfaceNormal, false );		

				// Are we facing the light
				if ( specLightDirection * surfaceNormal > 0.0f )
				{			
					float power2 = block.inputValue( aPower ).asFloat();
					MFloatVector rv = 2 * surfaceNormal * ( surfaceNormal * direction ) - direction;
					float s = spec * powf( rv * specLightDirection, power2 );
						
					specularR += lightIntensity[0] * s * lightAttenuation; 
					specularG += lightIntensity[1] * s * lightAttenuation; 
					specularB += lightIntensity[2] * s * lightAttenuation;
				}
			 }
       }
       if( !lightData.next() ) break;
    }

    // factor incident light with surface color and add incandescence
    resultColor[0] = ( diffuseR * surfaceColor[0] ) + specularR + incandescence[0];
    resultColor[1] = ( diffuseG * surfaceColor[1] ) + specularG + incandescence[1];
    resultColor[2] = ( diffuseB * surfaceColor[2] ) + specularB + incandescence[2];

	// add the reflection color
	if (reflectGain > 0.0) {

		MStatus status;

		// required attributes for using raytracer
		// origin, direction, sampler, depth, and object id.
		//
		MDataHandle originH = block.inputValue( aRayOrigin, &status);
		MFloatVector origin = originH.asFloatVector();

		MDataHandle directionH = block.inputValue( aRayDirection, &status);
		MFloatVector direction = directionH.asFloatVector();

		MDataHandle samplerH = block.inputValue( aRaySampler, &status);
		void*& samplerPtr = samplerH.asAddr();

		MDataHandle depthH = block.inputValue( aRayDepth, &status);
		short depth = depthH.asShort();

		MDataHandle objH = block.inputValue( aObjectId, &status);
		void*& objId = objH.asAddr();

		MFloatVector reflectColor;
		MFloatVector reflectTransparency;

		MFloatVector& triangleNormal = block.inputValue( aTriangleNormalCamera ).asFloatVector();

		// compute reflected ray
		MFloatVector l = -direction;
		float dot = l * normal;
		if( dot < 0.0 ) dot = -dot;
		MFloatVector refVector = 2 * normal * dot - l; 	// reflection ray
		float dotRef = refVector * triangleNormal;
		if( dotRef < 0.0 ) {
		    const float s = 0.01f;
			MFloatVector mVec = refVector - dotRef * triangleNormal;
			mVec.normalize();
			refVector = mVec + s * triangleNormal;
		}
		CHECK_MSTATUS ( refVector.normalize() );

		status = MRenderUtil::raytrace(
				point,    	//  origin
				refVector,  //  direction
				objId,		//  object id
				samplerPtr, //  sampler info
				depth,		//  ray depth
				reflectColor,	// output color and transp
				reflectTransparency);

		// add in the reflection color
		resultColor[0] += reflectGain * (reflectColor[0]);
		resultColor[1] += reflectGain * (reflectColor[1]);
		resultColor[2] += reflectGain * (reflectColor[2]);
	
	}

    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();

    return MS::kSuccess;
}
コード例 #23
0
ファイル: PtexUVNode.cpp プロジェクト: Mankua/PtexShaders
MStatus PtexUVNode::compute( const MPlug &plug, MDataBlock &data )
{
	MStatus stat;
	bool hasNoEffect = false;
	
	MDataHandle inMeshHnd = data.inputValue( inMesh );
	MDataHandle outMeshHnd = data.outputValue( outMesh );
	 
	MDataHandle stateHnd = data.inputValue( state );
	int state = stateHnd.asInt();

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

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

			int num_faces = meshFn.numPolygons();

			MIntArray uvCounts;
			uvCounts.setLength( num_faces );

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

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

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

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

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

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

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

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

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

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

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

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

	return stat;
}
コード例 #24
0
MStatus latticeNoiseNode::compute( const MPlug& plug, MDataBlock& data )
{ 
	MStatus returnStatus;

	float noiseAmplitude;
	float noiseFreq;
 
	if( plug == output )
	{
		// Get the lattice data from the input attribute.  First get the 
		// data object, and then use the lattice data function set to extract
		// the actual lattice.
		//

		// Get the data handle
		//
		MDataHandle inputData = data.inputValue( input, &returnStatus );
		McheckErr( returnStatus, "ERROR getting lattice data handle\n" ); 
		// Get the data object
		//
		MObject latticeData = inputData.data(); 
		MFnLatticeData dataFn( latticeData );
		// Get the actual geometry
		// 
		MObject lattice = dataFn.lattice();
		MFnLattice lattFn( lattice, &returnStatus );
		McheckErr( returnStatus, "ERROR getting lattice geometry\n" );  


		// Do the same for the output lattice
		//
		MDataHandle outputData = data.outputValue( output, &returnStatus ); 
		McheckErr( returnStatus, "ERROR getting lattice data handle\n" );
		// Get the data object
		//
		latticeData = outputData.data(); 
		if ( latticeData.isNull() ) { 
			// The data object for this attribute has not been created yet, so
			// we'll create it
			//
			latticeData = dataFn.create();
		} else {
			// Use the data object that is already there
			// 
			dataFn.setObject( latticeData );
		}
		// Get the actual geometry
		// 
		MObject outLattice = dataFn.lattice();
		MFnLattice outLattFn( outLattice, &returnStatus );
		McheckErr( returnStatus, "ERROR getting lattice geometry\n" );  

		// Get the amplitude and frequency
		//
		MDataHandle ampData = data.inputValue( amplitude, &returnStatus );
		McheckErr( returnStatus, "ERROR getting amplitude\n" );
		noiseAmplitude = ampData.asFloat(); 

		MDataHandle freqData = data.inputValue( frequency, &returnStatus );
		McheckErr( returnStatus, "ERROR getting frequency\n" );
		noiseFreq = freqData.asFloat(); 

		// Get the time.  
		//
		MDataHandle timeData = data.inputValue( time, &returnStatus ); 
		McheckErr( returnStatus, "ERROR getting time data handle\n" );
		MTime time = timeData.asTime();
		float seconds = (float)time.as( MTime::kSeconds );

		// Easiest way to modify frequency is by modifying the time
		//
		seconds = seconds * noiseFreq;

		// We have the information we need now.  We'll apply noise to the
		// points upon the lattice
		//
		unsigned s, t, u;
		lattFn.getDivisions( s, t, u );
		// match up the divisions in the lattices
		//
		outLattFn.setDivisions( s, t, u );   

		for ( unsigned i = 0; i < s; i++ ) {
			for ( unsigned j = 0; j < t; j++ ) {
				for ( unsigned k = 0; k < u; k++ ) {
					MPoint & point = lattFn.point( i, j, k );
					MPoint & outPoint = outLattFn.point( i, j, k );
					pnt noisePnt = noise::atPointAndTime( (float)point.x, (float)point.y, 
														  (float)point.z, seconds );
					// Make noise between -1 and 1 instead of 0 and 1
					//
					noisePnt.x =  ( noisePnt.x * 2.0F ) - 1.0F;
					noisePnt.y =  ( noisePnt.y * 2.0F ) - 1.0F;
					noisePnt.z =  ( noisePnt.z * 2.0F ) - 1.0F;

 					outPoint.x = point.x + ( noisePnt.x * noiseAmplitude );
 					outPoint.y = point.y + ( noisePnt.y * noiseAmplitude );
 					outPoint.z = point.z + ( noisePnt.z * noiseAmplitude );  
				}
			}
		} 
		outputData.set( latticeData );
		data.setClean(plug); 
	} else {
		return MS::kUnknownParameter;
	}

	return MS::kSuccess;
}
コード例 #25
0
MStatus AlembicCurvesDeformNode::deform(MDataBlock &dataBlock,
                                        MItGeometry &iter,
                                        const MMatrix &localToWorld,
                                        unsigned int geomIndex)
{
  // get the envelope data
  float env = dataBlock.inputValue(envelope).asFloat();
  if (env == 0.0f) {  // deformer turned off
    return MStatus::kSuccess;
  }

  // update the frame number to be imported
  double inputTime =
      dataBlock.inputValue(mTimeAttr).asTime().as(MTime::kSeconds);
  MString &fileName = dataBlock.inputValue(mFileNameAttr).asString();
  MString &identifier = dataBlock.inputValue(mIdentifierAttr).asString();

  // check if we have the file
  if (fileName != mFileName || identifier != mIdentifier) {
    mSchema.reset();
    if (fileName != mFileName) {
      delRefArchive(mFileName);
      mFileName = fileName;
      addRefArchive(mFileName);
    }
    mIdentifier = identifier;

    // get the object from the archive
    Abc::IObject iObj = getObjectFromArchive(mFileName, identifier);
    if (!iObj.valid()) {
      MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier +
                              "' not found in archive '" + mFileName + "'.");
      return MStatus::kFailure;
    }
    AbcG::ICurves obj(iObj, Abc::kWrapExisting);
    if (!obj.valid()) {
      MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier +
                              "' in archive '" + mFileName +
                              "' is not a Curves.");
      return MStatus::kFailure;
    }
    mSchema = obj.getSchema();
  }

  if (!mSchema.valid()) {
    return MStatus::kFailure;
  }

  {
    ESS_PROFILE_SCOPE("AlembicCurvesDeformNode::deform readProps");
    Alembic::Abc::ICompoundProperty arbProp = mSchema.getArbGeomParams();
    Alembic::Abc::ICompoundProperty userProp = mSchema.getUserProperties();
    readProps(inputTime, arbProp, dataBlock, thisMObject());
    readProps(inputTime, userProp, dataBlock, thisMObject());

    // Set all plugs as clean
    // Even if one of them failed to get set,
    // trying again in this frame isn't going to help
    for (unsigned int i = 0; i < mGeomParamPlugs.length(); i++) {
      dataBlock.outputValue(mGeomParamPlugs[i]).setClean();
    }

    for (unsigned int i = 0; i < mUserAttrPlugs.length(); i++) {
      dataBlock.outputValue(mUserAttrPlugs[i]).setClean();
    }
  }

  // get the sample
  SampleInfo sampleInfo = getSampleInfo(inputTime, mSchema.getTimeSampling(),
                                        mSchema.getNumSamples());

  // check if we have to do this at all
  if (mLastSampleInfo.floorIndex == sampleInfo.floorIndex &&
      mLastSampleInfo.ceilIndex == sampleInfo.ceilIndex) {
    return MStatus::kSuccess;
  }

  mLastSampleInfo = sampleInfo;

  // access the camera values
  AbcG::ICurvesSchema::Sample sample;
  AbcG::ICurvesSchema::Sample sample2;
  mSchema.get(sample, sampleInfo.floorIndex);
  if (sampleInfo.alpha != 0.0) {
    mSchema.get(sample2, sampleInfo.ceilIndex);
  }

  Abc::P3fArraySamplePtr samplePos = sample.getPositions();
  Abc::P3fArraySamplePtr samplePos2;
  if (sampleInfo.alpha != 0.0) {
    samplePos2 = sample2.getPositions();
  }

  // iteration should not be necessary. the iteration is only
  // required if the same mesh is attached to the same deformer
  // several times
  float blend = (float)sampleInfo.alpha;
  float iblend = 1.0f - blend;
  unsigned int index = 0;
  for (iter.reset(); !iter.isDone(); iter.next()) {
    index = iter.index();
    // MFloatPoint pt = iter.position();
    MPoint pt = iter.position();
    MPoint abcPos = pt;
    float weight = weightValue(dataBlock, geomIndex, index) * env;
    if (weight == 0.0f) {
      continue;
    }
    float iweight = 1.0f - weight;
    if (index >= samplePos->size()) {
      continue;
    }
    bool done = false;
    if (sampleInfo.alpha != 0.0) {
      if (samplePos2->size() == samplePos->size()) {
        abcPos.x = iweight * pt.x +
                   weight * (samplePos->get()[index].x * iblend +
                             samplePos2->get()[index].x * blend);
        abcPos.y = iweight * pt.y +
                   weight * (samplePos->get()[index].y * iblend +
                             samplePos2->get()[index].y * blend);
        abcPos.z = iweight * pt.z +
                   weight * (samplePos->get()[index].z * iblend +
                             samplePos2->get()[index].z * blend);
        done = true;
      }
    }
    if (!done) {
      abcPos.x = iweight * pt.x + weight * samplePos->get()[index].x;
      abcPos.y = iweight * pt.y + weight * samplePos->get()[index].y;
      abcPos.z = iweight * pt.z + weight * samplePos->get()[index].z;
    }
    iter.setPosition(abcPos);
  }
  return MStatus::kSuccess;
}
コード例 #26
0
ファイル: lambertShader.cpp プロジェクト: 2asoft/xray
// The compute() method does the actual work of the node using the inputs
// of the node to generate its output. 
//
// Compute takes two parameters: plug and data.
// - Plug is the the data value that needs to be recomputed
// - Data provides handles to all of the nodes attributes, only these
//   handles should be used when performing computations.
//
MStatus CXRayMtl::compute( const MPlug& plug, MDataBlock& block ) 
{ 
	// The plug parameter will allow us to determine which output attribute
	// needs to be calculated.
	//
	if( plug == aOutColor
			|| plug == aOutColorR
			|| plug == aOutColorG
			|| plug == aOutColorB
			|| plug == aOutTransparency
			|| plug == aOutTransR
			|| plug == aOutTransG
			|| plug == aOutTransB )
	{
		MStatus status;
		MFloatVector resultColor( 0.0, 0.0, 0.0 ); 

	
		// Get surface shading parameters from input block
		//
		MFloatVector& surfaceNormal = block.inputValue( aNormalCamera,
				&status ).asFloatVector();
		CHECK_MSTATUS( status );

		MFloatVector& surfaceColor = block.inputValue( aColor,
				&status ).asFloatVector();
		CHECK_MSTATUS( status );

		MFloatVector& incandescence = block.inputValue( aIncandescence,
				&status ).asFloatVector();
		CHECK_MSTATUS( status );

		float diffuseReflectivity = block.inputValue(
				aDiffuseReflectivity, &status ).asFloat();
		CHECK_MSTATUS( status );
	
// 		float translucenceCoeff = block.inputValue( aTranslucenceCoeff,
// 				&status ).asFloat();
// 		CHECK_MSTATUS( status );
  

		// Get light list
		//
		MArrayDataHandle lightData = block.inputArrayValue( aLightData,
				&status );
		CHECK_MSTATUS( status );

		int numLights = lightData.elementCount( &status );
		CHECK_MSTATUS( status );


		// Calculate the effect of the lights in the scene on the color
		//

		// Iterate through light list and get ambient/diffuse values
		//
		for( int count=1; count <= numLights; count++ )
		{
			// Get the current light out of the array
			//
			MDataHandle currentLight = lightData.inputValue( &status ); 
			CHECK_MSTATUS( status );


			// Get the intensity of that light
			//
			MFloatVector& lightIntensity = currentLight.child(
					aLightIntensity ).asFloatVector();

	 
			// Find ambient component
			//
			if ( currentLight.child( aLightAmbient ).asBool() )
			{
				resultColor += lightIntensity;
			}


			// Find diffuse component
			//
			if ( currentLight.child( aLightDiffuse ).asBool() )
			{
				MFloatVector& lightDirection = currentLight.child(
						aLightDirection ).asFloatVector();
				float cosln = lightDirection * surfaceNormal;
   
			   if ( cosln > 0.0f ) {
					resultColor += lightIntensity
							* ( cosln * diffuseReflectivity );
			   }
			}


			// Advance to the next light.
			//
			if ( count < numLights ) {
				status = lightData.next();
				CHECK_MSTATUS( status );
			}
		}


		// Factor incident light with surface color and add incandescence
		//
		resultColor[0] = resultColor[0] * surfaceColor[0] + incandescence[0];
		resultColor[1] = resultColor[1] * surfaceColor[1] + incandescence[1];
		resultColor[2] = resultColor[2] * surfaceColor[2] + incandescence[2];


		// Set ouput color attribute
		//
		if ( plug == aOutColor || plug == aOutColorR || plug == aOutColorG
				|| plug == aOutColorB)
		{
			// Get the handle to the attribute
			//
			MDataHandle outColorHandle = block.outputValue( aOutColor,
					&status );
			CHECK_MSTATUS( status );
			MFloatVector& outColor = outColorHandle.asFloatVector();
		
			outColor = resultColor;		// Set the output value
			outColorHandle.setClean(); // Mark the output value as clean
		}


		// Set ouput transparency
		//
		if ( plug == aOutTransparency || plug == aOutTransR
				|| plug == aOutTransG || plug == aOutTransB )
		{
			MFloatVector& transparency = block.inputValue(
					aInTransparency, &status ).asFloatVector();
			CHECK_MSTATUS( status );


			// Get the handle to the attribute
			//
			MDataHandle outTransHandle = block.outputValue(
					aOutTransparency, &status );
			CHECK_MSTATUS( status );
			MFloatVector& outTrans = outTransHandle.asFloatVector();
			
			outTrans = transparency;   // Set the output value
			outTransHandle.setClean(); // Mark the output value as clean
		}
	} 
	else
	{
		return( MS::kUnknownParameter ); // We got an unexpected plug
	}

	return( MS::kSuccess );
}
コード例 #27
0
MStatus vixo_hairStyleMaya::compute(const MPlug& plug, MDataBlock& data)
{
	if(plug==printBasicInfo)
	{
		if(data.inputValue(hairNum).asInt()==0)
		{
			return MS::kSuccess;
		}
		if(data.inputValue(inMesh).asMesh().hasFn(MFn::kMesh)==false)
		{
			return MS::kSuccess;
		}
		if(data.inputValue(hairInfoColorDir).asString()=="")
		{
			return MS::kSuccess;
		}
		MString hairInfoDirValue=data.inputValue(hairInfoColorDir).asString();
		int hairNumValue=data.inputValue(hairNum).asInt();
		//cout<<"hair"<<hairNumValue<<endl;
		MString follicleFileName=hairInfoDirValue+"/hairRoot.info";
		MString uvFileName=hairInfoDirValue+"/uv.info";
		exportFollicle(hairNumValue,uvFileName,follicleFileName,data);

		data.outputValue(printBasicInfo).setClean();

		return MS::kSuccess;
	}
	if(plug==printColorInfo)
	{
		if(data.inputValue(refreshColorInfo).asBool()==false)
			return MS::kSuccess;
		MString hairInfoDirValue=data.inputValue(hairInfoColorDir).asString();
		
		MString uvFileName=hairInfoDirValue+"/uv.info";
		fstream fileExist(uvFileName.asChar(),ios_base::in|ios_base::binary);
		if(!fileExist)
		{
			data.outputValue(refreshColorInfo).set(false);
			return MS::kSuccess;
		}
		MString colorInfoFileName=hairInfoDirValue+"/hairColor.info";
		exportColor(uvFileName,colorInfoFileName,data);

		data.outputValue(refreshColorInfo).set(false);
		data.outputValue(printColorInfo).setClean();

		return MS::kSuccess;
	}
	if(plug==printStyleInfo)
	{
		if(data.inputValue(refreshStyleInfo).asBool()==false)
			return MS::kSuccess;
		//follicleδµ¼³ö 
		MString hairInfoColorDirValue=data.inputValue(hairInfoColorDir).asString();
		MString hairInfoStyleDirValue=data.inputValue(hairInfoStyleDir).asString();

		if(hairInfoStyleDirValue=="")
		{
			data.outputValue(refreshStyleInfo).set(false);
			return MS::kSuccess;
		}

		MString uvFileName=hairInfoColorDirValue+"/uv.info";
		fstream fileExist(uvFileName.asChar(),ios_base::in|ios_base::binary);
		if(!fileExist)
			return MS::kSuccess;
		MString noiseInfoFileName=hairInfoStyleDirValue+"/hairStyle.info";
		exportNoise(uvFileName,noiseInfoFileName,data);

		data.outputValue(refreshStyleInfo).set(false);
		data.outputValue(printStyleInfo).setClean();
		return MS::kSuccess;
	}
	return MS::kSuccess;
}
コード例 #28
0
ファイル: dgTransform.cpp プロジェクト: jonntd/mayadev-1
MStatus dgTransform::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MDataHandle hTranslate = data.inputValue( aTranslate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hRotate    = data.inputValue( aRotate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hScale     = data.inputValue( aScale, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hShear     = data.inputValue( aShear, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hJointOrient     = data.inputValue( aJointOrient, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	MDataHandle hInputTranslate = data.inputValue( aInputTranslate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputRotate    = data.inputValue( aInputRotate, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputScale     = data.inputValue( aInputScale, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MDataHandle hInputShear     = data.inputValue( aInputShear, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );


	MPxTransformationMatrix inputMpxTrMtx;
	MEulerRotation inputEulerRot( hInputRotate.asVector() );

	inputMpxTrMtx.translateTo( hInputTranslate.asVector() );
	inputMpxTrMtx.rotateTo( inputEulerRot );
	inputMpxTrMtx.scaleTo( hInputScale.asVector() );
	inputMpxTrMtx.shearTo( hInputShear.asVector() );


	MMatrix parentMatrix = inputMpxTrMtx.asMatrix();


	MPxTransformationMatrix mpxTrMtx;
	MEulerRotation eulerRot( hRotate.asVector() );
	MEulerRotation joEulerRot( hJointOrient.asVector() );

	mpxTrMtx.translateTo( hTranslate.asVector() );
	mpxTrMtx.rotateTo( eulerRot );
	mpxTrMtx.rotateBy( joEulerRot );
	mpxTrMtx.scaleTo( hScale.asVector() );
	mpxTrMtx.shearTo( hShear.asVector() );

	if( plug == aMatrix )
	{
		//cout <<"matrix"<<endl;
		MDataHandle hMatrix = data.outputValue( aMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hMatrix.setMMatrix( mpxTrMtx.asMatrix() );
	}

	if( plug == aInverseMatrix )
	{
		//cout <<"inverseMatrix"<<endl;
		MDataHandle hInverseMatrix = data.outputValue( aInverseMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hInverseMatrix.setMMatrix( mpxTrMtx.asMatrix().inverse() );
	}

	if( plug == aWorldMatrix || plug == aWorldInverseMatrix )
	{
		MMatrix worldMatrix = mpxTrMtx.asMatrix()*parentMatrix;
		if( plug == aWorldMatrix )
		{
			//cout <<"worldMatrix"<<endl;
			MDataHandle hWorldMatrix = data.outputValue( aWorldMatrix, &status );
			CHECK_MSTATUS_AND_RETURN_IT( status );
			hWorldMatrix.setMMatrix( worldMatrix );
		}

		if( plug == aWorldInverseMatrix )
		{
			//cout <<"worldInverseMatrix"<<endl;
			MDataHandle hWorldInverseMatrix = data.outputValue( aWorldInverseMatrix, &status );
			CHECK_MSTATUS_AND_RETURN_IT( status );
			hWorldInverseMatrix.setMMatrix( worldMatrix.inverse() );
		}
	}

	if( plug == aParentMatrix )
	{
		//cout <<"parentMatrix"<<endl;
		MDataHandle hParentMatrix = data.outputValue( aParentMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hParentMatrix.setMMatrix( parentMatrix );
	}

	if( plug == aParentInverseMatrix )
	{
		//cout <<"parentInverseMatrix"<<endl;
		MDataHandle hParentInverseMatrix = data.outputValue( aParentInverseMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		hParentInverseMatrix.setMMatrix( parentMatrix.inverse() );
	}

	data.setClean( plug );

	return status;
}
コード例 #29
0
ファイル: cacheTransform.cpp プロジェクト: goofoo/algae
//
// 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);
}
コード例 #30
0
/*! 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;
}