From ee030261610775d82c37ff37379ba0114323fa27 Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 23 May 2021 11:11:06 +0200 Subject: [PATCH] #5622: Compare entities first --- radiantcore/map/Map.cpp | 6 ++++ radiantcore/map/algorithm/Import.cpp | 52 ++++++++++++++++------------ radiantcore/map/algorithm/Import.h | 1 + 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/radiantcore/map/Map.cpp b/radiantcore/map/Map.cpp index 2c381428a2..e74eeda665 100644 --- a/radiantcore/map/Map.cpp +++ b/radiantcore/map/Map.cpp @@ -941,6 +941,12 @@ void Map::mergeMap(const cmd::ArgumentList& args) { // No arguments passed, get the map file name to load auto fileInfo = MapFileManager::getMapFileSelection(true, _("Select Map File to merge"), filetype::TYPE_MAP); + + if (fileInfo.fullPath.empty()) + { + return; // operation cancelled + } + candidate = fileInfo.fullPath; } diff --git a/radiantcore/map/algorithm/Import.cpp b/radiantcore/map/algorithm/Import.cpp index 74505ff7ad..f696319171 100644 --- a/radiantcore/map/algorithm/Import.cpp +++ b/radiantcore/map/algorithm/Import.cpp @@ -414,48 +414,54 @@ ComparisonResult::Ptr compareGraphs(const scene::IMapRootNodePtr& target, const rMessage() << "Target Node Types: " << targetFingerprints.size() << std::endl; // Filter out all the matching nodes and store them in the result - for (const auto& sourceCollection : sourceFingerprints) + if (sourceFingerprints.count(scene::INode::Type::Entity) == 0) { - rMessage() << "Source Fingerprints for node type " << static_cast(sourceCollection.first) << ": " << sourceCollection.second.size() << std::endl; + // Cannot merge the source without any entities in it + throw cmd::ExecutionFailure(_("The source map doesn't contain any entities, cannot merge")); + } - auto targetNodesOfSameType = targetFingerprints.find(sourceCollection.first); + rMessage() << "Entity Fingerprints in source: " << sourceFingerprints[scene::INode::Type::Entity].size() << std::endl; - if (targetNodesOfSameType == targetFingerprints.end()) - { - // target has no nodes of that type, copy whole node collection to differingNodes - result->differingNodes[sourceCollection.first] = sourceCollection.second; - continue; - } + auto& targetEntities = targetFingerprints.try_emplace(scene::INode::Type::Entity).first->second; + for (const auto& sourceEntity : sourceFingerprints[scene::INode::Type::Entity]) + { // Create the collection to hold the of matching node pairs - auto& matchingNodeList = result->equivalentNodes.try_emplace(sourceCollection.first).first->second; - auto& differingNodes = result->differingNodes.try_emplace(sourceCollection.first).first->second; + auto& matchingNodeList = result->equivalentNodes.try_emplace(scene::INode::Type::Entity).first->second; + auto& differingNodes = result->differingNodes.try_emplace(scene::INode::Type::Entity).first->second; // Check each source node for an equivalent node in the target - for (const auto& sourcePair : sourceCollection.second) + auto matchingTargetNode = targetEntities.find(sourceEntity.first); + + if (matchingTargetNode != targetEntities.end()) + { + // Found an equivalent node + matchingNodeList.emplace_back(ComparisonResult::Match{ sourceEntity.first, sourceEntity.second, matchingTargetNode->second }); + } + else { - auto matchingTargetNode = targetNodesOfSameType->second.find(sourcePair.first); - - if (matchingTargetNode != targetNodesOfSameType->second.end()) - { - // Found an equivalent node - matchingNodeList.emplace_back(ComparisonResult::Match{ sourcePair.first, sourcePair.second, matchingTargetNode->second }); - } - else - { - differingNodes.insert(sourcePair); - } + differingNodes.emplace(sourceEntity.first, sourceEntity.second); } } for (const auto& pair : result->equivalentNodes) { rMessage() << "Equivalent Nodes of Type " << static_cast(pair.first) << ": " << pair.second.size() << std::endl; + + for (const auto& fingerprintedNode : pair.second) + { + rMessage() << " - Equivalent Node: " << fingerprintedNode.sourceNode->name() << std::endl; + } } for (const auto& pair : result->differingNodes) { rMessage() << "Different Nodes of Type " << static_cast(pair.first) << ": " << pair.second.size() << std::endl; + + for (const auto& fingerprintedNode : pair.second) + { + rMessage() << " - Differing Node: " << fingerprintedNode.second->name() << std::endl; + } } return result; diff --git a/radiantcore/map/algorithm/Import.h b/radiantcore/map/algorithm/Import.h index 7d9d026399..b276016841 100644 --- a/radiantcore/map/algorithm/Import.h +++ b/radiantcore/map/algorithm/Import.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace scene {