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