QString cc2Point5DimEditor::getGridSizeAsString() const { //vertical dimension const unsigned char Z = getProjectionDimension(); assert(Z >= 0 && Z <= 2); const unsigned char X = Z == 2 ? 0 : Z +1; const unsigned char Y = X == 2 ? 0 : X +1; //cloud bounding-box --> grid size ccBBox box = getCustomBBox(); if (!box.isValid()) { return "invalid grid box"; } double gridStep = getGridStep(); assert(gridStep != 0); CCVector3d boxDiag( static_cast<double>(box.maxCorner().x) - static_cast<double>(box.minCorner().x), static_cast<double>(box.maxCorner().y) - static_cast<double>(box.minCorner().y), static_cast<double>(box.maxCorner().z) - static_cast<double>(box.minCorner().z) ); unsigned gridWidth = static_cast<unsigned>(ceil(boxDiag.u[X] / gridStep)); unsigned gridHeight = static_cast<unsigned>(ceil(boxDiag.u[Y] / gridStep)); return QString("%1 x %2").arg(gridWidth).arg(gridHeight); }
bool ccVolumeCalcTool::updateGrid() { if (!m_cloud2) { assert(false); return false; } //per-cell Z computation ProjectionType projectionType = getTypeOfProjection(); //vertical dimension const unsigned char Z = getProjectionDimension(); assert(Z >= 0 && Z <= 2); const unsigned char X = Z == 2 ? 0 : Z +1; const unsigned char Y = X == 2 ? 0 : X +1; //cloud bounding-box --> grid size ccBBox box = getCustomBBox(); if (!box.isValid()) { return false; } double gridStep = getGridStep(); assert(gridStep != 0); CCVector3d boxDiag( static_cast<double>(box.maxCorner().x) - static_cast<double>(box.minCorner().x), static_cast<double>(box.maxCorner().y) - static_cast<double>(box.minCorner().y), static_cast<double>(box.maxCorner().z) - static_cast<double>(box.minCorner().z) ); if (boxDiag.u[X] <= 0 || boxDiag.u[Y] <= 0) { ccLog::Error("Invalid cloud bounding box!"); return false; } unsigned gridWidth = static_cast<unsigned>(ceil(boxDiag.u[X] / gridStep)); unsigned gridHeight = static_cast<unsigned>(ceil(boxDiag.u[Y] / gridStep)); //grid size unsigned gridTotalSize = gridWidth * gridHeight; if (gridTotalSize == 1) { if (QMessageBox::question(0,"Unexpected grid size","The generated grid will only have 1 cell! Do you want to proceed anyway?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return false; } else if (gridTotalSize > 10000000) { if (QMessageBox::question(0,"Big grid size","The generated grid will have more than 10.000.000 cells! Do you want to proceed anyway?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return false; } //memory allocation if (!m_grid.init(gridWidth,gridHeight)) { //not enough memory ccLog::Error("Not enough memory"); return false; } m_grid.gridStep = gridStep; m_grid.minCorner = CCVector3d::fromArray(box.minCorner().u); //ground ccGenericPointCloud* groundCloud = 0; double groundHeight = 0; switch (groundComboBox->currentIndex()) { case 0: groundHeight = groundEmptyValueDoubleSpinBox->value(); break; case 1: groundCloud = m_cloud1 ? m_cloud1 : m_cloud2; break; case 2: groundCloud = m_cloud2; break; default: assert(false); return false; } ccProgressDialog pDlg(true,this); RasterGrid groundRaster; if (groundCloud) { if (!groundRaster.init(gridWidth,gridHeight)) { //not enough memory ccLog::Error("Not enough memory"); return false; } groundRaster.gridStep = m_grid.gridStep; groundRaster.minCorner = m_grid.minCorner; if (groundRaster.fillWith( groundCloud, Z, projectionType, getFillEmptyCellsStrategy(fillGroundEmptyCellsComboBox) == INTERPOLATE, INVALID_PROJECTION_TYPE, &pDlg)) { groundRaster.fillEmptyGridCells(getFillEmptyCellsStrategy(fillGroundEmptyCellsComboBox), groundEmptyValueDoubleSpinBox->value()); ccLog::Print(QString("[Volume] Ground raster grid: size: %1 x %2 / heights: [%3 ; %4]").arg(m_grid.width).arg(m_grid.height).arg(m_grid.minHeight).arg(m_grid.maxHeight)); } else { return false; } } //ceil ccGenericPointCloud* ceilCloud = 0; double ceilHeight = 0; switch (ceilComboBox->currentIndex()) { case 0: ceilHeight = ceilEmptyValueDoubleSpinBox->value(); break; case 1: ceilCloud = m_cloud1 ? m_cloud1 : m_cloud2; break; case 2: ceilCloud = m_cloud2; break; default: assert(false); return false; } RasterGrid ceilRaster; if (ceilCloud) { if (!ceilRaster.init(gridWidth,gridHeight)) { //not enough memory ccLog::Error("Not enough memory"); return false; } ceilRaster.gridStep = m_grid.gridStep; ceilRaster.minCorner = m_grid.minCorner; if (ceilRaster.fillWith(ceilCloud, Z, projectionType, getFillEmptyCellsStrategy(fillCeilEmptyCellsComboBox) == INTERPOLATE, INVALID_PROJECTION_TYPE, &pDlg)) { ceilRaster.fillEmptyGridCells(getFillEmptyCellsStrategy(fillCeilEmptyCellsComboBox), ceilEmptyValueDoubleSpinBox->value()); ccLog::Print(QString("[Volume] Ceil raster grid: size: %1 x %2 / heights: [%3 ; %4]").arg(m_grid.width).arg(m_grid.height).arg(m_grid.minHeight).arg(m_grid.maxHeight)); } else { return false; } } //update grid and compute volume { pDlg.setMethodTitle("Volume computation"); pDlg.setInfo(qPrintable(QString("Cells: %1 x %2").arg(m_grid.width).arg(m_grid.height))); pDlg.start(); pDlg.show(); QApplication::processEvents(); CCLib::NormalizedProgress nProgress(&pDlg, m_grid.width*m_grid.height); ReportInfo repotInfo; size_t ceilNonMatchingCount = 0; size_t groundNonMatchingCount = 0; size_t cellCount = 0; //at least one of the grid is based on a cloud m_grid.nonEmptyCellCount = 0; for (unsigned i=0; i<m_grid.height; ++i) { for (unsigned j=0; j<m_grid.width; ++j) { RasterCell& cell = m_grid.data[i][j]; bool validGround = true; cell.minHeight = groundHeight; if (groundCloud) { cell.minHeight = groundRaster.data[i][j].h; validGround = (cell.minHeight == cell.minHeight); } bool validCeil = true; cell.maxHeight = ceilHeight; if (ceilCloud) { cell.maxHeight = ceilRaster.data[i][j].h; validCeil = (cell.maxHeight == cell.maxHeight); } if (validGround && validCeil) { cell.h = cell.maxHeight - cell.minHeight; cell.nbPoints = 1; repotInfo.volume += cell.h; repotInfo.surface += 1.0; ++m_grid.nonEmptyCellCount; //= matching count ++cellCount; } else { if (validGround) { ++cellCount; ++groundNonMatchingCount; } else if (validCeil) { ++cellCount; ++ceilNonMatchingCount; } cell.h = std::numeric_limits<double>::quiet_NaN(); cell.nbPoints = 0; } cell.avgHeight = (groundHeight + ceilHeight)/2; cell.stdDevHeight = 0; if (!nProgress.oneStep()) { ccLog::Warning("[Volume] Process cancelled by the user"); return false; } } } m_grid.validCellCount = m_grid.nonEmptyCellCount; //count the average number of valid neighbors { size_t validNeighborsCount = 0; size_t count = 0; for (unsigned i=1; i<m_grid.height-1; ++i) { for (unsigned j=1; j<m_grid.width-1; ++j) { RasterCell& cell = m_grid.data[i][j]; if (cell.h == cell.h) { for (unsigned k=i-1; k<=i+1; ++k) { for (unsigned l=j-1; l<=j+1; ++l) { if (k != i || l != j) { RasterCell& otherCell = m_grid.data[k][l]; if (otherCell.h == otherCell.h) { ++validNeighborsCount; } } } } ++count; } } } if (count) { repotInfo.averageNeighborsPerCell = static_cast<double>(validNeighborsCount) / count; } } repotInfo.matchingPrecent = static_cast<float>(m_grid.validCellCount * 100) / cellCount; repotInfo.groundNonMatchingPercent = static_cast<float>(groundNonMatchingCount * 100) / cellCount; repotInfo.ceilNonMatchingPercent = static_cast<float>(ceilNonMatchingCount * 100) / cellCount; float cellArea = static_cast<float>(m_grid.gridStep * m_grid.gridStep); repotInfo.volume *= cellArea; repotInfo.surface *= cellArea; outputReport(repotInfo); } m_grid.setValid(true); return true; }
void btParticlesDynamicsWorld::adjustGrid() { //btVector3 wmin( BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); //btVector3 wmax(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT); btVector3 wmin( BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); btVector3 wmax(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT); btVector3 boxDiag(m_particleRad, m_particleRad, m_particleRad); for(int i = 0; i < m_numParticles; i++) { btVector3 pos = m_hPos[i]; btVector3 boxMin = pos - boxDiag; btVector3 boxMax = pos + boxDiag; wmin.setMin(boxMin); wmax.setMax(boxMax); } m_worldMin = wmin; m_worldMax = wmax; btVector3 wsize = m_worldMax - m_worldMin; wsize[3] = 1.0f; glBindBufferARB(GL_ARRAY_BUFFER, m_colVbo); btVector3* color = (btVector3*)glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY); for(int i = 0; i < m_numParticles; i++, color++) { *color = (m_hPos[i] - m_worldMin) / wsize; (*color)[3] = 1.f; } glUnmapBufferARB(GL_ARRAY_BUFFER); /* wsize[0] *= 0.5f; wsize[1] *= 0.1f; wsize[2] *= 0.5f; m_worldMin -= wsize; m_worldMax += wsize; */ m_worldMin.setValue(-1.f, -1.f, -1.f); m_worldMax.setValue( 1.f, 1.f, 1.f); wsize = m_worldMax - m_worldMin; m_cellSize[0] = m_cellSize[1] = m_cellSize[2] = m_particleRad * btScalar(2.f); m_simParams.m_worldMin[0] = m_worldMin[0]; m_simParams.m_worldMin[1] = m_worldMin[1]; m_simParams.m_worldMin[2] = m_worldMin[2]; m_simParams.m_worldMax[0] = m_worldMax[0]; m_simParams.m_worldMax[1] = m_worldMax[1]; m_simParams.m_worldMax[2] = m_worldMax[2]; m_simParams.m_cellSize[0] = m_cellSize[0]; m_simParams.m_cellSize[1] = m_cellSize[1]; m_simParams.m_cellSize[2] = m_cellSize[2]; m_simParams.m_gridSize[0] = (int)(wsize[0] / m_cellSize[0]); m_simParams.m_gridSize[1] = (int)(wsize[1] / m_cellSize[1]); m_simParams.m_gridSize[2] = (int)(wsize[2] / m_cellSize[2]); m_numGridCells = m_simParams.m_gridSize[0] * m_simParams.m_gridSize[1] * m_simParams.m_gridSize[2]; m_hCellStart.resize(m_numGridCells); unsigned int memSize = sizeof(int) * m_numGridCells; cl_int ciErrNum; m_dCellStart = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); oclCHECKERROR(ciErrNum, CL_SUCCESS); }
bool ccRasterizeTool::updateGrid(bool interpolateSF/*=false*/) { if (!m_cloud) { assert(false); return false; } //main parameters ProjectionType projectionType = getTypeOfProjection(); ProjectionType sfInterpolation = interpolateSF ? getTypeOfSFInterpolation() : INVALID_PROJECTION_TYPE; //vertical dimension const unsigned char Z = getProjectionDimension(); assert(Z >= 0 && Z <= 2); const unsigned char X = Z == 2 ? 0 : Z +1; const unsigned char Y = X == 2 ? 0 : X +1; //cloud bounding-box --> grid size ccBBox box = getCustomBBox(); if (!box.isValid()) return false; double gridStep = getGridStep(); assert(gridStep != 0); CCVector3d boxDiag( static_cast<double>(box.maxCorner().x) - static_cast<double>(box.minCorner().x), static_cast<double>(box.maxCorner().y) - static_cast<double>(box.minCorner().y), static_cast<double>(box.maxCorner().z) - static_cast<double>(box.minCorner().z) ); if (boxDiag.u[X] <= 0 || boxDiag.u[Y] <= 0) { ccLog::Error("Invalid cloud bounding box!"); return false; } unsigned gridWidth = static_cast<unsigned>(ceil(boxDiag.u[X] / gridStep)); unsigned gridHeight = static_cast<unsigned>(ceil(boxDiag.u[Y] / gridStep)); //grid size unsigned gridTotalSize = gridWidth * gridHeight; if (gridTotalSize == 1) { if (QMessageBox::question(0,"Unexpected grid size","The generated grid will only have 1 cell! Do you want to proceed anyway?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return false; } else if (gridTotalSize > 10000000) { if (QMessageBox::question(0,"Big grid size","The generated grid will have more than 10.000.000 cells! Do you want to proceed anyway?",QMessageBox::Yes,QMessageBox::No) == QMessageBox::No) return false; } removeContourLines(); //memory allocation if (!m_grid.init(gridWidth,gridHeight)) { //not enough memory ccLog::Error("Not enough memory"); return false; } m_grid.gridStep = gridStep; m_grid.minCorner = CCVector3d::fromArray(box.minCorner().u); ccProgressDialog pDlg(true,this); if (m_grid.fillWith(m_cloud, Z, projectionType, getFillEmptyCellsStrategy(fillEmptyCellsComboBox) == INTERPOLATE, sfInterpolation, &pDlg)) { ccLog::Print(QString("[Rasterize] Current raster grid: size: %1 x %2 / heights: [%3 ; %4]").arg(m_grid.width).arg(m_grid.height).arg(m_grid.minHeight).arg(m_grid.maxHeight)); } return true; }