/**************************************************************************** Copyright (C) 2010-2012 the Office National des Forêts (ONF), France All rights reserved. Contact : alexandre.piboule@onf.fr Developers : Alexandre PIBOULE (ONF) This file is part of PluginONF library. PluginONF is free library: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PluginONF is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PluginONF. If not, see . *****************************************************************************/ #include "onf_stepvoxelclusterization.h" #include ONF_StepVoxelClusterization::ONF_StepVoxelClusterization() : SuperClass() { _res = 0.1; _gridMode = 0; _xBase = 0; _yBase = 0; _zBase = 0; } QString ONF_StepVoxelClusterization::description() const { // Gives the descrption to print in the GUI return tr("Clusterisation selon une grille voxel"); } QString ONF_StepVoxelClusterization::detailledDescription() const { return tr(""); } QString ONF_StepVoxelClusterization::inputDescription() const { return SuperClass::inputDescription() + tr("

"); } QString ONF_StepVoxelClusterization::outputDescription() const { return SuperClass::outputDescription() + tr("

"); } QString ONF_StepVoxelClusterization::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepVoxelClusterization::createNewInstance() const { // Creates an instance of this step return new ONF_StepVoxelClusterization(); } void ONF_StepVoxelClusterization::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Scene(s)")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inScene, tr("Item à clusteriser")); } void ONF_StepVoxelClusterization::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addGroup(_inGroup, _outPointClusterGroup, tr("Cluster (Grp)")); manager.addItem(_outPointClusterGroup, _outPointCluster, tr("Cluster (Points)")); } void ONF_StepVoxelClusterization::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Résolution de la grille"),tr("meters"),0.0001,10000,2, _res ); postInputConfigDialog->addText(tr("Callage du coin (minX, minY, minZ) :"),"", ""); CT_ButtonGroup &bg_gridMode = postInputConfigDialog->addButtonGroup(_gridMode); postInputConfigDialog->addExcludeValue("", "", tr("Sur la boite englobante de la scène"), bg_gridMode, 0); postInputConfigDialog->addExcludeValue("", "", tr("Par rapport aux coordonnées suivantes :"), bg_gridMode, 1); postInputConfigDialog->addDouble(tr("Coordonnée X :"), "", -double(std::numeric_limits::max()), double(std::numeric_limits::max()), 4, _xBase); postInputConfigDialog->addDouble(tr("Coordonnée Y :"), "", -double(std::numeric_limits::max()), double(std::numeric_limits::max()), 4, _yBase); postInputConfigDialog->addDouble(tr("Coordonnée Z :"), "", -double(std::numeric_limits::max()), double(std::numeric_limits::max()), 4, _zBase); } void ONF_StepVoxelClusterization::compute() { auto iterator = _inScene.iterateOutputs(_inResult); auto it = iterator.begin(); auto end = iterator.end(); while(it != end) { const CT_AbstractItemDrawableWithPointCloud* scene = *it; CT_StandardItemGroup* grp = it.currentParent(); if (isStopped()) return; double minX = _xBase; double minY = _yBase; double minZ = _zBase; if (_gridMode == 0) { minX = scene->minX(); minY = scene->minY(); minZ = scene->minZ(); } else { while (minX < scene->minX()) {minX += _res;}; while (minY < scene->minY()) {minY += _res;}; while (minZ < scene->minZ()) {minZ += _res;}; while (minX > scene->minX()) {minX -= _res;}; while (minY > scene->minY()) {minY -= _res;}; while (minZ > scene->minZ()) {minZ -= _res;}; } // Declaring the output grids CT_Grid3D_Sparse* hitGrid = CT_Grid3D_Sparse::createGrid3DFromXYZCoords(minX, minY, minZ, scene->maxX(), scene->maxY(), scene->maxZ(), _res, -1, 0); QList clusters; clusters.append(nullptr); int clusterNumber = 1; CT_PointIterator itP(scene->pointCloudIndex()); while(itP.hasNext()) { if (isStopped()) return; const CT_Point& point = itP.next().currentPoint(); const size_t index = itP.currentGlobalIndex(); int val = hitGrid->valueAtXYZ(point(0), point(1), point(2)); if (val == 0) { val = clusterNumber; hitGrid->setValueAtXYZ(point(0), point(1), point(2), clusterNumber++); clusters.append(new CT_PointCluster()); } clusters.at(val)->addPoint(index); } for (int i = 1 ; i < clusters.size() ; i++) { CT_StandardItemGroup* newGroup = _outPointClusterGroup.createInstance(); grp->addGroup(_outPointClusterGroup, newGroup); newGroup->addSingularItem(_outPointCluster, clusters.at(i)); } delete hitGrid; ++it; } setProgress(99); }