void ccDBRoot::removeElement(ccHObject* anObject) { if (!anObject) return; //we hide properties view in case this is the deleted object that is currently selected hidePropertiesView(); //every object in tree must have a parent! ccHObject* parent = anObject->getParent(); if (!parent) { ccConsole::Warning("[ccDBRoot::removeElement] Internal error: object has no parent!"); return; } int childPos = parent->getChildIndex(anObject); assert(childPos>=0); //row removal operation (start) beginRemoveRows(index(parent),childPos,childPos); parent->removeChild(childPos); //row removal operation (end) endRemoveRows(); //we restablish properties view updatePropertiesView(); }
void ccDBRoot::updatePropertiesView() { assert(m_propertiesTreeWidget); QItemSelectionModel* qism = m_dbTreeWidget->selectionModel(); QModelIndexList selectedIndexes = qism->selectedIndexes(); if (selectedIndexes.size()==1) showPropertiesView(static_cast<ccHObject*>(selectedIndexes[0].internalPointer())); else hidePropertiesView(); }
void ccDBRoot::toggleSelectedEntitiesProperty(unsigned prop) { if (prop>6) { ccConsole::Warning("[ccDBRoot::toggleSelectedEntitiesProperty] Internal error: invalid 'prop' value"); return; } QItemSelectionModel* qism = m_dbTreeWidget->selectionModel(); QModelIndexList selectedIndexes = qism->selectedIndexes(); int i,selCount = selectedIndexes.size(); if (selCount == 0) return; //hide properties view hidePropertiesView(); for (i=0;i<selCount;++i) { ccHObject* item = static_cast<ccHObject*>(selectedIndexes[i].internalPointer()); assert(item); if (!item) continue; switch(prop) { case 0: //enable state item->setEnabled(!item->isEnabled()); break; case 1: //visibility item->toggleVisibility(); break; case 2: //color item->toggleColors(); break; case 3: //normal item->toggleNormals(); break; case 4: //SF item->toggleSF(); break; case 5: //Materials/textures item->toggleMaterials(); break; case 6: //3D name item->toggleShowName(); break; } item->prepareDisplayForRefresh(); } //we restablish properties view updatePropertiesView(); MainWindow::RefreshAllGLWindow(); }
void ccDBRoot::deleteSelectedEntities() { QItemSelectionModel* qism = m_dbTreeWidget->selectionModel(); QModelIndexList selectedIndexes = qism->selectedIndexes(); if (selectedIndexes.size() < 1) return; unsigned selCount = (unsigned)selectedIndexes.size(); hidePropertiesView(); //specific case: shared labels ccHObject::Container allLabels; bool hasSharedLabels = false; std::set<ccHObject*> cloudsToBeDeleted; //will only be used if 'hasSharedLabels' is true if (m_treeRoot->filterChildren(allLabels,true,CC_2D_LABEL) != 0) { for (unsigned i=0; i<allLabels.size(); ++i) { cc2DLabel* label = static_cast<cc2DLabel*>(allLabels[i]); //shared labels are labels shared by at least 2 different clouds if (label->size() > 1 && label->getPoint(0).cloud != label->getPoint(1).cloud || label->size() > 2 && label->getPoint(1).cloud != label->getPoint(2).cloud) { hasSharedLabels = true; break; } } } //we remove all objects that are children of other deleted ones! //(otherwise we may delete the parent before the child!) std::vector<ccHObject*> toBeDeleted; for (unsigned i=0;i<selCount;++i) { ccHObject* obj = static_cast<ccHObject*>(selectedIndexes[i].internalPointer()); //we don't take care of parentless objects (i.e. the tree root) if (!obj->getParent() || obj->isLocked()) { ccConsole::Warning(QString("Object '%1' can't be deleted this way (locked)").arg(obj->getName())); continue; } //we don't take objects that are siblings of others bool isSiblingOfAnotherOne = false; for (unsigned j=0;j<selCount;++j) { if (i != j) { ccHObject* otherObj = static_cast<ccHObject*>(selectedIndexes[j].internalPointer()); if (otherObj->isAncestorOf(obj)) { isSiblingOfAnotherOne = true; break; } } } if (!isSiblingOfAnotherOne) { //last check: mesh vertices if (obj->isKindOf(CC_POINT_CLOUD) && obj->getParent()->isKindOf(CC_MESH)) if (ccHObjectCaster::ToGenericMesh(obj->getParent())->getAssociatedCloud() == obj) { ccConsole::Warning("Mesh vertices can't be deleted without their parent mesh!"); continue; } toBeDeleted.push_back(obj); if (hasSharedLabels) { //we must keep a parallel list for clouds only if (obj->isA(CC_POINT_CLOUD)) { cloudsToBeDeleted.insert(obj); } else { ccHObject::Container subClouds; if (obj->filterChildren(subClouds,true,CC_POINT_CLOUD) != 0) for (size_t i=0; i<subClouds.size(); ++i) cloudsToBeDeleted.insert(subClouds[i]); } } } } qism->clear(); //check now that we don't delete clouds on which some labels are dependent if (hasSharedLabels) { size_t labelCount = allLabels.size(); for (size_t i=0;i<labelCount;++i) { cc2DLabel* label = static_cast<cc2DLabel*>(allLabels[i]); if (label->size() > 1) //there's no issue with 1-point labels! { for (unsigned j=1;j<label->size();++j) //1st cloud is always the parent! if (label->getPoint(j).cloud && label->getPoint(j).cloud != label->getPoint(0).cloud && cloudsToBeDeleted.find(label->getPoint(j).cloud) != cloudsToBeDeleted.end()) { ccLog::Warning(QString("Label '%1' has been deleted as it is dependent on '%2'").arg(label->getName()).arg(label->getPoint(j).cloud->getName())); label->clear(); toBeDeleted.push_back(label); } } } } while (!toBeDeleted.empty()) { ccHObject* anObject = toBeDeleted.back(); assert(anObject); toBeDeleted.pop_back(); anObject->prepareDisplayForRefresh_recursive(); if (anObject->isKindOf(CC_MESH)) { //specific case: the object is a mesh and its parent is its vertices! //(can happen if a Delaunay mesh is computed directly in CC) if (anObject->getParent() && anObject->getParent() == ccHObjectCaster::ToGenericMesh(anObject)->getAssociatedCloud()) anObject->getParent()->setVisible(true); } ccHObject* parent = anObject->getParent(); int childPos = parent->getChildIndex(anObject); assert(childPos>=0); beginRemoveRows(index(anObject).parent(),childPos,childPos); parent->removeChild(childPos); endRemoveRows(); } updatePropertiesView(); MainWindow::RefreshAllGLWindow(); }
void ccDBRoot::deleteSelectedEntities() { QItemSelectionModel* qism = m_dbTreeWidget->selectionModel(); QModelIndexList selectedIndexes = qism->selectedIndexes(); if (selectedIndexes.size() < 1) return; unsigned selCount = (unsigned)selectedIndexes.size(); hidePropertiesView(); //we remove all objects that are children of other deleted ones! //(otherwise we may delete the parent before the child!) std::vector<ccHObject*> toBeDeleted; for (unsigned i=0;i<selCount;++i) { ccHObject* obj = static_cast<ccHObject*>(selectedIndexes[i].internalPointer()); //we don't take care of parentless objects (i.e. the tree root) if (!obj->getParent() || obj->isLocked()) { ccConsole::Warning(QString("Object '%1' can't be deleted this way (locked)").arg(obj->getName())); continue; } //we don't take objects that are siblings of others bool isSiblingOfAnotherOne = false; for (unsigned j=0;j<selCount;++j) { if (i != j) { ccHObject* otherObj = static_cast<ccHObject*>(selectedIndexes[j].internalPointer()); if (otherObj->isAncestorOf(obj)) { isSiblingOfAnotherOne = true; break; } } } if (!isSiblingOfAnotherOne) { //last check: mesh vertices if (obj->isKindOf(CC_POINT_CLOUD) && obj->getParent()->isKindOf(CC_MESH)) if (static_cast<ccGenericMesh*>(obj->getParent())->getAssociatedCloud() == obj) { ccConsole::Warning("Mesh vertices can't be deleted without their parent mesh!"); continue; } toBeDeleted.push_back(obj); } } qism->clear(); while (!toBeDeleted.empty()) { ccHObject* anObject = toBeDeleted.back(); assert(anObject); toBeDeleted.pop_back(); anObject->prepareDisplayForRefresh_recursive(); //DGM FIXME: what a burden... we should find something simpler (shared pointers?) //specific case: if the entity is a cloud, we must look for 2-points //or 3-points labels that may have a dependence to it if (anObject->isKindOf(CC_POINT_CLOUD)) { ccHObject::Container allLabels; if (m_treeRoot->filterChildren(allLabels,true,CC_2D_LABEL) != 0) { unsigned labelCount = allLabels.size(); for (unsigned i=0;i<allLabels.size();++i) { cc2DLabel* label = static_cast<cc2DLabel*>(allLabels[i]); for (unsigned j=1;j<label->size();++j) //the first point is always the parent cloud! if (label->getPoint(j).cloud == anObject) { ccLog::Warning(QString("Label '%1' has been deleted as it is dependent on '%2'").arg(label->getName()).arg(anObject->getName())); label->clear(); toBeDeleted.push_back(label); } } } } ccHObject* parent = anObject->getParent(); int childPos = parent->getChildIndex(anObject); assert(childPos>=0); beginRemoveRows(index(anObject).parent(),childPos,childPos); parent->removeChild(childPos); endRemoveRows(); } updatePropertiesView(); MainWindow::RefreshAllGLWindow(); }