/**************************************************************************** Copyright (C) 2010-2021 the Office National des Forêts (ONF), France All rights reserved. Contact : alexandre.piboule@onf.fr Developers : Michael Krebbs (Independant) Alexandre PIBOULE (ONF) This file is part of PluginGenerate library. PluginGenerate 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. PluginGenerate 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 PluginGenerate. If not, see . *****************************************************************************/ #include "gen_stepgeneratetorus.h" #include #include #include "ct_math/ct_mathpoint.h" #define DEG_TO_RAD 0.01745329251 GEN_StepGenerateTorus::GEN_StepGenerateTorus() : SuperClass() { _centerX = 0; _centerY = 0; _centerZ = 0; _radiusCircle = 1; _distanceToCenter = 3; _alphaMin = 0; _alphaMax = 360; _betaMin = 0; _betaMax = 360; _resAlpha = 1; _resBeta = 1; _noiseAlpha = 0; _noiseBeta = 0; _noiseRadiusCircle = 0; _noiseDistanceToCenter = 0; } QString GEN_StepGenerateTorus::description() const { return tr("Créer un Torus de points"); } CT_VirtualAbstractStep* GEN_StepGenerateTorus::createNewInstance() const { return new GEN_StepGenerateTorus(); } //////////////////// PROTECTED METHODS ////////////////// void GEN_StepGenerateTorus::declareInputModels(CT_StepInModelStructureManager& manager) { manager.setNotNeedInputResult(); } void GEN_StepGenerateTorus::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResult(m_hOutResult, tr("Generated Point Cloud")); manager.setRootGroup(m_hOutResult, m_hOutRootGroup); manager.addItem(m_hOutRootGroup, m_hOutScene, tr("Generated Torus Cloud")); } void GEN_StepGenerateTorus::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addText(tr("Thore center"), "", ""); postInputConfigDialog->addDouble("X", "", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _centerX); postInputConfigDialog->addDouble("Y", "", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _centerY); postInputConfigDialog->addDouble("Z", "", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _centerZ); postInputConfigDialog->addText(tr("Thore radius"), "", ""); postInputConfigDialog->addDouble(tr("Circle radius"), "", 1e-10, std::numeric_limits::max(), 4, _radiusCircle); postInputConfigDialog->addDouble(tr("Distance to center"), "", 1e-10, std::numeric_limits::max(), 4, _distanceToCenter); postInputConfigDialog->addText(tr("Limits"), "", ""); postInputConfigDialog->addDouble(tr("Minimum alpha"), "°", 0, 359.9999, 4, _alphaMin, DEG_TO_RAD); postInputConfigDialog->addDouble(tr("Maximum alpha"), "°", 0, 360, 4, _alphaMax, DEG_TO_RAD); postInputConfigDialog->addDouble(tr("Minimum beta"), "°", 0, 359.9999, 4, _betaMin, DEG_TO_RAD); postInputConfigDialog->addDouble(tr("Maximum beta"), "°", 0, 360, 4, _betaMax, DEG_TO_RAD); postInputConfigDialog->addText(tr("Resolution"), "", ""); postInputConfigDialog->addDouble(tr("Alpha"), "°", 0.0001, std::numeric_limits::max(), 4, _resAlpha, DEG_TO_RAD); postInputConfigDialog->addDouble(tr("Beta"), "°", 0.0001, std::numeric_limits::max(), 4, _resBeta, DEG_TO_RAD); postInputConfigDialog->addText(tr("Add noise"), "", ""); postInputConfigDialog->addDouble(tr("Alpha"), "°", 0, std::numeric_limits::max(), 4, _noiseAlpha, DEG_TO_RAD); postInputConfigDialog->addDouble(tr("Beta"), "°", 0, std::numeric_limits::max(), 4, _noiseBeta, DEG_TO_RAD); postInputConfigDialog->addDouble(tr("Circle radius"), "", 0, std::numeric_limits::max(), 4, _noiseRadiusCircle); postInputConfigDialog->addDouble(tr("Distance to center"), "", 0, std::numeric_limits::max(), 4, _noiseDistanceToCenter); } void GEN_StepGenerateTorus::compute() { assert(_alphaMin < _alphaMax); if (_alphaMin >= _alphaMax) {qDebug() << "GEN_StepGenerateTorus::compute" << ", " << "_alphaMin >= _alphaMax";} assert(_betaMin < _betaMax); if (_betaMin >= _betaMax) {qDebug() << "GEN_StepGenerateTorus::compute" << ", " << "_betaMin >= _betaMax";} for(CT_ResultGroup* result : m_hOutResult.iterateOutputs()) { CT_StandardItemGroup* rootGroup = m_hOutRootGroup.createInstance(); result->addRootGroup(m_hOutRootGroup, rootGroup); // On initialise l'aleatoire pour le bruit par la suite srand(uint(time(nullptr))); int nbPts = 0; int nbPtsTheta = int(ceil((_alphaMax - _alphaMin) / _resAlpha)); int nbPtsPhi = int(ceil((_betaMax - _betaMin) / _resBeta)); int nbPtsTotal = nbPtsPhi * nbPtsTheta; CT_AbstractUndefinedSizePointCloud *undepositPointCloud = PS_REPOSITORY->createNewUndefinedSizePointCloud(); // Construction du tore double valAlpha, valBeta, valRadius, valDistance; for (double i = _alphaMin ; (i < _alphaMax) && !isStopped() ; i += _resAlpha) { for (double j = _betaMin ; (j <= _betaMax) && !isStopped() ; j += _resBeta) { // On ajoute un point en tenant compte de la variabilité en epsilone valAlpha = i - _noiseAlpha + ((double(rand())/RAND_MAX) * 2 * _noiseAlpha); valBeta = j - _noiseBeta + ((double(rand())/RAND_MAX) * 2 * _noiseBeta); valRadius = _radiusCircle - _noiseRadiusCircle + ((double(rand())/RAND_MAX) * 2 * _noiseRadiusCircle); valDistance = _distanceToCenter - _noiseDistanceToCenter + ((double(rand())/RAND_MAX) * 2 * _noiseDistanceToCenter); undepositPointCloud->addPoint(Eigen::Vector3d((valDistance + valRadius * cos(valAlpha)) * cos(valBeta), (valDistance + valRadius * cos(valAlpha)) * sin(valBeta), valRadius * sin(valAlpha))); nbPts++; // Barre de progression (multiplie par 100/6 parce qu'on a huit face et qu'on est a la premiere setProgress(100.0f*float(nbPts) / float(nbPtsTotal)); // On regarde si on est en debug mode waitForAckIfInDebugMode(); } } // On enregistre le nuage de points cree dans le depot CT_NMPCIR depositPointCloud = PS_REPOSITORY->registerUndefinedSizePointCloud(undepositPointCloud); if(!isStopped()) { CT_Scene* itemOut_scene = new CT_Scene(depositPointCloud); itemOut_scene->updateBoundingBox(); rootGroup->addSingularItem(m_hOutScene, itemOut_scene); } } }