#include "tk_steprotatecloud.h" // Utilise le depot #include "ct_global/ct_context.h" #include "ct_math/ct_mathpoint.h" #include "ct_view/ct_stepconfigurabledialog.h" #include "ct_result/model/inModel/ct_inresultmodelgroup.h" #include "ct_result/model/outModel/ct_outresultmodelgroup.h" #include "ct_result/model/inModel/ct_inresultmodelgrouptocopy.h" #include "ct_result/model/outModel/ct_outresultmodelgroupcopy.h" #include "ct_result/model/outModel/tools/ct_outresultmodelgrouptocopypossibilities.h" // Inclusion of standard result class #include "ct_result/ct_resultgroup.h" // Inclusion of used ItemDrawable classes #include "ct_itemdrawable/ct_scene.h" #include "ct_iterator/ct_pointiterator.h" #include "ct_iterator/ct_mutablepointiterator.h" // Alias for indexing in models #define DEF_resultIn_inputResult "inputResult" #define DEF_groupIn_inputScene "inputGroup" #define DEF_itemIn_scene "inputScene" #include #include "Eigen/Geometry" #define RAD_TO_DEG 57.2957795131 #define DEG_TO_RAD 0.01745329251 // Constructor : initialization of parameters TK_StepRotateCloud::TK_StepRotateCloud(CT_StepInitializeData &dataInit) : CT_AbstractStep(dataInit) { _alpha = 0; _axisX = 0; _axisY = 0; _axisZ = 1; _x = 0; _y = 0; _z = 0; // Cette etape est CT_debugable setDebuggable( true ); } // Step description (tooltip of contextual menu) QString TK_StepRotateCloud::getStepDescription() const { return tr("Rotation des points"); } // Step copy method CT_VirtualAbstractStep* TK_StepRotateCloud::createNewInstance(CT_StepInitializeData &dataInit) { return new TK_StepRotateCloud(dataInit); } //////////////////// PROTECTED METHODS ////////////////// // Creation and affiliation of IN models void TK_StepRotateCloud::createInResultModelListProtected() { CT_InResultModelGroupToCopy *resultModel = createNewInResultModelForCopy(DEF_resultIn_inputResult, tr("Scene(s)")); resultModel->setZeroOrMoreRootGroup(); resultModel->addGroupModel("", DEF_groupIn_inputScene, CT_AbstractItemGroup::staticGetType(), tr("Group")); resultModel->addItemModel(DEF_groupIn_inputScene, DEF_itemIn_scene, CT_Scene::staticGetType(), tr("Scene(s)")); } // Creation and affiliation of OUT models void TK_StepRotateCloud::createOutResultModelListProtected() { CT_OutResultModelGroupToCopyPossibilities *resultModel = createNewOutResultModelToCopy(DEF_resultIn_inputResult); if (resultModel != NULL) { resultModel->addItemModel(DEF_groupIn_inputScene, _outSceneModelName, new CT_Scene(), tr("Rotated Scene")); } } // Semi-automatic creation of step parameters DialogBox void TK_StepRotateCloud::createPostConfigurationDialog() { CT_StepConfigurableDialog *configDialog = newStandardPostConfigurationDialog(); configDialog->addDouble(tr("Angle de rotation"), "", -360, 360, 4, _alpha); configDialog->addText(tr("Axe de rotation (direction)"), "", ""); configDialog->addDouble("X", "", -1e+10, 1e+10, 4, _axisX); configDialog->addDouble("Y", "", -1e+10, 1e+10, 4, _axisY); configDialog->addDouble("Z", "", -1e+10, 1e+10, 4, _axisZ); configDialog->addText(tr("Point sur l'axe"), "", ""); configDialog->addDouble("X", "", -1e+10, 1e+10, 4, _x); configDialog->addDouble("Y", "", -1e+10, 1e+10, 4, _y); configDialog->addDouble("Z", "", -1e+10, 1e+10, 4, _z); } void TK_StepRotateCloud::compute() { CT_ResultGroup *outResult = getOutResultList().first(); CT_ResultGroupIterator it(outResult, this, DEF_groupIn_inputScene); while(!isStopped() && it.hasNext()) { CT_StandardItemGroup *group = (CT_StandardItemGroup*) it.next(); if (group != NULL) { const CT_Scene* itemIn_scene = (CT_Scene*) group->firstItemByINModelName(this, DEF_itemIn_scene); const CT_AbstractPointCloudIndex *cloudIndex = itemIn_scene->getPointCloudIndex(); CT_PointIterator itP(cloudIndex); // Cloud bounding box Eigen::Vector3d bboxBot; Eigen::Vector3d bboxTop; for ( int i = 0 ; i < 3 ; i++ ) { bboxBot[i] = std::numeric_limits::max(); bboxTop[i] = -std::numeric_limits::max(); } // On cree le vecteur d'axe de rotation et le vecteur du centre de rotation Eigen::Vector3d axisVector( _axisX, _axisY, _axisZ ); Eigen::Vector3d center( _x, _y, _z ); double alpha = _alpha * DEG_TO_RAD; Eigen::Affine3d transformation(Eigen::AngleAxisd(alpha, axisVector)); // On Cree un nouveau nuage qui sera le translate CT_NMPCIR rotatedCloud = PS_REPOSITORY->createNewPointCloud(cloudIndex->size()); CT_MutablePointIterator itPM(rotatedCloud); size_t i = 0; // On applique la translation a tous les points du nuage while (itP.hasNext() && itPM.hasNext()) { itP.next(); CT_Point point = itP.currentPoint(); // Translation au centre point = point - center; // Rotation point = transformation * point; // Translation inverse point += center; // Update BBox for ( int j = 0 ; j < 3 ; j++ ) { if ( point[j] < bboxBot[j] ) { bboxBot[j] = point[j]; } if ( point[j] > bboxTop[j] ) { bboxTop[j] = point[j]; } } itPM.next().replaceCurrentPoint(point); // Barre de progression setProgress( 100.0*i++ /cloudIndex->size() ); // On regarde si on est en debug mode waitForAckIfInDebugMode(); } CT_Scene* itemOut_scene = new CT_Scene(_outSceneModelName.completeName(), outResult, rotatedCloud); itemOut_scene->setBoundingBox( bboxBot(0), bboxBot(1), bboxBot(2), bboxTop(0), bboxTop(1), bboxTop(2) ); group->addItemDrawable(itemOut_scene); } } }