bool Cloud2CloudDist::Compute( const Cloth& cloth, const wl::PointCloud& pc, double class_threshold, std::vector<int>& groundIndexes, std::vector<int>& offGroundIndexes, unsigned N/*=3*/) { CCLib::SimpleCloud particlePoints; if (!particlePoints.reserve(static_cast<unsigned>(cloth.getSize()))) { //not enough memory return false; } for (int i = 0; i < cloth.getSize(); i++) { const Particle& particle = cloth.getParticleByIndex(i); particlePoints.addPoint(CCVector3(static_cast<PointCoordinateType>(particle.pos.x), 0, static_cast<PointCoordinateType>(particle.pos.z))); } CCLib::SimpleCloud pcPoints; if ( !pcPoints.reserve(static_cast<unsigned>(pc.size())) || !pcPoints.enableScalarField()) { //not enough memory return false; } for (size_t i = 0; i < pc.size(); i++) { const wl::Point& P = pc[i]; pcPoints.addPoint(CCVector3(P.x, 0, P.z)); } try { //we spatially 'synchronize' the cloud and particles octrees CCLib::DgmOctree *cloudOctree = 0, *particleOctree = 0; CCLib::DistanceComputationTools::SOReturnCode soCode = CCLib::DistanceComputationTools::synchronizeOctrees ( &particlePoints, &pcPoints, particleOctree, cloudOctree, 0, 0 ); if (soCode != CCLib::DistanceComputationTools::SYNCHRONIZED && soCode != CCLib::DistanceComputationTools::DISJOINT) { //not enough memory (or invalid input) return false; } //additional parameters void* additionalParameters[] = {(void*)(&cloth), (void*)(particleOctree), (void*)(&N) }; int octreeLevel = particleOctree->findBestLevelForAGivenPopulationPerCell(std::max<unsigned>(2, N)); int result = cloudOctree->executeFunctionForAllCellsAtLevel( octreeLevel, ComputeMeanNeighborAltitude, additionalParameters, true, 0, "Rasterization", QThread::idealThreadCount()); delete cloudOctree; cloudOctree = 0; delete particleOctree; particleOctree = 0; if (result == 0) { //something went wrong return false; } //now classify the points for (unsigned i = 0; i < pcPoints.size(); ++i) { if (std::fabs(pcPoints.getPointScalarValue(i) - pc[i].y) < class_threshold) { groundIndexes.push_back(i); } else { offGroundIndexes.push_back(i); } } } catch (const std::bad_alloc&) { //not enough memory return false; } return true; }
CCLib::SimpleCloud* ccGBLSensor::project(CCLib::GenericCloud* theCloud, int& errorCode, bool autoParameters/*false*/) { assert(theCloud); CCLib::SimpleCloud* newCloud = new CCLib::SimpleCloud(); unsigned pointCount = theCloud->size(); if (!newCloud->reserve(pointCount) || !newCloud->enableScalarField()) //not enough memory { errorCode = -4; delete newCloud; return 0; } ScalarType maxDepth = 0; theCloud->placeIteratorAtBegining(); { for (unsigned i=0; i<pointCount; ++i) { const CCVector3 *P = theCloud->getNextPoint(); CCVector2 Q; ScalarType depth; projectPoint(*P,Q,depth); newCloud->addPoint(CCVector3(Q.x,Q.y,0)); newCloud->setPointScalarValue(i,depth); if (i != 0) maxDepth = std::max(maxDepth,depth); else maxDepth = depth; } } if (autoParameters) { //dimensions = theta, phi, 0 PointCoordinateType bbMin[3],bbMax[3]; newCloud->getBoundingBox(bbMin,bbMax); setTheta(bbMin[0],bbMax[0]); setPhi(bbMin[1],bbMax[1]); setSensorRange(maxDepth); } //clear previous Z-buffer { if (m_depthBuffer.zBuff) delete[] m_depthBuffer.zBuff; m_depthBuffer.zBuff=0; m_depthBuffer.width=0; m_depthBuffer.height=0; } //init new Z-buffer { int width = static_cast<int>(ceil((thetaMax-thetaMin)/deltaTheta)); int height = static_cast<int>(ceil((phiMax-phiMin)/deltaPhi)); if (width*height == 0 || std::max(width,height) > 2048) //too small or... too big! { errorCode = -2; delete newCloud; return 0; } unsigned zBuffSize = width*height; m_depthBuffer.zBuff = new ScalarType[zBuffSize]; if (!m_depthBuffer.zBuff) //not enough memory { errorCode = -4; delete newCloud; return 0; } m_depthBuffer.width = width; m_depthBuffer.height = height; memset(m_depthBuffer.zBuff,0,zBuffSize*sizeof(ScalarType)); } //project points and accumulate them in Z-buffer newCloud->placeIteratorAtBegining(); for (unsigned i=0; i<newCloud->size(); ++i) { const CCVector3 *P = newCloud->getNextPoint(); ScalarType depth = newCloud->getPointScalarValue(i); int x = static_cast<int>(floor((P->x-thetaMin)/deltaTheta)); int y = static_cast<int>(floor((P->y-phiMin)/deltaPhi)); ScalarType& zBuf = m_depthBuffer.zBuff[y*m_depthBuffer.width+x]; zBuf = std::max(zBuf,depth); } errorCode = 0; return newCloud; }