/**************************************************************************** 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_stepextractpointsforplots.h" #include "ct_log/ct_logmanager.h" ONF_StepExtractPointsForPlots::ONF_StepExtractPointsForPlots() : SuperClass() { _cellSize = 50.0; } QString ONF_StepExtractPointsForPlots::description() const { return tr("Extraire les points par placette"); } QString ONF_StepExtractPointsForPlots::detailledDescription() const { return tr(""); } QString ONF_StepExtractPointsForPlots::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepExtractPointsForPlots::detailsDescription() const { return tr(""); } QString ONF_StepExtractPointsForPlots::URL() const { //return tr("STEP URL HERE"); return SuperClass::URL(); //by default URL of the plugin } CT_VirtualAbstractStep* ONF_StepExtractPointsForPlots::createNewInstance() const { return new ONF_StepExtractPointsForPlots(); } //////////////////// PROTECTED METHODS ////////////////// void ONF_StepExtractPointsForPlots::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Placettes"), tr(""), true); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGrpScene, tr("Groupe Scene")); manager.addItem(_inGrpScene, _inScene, tr("Scène complete")); manager.addGroup(_inGrpScene, _inGrpPlot, tr("Groupe Placette")); manager.addItem(_inGrpPlot, _inPlot, tr("Emprise placette")); } void ONF_StepExtractPointsForPlots::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGrpPlot, _outPoints, tr("Points")); } void ONF_StepExtractPointsForPlots::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Taille de la cellule pour l'optimisation"), "m", 0, 1e+5, 2, _cellSize); } void ONF_StepExtractPointsForPlots::compute() { for (CT_StandardItemGroup* groupScene : _inGrpScene.iterateOutputs(_inResult)) { const CT_AbstractItemDrawableWithPointCloud* inScene = groupScene->singularItem(_inScene); if (inScene != nullptr) { QMap shapes; QList shapesList; QList plotPointsIndicesList; double xmin = std::numeric_limits::max(); double ymin = std::numeric_limits::max(); double xmax = -std::numeric_limits::max(); double ymax = -std::numeric_limits::max(); for (const CT_StandardItemGroup* groupPlot : groupScene->groups(_inGrpPlot)) { if (isStopped()) {return;} const CT_AbstractAreaShape2D* areaShape = groupPlot->singularItem(_inPlot); if (areaShape != nullptr) { if (areaShape->minX() < xmin) {xmin = areaShape->minX();} if (areaShape->minY() < ymin) {ymin = areaShape->minY();} if (areaShape->maxX() > xmax) {xmax = areaShape->maxX();} if (areaShape->maxY() > ymax) {ymax = areaShape->maxY();} shapesList.append(areaShape); plotPointsIndicesList.append(PlotPointsIndices(const_cast(groupPlot))); } } int sizeShapes = shapesList.size(); if (sizeShapes <= 0) {return;} // Construction of quadTree xmin -= _cellSize; ymin -= _cellSize; xmax += _cellSize; ymax += _cellSize; CT_Image2D* quadTree = CT_Image2D::createImage2DFromXYCoords(xmin, ymin, xmax, ymax, _cellSize, 0, -1, -1); for (size_t index = 0 ; index < quadTree->nCells() ; index++) { quadTree->setValueAtIndex(index,int(index)); } QVector > shapeLists(int(quadTree->nCells())); for (int sh = 0 ; sh < sizeShapes ; sh++) { const CT_AbstractAreaShape2D* shape = shapesList.at(sh); Eigen::Vector3d min, max; shape->boundingBox(min, max); int colB, colE, linB, linE; if (!quadTree->xcol(min(0), colB)) {colB = 0;} if (!quadTree->xcol(max(0), colE)) {colE = quadTree->xdim() - 1;} if (!quadTree->lin(min(1), linE)) {linE = quadTree->ydim() - 1;} if (!quadTree->lin(max(1), linB)) {linB = 0;} for (int cc = colB; cc <= colE ; cc++) { for (int ll = linB ; ll <= linE ; ll++) { int shIdx = quadTree->value(cc, ll); shapeLists[shIdx].append(sh); } } } setProgress(10); const CT_AbstractPointCloudIndex *pointCloudIndex = inScene->pointCloudIndex(); size_t sizeCloud = pointCloudIndex->size(); PS_LOG->addInfoMessage(LogInterface::step, tr("Le nuage de points contient %1 points").arg(sizeCloud)); size_t cpt = 0; CT_PointIterator itP(pointCloudIndex); while(itP.hasNext() && (!isStopped())) { const CT_Point &point = itP.next().currentPoint(); size_t index = itP.currentGlobalIndex(); int shIdx = quadTree->valueAtCoords(point(0), point(1)); if (shIdx >= 0) { const QList &shNumberList = shapeLists.at(shIdx); for (int sh = 0 ; sh < shNumberList.size() ; sh++) { int shNum = shNumberList.at(sh); if (shapesList.at(shNum)->contains(point(0), point(1))) { plotPointsIndicesList[shNum]._indices->addIndex(index); } } } setProgress(10.0f + 79.0f*(float(cpt++) / float(sizeCloud))); } delete quadTree; setProgress(90); cpt = 0; for (int sh = 0 ; sh < sizeShapes ; sh++) { PlotPointsIndices& plotPointsIndices = plotPointsIndicesList[sh]; CT_StandardItemGroup* grpSh = plotPointsIndices._group; CT_PointCloudIndexVector *plotPointCloudIndex = plotPointsIndices._indices; // if (plotPointCloudIndex->size() > 0) // { plotPointCloudIndex->setSortType(CT_PointCloudIndexVector::SortedInAscendingOrder); CT_Scene* plotScene = new CT_Scene(PS_REPOSITORY->registerPointCloudIndex(plotPointCloudIndex)); plotScene->updateBoundingBox(); grpSh->addSingularItem(_outPoints, plotScene); // } else { // delete plotPointCloudIndex; // } setProgress(90.0f + 9.0f*(float(cpt++) / float(sizeShapes))); } setProgress(99); } } }