Skip to content

Commit

Permalink
#5639: Start implementing the LayerMerger.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jun 7, 2021
1 parent fafd8a6 commit 7f74453
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 45 deletions.
90 changes: 46 additions & 44 deletions libs/scene/merge/LayerMerger.h
Expand Up @@ -37,7 +37,7 @@ class LayerMerger
BaseLayerRemoved,
};

std::size_t groupId;
int layerId;
INodePtr member;
Type type;
};
Expand Down Expand Up @@ -88,36 +88,32 @@ class LayerMerger

void adjustBaseLayers()
{
#if 0
// Collect all source and base nodes for easier lookup
_sourceRoot->foreachNode([&](const INodePtr& node)
{
if (!std::dynamic_pointer_cast<IGroupSelectable>(node)) return true;

_sourceNodes.emplace(NodeUtils::GetGroupMemberFingerprint(node), node);
_sourceNodes.emplace(NodeUtils::GetLayerMemberFingerprint(node), node);
return true;
});

_log << "Got " << _sourceNodes.size() << " groups in the source map" << std::endl;
_log << "Got " << _sourceNodes.size() << " nodes in the source map" << std::endl;

_baseRoot->foreachNode([&](const INodePtr& node)
{
if (!std::dynamic_pointer_cast<IGroupSelectable>(node)) return true;

_baseNodes.emplace(NodeUtils::GetGroupMemberFingerprint(node), node);
_baseNodes.emplace(NodeUtils::GetLayerMemberFingerprint(node), node);
return true;
});

_log << "Got " << _baseNodes.size() << " in the base map" << std::endl;
_log << "Got " << _baseNodes.size() << " nodes in the base map" << std::endl;

_log << "Start Processing base groups" << std::endl;
_log << "Start Processing base layers" << std::endl;

// Remove all base groups not present in the source scene, unless we decide to keep it
_baseManager.foreachSelectionGroup(
std::bind(&SelectionGroupMerger::processBaseGroup, this, std::placeholders::_1));
// Remove all base layers not present in the source scene, unless we decide to keep it
_baseManager.foreachLayer(
std::bind(&LayerMerger::processBaseLayer, this, std::placeholders::_1, std::placeholders::_2));

_log << "Start Processing source groups" << std::endl;
_log << "Start Processing source layers" << std::endl;

#if 0
_sourceManager.foreachSelectionGroup(
std::bind(&SelectionGroupMerger::processSourceGroup, this, std::placeholders::_1));

Expand All @@ -138,30 +134,29 @@ class LayerMerger
private:
using LayerMembers = std::map<std::string, scene::INodePtr>;

#if 0
void processBaseGroup(selection::ISelectionGroup& group)
void processBaseLayer(int baseLayerId, const std::string& baseLayerName)
{
// Check if there's a counter-part in the source scene
auto sourceGroup = _sourceManager.getSelectionGroup(group.getId());
// Check if there's a counter-part in the source scene (by name)
auto sourceLayer = _sourceManager.getLayerID(baseLayerName);

// Existing groups are ok, leave them, conflicts will be resolved in processSourceGroup
if (sourceGroup)
// Existing layers are ok, leave them, conflicts will be resolved in processSourceLayer
if (sourceLayer != -1)
{
_log << "Base group " << group.getId() << " is present in source too, skipping." << std::endl;
_log << "Base layer " << baseLayerName << " is present in source too, skipping." << std::endl;
return;
}

// This base group is no longer present in the source scene,
// This base layer is no longer present in the source scene,
// we'll remove it, unless it's referenced by nodes which are base-only
// which indicates that the base nodes have explicitly been chosen by the user
// to be kept during the merge operation
std::vector<INodePtr> nodesToRemove;

group.foreachNode([&](const INodePtr& node)
foreachNodeInLayer(baseLayerId, [&](const INodePtr& node)
{
auto fingerprint = NodeUtils::GetGroupMemberFingerprint(node);
auto fingerprint = NodeUtils::GetLayerMemberFingerprint(node);

// All nodes that are also present in the source map are removed from this group
// All nodes that are also present in the source map are removed from this layer
// we only keep the base nodes that are preserved during merge
if (_sourceNodes.count(fingerprint) > 0)
{
Expand All @@ -172,33 +167,40 @@ class LayerMerger
for (const auto& node : nodesToRemove)
{
_changes.emplace_back(Change
{
group.getId(),
node,
Change::Type::NodeRemovedFromGroup
});
{
baseLayerId,
node,
Change::Type::NodeRemovedFromLayer
});

_log << "Removing node " << node->name() << " from group " <<
group.getId() << ", since it is not exclusive to the base map." << std::endl;
_log << "Removing node " << node->name() << " from layer " <<
baseLayerName << ", since it is not exclusive to the base map." << std::endl;

group.removeNode(node);
node->removeFromLayer(baseLayerId);
}
}

if (group.size() < 2)
void foreachNodeInLayer(int layerId, const std::function<void(const INodePtr&)>& functor)
{
_baseRoot->foreachNode([&](const INodePtr& node)
{
_log << "Base group " << group.getId() << " ends up with less than two members and is marked for removal." << std::endl;
if (node->getNodeType() != INode::Type::Entity &&
node->getNodeType() != INode::Type::Brush &&
node->getNodeType() != INode::Type::Patch)
{
return true;
}

_changes.emplace_back(Change
{
group.getId(),
INodePtr(),
Change::Type::BaseGroupRemoved
});
if (node->getLayers().count(layerId) > 0)
{
functor(node);
}

_baseGroupIdsToRemove.push_back(group.getId());
}
return true;
});
}

#if 0
void processSourceGroup(selection::ISelectionGroup& group)
{
_log << "Processing source group with ID: " << group.getId() << ", size: " << group.size() << std::endl;
Expand Down
13 changes: 12 additions & 1 deletion libs/scene/merge/NodeUtils.h
Expand Up @@ -22,10 +22,21 @@ class NodeUtils
}

static std::string GetGroupMemberFingerprint(const INodePtr& member)
{
return GetEntityNameOrFingerprint(member);
}

static std::string GetLayerMemberFingerprint(const INodePtr& member)
{
return GetEntityNameOrFingerprint(member);
}

private:
static std::string GetEntityNameOrFingerprint(const INodePtr& member)
{
if (member->getNodeType() == INode::Type::Entity)
{
// Group links between entities should use the entity's name to check for equivalence
// Links between entities should use the entity's name to check for equivalence
// even if the entity has changed key values or primitives, the link is intact when the name is equal
return GetEntityName(member);
}
Expand Down

0 comments on commit 7f74453

Please sign in to comment.