EX> // Inclusion du fichier d'entête EX> #include "{{CODE_LOWER}}_step{{NAME_LOWER}}.h" EX> EX> // Inclure ensuite les éventuelles classes de définitions nécessaires à votre étape EX> #include "ct_itemdrawable/ct_scene.h" EX> #include "ct_itemdrawable/ct_pointcluster.h" EX> EX> // Pour les vecteurs en 3D EX> #include EX> EX> // Pour afficher des messages à la console EX> #include EX> EX> // Pour inclure certaines fonctions mathématiques EX> #include EX> EX> // Constructeur : appel du constructeur de la classe mère EX> // et initialisation des paramètres (valeurs par défaut) EX> {{CODE_UPPER}}_Step{{NAME}}::{{CODE_UPPER}}_Step{{NAME}}() : SuperClass() EX> { EX> _nx = 3; EX> _ny = 3; EX> _nz = 3; EX> } EX> EX> // Destructeur EX> {{CODE_UPPER}}_Step{{NAME}}::~{{CODE_UPPER}}_Step{{NAME}}() EX> { EX> } EX> EX> // Description de l'étape (tooltip du menu contextuel) EX> QString {{CODE_UPPER}}_Step{{NAME}}::description() const EX> { EX> return QString(tr("Découpe une scène de points")); EX> } EX> EX> // Description détaillée de l'étape (dans le menu de description) EX> QString {{CODE_UPPER}}_Step{{NAME}}::detailledDescription() const EX> { EX> return QString(tr("Découpe une scène de points en groupes paralellepipediques")); EX> } EX> EX> // Méthode de recopie de l'étape EX> CT_VirtualAbstractStep* {{CODE_UPPER}}_Step{{NAME}}::createNewInstance() const EX> { EX> // cree une copie de cette étape EX> return new {{CODE_UPPER}}_Step{{NAME}}(); EX> } EX> EX> // Création et affiliation des modèles IN EX> void {{CODE_UPPER}}_Step{{NAME}}::declareInputModels(CT_StepInModelStructureManager& manager) EX> { EX> // On se base sur les résultats entrants EX> manager.addResult(_inResult, tr("Scène(s)")); EX> // Déclaration et création du modèle de groupe de référence EX> manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); EX> // Déclaration et création du modèle de groupe EX> manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); EX> // On ajoute le modèle d'item au modèle du groupe racine (le type d'item sera automatiquement déduit) EX> manager.addItem(_inGroup, _inScene, tr("Scène source")); EX> } EX> EX> // Création et affiliation des modèles OUT EX> void {{CODE_UPPER}}_Step{{NAME}}::declareOutputModels(CT_StepOutModelStructureManager& manager) EX> { EX> // On se base sur les résultats entrants (copie) EX> manager.addResultCopy(_inResult); EX> // Déclaration et création du modèle de groupe EX> manager.addGroup(_inGroup, _outGroup); EX> // On ajoute le modèle d'item au modèle du groupe racine (le type d'item sera automatiquement déduit) EX> manager.addItem(_outGroup, _outScene, tr("Scène extraite")); EX> } EX> EX> // Création semi-automatique de la boite de dialogue de paramétrage de l'étape EX> void {{CODE_UPPER}}_Step{{NAME}}::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) EX> { EX> // Ajout de contrôles unitaires de paramètrages à la boite (un par paramètre en général) EX> postInputConfigDialog->addInt("Nombre clusters selon x", "", 1, 100, _nx); EX> postInputConfigDialog->addInt("Nombre clusters selon y", "", 1, 100, _ny); EX> postInputConfigDialog->addInt("Nombre clusters selon z", "", 1, 100, _nz); EX> } EX> EX> // Etape de calcul, créant les données des résultats de sortie EX> void {{CODE_UPPER}}_Step{{NAME}}::compute() EX> { EX> // Ici on peut faire quelques initialisations et/ou calculs préliminaires EX> EX> // Récupération de la liste des groupes d'entrée et leurs items EX> // L'ordre dans cette liste est celui des ajouts successifs EX> for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) EX> { EX> for (const CT_AbstractItemDrawableWithPointCloud* inScene : group->singularItems(_inScene)) EX> { EX> if (isStopped()) EX> return; EX> EX> // Ici on peut faire d'autre calculs préliminaires pour l'item en cours EX> EX> // Récupération des limites min et max en (x,y,z) de la scène d'entrée EX> Eigen::Vector3d min, max; EX> inScene->boundingBox(min, max); EX> EX> // Calcul de la taille des clusters EX> float xClusterSize = (max.x() - min.x())/_nx; EX> float yClusterSize = (max.y() - min.y())/_ny; EX> float zClusterSize = (max.z() - min.z())/_nz; EX> EX> // On Cree un nouveau tableau qui stockera les nuages EX> QVector extractedCloud; EX> extractedCloud.resize(_nx*_ny*_nz); EX> EX> const CT_AbstractPointCloudIndex *pointCloudIndex = inScene->pointCloudIndex(); EX> CT_PointIterator itP(pointCloudIndex); EX> EX> size_t nbPoints = pointCloudIndex->size(); EX> size_t i = 0; EX> EX> while (itP.hasNext()) EX> { EX> if (isStopped()) EX> return; EX> EX> const CT_Point &point = itP.next().currentPoint(); EX> size_t point_index = itP.currentGlobalIndex(); EX> EX> // Calcul des indices x, y et z du cluster où affecter le point EX> int blockX = (int) floor((point.x() - min.x()) / xClusterSize); EX> int blockY = (int) floor((point.y() - min.y()) / yClusterSize); EX> int blockZ = (int) floor((point.z() - min.z()) / zClusterSize); EX> EX> // Indice dans le tableau de clusters EX> int block = blockX + blockY*_nx + blockZ*_nx*_ny; EX> EX> // Si le cluster n'existe pas on le créée EX> if (extractedCloud[block]==NULL) EX> extractedCloud[block] = new CT_PointCluster(); EX> EX> // Ajout du point au cluster (son index en fait) EX> extractedCloud[block]->addPoint(point_index, false); EX> EX> // On fait avancer le % de progression (ici par rapport au nombre de points traités sur le total) EX> setProgress(float(100.0 * i++ / nbPoints)); EX> } EX> EX> // On parcourt les clusters créés EX> for (int k = 0 ; k < extractedCloud.size() ; k++) EX> { EX> // Création du cluster, qui est un morceau de la scène EX> CT_PointCluster* cluster = extractedCloud[k]; EX> EX> if (cluster!=NULL) EX> { EX> // On ajuste les limites EX> cluster->updateBoundingBox(); EX> EX> // Création du groupe contenant le(s) item(s) EX> CT_StandardItemGroup* outGroup = new CT_StandardItemGroup(); EX> EX> // Ajout du groupe au résultat (AVANT d'ajouter l'item !) EX> group->addGroup(_outGroup, outGroup); EX> EX> // Ajout de l'item au groupe EX> outGroup->addSingularItem(_outScene, cluster); EX> } EX> } EX> } EX> } EX> }