/**************************************************************************** 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 . *****************************************************************************/ #ifndef ONF_STEPSEGMENTCROWNSFROMSTEMCLUSTERS_H #define ONF_STEPSEGMENTCROWNSFROMSTEMCLUSTERS_H #include "ct_step/abstract/ct_abstractstep.h" #include "ct_itemdrawable/ct_pointcluster.h" class ONF_StepSegmentCrownsFromStemClusters: public CT_AbstractStep { Q_OBJECT using SuperClass = CT_AbstractStep; public: ONF_StepSegmentCrownsFromStemClusters(); QString description() const override; QString detailledDescription() const override; QString inputDescription() const override; QString outputDescription() const override; QString detailsDescription() const override; QString URL() const override; CT_VirtualAbstractStep* createNewInstance() const final; protected: void declareInputModels(CT_StepInModelStructureManager& manager) final; void fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) final; void declareOutputModels(CT_StepOutModelStructureManager& manager) final; void compute() final; private: double _distMax; CT_HandleInResultGroupCopy<> _inResult; CT_HandleInStdZeroOrMoreGroup _inZeroOrMoreRootGroup; CT_HandleInStdGroup<> _inGroup; CT_HandleInSingularItem _inScene; CT_HandleInStdGroup<> _inGroupStem; CT_HandleInSingularItem _inStem; CT_HandleOutSingularItem _outCluster; CT_HandleOutStdItemAttribute _outAtt; struct PointData { PointData(size_t index, double x, double y, double z) { _index = index; _x = x; _y = y; _z = z; } size_t _index; double _x; double _y; double _z; }; struct StemData { StemData(CT_StandardItemGroup* group, double distMax) { _group = group; _distMax1 = distMax; _distMax2 = distMax*distMax; } ~StemData() { qDeleteAll(_points); } int size() {return _points.size();} double maxZ() { if (_points.size() > 0) { return _points.last()->_z; } else { return 0.0; } } bool addPoint(PointData* point) { if (point == nullptr) {return false;} if (_points.size() == 0 || point->_z < _points.first()->_z) { _points.push_front(point); } else { bool inserted = false; for (int i = 0 ; !inserted && i < _points.size(); i++) { if (point->_z < _points.at(i)->_z) { _points.insert(i, point); inserted = true; } } if (!inserted) {_points.append(point);} } return true; } double getDistance(PointData* point, bool &alreadyInserted) { alreadyInserted = false; double zMin = point->_z - _distMax1; double distance = _distMax2; bool stop = false; for (int i = _points.size() - 1 ; !stop && i >= 0 ; i--) { PointData* pt = _points.at(i); if (point->_index == pt->_index) {alreadyInserted = true; return 0.0;} if (pt->_z >= zMin) { double dist2 = pow(pt->_x - point->_x, 2) + pow(pt->_y - point->_y, 2) + pow(pt->_z - point->_z, 2); if (dist2 < distance) { distance = dist2; } } else { stop = true; } } return sqrt(distance); } double _distMax1; double _distMax2; CT_StandardItemGroup* _group; QList _points; }; static bool lessThan(ONF_StepSegmentCrownsFromStemClusters::PointData *p1, ONF_StepSegmentCrownsFromStemClusters::PointData *p2) { return p1->_z < p2->_z; } }; #endif // ONF_STEPSEGMENTCROWNSFROMSTEMCLUSTERS_H