Пример #1
0
MThreadRetVal slidingDeformer2::compute_sliding( void* voidPThread )
{
	slidingDeformer2SlidingThread* pThread = ( slidingDeformer2SlidingThread* )voidPThread;
	slidingDeformer2SlidingTask*   pTask   = pThread->pTask;
	
	MPointOnMesh	pointOnMesh;
	MIntArray& indicesMoved = *pTask->pIndicesCheck;
	MPointArray& pointsMoved  = *pTask->pPointsMoved;
	MPointArray& pointsResult = *pTask->pPointsResult;
	MVectorArray& vectorArr   = *pTask->pVectorArr;

	MPoint pointClose;
	MVector normal;
	int index;

	float env    = pTask->env;
	float invEnv = 1-pTask->env;

	for( int i = pThread->start; i < pThread->end; i++ )
	{
		index = indicesMoved[i];
		pTask->pMeshIntersector->getClosestPoint( pointsMoved[ index ], pointOnMesh );
		pointClose = pointOnMesh.getPoint();
		pointsResult[ index ] = vectorArr[index] + pointClose*env + pointsMoved[ index ]*invEnv;
	}
	return MThreadRetVal( 0 );
}
Пример #2
0
MThreadRetVal slidingDeformer2::compute_getDist( void* voidPThread )
{
	slidingDeformer2GetDistThread* pThread = ( slidingDeformer2GetDistThread* )voidPThread;
	slidingDeformer2GetDistTask*   pTask   = pThread->pTask;
	
	MPointOnMesh  pointOnMesh;
	MVectorArray& vectorArr   = *pTask->pVectors;
	MPointArray&  pointsOrig = *pTask->pPointsOrig;

	MVector vPoint;
	MVector getPoint;
	MVector normal;
	double dot;
	for( int i = pThread->start; i < pThread->end; i++ )
	{
		pTask->pMeshIntersector->getClosestPoint( pointsOrig[i], pointOnMesh );
		getPoint = pointOnMesh.getPoint();
		vectorArr[i] = MVector( pointsOrig[i] ) - getPoint;
	}
	return MThreadRetVal( 0 );
}
Пример #3
0
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;
}