/**************************************************************************** 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_stepmergeneighbourclustersingrid.h" #include "ct_math/ct_mathpoint.h" #include #include ONF_StepMergeNeighbourClustersInGrid::ONF_StepMergeNeighbourClustersInGrid() : SuperClass() { _ncellsXY = 1; _ncellsZ = 3; } QString ONF_StepMergeNeighbourClustersInGrid::description() const { return tr("Fusionner les clusters jointifs d'une grille"); } QString ONF_StepMergeNeighbourClustersInGrid::detailledDescription() const { return tr(""); } QString ONF_StepMergeNeighbourClustersInGrid::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepMergeNeighbourClustersInGrid::detailsDescription() const { return tr(""); } QString ONF_StepMergeNeighbourClustersInGrid::URL() const { //return tr("STEP URL HERE"); return SuperClass::URL(); //by default URL of the plugin } CT_VirtualAbstractStep* ONF_StepMergeNeighbourClustersInGrid::createNewInstance() const { return new ONF_StepMergeNeighbourClustersInGrid(); } //////////////////// PROTECTED METHODS ////////////////// void ONF_StepMergeNeighbourClustersInGrid::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Grilles")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inGrid, tr("Grilles")); } void ONF_StepMergeNeighbourClustersInGrid::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _outGrid, tr("Scene")); } void ONF_StepMergeNeighbourClustersInGrid::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addInt(tr("Voisinnage de fusion en XY"), tr("cases"), 1, 9999, _ncellsXY); postInputConfigDialog->addInt(tr("Voisinnage de fusion en Z"), tr("cases"), 1, 9999, _ncellsZ); } void ONF_StepMergeNeighbourClustersInGrid::compute() { CT_StandardItemGroup* grp = nullptr; for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) { if (isStopped()) {return;} const CT_Grid3D_Sparse* gridIn = group->singularItem(_inGrid); if (gridIn != nullptr) { CT_Grid3D_Sparse* outGrid = new CT_Grid3D_Sparse(gridIn->minX(), gridIn->minY(), gridIn->minZ(), gridIn->xdim(), gridIn->ydim(), gridIn->zdim(), gridIn->resolution(), -1, -1); QMultiMap corresp; // recherche les clusters voisins for (int zz = 0 ; zz < gridIn->zdim() ; zz++) { for (int xx = 0 ; xx < gridIn->xdim() ; xx++) { for (int yy = 0 ; yy < gridIn->ydim() ; yy++) { size_t currentIndex; if (gridIn->index(xx, yy, zz, currentIndex)) { int currentCluster = gridIn->valueAtIndex(currentIndex); if (currentCluster >= 0) { int minz, minx, miny, maxz, maxx, maxy; if (zz >= _ncellsZ) {minz = zz - _ncellsZ;} else {minz = 0;} if (xx >= _ncellsXY) {minx = xx - _ncellsXY;} else {minx = 0;} if (yy >= _ncellsXY) {miny = yy - _ncellsXY;} else {miny = 0;} if (zz < gridIn->zdim() - _ncellsZ) {maxz = zz + _ncellsZ;} else {maxz = gridIn->zdim() - 1;} if (xx < gridIn->xdim() - _ncellsXY) {maxx = xx + _ncellsXY;} else {maxx = gridIn->xdim() - 1;} if (yy < gridIn->ydim() - _ncellsXY) {maxy = yy + _ncellsXY;} else {maxy = gridIn->ydim() - 1;} for (int zzz = minz ; zzz <= maxz ; zzz++) { for (int xxx = minx ; xxx <= maxx ; xxx++) { for (int yyy = miny ; yyy <= maxy ; yyy++) { size_t neighbourIndex; if (gridIn->index(xxx, yyy, zzz, neighbourIndex)) { int neighbourCluster = gridIn->valueAtIndex(neighbourIndex); if (neighbourCluster != -1 && neighbourCluster != currentCluster) { if (!corresp.contains(currentCluster, neighbourCluster)) {corresp.insert(currentCluster, neighbourCluster);} if (!corresp.contains(neighbourCluster, currentCluster)) {corresp.insert(neighbourCluster, currentCluster);} } } } } } } } } } } // Créer le vecteur de correspondances QVector newClusters(gridIn->dataMax() + 1); QVector removed(gridIn->dataMax() + 1); removed.fill(false); for (int i = 0 ; i < newClusters.size() ; i++) { newClusters[i] = i; } QList keys = corresp.uniqueKeys(); for (int i = 0 ; i < keys.size() ; i++) { int key = keys.at(i); if (!removed[key]) { QList neighbours; neighbours.append(key); removed[key] = true; int cpt = 0; while (cpt < neighbours.size()) { int k = neighbours.at(cpt); QList values = corresp.values(k); for (int j = 0 ; j < values.size() ; j++) { int value = values.at(j); if (!removed[value]) { neighbours.append(value); removed[value] = true; } } cpt++; } for (int j = 0 ; j < neighbours.size() ; j++) { int value = neighbours.at(j); newClusters[value] = key; } } } // répercuter sur la grille de sortie for (int zz = 0 ; zz < gridIn->zdim() ; zz++) { for (int xx = 0 ; xx < gridIn->xdim() ; xx++) { for (int yy = 0 ; yy < gridIn->ydim() ; yy++) { size_t currentIndex; if (gridIn->index(xx, yy, zz, currentIndex)) { int currentCluster = gridIn->valueAtIndex(currentIndex); if (currentCluster >= 0) { outGrid->setValue(xx, yy, zz, newClusters[currentCluster]); } } } } } outGrid->computeMinMax(); grp->addSingularItem(_outGrid, outGrid); } } }