#ifndef CT_GLOBALCLOUDMANAGERT_HPP #define CT_GLOBALCLOUDMANAGERT_HPP #include "ct_cloud/tools/ct_globalcloudmanagert.h" #include "ct_cloudindex/ct_cloudindexstdvectort.h" #include "ct_cloudindex/registered/ct_standardnotmodifiablecloudindexregisteredt.h" template CT_GlobalCloudManagerT::CT_GlobalCloudManagerT() : CT_AbstractGlobalCloudManagerT() { m_nCallToMultipleDelete = 0; } template template< class IndexMemoryOptim, class IndexAccessOptim > typename CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR CT_GlobalCloudManagerT::createNewCloud(size_t size, typename CT_AbstractGlobalCloudManagerT::IndexOptimization optim) { size_t beginIndex = m_cloud.size(); // redimensionne le nuage de points global m_cloud.resize(m_cloud.size() + size); // retourne un nuage d'index enregistré return createCIR(beginIndex, size, optim); } template template< class IndexMemoryOptim, class IndexAccessOptim > typename CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR CT_GlobalCloudManagerT::copyCloud(typename CT_GlobalCloudManagerT::CT_AbstractCIR cir, typename CT_AbstractGlobalCloudManagerT::IndexOptimization optim) { size_t beginIndex = m_cloud.size(); size_t size = cir->size(); // redimensionne le nuage de points global pour ajouter les nouveaux points m_cloud.resize(beginIndex + size); // crée un nuage de points enregistré (il contient le nuage de points global et le nuage d'index) CT_AbstractNotModifiableCIR newCir = createCIR(beginIndex, size, optim); // puis on recopie les points // si c'est un nuage non modifiable const CT_AbstractNotModifiableCloudIndexRegisteredT *cirNotModifiable = dynamic_cast< const CT_AbstractNotModifiableCloudIndexRegisteredT* >(cir.data()); if(cirNotModifiable != NULL) { // celui-ci contient juste le début et la taille du nuage de points // dont on peut recopier les données plus rapidement // internalCopyData(index de destination, index de source, taille) m_cloud.internalCopyData(beginIndex, cirNotModifiable->first(), size); } // sinon else { const CT_AbstractCloudIndexT *sourceIndex = cir->abstractCloudIndexT(); // on boucle sur les index pour la copie size_t p = beginIndex; for(size_t i=0; i template< class IndexMemoryOptim, class IndexAccessOptim > typename CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR CT_GlobalCloudManagerT::copyCloud(const CT_AbstractCloudIndexT *index, typename CT_AbstractGlobalCloudManagerT::IndexOptimization optim) { size_t beginIndex = m_cloud.size(); size_t size = index->size(); // redimensionne le nuage de points global pour ajouter les nouveaux points m_cloud.resize(beginIndex + size); // crée un nuage de points enregistré (il contient le nuage de points global et le nuage d'index) CT_AbstractNotModifiableCIR newCir = createCIR(beginIndex, size, optim); // puis on recopie les points // on boucle sur les index pour la copie size_t p = beginIndex; for(size_t i=0; i typename CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR CT_GlobalCloudManagerT::resizeCloudAndCloudIndex(typename CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR cir, const size_t &newSize) { size_t s = newSize - cir->abstractCloudIndexT()->size(); if(!this->m_cirArray.contains(cir.data()) || (cir->last() != (m_cloud.size()-1))) return CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR(NULL); cir->abstractCloudIndexT()->resize(newSize); // informe les gestionnaire de synchronisation de nuage qu'un nouveau nuage a été ajouté this->informThatCloudAdded(s); m_cloud.resize(m_cloud.size() + s); return cir; } template CT_AbstractCloud *CT_GlobalCloudManagerT::globalAbstractCloud() const { return (CT_AbstractCloud*)&m_cloud; } template CT_AbstractCloudT* CT_GlobalCloudManagerT::globalAbstractCloudT() const { return (CT_AbstractCloudT*)&m_cloud; } template CLOUD* CT_GlobalCloudManagerT::globalCloud() const { return (CLOUD*)&m_cloud; } template void CT_GlobalCloudManagerT::beginMultiDelete() { ++m_nCallToMultipleDelete; if(m_nCallToMultipleDelete == 1) this->lockAllDocuments(); } template void CT_GlobalCloudManagerT::endMultiDelete() { --m_nCallToMultipleDelete; if(m_nCallToMultipleDelete == 0) { deleteMultipleCloud(); this->unlockAllDocuments(); } } template void CT_GlobalCloudManagerT::resizeCloud(const size_t &newSize) { m_cloud.resize(newSize); } template template< class IndexMemoryOptim, class IndexAccessOptim > typename CT_GlobalCloudManagerT::CT_AbstractNotModifiableCIR CT_GlobalCloudManagerT::createCIR(const size_t &beginIndex, const size_t &size, typename CT_AbstractGlobalCloudManagerT::IndexOptimization optim) { // informe les gestionnaire de synchronisation de nuage qu'un nouveau nuage a été ajouté this->informThatCloudAdded(size); CT_AbstractNotModifiableCloudIndexRegisteredT *cir = NULL; if(optim == CT_AbstractGlobalCloudManagerT::MemoryOptimized) { cir = this->template createNewIndexRegistered< CT_StandardNotModifiableCloudIndexRegisteredT, IndexMemoryOptim >(new IndexMemoryOptim(beginIndex, size)); } else { IndexAccessOptim *nIndex = new IndexAccessOptim(size); std::vector< ct_index_type > *data = this->template getInternalDataOfIndex< IndexAccessOptim >(nIndex); ct_index_type a = beginIndex; for(size_t i=0; itemplate createNewIndexRegistered< CT_StandardNotModifiableCloudIndexRegisteredT, IndexAccessOptim >(nIndex); } this->m_cirArray.append(cir); return CT_AbstractNotModifiableCIR(cir, &CT_GlobalCloudManagerT::staticDeleteCIR); } template void CT_GlobalCloudManagerT::staticDeleteCIR(CT_AbstractNotModifiableCloudIndexRegisteredT *cir) { CT_GlobalCloudManagerT *thisPtr = dynamic_cast*>(PS_REPOSITORY->globalCloudManager()); thisPtr->internalUnregisterIndex(cir, true, true); } template bool CT_GlobalCloudManagerT::internalUnregisterIndex(CT_AbstractCloudIndexRegisteredT *cir, bool informCloudDeleted, bool deleteCIR) { if(m_nCallToMultipleDelete == 0) { this->lockAllDocuments(); int at = this->m_cirArray.indexOf(cir); if(at < 0) { if(deleteCIR) delete cir; this->unlockAllDocuments(); return false; } const CT_AbstractCloudIndexT *index = cir->abstractCloudIndexT(); size_t beginIndex = index->first(); size_t size = index->size(); // on décale les nuages de points qui sont après le nuage supprimé (ils ne sont pas décalé // automatiquement puisqu'ils ne sont pas modifiables et non enregistré auprès du gestionnaire // de nuages d'index) this->shiftAllCloudIndexFrom(at+1, size, true); // on informe le gestionnaire d'index qu'on va supprimer le nuage afin qu'il // synchronise les nuages d'index. // et on informe les gestionnaire de synchronisation de nuages qu'on va supprimer le nuage if(informCloudDeleted) this->informThatCloudDeleted(beginIndex, size); // on supprime de la mémoire le nuage de points. // pour cela on decale le reste du nuage de points vers la gauche et on supprime la fin this->m_cloud.erase(beginIndex, size); this->m_cirArray.removeAt(at); this->m_cirArrayUnsync.removeOne(cir); if(deleteCIR) delete cir; this->unlockAllDocuments(); } else { int at = this->m_cirArray.indexOf(cir); if(at < 0) { if(deleteCIR) delete cir; return false; } const CT_AbstractCloudIndexT *index = cir->abstractCloudIndexT(); CT_GlobalCloudIndex cloudIndex; cloudIndex.m_begin = index->first(); cloudIndex.m_end = index->last(); m_multipleDeleteCollection.push_back(cloudIndex); this->m_cirArray.removeAt(at); this->m_cirArrayUnsync.removeOne(cir); if(deleteCIR) delete cir; } return true; } template void CT_GlobalCloudManagerT::deleteMultipleCloud() { if(!m_multipleDeleteCollection.empty()) { m_multipleDeleteCollection.sort(); std::list< CT_GlobalCloudIndex >::iterator it = m_multipleDeleteCollection.begin(); std::list< CT_GlobalCloudIndex >::iterator next = it; ++next; std::list< CT_GlobalCloudIndex >::iterator end = m_multipleDeleteCollection.end(); // merge all index in the list while(next != end) { CT_GlobalCloudIndex &a = *it; CT_GlobalCloudIndex &b= *next; if((a.m_end+1) == b.m_begin) { a.m_end = b.m_end; next = this->m_multipleDeleteCollection.erase(next); end = this->m_multipleDeleteCollection.end(); } else { ++it; ++next; } } it = this->m_multipleDeleteCollection.begin(); end = this->m_multipleDeleteCollection.end(); while(it != end) { CT_GlobalCloudIndex &a = *it; size_t beginIndex = a.m_begin; size_t size = (a.m_end - a.m_begin)+1; next = it; ++next; // shift all index after this while(next != end) { CT_GlobalCloudIndex &b = *next; b.m_begin -= size; b.m_end -= size; ++next; } // search CIR after this index int at = -1; int i = 0; QListIterator< CT_AbstractCloudIndexRegisteredT* > cirIt(this->m_cirArray); while(cirIt.hasNext() && (at < 0)) { CT_AbstractCloudIndexRegisteredT *cir = cirIt.next(); if(cir->first() > a.m_end) at = i; ++i; } // on décale les nuages de points qui sont après le nuage supprimé (ils ne sont pas décalé // automatiquement puisqu'ils ne sont pas modifiables et non enregistré auprès du gestionnaire // de nuages d'index) if(at >= 0) this->shiftAllCloudIndexFrom(at, size, true); // on informe le gestionnaire d'index qu'on va supprimer le nuage afin qu'il // synchronise les nuages d'index. // et on informe les gestionnaire de synchronisation de nuages qu'on va supprimer le nuage this->informThatCloudDeleted(beginIndex, size); // on supprime de la mémoire le nuage de points. // pour cela on decale le reste du nuage de points vers la gauche et on supprime la fin this->m_cloud.erase(beginIndex, size); ++it; } this->m_multipleDeleteCollection.clear(); } } #endif // CT_GLOBALCLOUDMANAGERT_HPP