Merge 2 - Smash them together
The next version of merging is extreme difference from simple overlays. We will extract all the component objects from each commit. This is a bit more involved as we need to load the things from the server and reconstruct a commit.
- Take the content of the 3 commits and commit that to speckle.
- View that commit in the embedded viewer
Firstly, we’ll get the commit objects
commit_objects = [
client.commit.get(stream_id, commit_id) for commit_id in commit_ids
]
If the 3 URLs given are all commits, then the first name object has a property called referencedObject
which is the id of the wrapper object for the commit data.
referenced_objects = [r.referencedObject for r in commit_objects]
We then’ Receive’ each reference object to assemble a large array of all the committed things.
from specklepy.api import operations
commit_data = [
operations.receive(obj_id=ref_obj, remote_transport=wrap.get_transport())
for ref_obj, wrap in zip(referenced_objects, wrappers)
]
For this example, I will create a commit that retains the structure of the three separate. If you were trying to apply any filters or run diffing operations, this is the stage where you could merge the three only to include the latest objects etc. The subject of a future post on this topic
I happen to know there is no overlap, so I’ll proceed.
from specklepy.objects import Base
granular_commit_object = Base(speckle_type="Federation.Granular")
granular_commit_object["@Components"] = commit_data
… and hash them
hash3 = operations.send(base=granular_commit_object , transports=[transport])
Suppose we follow the reasoning from other discussions around Versions, Federations, Assemblies, Exchanges etc. We should store this new commit on a dedicated branch.
def try_get_branch_or_create(client, stream_id, branch_name):
try:
client.branch.get(
stream_id=stream_id, name=branch_name
) or client.branch.create(stream_id=stream_id, name=branch_name)
return client.branch.get(
stream_id=stream_id, name=branch_name)
except GraphQLException:
return client.branch.create(stream_id=stream_id, name=branch_name)
branch = try_get_branch_or_create(client, stream_id, "federated")
And then we create a new commit that contains the resolved objects
commit_id3 = client.commit.create(
branch_name=branch.name,
stream_id=stream_id,
object_id=hash3,
message="federated commit",
)
Then as with part 1, we generate an embedded viewer URL to demonstrate the federation:
embed_url3 = (f"https://speckle.xyz/embed?stream={stream_id}"
f"&commit={commit_id3}"
f"&transparent={transparency}"
f"&autoload={autoload}"
f"&hidecontrols={hide_controls}"
f"&hidesidebar={hide_sidebar}"
f"&hideselectioninfo={hide_selection_info}")
from IPython.display import IFrame
IFrame(embed_url3, width=400, height=300)
As mentioned, this version could be a jumping-off point for clever logic employed over what objects to include and which not to.