diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9e98b51442..6ef440843f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2480,6 +2480,7 @@ bool Application::importEntities(const QString& urlOrFilename) { bool success = _entityClipboard->readFromURL(url.toString()); if (success) { + _entityClipboard->remapIDs(); _entityClipboard->reaverageOctreeElements(); } return success; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 892b186a25..c0ef3e0fe3 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -24,6 +24,7 @@ #include "EntitiesLogging.h" #include "RecurseOctreeToMapOperator.h" #include "LogHandler.h" +#include "RemapIDOperator.h" static const quint64 DELETED_ENTITIES_EXTRA_USECS_TO_CONSIDER = USECS_PER_MSEC * 50; @@ -1194,6 +1195,11 @@ bool EntityTree::sendEntitiesOperation(OctreeElementPointer element, void* extra return true; } +void EntityTree::remapIDs() { + RemapIDOperator theOperator; + recurseTreeWithOperator(&theOperator); +} + bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) { if (! entityDescription.contains("Entities")) { entityDescription["Entities"] = QVariantList(); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index d1e0462f64..97a23124bb 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -196,6 +196,8 @@ public: bool wantTerseEditLogging() const { return _wantTerseEditLogging; } void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; } + void remapIDs(); + bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues); bool readFromMap(QVariantMap& entityDescription); diff --git a/libraries/entities/src/RemapIDOperator.cpp b/libraries/entities/src/RemapIDOperator.cpp new file mode 100644 index 0000000000..eee6e49a1c --- /dev/null +++ b/libraries/entities/src/RemapIDOperator.cpp @@ -0,0 +1,33 @@ +// +// RemapIDOperator.cpp +// libraries/entities/src +// +// Created by Seth Alves on 2015-12-6. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +#include "EntityTree.h" +#include "RemapIDOperator.h" + +QUuid RemapIDOperator::remap(const QUuid& oldID) { + if (oldID.isNull()) { + return oldID; + } + if (!_oldToNew.contains(oldID)) { + _oldToNew[oldID] = QUuid::createUuid(); + } + return _oldToNew[oldID]; +} + +bool RemapIDOperator::postRecursion(OctreeElementPointer element) { + EntityTreeElementPointer entityTreeElement = std::static_pointer_cast(element); + entityTreeElement->forEachEntity([&](EntityItemPointer entityItem) { + entityItem->setID(remap(entityItem->getID())); + entityItem->setParentID(remap(entityItem->getParentID())); + }); + return true; +} diff --git a/libraries/entities/src/RemapIDOperator.h b/libraries/entities/src/RemapIDOperator.h new file mode 100644 index 0000000000..439aec28fc --- /dev/null +++ b/libraries/entities/src/RemapIDOperator.h @@ -0,0 +1,30 @@ +// +// RemapIDOperator.h +// libraries/entities/src +// +// Created by Seth Alves on 2015-12-6. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_RemapIDOperator_h +#define hifi_RemapIDOperator_h + +#include "Octree.h" + +// this will change all the IDs in an EntityTree. Parent/Child relationships are maintained. + +class RemapIDOperator : public RecurseOctreeOperator { +public: + RemapIDOperator() : RecurseOctreeOperator() {} + ~RemapIDOperator() {} + virtual bool preRecursion(OctreeElementPointer element) { return true; } + virtual bool postRecursion(OctreeElementPointer element); +private: + QUuid remap(const QUuid& oldID); + QHash _oldToNew; +}; + +#endif // hifi_RemapIDOperator_h