/**************************************************************************** Copyright (C) 2010-2012 the Office National des Forêts (ONF), France and the Laboratoire des Sciences de l'Information et des Systèmes (LSIS), Marseille, France. All rights reserved. Contact : alexandre.piboule@onf.fr alexandra.bac@esil.univmed.fr Developers : Joris Ravaglia (ONF/LSIS) With modifications by : Alexandre PIBOULE (ONF) This file is part of PluginONFLSIS library 2.0. PluginONFLSIS 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. PluginShared 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 PluginShared. If not, see . *****************************************************************************/ #ifndef OL_STEPTHROWPARTICULES05_H #define OL_STEPTHROWPARTICULES05_H #include "ct_step/abstract/ct_abstractstep.h" #include "ct_tools/model/ct_autorenamemodels.h" #include "ct_itemdrawable/ct_pointcluster.h" #include "ct_itemdrawable/abstract/ct_abstractitemgroup.h" #include "ct_pointcloudindex/ct_pointcloudindexvector.h" #ifdef USE_PCL #include "pcl/octree/octree_search.h" #endif /*! * \class OL_StepThrowParticules05 * \ingroup Steps_OL * \brief Simplify clusters of points by a particules throwing algorithm * * A smallest number of points (named particules) is choosen (using _distanceBetweenPoints parameter) as simplified cluster number of points. * Iteratively particules are \n * 1) attracted to original points position (using k-neighbors approach k = _kNeighborsParticle).\n * 2) repulsed by others particules using _radiusRepulsion sphere of influence.\n * This process should efficiently distribute particules along original cluster. * Each particule is granted to occupy the position of an original point. No fictive point is created. * To avoid cylcing problems in iterations, should choose _radiusRepulsion ~ _distanceBetweenPoints/2 if _kRepulsion = 1. * But feel free to try others possibilities. * * \param _nbPtsMin Minimum number of points in group to do a simplification. Under this number all points are kept * \param _distanceBetweenPoints Parameter used to compute the number of simplified points needed. * Specify what would be the distance beetween two simplified points if the cluster would be a circle arc. * The arc length is approximated using (XY) bounding box of the cluster. * \param _kNeighborsParticle Number of neighboors to consider for particules attraction on original cloud * \param _radiusRepulsion Repulsion radius of a particule * \param _kRepulsion Multiplicative constant applied to repulsion radius * \param _convergeThresh Convergence threshold * \param _nbIterMax Maximum number of iteration to obtain convergence * \param _useOfOctree If true the algorithm use an PCL octree structure to optimize computing time * \param _octreeResolution Octree resolution (in m) * \param _nbPtsForUsingOctree Minimum number in cluster to activate octree optimisation (under this threshold octree is considered to expansive) * \param _multiThread If true use parallel computing (set to false if only one core is available on the computer) * * * Input Models: * * - CT_ResultGroup \n * (...) * - CT_StandardItemGroup... \n * - CT_PointCluster (Cluster of points) \n * * Output Models: * * - CT_ResultGroup \n * (...) * - CT_StandardItemGroup... \n * - cpy CT_PointCluster (Cluster of points) \n * - cpy+ CT_PointCluster (Particules) \n * */ class OL_StepThrowParticules05 : public CT_AbstractStep { // IMPORTANT pour avoir le nom de l'étape Q_OBJECT public: /*! \brief Step constructor * * Create a new instance of the step * * \param dataInit Step parameters object */ OL_StepThrowParticules05(CT_StepInitializeData &dataInit); /*! \brief Step description * * Return a description of the step function */ QString getStepDescription() const; /*! \brief Step copy * * Step copy, used when a step is added by step contextual menu */ CT_VirtualAbstractStep* createNewInstance(CT_StepInitializeData &dataInit); protected: /*! \brief Input results specification * * Specification of input results models needed by the step (IN) */ void createInResultModelListProtected(); /*! \brief Parameters DialogBox * * DialogBox asking for step parameters */ void createPostConfigurationDialog(); /*! \brief Output results specification * * Specification of output results models created by the step (OUT) */ void createOutResultModelListProtected(); /*! \brief Algorithm of the step * * Step computation, using input results, and creating output results */ void compute(); private: CT_AutoRenameModels _outParticulesModelName; CT_ResultGroup* _outRes; int _nbPtsMin; /** Nombre de points a partir duquel on opere une simplification sur le groupe */ double _distanceBetweenPoints; /** Distance entre deux points sur l'arc */ int _kNeighborsParticle; /** Nombre de voisins a prendre en compte lors de la projection des particules sur le nuage. */ double _radiusRepulsion; /** Rayon d'effet de la repulsion d'une particule sur les autres. */ int _kRepulsion; /** Constante entrant en jeu dans le calcul de la repulsion des particules entre elles. */ double _convergeThresh; /** Seuil pour dire si les particules ont converge ou non */ int _nbIterMax; /** Nombre d'iteration maximum sans convergence lors de la recherche des k-voisins */ bool _multiThread; bool _useOfOctree; /** Booleen qui indique si on souhaite utiliser un octree pour les gros groupes ou non */ double _octreeResolution; /** Resolution de l'octree pour la recherche des k-voisins */ int _nbPtsForUsingOctree; /** Nombre de points au dela duquel on utilise un octree lors de la simplification */ CT_PointCluster* simplifyPointCluster (const CT_PointCluster *inputGrp, double length); QList > createParticles(const CT_PointCluster *group, size_t n); #ifdef USE_PCL void projectParticles(const CT_PointCluster *inCluster, QList > &particles, size_t kNeighbors, pcl::octree::OctreePointCloudSearch *octree); #else void projectParticles(const CT_PointCluster *inCluster, QList > &particles, size_t kNeighbors); #endif void relaxParticles(QList > &particles, const double _repulsionRadius, const size_t kRepulsion); CT_Point computeParticleToParticleRepulsion(const CT_Point &query, const CT_Point &repulser, const double repulsionRadius, const size_t kRepulsion); bool hasConverged(const QList > &before, const QList > &after, const double convergeThresh); static void staticSimplifyPointCluster(CT_AbstractItemGroup *group); }; #endif // OL_STEPTHROWPARTICULES05_H