void ccContourExtractorDlg::zoomOn(const ccBBox& box) { if (!m_glWindow) return; float pixSize = std::max(box.getDiagVec().x / std::max(20,m_glWindow->width()-20), box.getDiagVec().y / std::max(20,m_glWindow->height()-20)); m_glWindow->setPixelSize(pixSize); m_glWindow->setCameraPos(CCVector3d::fromArray(box.getCenter().u)); }
ccComputeOctreeDlg::ccComputeOctreeDlg(const ccBBox& baseBBox, double minCellSize, QWidget* parent/*=0*/) : QDialog(parent) , Ui::ComputeOctreeDialog() , m_bbEditorDlg(0) { setupUi(this); headerLabel->setText(QString("Max subdivision level: %1").arg(ccOctree::MAX_OCTREE_LEVEL)); //minimum cell size if (minCellSize > 0.0) { cellSizeDoubleSpinBox->setMinimum(minCellSize); cellSizeDoubleSpinBox->setMaximum(1.0e9); } else { ccLog::Warning("[ccComputeOctreeDlg] Invalid minimum cell size specified!"); cellSizeRadioButton->setEnabled(false); } //custom bbox editor if (baseBBox.isValid()) { m_bbEditorDlg = new ccBoundingBoxEditorDlg(this); m_bbEditorDlg->setBaseBBox(baseBBox,true); m_bbEditorDlg->forceKeepSquare(true); connect(customBBToolButton, SIGNAL(clicked()), m_bbEditorDlg, SLOT(exec())); } else { ccLog::Warning("[ccComputeOctreeDlg] Invalid base bounding-box specified!"); customBBRadioButton->setEnabled(false); } }
void visit(ccKdTree::BaseNode* node) { assert(node); if (node && node->parent) { assert(node->parent->isNode()); //a leaf can't have children! ccKdTree::Node* parent = static_cast<ccKdTree::Node*>(node->parent); //we choose the right 'side' of the box that corresponds to the parent's split plane CCVector3& boxCorner = (parent->leftChild == node ? m_UpdatedBox.maxCorner() : m_UpdatedBox.minCorner()); //if this side has not been setup yet... if (boxCorner.u[parent->splitDim] != boxCorner.u[parent->splitDim]) //NaN boxCorner.u[parent->splitDim] = parent->splitValue; visit(node->parent); } }
//Helper void MakeSquare(ccBBox& box, int pivotType, int defaultDim = -1) { assert(defaultDim<3); assert(pivotType>=0 && pivotType<3); CCVector3 W = box.getDiagVec(); if (W.x != W.y || W.x != W.z) { if (defaultDim < 0) { //we take the largest one! defaultDim = 0; if (W.u[1] > W.u[defaultDim]) defaultDim = 1; if (W.u[2] > W.u[defaultDim]) defaultDim = 2; } CCVector3 newW(W.u[defaultDim], W.u[defaultDim], W.u[defaultDim]); switch(pivotType) { case 0: //min corner { CCVector3 A = box.minCorner(); box = ccBBox(A, A + newW); } break; case 1: //center { CCVector3 C = box.getCenter(); box = ccBBox(C - newW / 2.0, C + newW / 2.0); } break; case 2: //max corner { CCVector3 B = box.maxCorner(); box = ccBBox(B-newW,B); } break; } } }
ccBoundingBoxEditorDlg::ccBoundingBoxEditorDlg(QWidget* parent/*=0*/) : QDialog(parent, Qt::Tool) , Ui::BoundingBoxEditorDialog() , m_baseBoxIsMinimal(false) , m_showInclusionWarning(true) { setupUi(this); showBoxAxes(false); xDoubleSpinBox->setMinimum(-1.0e9); yDoubleSpinBox->setMinimum(-1.0e9); zDoubleSpinBox->setMinimum(-1.0e9); xDoubleSpinBox->setMaximum( 1.0e9); yDoubleSpinBox->setMaximum( 1.0e9); zDoubleSpinBox->setMaximum( 1.0e9); dxDoubleSpinBox->setMinimum( 0.0); dyDoubleSpinBox->setMinimum( 0.0); dzDoubleSpinBox->setMinimum( 0.0); dxDoubleSpinBox->setMaximum(1.0e9); dyDoubleSpinBox->setMaximum(1.0e9); dzDoubleSpinBox->setMaximum(1.0e9); connect(pointTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(reflectChanges(int))); connect(keepSquareCheckBox, SIGNAL(toggled(bool)), this, SLOT(squareModeActivated(bool))); connect(okPushButton, SIGNAL(clicked()), this, SLOT(saveBoxAndAccept())); connect(cancelPushButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(defaultPushButton, SIGNAL(clicked()), this, SLOT(resetToDefault())); connect(lastPushButton, SIGNAL(clicked()), this, SLOT(resetToLast())); connect(xDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateCurrentBBox(double))); connect(yDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateCurrentBBox(double))); connect(zDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateCurrentBBox(double))); connect(dxDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateXWidth(double))); connect(dyDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateYWidth(double))); connect(dzDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateZWidth(double))); connect(xOriXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(xOriYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(xOriZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(yOriXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(yOriYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(yOriZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(zOriXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(zOriYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); connect(zOriZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double))); defaultPushButton->setVisible(false); lastPushButton->setVisible(s_lastBBox.isValid()); checkBaseInclusion(); }
void cc2Point5DimEditor::update2DDisplayZoom(ccBBox& box) { if (!m_window || !m_grid.isValid()) return; //equivalent to 'ccGLWindow::updateConstellationCenterAndZoom' but we take aspect ratio into account //we compute the pixel size (in world coordinates) { ccViewportParameters params = m_window->getViewportParameters(); double realGridWidth = m_grid.width * m_grid.gridStep; double realGridHeight = m_grid.height * m_grid.gridStep; static const int screnMargin = 20; int screenWidth = std::max(1,m_window->width() - 2*screnMargin); int screenHeight = std::max(1,m_window->height() - 2*screnMargin); int pointSize = 1; if ( static_cast<int>(m_grid.width) < screenWidth && static_cast<int>(m_grid.height) < screenHeight) { int vPointSize = static_cast<int>(ceil(static_cast<float>(screenWidth) /m_grid.width)); int hPointSize = static_cast<int>(ceil(static_cast<float>(screenHeight)/m_grid.height)); pointSize = std::min(vPointSize, hPointSize); //if the grid is too small (i.e. necessary point size > 10) if (pointSize > 10) { pointSize = 10; screenWidth = m_grid.width * pointSize; screenHeight = m_grid.height * pointSize; } } params.pixelSize = static_cast<float>( std::max( realGridWidth/screenWidth, realGridHeight/screenHeight ) ); params.zoom = 1.0f; m_window->setViewportParameters(params); m_window->setPointSize(pointSize); } //we set the pivot point on the box center CCVector3 P = box.getCenter(); m_window->setPivotPoint(CCVector3d::fromArray(P.u)); m_window->setCameraPos(CCVector3d::fromArray(P.u)); m_window->invalidateViewport(); m_window->invalidateVisualization(); m_window->redraw(); }
ccHeightGridGenerationDlg::ccHeightGridGenerationDlg(const ccBBox& gridBBox, QWidget* parent/*=0*/) : QDialog(parent) , Ui::HeightGridGenerationDialog() , m_bbEditorDlg(0) { setupUi(this); setWindowFlags(Qt::Tool/*Qt::Dialog | Qt::WindowStaysOnTopHint*/); #ifndef CC_GDAL_SUPPORT generateRasterCheckBox->setDisabled(true); generateRasterCheckBox->setChecked(false); #endif connect(buttonBox, SIGNAL(accepted()), this, SLOT(saveSettings())); connect(fillEmptyCells, SIGNAL(currentIndexChanged(int)), this, SLOT(projectionChanged(int))); connect(generateCloudGroupBox, SIGNAL(toggled(bool)), this, SLOT(toggleFillEmptyCells(bool))); connect(generateImageCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleFillEmptyCells(bool))); connect(generateRasterCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleFillEmptyCells(bool))); connect(generateASCIICheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleFillEmptyCells(bool))); connect(typeOfProjectionComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(projectionTypeChanged(int))); //custom bbox editor if (gridBBox.isValid()) { m_bbEditorDlg = new ccBoundingBoxEditorDlg(this); m_bbEditorDlg->setBaseBBox(gridBBox,false); connect(editGridToolButton, SIGNAL(clicked()), this, SLOT(showGridBoxEditor())); } else { editGridToolButton->setEnabled(false); } loadSettings(); }
bool ccVolumeCalcTool::ComputeVolume( ccRasterGrid& grid, ccGenericPointCloud* ground, ccGenericPointCloud* ceil, const ccBBox& gridBox, unsigned char vertDim, double gridStep, unsigned gridWidth, unsigned gridHeight, ccRasterGrid::ProjectionType projectionType, ccRasterGrid::EmptyCellFillOption emptyCellFillStrategy, ccVolumeCalcTool::ReportInfo& reportInfo, double groundHeight = std::numeric_limits<double>::quiet_NaN(), double ceilHeight = std::numeric_limits<double>::quiet_NaN(), QWidget* parentWidget/*=0*/) { if ( gridStep <= 1.0e-8 || gridWidth == 0 || gridHeight == 0 || vertDim > 2) { assert(false); ccLog::Warning("[Volume] Invalid input parameters"); return false; } if (!ground && !ceil) { assert(false); ccLog::Warning("[Volume] No valid input cloud"); return false; } if (!gridBox.isValid()) { ccLog::Warning("[Volume] Invalid bounding-box"); return false; } //grid size unsigned gridTotalSize = gridWidth * gridHeight; if (gridTotalSize == 1) { if (parentWidget && QMessageBox::question(parentWidget, "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 (parentWidget && QMessageBox::question(parentWidget, "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 CCVector3d minCorner = CCVector3d::fromArray(gridBox.minCorner().u); if (!grid.init(gridWidth, gridHeight, gridStep, minCorner)) { //not enough memory return SendError("Not enough memory", parentWidget); } //progress dialog QScopedPointer<ccProgressDialog> pDlg(0); if (parentWidget) { pDlg.reset(new ccProgressDialog(true, parentWidget)); } ccRasterGrid groundRaster; if (ground) { if (!groundRaster.init(gridWidth, gridHeight, gridStep, minCorner)) { //not enough memory return SendError("Not enough memory", parentWidget); } if (groundRaster.fillWith( ground, vertDim, projectionType, emptyCellFillStrategy == ccRasterGrid::INTERPOLATE, ccRasterGrid::INVALID_PROJECTION_TYPE, pDlg.data())) { groundRaster.fillEmptyCells(emptyCellFillStrategy, groundHeight); ccLog::Print(QString("[Volume] Ground raster grid: size: %1 x %2 / heights: [%3 ; %4]").arg(groundRaster.width).arg(groundRaster.height).arg(groundRaster.minHeight).arg(groundRaster.maxHeight)); } else { return false; } } //ceil ccRasterGrid ceilRaster; if (ceil) { if (!ceilRaster.init(gridWidth, gridHeight, gridStep, minCorner)) { //not enough memory return SendError("Not enough memory", parentWidget); } if (ceilRaster.fillWith(ceil, vertDim, projectionType, emptyCellFillStrategy == ccRasterGrid::INTERPOLATE, ccRasterGrid::INVALID_PROJECTION_TYPE, pDlg.data())) { ceilRaster.fillEmptyCells(emptyCellFillStrategy, ceilHeight); ccLog::Print(QString("[Volume] Ceil raster grid: size: %1 x %2 / heights: [%3 ; %4]").arg(ceilRaster.width).arg(ceilRaster.height).arg(ceilRaster.minHeight).arg(ceilRaster.maxHeight)); } else { return false; } } //update grid and compute volume { if (pDlg) { pDlg->setMethodTitle(QObject::tr("Volume computation")); pDlg->setInfo(QObject::tr("Cells: %1 x %2").arg(grid.width).arg(grid.height)); pDlg->start(); pDlg->show(); QCoreApplication::processEvents(); } CCLib::NormalizedProgress nProgress(pDlg.data(), grid.width * grid.height); size_t ceilNonMatchingCount = 0; size_t groundNonMatchingCount = 0; size_t cellCount = 0; //at least one of the grid is based on a cloud grid.nonEmptyCellCount = 0; for (unsigned i = 0; i < grid.height; ++i) { for (unsigned j = 0; j < grid.width; ++j) { ccRasterCell& cell = grid.rows[i][j]; bool validGround = true; cell.minHeight = groundHeight; if (ground) { cell.minHeight = groundRaster.rows[i][j].h; validGround = std::isfinite(cell.minHeight); } bool validCeil = true; cell.maxHeight = ceilHeight; if (ceil) { cell.maxHeight = ceilRaster.rows[i][j].h; validCeil = std::isfinite(cell.maxHeight); } if (validGround && validCeil) { cell.h = cell.maxHeight - cell.minHeight; cell.nbPoints = 1; reportInfo.volume += cell.h; if (cell.h < 0) { reportInfo.removedVolume -= cell.h; } else if (cell.h > 0) { reportInfo.addedVolume += cell.h; } reportInfo.surface += 1.0; ++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 (pDlg && !nProgress.oneStep()) { ccLog::Warning("[Volume] Process cancelled by the user"); return false; } } } grid.validCellCount = grid.nonEmptyCellCount; //count the average number of valid neighbors { size_t validNeighborsCount = 0; size_t count = 0; for (unsigned i = 1; i < grid.height - 1; ++i) { for (unsigned j = 1; j < grid.width - 1; ++j) { ccRasterCell& cell = grid.rows[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) { ccRasterCell& otherCell = grid.rows[k][l]; if (std::isfinite(otherCell.h)) { ++validNeighborsCount; } } } } ++count; } } } if (count) { reportInfo.averageNeighborsPerCell = static_cast<double>(validNeighborsCount) / count; } } reportInfo.matchingPrecent = static_cast<float>(grid.validCellCount * 100) / cellCount; reportInfo.groundNonMatchingPercent = static_cast<float>(groundNonMatchingCount * 100) / cellCount; reportInfo.ceilNonMatchingPercent = static_cast<float>(ceilNonMatchingCount * 100) / cellCount; float cellArea = static_cast<float>(grid.gridStep * grid.gridStep); reportInfo.volume *= cellArea; reportInfo.addedVolume *= cellArea; reportInfo.removedVolume *= cellArea; reportInfo.surface *= cellArea; } grid.setValid(true); return true; }
int IcmFilter::LoadCalibratedImages(ccHObject* entities, const QString& path, const QString& imageDescFilename, const ccBBox& globalBBox) { assert(entities); //ouverture du fichier QString completeImageDescFilename = QString("%0/%1").arg(path).arg(imageDescFilename); FILE* fp = fopen(qPrintable(completeImageDescFilename), "rt"); if (fp == NULL) { ccLog::Error(QString("[IcmFilter::loadCalibratedImages] Error opening file %1!").arg(completeImageDescFilename)); return -1; } //buffers char line[MAX_ASCII_FILE_LINE_LENGTH]; #ifdef INCLUDE_PHOTOS char totalFileName[256]; #endif int loadedImages = 0; //IL FAUDRAIT ETRE PLUS SOUPLE QUE CA !!! while (fgets(line, MAX_ASCII_FILE_LINE_LENGTH , fp) != NULL) { if (line[0] == 'D' && line[1] == 'E' && line[2] == 'F') { char imageFileName[256]; sscanf(line,"DEF %s Viewpoint {",imageFileName); //add absolute path ccImage* CI = new ccImage(); QString errorStr; if (!CI->load(QString("%0/%1").arg(path).arg(imageFileName),errorStr)) { ccLog::Warning(QString("[IcmFilter] Failed to load image %1 (%2)! Process stopped...").arg(imageFileName).arg(errorStr)); delete CI; fclose(fp); return loadedImages; } ccLog::Print("[IcmFilter] Image '%s' loaded",imageFileName); CI->setEnabled(false); CI->setName(imageFileName); #ifdef INCLUDE_PHOTOS CI->setCompleteFileName(totalFileName); #endif //FOV if (!fgets(line, MAX_ASCII_FILE_LINE_LENGTH , fp)) { ccLog::Print("[IcmFilter] Read error (fieldOfView)!"); delete CI; fclose(fp); return loadedImages; } float fov_rad = 0; sscanf(line,"\t fieldOfView %f\n",&fov_rad); float fov_deg = fov_rad*static_cast<float>(CC_RAD_TO_DEG); ccLog::Print("\t FOV=%f (degrees)",fov_deg); //Position float t[3]; if (!fgets(line, MAX_ASCII_FILE_LINE_LENGTH , fp)) { ccLog::Error("[IcmFilter] Read error (position)!"); delete CI; fclose(fp); return loadedImages; } sscanf(line,"\t position %f %f %f\n",t,t+1,t+2); ccLog::Print("\t Camera pos=(%f,%f,%f)",t[0],t[1],t[2]); //Description char desc[MAX_ASCII_FILE_LINE_LENGTH]; if (!fgets(line, MAX_ASCII_FILE_LINE_LENGTH , fp)) { ccLog::Error("[IcmFilter] Read error (description)!"); delete CI; fclose(fp); return loadedImages; } sscanf(line,"\t description \"%s\"\n",desc); //CI->setDescription(desc); ccLog::Print("\t Description: '%s'",desc); //Orientation float axis[3], angle_rad; if (!fgets(line, MAX_ASCII_FILE_LINE_LENGTH , fp)) { ccLog::Error("[IcmFilter] Read error (orientation)!"); fclose(fp); return loadedImages; } sscanf(line,"\t orientation %f %f %f %f\n",axis,axis+1,axis+2,&angle_rad); ccLog::Print("\t Camera orientation=(%f,%f,%f)+[%f]",axis[0],axis[1],axis[2],angle_rad); ccCameraSensor::IntrinsicParameters params; params.vFOV_rad = fov_rad; params.arrayWidth = CI->getW(); params.arrayHeight = CI->getH(); params.principal_point[0] = params.arrayWidth / 2.0f; params.principal_point[1] = params.arrayHeight / 2.0f; params.vertFocal_pix = 1.0f; //default focal (for the 3D symbol) params.pixelSize_mm[0] = params.pixelSize_mm[1] = 1.0f; ccCameraSensor* sensor = new ccCameraSensor(params); ccGLMatrix mat; mat.initFromParameters(angle_rad,CCVector3::fromArray(axis),CCVector3::fromArray(t)); sensor->setRigidTransformation(mat); sensor->setGraphicScale(globalBBox.getDiagNorm() / 20); sensor->setVisible(true); sensor->setEnabled(false); CI->addChild(sensor); CI->setAssociatedSensor(sensor); entities->addChild(CI); ++loadedImages; } } fclose(fp); return loadedImages; }
GetCellBBoxVisitor() { //invalidate the initial bounding box m_UpdatedBox.maxCorner() = CCVector3(PC_NAN,PC_NAN,PC_NAN); m_UpdatedBox.minCorner() = CCVector3(PC_NAN,PC_NAN,PC_NAN); }