/**************************************************************************** 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_stepchangeclusterthickness02.h" #include "qfuture.h" #include ONF_StepChangeClusterThickness02::ONF_StepChangeClusterThickness02() : SuperClass() { _thickness = 0.1; } QString ONF_StepChangeClusterThickness02::description() const { return tr("Modifier épaisseur de clusters horizontaux"); } QString ONF_StepChangeClusterThickness02::detailledDescription() const { return tr("Cette étape permet de changer l'épaisseur (verticale) de clusters, contenus dans des billons." "Il y a donc deux niveaux de groupes : chaque billon contient plusieurs clusters. " "Ce sont les nuages de points du second niveau qui sont reconstruits avec une nouvelle épaisseur calée sur le point le plus bas. "); } QString ONF_StepChangeClusterThickness02::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepChangeClusterThickness02::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepChangeClusterThickness02::createNewInstance() const { // cree une copie de cette etape return new ONF_StepChangeClusterThickness02(); } //////////////////// PROTECTED ////////////////// void ONF_StepChangeClusterThickness02::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Billons / Clusters")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inSectionGroup, tr("Billon (Grp)")); manager.addGroup(_inSectionGroup, _inClusterGroup, tr("Cluster (Grp)")); manager.addItem(_inClusterGroup, _inPointCluster, tr("Points")); } void ONF_StepChangeClusterThickness02::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Epaisseur en Z :"), "cm", 0, 1000, 2, _thickness, 100); } void ONF_StepChangeClusterThickness02::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addGroup(_inSectionGroup, _outClusterGroup, tr("Nouveau Cluster (Grp)")); manager.addItem(_outClusterGroup, _outOutPointCluster, tr("Points")); } void ONF_StepChangeClusterThickness02::compute() { QList sections; for (CT_StandardItemGroup* inSectionGroup : _inSectionGroup.iterateOutputs(_inResult)) { if (isStopped()) {return;} sections.append(SectionWithStep(inSectionGroup, this)); } QFuture futur = QtConcurrent::map(sections, ONF_StepChangeClusterThickness02::computeOneSection); int progressMin = futur.progressMinimum(); int progressTotal = futur.progressMaximum() - futur.progressMinimum(); while (!futur.isFinished()) { setProgress(float(99.0*(futur.progressValue() - progressMin)/progressTotal)); } setProgress(100.0f); } void ONF_StepChangeClusterThickness02::computeOneSection(SectionWithStep sectionWithStep) { CT_StandardItemGroup* inSectionGroup = sectionWithStep._section; ONF_StepChangeClusterThickness02* step = sectionWithStep._step; QList liste; for (const CT_StandardItemGroup* group : inSectionGroup->groups(step->_inClusterGroup)) { const CT_PointCluster *item = group->singularItem(step->_inPointCluster); if (item != nullptr) { liste.append(item); } } QMultiMap indexesSortedByZ; int size = liste.size(); for (int g = 0 ; g < size ; g++) { const CT_PointCluster *item = liste.at(g); CT_PointIterator itP(item->pointCloudIndex()); while (itP.hasNext()) { size_t index = itP.next().currentGlobalIndex(); double z = itP.currentPoint()(2); indexesSortedByZ.insert(z, index); } } QMapIterator itPoints(indexesSortedByZ); if (itPoints.hasNext()) { double maxzPoint = itPoints.next().key(); maxzPoint += step->_thickness; CT_PointCluster* activecluster = nullptr; itPoints.toFront(); while (itPoints.hasNext()) { itPoints.next(); double zPoint = itPoints.key(); size_t indexPoint = itPoints.value(); while ((maxzPoint - zPoint) < 0) { maxzPoint += step->_thickness; activecluster = nullptr; } if (activecluster == nullptr) { CT_StandardItemGroup* clustergroup = new CT_StandardItemGroup(); inSectionGroup->addGroup(step->_outClusterGroup, clustergroup); activecluster = new CT_PointCluster(); clustergroup->addSingularItem(step->_outOutPointCluster, activecluster); } activecluster->addPoint(indexPoint, false); } } }