Object Tracking/Binding - Speckle Objects

Hey guys,

Do you have any plans for object tracking🛤️ for Speckle objects?

Let’s say I send geometry from Revit to Sketchup. When received, geometry in Sketchup has no connection with Speckle/Revit anymore. So when I receive the latest commit from the same stream where a slight change happened in the model, it creates new geometry from scratch. Is there any way to Track/Bind geometry send/received?

Thanksđź‘‹

1 Like

The answer is “partly yes”, let me explain:

When you send data to Speckle an object will have a few identifiers:

  • the Speckle id: is a hash of the object, if any of its properties change it will change too => not ideal for what you’re after
  • the host application unique id (ie elementId if coming from Revit) => this will stay consistent as long as it is consistent in Revit (which not always is!). Not every application tracks elements with an internal id, so it might not always be available.

In your specific scenario, I’m not sure what Sketchup does with the metatada attached to Speckle elements (ping @izzylys ), but the same Revit element should consistently keep the same elementId even after it’s been modified.

1 Like

I feel like this is what a lot of people are after. There is a great potential in Syncing/Updating models. When a change happens in one environment, it will be reflected in others too (Revit, Sketchup, Blender etc.). At least an optional object tracking for streams is much need IMO. (doesn’t have to be a top priority though :slight_smile: )

1 Like

heya!

TL;DR as of right now, applicationIds are preserved in Blender, but not in SketchUp (tho I’ll add it to the list!). however, keep in mind that receiving a Revit element into Blender/SketchUp/other geometry focussed apps will turn it into a Mesh, so sending it back out again will not preserve the Revit element, even if it has the same applicationId

so this is a bit more complicated than it may seem from the surface when we’re talking about going between geometry focussed applications (eg SketchUp, Blender, in some cases Rhino) and BIM focussed application (eg Revit, Archicad, etc). this is because BIM focussed applications are dealing with BuiltElements while a geo focussed application is dealing with Geometry.

so in eg SketchUp, the incoming data is traversed until it hits something it can convert which could for example be the displayValue Mesh of a FamilyInstance. it then converts only this mesh to SketchUp. this mesh will of course have a different applicationId than the parent object.

in Blender I have actually temporarily solved this issue by passing down parent props to child geometry (eg see this commit here which preserves all the Revit applicationIds and custom props in the properties field on each object. ((I can probably get this working in SketchUp as well! I’ll add it to the list.))

in both cases, what is actually being converted is a Mesh, not a BuiltElement, so sending the object from SketchUp/Blender and back into Revit will give you a Direct Shape and not the original BIM element, even if the applicationId is the same.

so what this means is you can currently have one-way object tracking/binding but not two-way. this means that for example, you could have two models

  1. a Blender model where you are:
    • modelling objects and sending updates to Speckle
    • receiving from a Speckle/Revit model and receiving continuous updates on those objects
  2. a Revit model where you are:
    • doin your BIM stuff and sending updates to Speckle
    • receiving from a Speckle/Blender model and getting continuous updates on those objects
3 Likes

Thanks for clarifying @izzylys :handshake:

I think this is more than enough for now. Having a one-way link will create lots of potential workflows. And probably it will increase the performance too, instead of receiving the whole geometry from scratch, only those that changed will be received. (maybe🤔, not an expert.)

Great👏, can’t wait to play with it.

1 Like

Hey,

Just wanted to up this discussion:
if we want to work cross-application on the same elements
(Say I create a preliminary design of pipenetworks in Revit and then switch to Civl3D to match it to the toposurface, or the other way around) currently I have a hard time figuring out how speckle figures out which one is the same object.

As I understand of this thread; It does not register this element as modified, but rather as deleted and then newly created. What is the argument for not writing a Speckle_Id on the actual elements in the applications? (like IFC)

It would make it much easier to track if an element already exists in the DB or not, and just find the item on the speckle_Id when working cross-applications.

As you can see, this is a long topic, and it comes up a lot.

There is no correct answer either.

When a host application sends data to Speckle using our Connectors, the Speckle ID is a hash of that’s objects content. This registers that version of the object uniquely in the database. Change the source object in the host application, and a subsequent send will produce a new entry in the Speckle DB.

To track that the element is a new version of an existing one, the Connector apply the internal ID from the host application as applicationId. This is used alongside the Connector cache to see what is new, deleted or updated (within the same host application)

If that data is received in a different application, then the conversion of Speckle to Native produces a brand new object in the target application. By default, this application will have its internal db for objects and their IDs - using the source application_id may work, or it may not.

If that object is now native in the target application and is sent to Speckle, it will have a new speckle_id and quite possibly a new application_id. This will almost certainly be seen as a newly created element in the original host application.

A user’s experience in all of this will vary between a single user and a multiplayer experience depending on whether caches are present on a machine or a source file.

What has come up before and is a source of significant continuing debates in the Speckle team, and what is, I think, insinuated by your post is a need for Yet Another ID (YAID)? Upon first publishing to Speckle, a unique canonical ID is generated and maintained on all those paths into and out of Connectors and the Speckle DB.

You correctly state that IFC elements have a unique ID separate from the source applications. In your experience, is this retained as an immutable ID on Interop? My experience is that it isn’t always, or at least inconsistently and cannot be 100% relied upon.

As I said, there is no correct answer, and we have many opinions internally on the best solution, which frankly doesn’t reliably exist outside of the Speckle ecosystem either for multiplayer and/or roundtrip interop workflows.

1 Like

Hey,

Thanks for the swift reply!

This is indeed what I mean, I fully understand that not all applications are built to this. (some applications also do not consistently allow creation of properties on all geometric classes). As you state correctly: even the IFC UID is not always reliable as per object type the id’s are not always saved/maintained/protected properly.

I can also imagine it being beneficial to not write it on some objects: e.g. points/pointgroups that are used for creating a toposurface are a great example of this.

Not to contradict myself too much though, my main point/goal is:
should I want to track my object throughout the lifecycle of the project, it is better to have a uniqueId that is consistent (can also be a copy of the Id the first time it is registered in the SpeckleDB) rather than having it rely on the mutations done in the applications.

Another brainfart: of course we can also use the YAID field to save the previous “speckle_Id” and trace it in this way. So whenever an object is loaded, the YAID field is filled with the speckle_Id. When the object is changed, and thus sent, it gets a new id in the way it is working now.

How do you do the diffing when you use versioncompare? Is this purely done on the applicationID + elementID?