Cette section vous explique en détails comment :
Lors du lancement de l’application le système crée un vecteur de points qui contiendra l’ensemble des points créés dans vos étapes / readers.
Voici par exemple le nuage de point global qui contient les points de 3 scènes différentes (créées à partir de 3 étapes différentes) :
La classe CT_Scene ne retient qu’une liste de tous les indices des points créés (classe CT_NMPCIR). Par exemple :
Le nuage de points global contient 2504 points au total.
En utilisant ce système il a fallu mettre en place un élément qui va synchroniser les nuages d’indices si certains points sont supprimés du nuage de points global.
Par exemple si la scène 2 est supprimée de la mémoire il va falloir synchroniser les indices de la scène 3 puisqu’il ne correspondront plus avec les bon points. Pour cela le système va décaler tous les indices de la scène 3 automatiquement lorsque la scène 2 est supprimée. Vous n’avez donc pas à vous préoccuper de cet aspect puisqu’il est gérer automatiquement et est totalement transparent.
En interne le système stocke les points dans le nuage de points global en utilisant le type CT_PointData qui est une classe dérivant de Eigen::Vector3f.
En effet OpenGL n’utilise pas le type double pour dessiner des points. De ce fait, en considérant une précision au mm, les coordonnées peuvent aller de -16 777, 216 m à 16 777, 216 m. Ce qui signifie qu’on ne peut avoir des scènes excédant 32 km de diamètre à cette précision, et que des données en projection géographique dont les coordonnées sont en million de mètres perdent (fortement) en précision. Lors de l’affichage en 3D d’une scène dépassant la précision d’un float les points “sautent” d’un endroit à l’autre puisqu’OpenGL arrondi les valeurs.
Les systèmes de coordonnées sont des éléments qui transforment les points à la lecture et à l’export pour ne pas perdre en précision lors de l’affichage. Ce chapitre n’est qu’à titre d’information puisque l’utilisation des systèmes de coordonnées est totalement transparent pour le développeur.
A l’affichage, lors des traitements ou lors de l’exportation les points sont convertis (float → double) automatiquement en utilisant les systèmes de coordonnées pour que la précision ne soit pas perdu.
Afin de rendre transparent la conversion d’un point interne vers sa représentation en double nous avons créé la classe CT_Point qui dérive de Eigen::Vector3d (double) et qui est renvoyé par les objets permettant d’accéder aux point d’un nuage. Un CT_PointData est automatiquement convertit en un CT_Point à l’aide de son système de coordonnée assigné. Nous verrons dans un prochain chapitre comment récupérer facilement un CT_Point.
Dans cet exemple nous allons voir comment créer un nouveau nuage de points dont la taille est connue par avance.
// variable qui va contenir le nombre de points (lu dans le fichier) size_t size = 0; // initialisation pour la lecture du fichier ....... // création du nuage de point. On récupère le nuage d'indice des points créés qu'il faudra donner à la scène. CT_NMPCIR pcir = PS_REPOSITORY->createNewPointCloud(size); // création d'un itérateur qui va permettre de parcourir les points créés et les modifier CT_MutablePointIterator it(pcir); // tant qu'il y a des points à parcourir et tant que l'utilisateur n'a pas stoppé le traitement while(it.hasNext() && !isStopped()) { // récupération du point du fichier CT_Point p = nextPointInFile(); // passe au point suivant du nuage it.next(); // modification du point courant afin qu'il prenne la nouvelle valeur et utilise le système de coordonnée passés en paramètre it.replaceCurrentPoint(p); } // création de la scène CT_Scene *scene = new CT_Scene(....); // définit les indices des points que la scène doit dessiner scene->setPointCloudIndexRegistered(pcir);
Dans cet exemple nous allons voir comment créer un nouveau nuage de points dont la taille n’est pas connue par avance.
// initialisation pour la lecture du fichier ....... // Demande de création d'un nuage de points dont la taille est inconnu CT_AbstractUndefinedSizePointCloud *cloud = PS_REPOSITORY->createNewUndefinedSizePointCloud(); // tant qu'il y a des points dans le fichier à parcourir et tant que l'utilisateur n'a pas stoppé le traitement while(hasNextPointInFile() && !isStopped()) { // récupération du point du fichier CT_Point p = nextPointInFile(); // ajout du point avec l'indice du système de coordonnée qu'il doit utiliser cloud->addPoint(p); } // récupération du nuage d'indice des points qu'on vient de créer CT_NMPCIR pcir = PS_REPOSITORY->registerUndefinedSizePointCloud(cloud); // création de la scène CT_Scene *scene = new CT_Scene(....); // définit les indices des points que la scène doit dessiner scene->setPointCloudIndexRegistered(pcir);
Lorsque vous récupérer un nuage d’indices d’une scène (par exemple) et que vous souhaitez parcourir les points il vous faut utiliser un itérateur de lecture.
// on récupère le nuage d'indices de la scène CT_PCIR pcir = scene->getPointCloudIndexRegistered(); // création de l'itérateur CT_PointIterator it(pcir); // parcours tant qu'il y a des points et tant que l'utilisateur n'a pas stoppé le traitement while(it.hasNext() && !isStopped()) { it.next(); // récupération du point const CT_Point &p = it.currentPoint(); // on peut si l'on veut récupérer son index dans le nuage global size_t globalIndex = it.currentGlobalIndex(); // traitement ....... }
Si vous voulez accéder directement à un point à partir de son indice global voici l’exemple qui vous montre comment faire :
// on crée un objet qui permet d'accéder au nuage de point global CT_PointAccessor pAccess; while(...) { // traitement ..... // récupération d'un point à partir de son indice global CT_Point point = pAccess.pointAt(globalIndex); }