/**************************************************************************** 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_stepsmoothskeleton.h" #include "ct_shapedata/ct_linedata.h" ONF_StepSmoothSkeleton::ONF_StepSmoothSkeleton() : SuperClass() { } QString ONF_StepSmoothSkeleton::description() const { return tr("Lisser une séquence de points de référence"); } QString ONF_StepSmoothSkeleton::detailledDescription() const { return tr(""); } QString ONF_StepSmoothSkeleton::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepSmoothSkeleton::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepSmoothSkeleton::createNewInstance() const { // cree une copie de cette etape return new ONF_StepSmoothSkeleton(); } //////////////////// PROTECTED ////////////////// void ONF_StepSmoothSkeleton::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Billons / Clusters / Points de référence")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroupSection, tr("Billon (Grp)")); manager.addGroup(_inGroupSection, _inGroup, tr("Cluster (Grp)")); manager.addItem(_inGroup, _inRefPoint, tr("Point de référence")); } void ONF_StepSmoothSkeleton::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _outRefPoint, tr("Point de référence (lissé)")); } void ONF_StepSmoothSkeleton::compute() { for (CT_StandardItemGroup* section : _inGroupSection.iterateOutputs(_inResult)) { QList refPoints; QList outRefPoints; QMap groups; for (const CT_StandardItemGroup* group : section->groups(_inGroup)) { const CT_ReferencePoint* refPoint = group->singularItem(_inRefPoint); refPoints.append(refPoint); groups.insert(refPoint, const_cast(group)); } Eigen::Vector3d vert(0,0,1); // verticale CT_ReferencePoint* mp = nullptr; double xm = 0; double ym = 0; double zm = 0; int size = refPoints.size(); if (size==0) {return;} // lissage des points autres que les extrêmes for (int i = 1 ; i < (size-1) ; i++) { const CT_ReferencePoint* p1 = refPoints.at(i-1); const CT_ReferencePoint* p2 = refPoints.at(i); const CT_ReferencePoint* p3 = refPoints.at(i+1); CT_LineData line(Eigen::Vector3d(p1->x(), p1->y(), p1->z()), Eigen::Vector3d(p3->x(), p3->y(), p3->z())); if (line.intersectionWithRect3D(p2->x(), p2->y(), p2->z(), vert, &xm, &ym, &zm)) { xm = (xm + p2->x())/2; ym = (ym + p2->y())/2; zm = p2->z(); mp = new CT_ReferencePoint(xm, ym, zm, p2->xyBuffer()); } else { qDebug() << "Problème : Pas d'intersection trouvée, RefID=" << p2->refId(); mp = new CT_ReferencePoint(*p2); } outRefPoints.append(mp); groups.value(p2)->addSingularItem(_outRefPoint, mp); } // Gestion des premier et dernier points const CT_ReferencePoint* firstIn = refPoints.first(); const CT_ReferencePoint* lastIn = refPoints.last(); CT_ReferencePoint* firstOut = nullptr; CT_ReferencePoint* lastOut = nullptr; int sizeOut = outRefPoints.size(); if (size <= 2) { firstOut = new CT_ReferencePoint(*firstIn); groups.value(firstIn)->addSingularItem(_outRefPoint, firstOut); } if (size == 2 || size==3) { lastOut = new CT_ReferencePoint(*lastIn); groups.value(lastIn)->addSingularItem(_outRefPoint, lastOut); } if (size > 3) { CT_ReferencePoint* p1 = outRefPoints.at(0); CT_ReferencePoint* p2 = outRefPoints.at(1); CT_LineData lineF(Eigen::Vector3d(p1->x(), p1->y(), p1->z()), Eigen::Vector3d(p2->x(), p2->y(), p2->z())); if (lineF.intersectionWithRect3D(firstIn->x(), firstIn->y(), firstIn->z(), vert, &xm, &ym, &zm)) { firstOut = new CT_ReferencePoint(xm, ym, zm, firstIn->xyBuffer()); } else { qDebug() << "Problème : Pas d'intersection trouvée, RefID=" << firstIn->refId(); firstOut = new CT_ReferencePoint(*firstIn); } groups.value(firstIn)->addSingularItem(_outRefPoint, firstOut); CT_ReferencePoint* p3 = outRefPoints.at(sizeOut-2); CT_ReferencePoint* p4 = outRefPoints.at(sizeOut-1); CT_LineData lineL(Eigen::Vector3d(p3->x(), p3->y(), p3->z()), Eigen::Vector3d(p4->x(), p4->y(), p4->z())); if (lineL.intersectionWithRect3D(lastIn->x(), lastIn->y(), lastIn->z(), vert, &xm, &ym, &zm)) { lastOut = new CT_ReferencePoint(xm, ym, zm, firstIn->xyBuffer()); } else { qDebug() << "Problème : Pas d'intersection trouvée, RefID=" << lastIn->refId(); lastOut = new CT_ReferencePoint(*lastIn); } groups.value(lastIn)->addSingularItem(_outRefPoint, lastOut); } } }