示例#1
0
MStatus PushDeformer::deform(MDataBlock& dataBlock,
								MItGeometry& itGeo,
								const MMatrix& localToWorldMatrix,
								unsigned int geomIndex)
{
	MStatus status;
	//get attribute handles
	double bulgeAmount = dataBlock.inputValue(aAmount, &status).asDouble();
	CHECK_MSTATUS_AND_RETURN_IT(status);
	m_taskData.envelope = dataBlock.inputValue(envelope, &status).asFloat();
	CHECK_MSTATUS_AND_RETURN_IT(status);
	bool useStressV = dataBlock.inputValue(aUseStress, &status).asBool();
	CHECK_MSTATUS_AND_RETURN_IT(status);
	int multiThreadingType = dataBlock.inputValue(aMultiThreadingType, &status).asBool();
	CHECK_MSTATUS_AND_RETURN_IT(status);

	if (m_taskData.envelope <= 0.001)
	{
		return MS::kSuccess;
	}
	// if the use stress plug is turned on pull 
	MDoubleArray stressV;
	if (useStressV == true)
	{
		//pull out the raw data as an Mobject
		MObject stressMap = dataBlock.inputValue(aStressMap, &status).data();
		CHECK_MSTATUS_AND_RETURN_IT(status);
		MFnDoubleArrayData stressDataFn(stressMap);
    m_taskData.stressV = stressDataFn.array();
	}

	//retrieve the handle to the output array attribute
	MArrayDataHandle hInput = dataBlock.outputArrayValue(input, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	//get the input array index handle
	status = hInput.jumpToElement(geomIndex);
	//get the handle of geomIndex attribute
	MDataHandle hInputElement = hInput.outputValue(&status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	//Get the MObject of the input geometry of geomindex
	MObject oInputGeom = hInputElement.child(inputGeom).asMesh();
	MFnMesh fnMesh(oInputGeom, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);

  
	fnMesh.getVertexNormals(false, m_taskData.normals, MSpace::kWorld);
	itGeo.allPositions(m_taskData.points, MSpace::kWorld);
  //MGlobal::displayInfo( "test" );
  /*for (int i = 0; i < itGeo.count();  i++)
	{
    MGlobal::displayInfo( MFnAttribute(weightList).isArray );
  }*/
  m_taskData.bulgeAmount = bulgeAmount;

  if(multiThreadingType == 1)
  {
    ThreadData* pThreadData = createThreadData( NUM_TASKS, &m_taskData );
    MThreadPool::newParallelRegion( createTasks, (void*)pThreadData );
    itGeo.setAllPositions(m_taskData.points);
    delete [] pThreadData;
    return MS::kSuccess;
  }


  else if(multiThreadingType == 2)
  {
    tbb::parallel_for(size_t(0), size_t(itGeo.count()), [this](size_t i)
    {
		  //const float w = weightValue(dataBlock, geomIndex, i);
      const float w = 1.0;
		  if (m_taskData.useStressV == true && (m_taskData.stressV.length() > 0))
		  {
			  //deform
			  m_taskData.points[i] += (MVector(m_taskData.normals[i]) * m_taskData.bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[i]);
		  }
		  else
		  {
			  //deform
        m_taskData.points[i] += m_taskData.normals[i] * m_taskData.bulgeAmount * m_taskData.envelope * w;
		  }  
  
    });
  }

  
	//
  else if(multiThreadingType == 3)
  #pragma omp parallel for 

  for (int i = 0; i < itGeo.count();  i++)
	{
		float w = weightValue(dataBlock, geomIndex, itGeo.index());
		if (useStressV == true && (stressV.length() > 0))
		{
			//deform
      m_taskData.points[i] += (MVector(m_taskData.normals[i]) * bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[i]);
			
		}
		else
		{
			//deform
      m_taskData.points[i] += m_taskData.normals[i] * bulgeAmount * m_taskData.envelope * w;

		}
	}
  else
  {
    for (; !itGeo.isDone(); itGeo.next())
	  {
		  float w = weightValue(dataBlock, geomIndex, itGeo.index());
		  if (useStressV == true && (stressV.length() > 0))
		  {
			  //deform
        m_taskData.points[itGeo.index()] += (MVector(m_taskData.normals[itGeo.index()]) * bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[itGeo.index()]);
			
		  }
		  else
		  {
			  //deform
        m_taskData.points[itGeo.index()] += m_taskData.normals[itGeo.index()] * bulgeAmount * m_taskData.envelope * w;
		  }
	  }
  }
	itGeo.setAllPositions(m_taskData.points);

	return MS::kSuccess;

}
int thresmain(int argc, char *argv[]) {
	int thread_count;
	int xsize, ysize, colmax;
	pixel * src;
	pixel * dst;
	imagethread * imageThreads;
	thresfilterdata * thresdata;
	pthread_mutex_t thresholdsum_mutex = PTHREAD_MUTEX_INITIALIZER;
	unsigned int thresholdsum = 0;
	int i;
	char * inputFilepath;
	char * outputFilepath;
	struct timespec stime, etime;

	src = allocate_image(MAX_PIXELS);
	dst = allocate_image(MAX_PIXELS);

	/* Take care of the arguments */

	if (argc != 4) {
		fprintf(stderr, "Usage: %s thread_count infile outfile\n", argv[0]);
		return 1;
	}

	thread_count = atoi(argv[1]);
	if(thread_count < 1){
		fprintf(stderr, "Too few threads\n");
		return 1;
	}

	inputFilepath = strdup(argv[2]);
	outputFilepath = strdup(argv[3]);

	/* read file */
	if(read_ppm (inputFilepath, &xsize, &ysize, &colmax, (char *) src) != 0)
		return 1;

	if (colmax > 255) {
		fprintf(stderr, "Too large maximum color-component value\n");
		return 1;
	}

	printf("Creating threads\n");
	imageThreads = createThreadData(thread_count);

	printf("Dividing image\n");
	divide(imageThreads, thread_count, src, dst, xsize, ysize);
	printf("\n");

	printf("Setting arguments\n");
	thresdata = (thresfilterdata*) malloc(sizeof(thresfilterdata) * thread_count);
	for(i = 0; i < thread_count; i++){
		thresdata[i].xsize = xsize;
		thresdata[i].ysize = ysize;
		thresdata[i].src = src;
		thresdata[i].dst = dst;
		thresdata[i].thresholdsum = &thresholdsum;
		thresdata[i].imageThreads = imageThreads;
		thresdata[i].rank = i;
		thresdata[i].thresholdsum_mutex = &thresholdsum_mutex;
	}

	clock_gettime(CLOCK_REALTIME, &stime);
	printf("Starting threads\n");
	setThreadSyncCount(thread_count);
	for(i = 0; i < thread_count; i++){
		//printf("Starting thread %d\n", i);
		imageThreads[i].argument = &thresdata[i];
		imageThreads[i].thread = createThread(thresfilterwrapper, imageThreads[i].argument);
	}

	printf("Threads working on average value\n");
	SynchronizationPoint();
	printf("Average value is %d\n", thresholdsum/(xsize*ysize));
	printf("Threads working on threshold\n");
	SynchronizationPoint();
	printf("Threads done\n");
	clock_gettime(CLOCK_REALTIME, &etime);

	printf("Filtering took: %g secs\n", (etime.tv_sec  - stime.tv_sec) +
		1e-9*(etime.tv_nsec  - stime.tv_nsec)) ;

	/* write result */
	printf("Writing output file\n");

	if(write_ppm (outputFilepath, xsize, ysize, (char *)src) != 0){
		return 1;
	}

	return 0;
}