/**************************************************************************** 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_stepextractdiametersfromcylinders.h" #include "qvector2d.h" #include "qvector3d.h" #include "ct_math/ct_mathfittedline2d.h" #include #include #include #include ONF_StepExtractDiametersFromCylinders::ONF_StepExtractDiametersFromCylinders() : SuperClass() { _h = 1.3; _hmin = 1.0; _hmax = 1.6; _deltaDMax = 0.05; _minCylinderNumber = 3; } QString ONF_StepExtractDiametersFromCylinders::description() const { return tr("Calcul d'un diamètre par billon à partir des cylindres"); } QString ONF_StepExtractDiametersFromCylinders::detailledDescription() const { return tr(""); } QString ONF_StepExtractDiametersFromCylinders::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepExtractDiametersFromCylinders::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepExtractDiametersFromCylinders::createNewInstance() const { // cree une copie de cette etape return new ONF_StepExtractDiametersFromCylinders(); } //////////////////// PROTECTED ////////////////// void ONF_StepExtractDiametersFromCylinders::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Billons")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inSectionGroup, tr("Billon (Grp)")); manager.addItem(_inSectionGroup, _inFootCoordinate, tr("Cordonnée MNT")); manager.addGroup(_inSectionGroup, _inClusterGroup, tr("Cluster (Grp)")); manager.addItem(_inClusterGroup, _inCylinder, tr("Cylindre")); } void ONF_StepExtractDiametersFromCylinders::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Hauteur de référence : "), "m", 0, 1000, 2, _h); postInputConfigDialog->addDouble(tr("Hauteur minimale d'évaluation :"), "m", 0, 1000, 2, _hmin); postInputConfigDialog->addDouble(tr("Hauteur maximale d'évaluation : "), "m", 0, 1000, 2, _hmax); postInputConfigDialog->addDouble(tr("Décroissance métrique maximale : "), "cm", 0, 100, 2, _deltaDMax, 100); postInputConfigDialog->addInt(tr("Nombre de cylindres minimum pour ajuster un cercle : "), "", 2, 100, _minCylinderNumber); } void ONF_StepExtractDiametersFromCylinders::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inSectionGroup, _outCircle, tr("Diamètre à 1.30m")); } void ONF_StepExtractDiametersFromCylinders::compute() { for (CT_StandardItemGroup* section : _inSectionGroup.iterateOutputs(_inResult)) { for (const CT_ReferencePoint* footCoordinate : section->singularItems(_inFootCoordinate)) { QList diameters; double deltaHmax = std::max(fabs(_hmax - _h), fabs(_h - _hmin)); double xSection = footCoordinate->x(); double ySection = footCoordinate->y(); for (const CT_StandardItemGroup* group : section->groups(_inClusterGroup)) { for (const CT_Cylinder* cylinder : group->singularItems(_inCylinder)) { if (isStopped()) {return;} double h_value = cylinder->centerZ() - footCoordinate->z(); double deltaH = fabs(h_value - _h); if ((h_value >= _hmin) && (h_value <= _hmax)) { diameters.append(new Eigen::Vector2d(h_value, cylinder->getRadius())); if (deltaH < deltaHmax) { deltaHmax = deltaH; xSection = cylinder->centerX(); ySection = cylinder->centerY(); } } } } if (diameters.size() >= _minCylinderNumber) { CT_MathFittedLine2D fittedLine(diameters); if (fabs(fittedLine._a) < _deltaDMax) { double radius = fittedLine._a*_h + fittedLine._b; CT_CircleData *cData = new CT_CircleData(Eigen::Vector3d(xSection, ySection, _h + footCoordinate->z()), Eigen::Vector3d(0, 0, 1), radius); if(cData != nullptr) { section->addSingularItem(_outCircle, new CT_Circle(cData)); } } } qDeleteAll(diameters); diameters.clear(); } } }