/**************************************************************************** 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_stepselectcellsingrid3dbybinarypattern.h" #include "ct_log/ct_logmanager.h" ONF_StepSelectCellsInGrid3DByBinaryPattern::ONF_StepSelectCellsInGrid3DByBinaryPattern() : SuperClass() { _inThreshold = 1; _pattern = "1,1,0,0,0\n" "1,1,0,0,0\n" "1,1,0,0,0\n" "1,1,0,0,0\n" "1,1,0,0,0\n" "1,0,0,0,0\n" "0,0,0,0,0\n" "0,0,0,0,0\n" "0,0,0,0,0\n" "0,0,0,0,0\n" "0,0,0,0,0\n" "0,0,0,0,0\n" "0,0,0,0,0\n"; _outThresholdAbsolute = 20; _outThresholdRelative = 0.9; _selectMode = 1; } QString ONF_StepSelectCellsInGrid3DByBinaryPattern::description() const { return tr("Créer Grille Booléenne à partir d'une Grille de Convolution"); } QString ONF_StepSelectCellsInGrid3DByBinaryPattern::detailledDescription() const { return tr(""); } QString ONF_StepSelectCellsInGrid3DByBinaryPattern::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepSelectCellsInGrid3DByBinaryPattern::detailsDescription() const { return tr(""); } QString ONF_StepSelectCellsInGrid3DByBinaryPattern::URL() const { //return tr("STEP URL HERE"); return SuperClass::URL(); //by default URL of the plugin } CT_VirtualAbstractStep* ONF_StepSelectCellsInGrid3DByBinaryPattern::createNewInstance() const { return new ONF_StepSelectCellsInGrid3DByBinaryPattern(); } //////////////////// PROTECTED METHODS ////////////////// void ONF_StepSelectCellsInGrid3DByBinaryPattern::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Grille")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inGrid, tr("Grille")); } void ONF_StepSelectCellsInGrid3DByBinaryPattern::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResult(_outResult, tr("Grille de séléction")); manager.setRootGroup(_outResult, _outGrp); manager.addItem(_outGrp, _outGrid, tr("Grille de comptage")); manager.addItem(_outGrp, _outGridBool, tr("Grille de séléction")); } void ONF_StepSelectCellsInGrid3DByBinaryPattern::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Valeur minimale de la grille d'entrée"), "", -1e+09, 1e+09, 4, _inThreshold, 1); postInputConfigDialog->addString(tr("Motif binaire"), "", _pattern); postInputConfigDialog->addEmpty(); postInputConfigDialog->addTitle(tr("Choix du mode de fitrage :")); CT_ButtonGroup &bg_gridMode = postInputConfigDialog->addButtonGroup(_selectMode); postInputConfigDialog->addExcludeValue("", "", tr("En valeur absolue :"), bg_gridMode, 0); postInputConfigDialog->addInt(tr("Seuil de séléction"), "", 0, 1e+09, _outThresholdAbsolute); postInputConfigDialog->addExcludeValue("", "", tr("En % de la valeur maximale :"), bg_gridMode, 1); postInputConfigDialog->addDouble(tr("Seuil de séléction (en % du max)"), "", 0, 100, 2, _outThresholdRelative, 100); } void ONF_StepSelectCellsInGrid3DByBinaryPattern::compute() { QList parsedPattern; if (!parsePattern(parsedPattern)) {return;} for (const CT_StandardItemGroup* group : _inGroup.iterateInputs(_inResult)) { if (isStopped()) {return;} const CT_AbstractGrid3D* inGrid = group->singularItem(_inGrid); if (inGrid != nullptr) { for (CT_ResultGroup* outResult : _outResult.iterateOutputs()) { CT_StandardItemGroup* grp = new CT_StandardItemGroup(); outResult->addRootGroup(_outGrp, grp); CT_Grid3D_Sparse* outGrid = new CT_Grid3D_Sparse(inGrid->minX(), inGrid->minY(), inGrid->minZ(), inGrid->xdim(), inGrid->ydim(), inGrid->zdim(), inGrid->resolution(), -1, -1); grp->addSingularItem(_outGrid, outGrid); const CT_Grid3D_Sparse* sparseInGrid = dynamic_cast*>(inGrid); if (sparseInGrid != nullptr) { QList indices; sparseInGrid->getIndicesWithData(indices); for (int i = 0 ; i < indices.size() ; i++) { size_t indexOut = indices.at(i); double sum = 0; int row, col, lev; if (inGrid->indexToGrid(indexOut, col, row, lev)) { if (inGrid->valueAtIndexAsDouble(indexOut) > 0) { QListIterator it(parsedPattern); while (it.hasNext()) { const PatternCell &pat = it.next(); size_t modifiedIndex; if (inGrid->index(col + pat._colRel, row + pat._rowRel, lev + pat._levRel, modifiedIndex)) { if (inGrid->valueAtIndexAsDouble(modifiedIndex) > _inThreshold) { sum += pat._val; } } } outGrid->setValueAtIndex(indexOut, sum); } } } } else { for (size_t indexOut = 0 ; indexOut < outGrid->nCells() ; indexOut++) { double sum = 0; int row, col, lev; if (inGrid->indexToGrid(indexOut, col, row, lev)) { if (inGrid->valueAtIndexAsDouble(indexOut) > 0) { QListIterator it(parsedPattern); while (it.hasNext()) { const PatternCell &pat = it.next(); size_t modifiedIndex; if (inGrid->index(col + pat._colRel, row + pat._rowRel, lev + pat._levRel, modifiedIndex)) { if (inGrid->valueAtIndexAsDouble(modifiedIndex) > _inThreshold) { sum += pat._val; } } } outGrid->setValueAtIndex(indexOut, sum); } } } } outGrid->computeMinMax(); CT_Grid3D_Sparse* outGridBool = new CT_Grid3D_Sparse(inGrid->minX(), inGrid->minY(), inGrid->minZ(), inGrid->xdim(), inGrid->ydim(), inGrid->zdim(), inGrid->resolution(), false, false); grp->addSingularItem(_outGridBool, outGridBool); int threshold = _outThresholdAbsolute; if (_selectMode == 1) { threshold = int(std::floor(outGrid->dataMax()*_outThresholdRelative)); } PS_LOG->addMessage(LogInterface::info, LogInterface::step, QString("Seuil de séléction : %1 (valeurs observées : %2 - %3)").arg(threshold).arg(outGrid->dataMin()).arg(outGrid->dataMax())); if (sparseInGrid != nullptr) { QList indices; sparseInGrid->getIndicesWithData(indices); for (int i = 0 ; i < indices.size() ; i++) { size_t indexOut = indices.at(i); double value = outGrid->valueAtIndexAsDouble(indexOut); if (value >= threshold) { outGridBool->setValueAtIndex(indexOut, true); } } } else { for (size_t indice = 0 ; indice < outGrid->nCells() ; indice++) { double value = outGrid->valueAtIndexAsDouble(indice); if (value >= threshold) { outGridBool->setValueAtIndex(indice, true); } } } setProgress(100.0); } } } } bool ONF_StepSelectCellsInGrid3DByBinaryPattern::parsePattern(QList &parsedPattern) { // Pattern parsing QStringList levels = _pattern.split("\n", Qt::SkipEmptyParts); int nlevels = levels.size(); if (nlevels < 1) {return false;} if (nlevels % 2 == 0) {return false;} int maxLevel = nlevels / 2; for (int lev = 0 ; lev < nlevels ; lev++) { int levelNumber = maxLevel - lev; QStringList cells = levels.at(lev).split(","); int ncells = cells.size(); if (ncells > 0) { bool ok; double val = cells.at(0).toDouble(&ok); if (ok && !qFuzzyIsNull(val)) { parsedPattern.append(PatternCell(0, 0, levelNumber, val)); } for (int c = 1 ; c < ncells ; c++) { val = cells.at(c).toDouble(&ok); if (ok && !qFuzzyIsNull(val)) { for (int j = -c ; j < c ; j++) { parsedPattern.append(PatternCell(-c, j, levelNumber, val)); parsedPattern.append(PatternCell( j, c, levelNumber, val)); parsedPattern.append(PatternCell( c, -j, levelNumber, val)); parsedPattern.append(PatternCell(-j, -c, levelNumber, val)); } } } } } return true; }