glTF-Transform icon indicating copy to clipboard operation
glTF-Transform copied to clipboard

Support transferring properties to another Document

Open donmccurdy opened this issue 1 year ago • 11 comments

The graph datastructure under glTF Transform prevents sharing property resources (materials, textures, animations...) between multiple Document instances. That's important for reference tracking, but does make certain cases harder than they need to be. For example, moving a material from one glTF file into another.

We could consider creating a simple API to handle this case. Possible APIs...

const material = document.transfer(externalMaterial); // single

const materials = document.transfer(externalMaterials); // multiple

const material = externalMaterial.cloneExternal(document);

I think I'm leaning toward dstProperties = document.transfer(srcProperties). Accepting an array would be important on the assumption that the transferred properties might share references to underlying resources like textures, and we don't want to create duplicates of those.

donmccurdy avatar Apr 25 '23 20:04 donmccurdy

For my own understanding, it would be helpful to see the API examples in terms of doc1 and doc2 to show how the transfer completes. Does transfer go into or out of the document? I also noticed a detach() method in your docs, but I'm unclear what it's for - could it be related to these flows?

elalish avatar Apr 25 '23 21:04 elalish

Sure, in terms of src and dst documents —

src.getRoot().listTextures(); // → [texture1, texture2, texture3, ...]
dst.getRoot().listTextures(); // → []

dst.transfer(src.getRoot().listTextures());

src.getRoot().listTextures(); // → []
dst.getRoot().listTextures(); // → [texture1, texture2, texture3, ...]

I'm thinking it's fine for these resource to be removed from the src document, but I'm not married to that idea. The detach() method is probably part of this solution, but not all of it — detaching removes all inbound references to a resource from other resources in the document, but doesn't remove the resource's connection to the document itself.

donmccurdy avatar Apr 25 '23 21:04 donmccurdy

Interesting - the problem I see here is with a material that references a texture. I'd like to transfer that material and not have it broken, so I need its texture transferred too, automatically ideally. However, if another material in the src document also references that texture, then removing it seems problematic. Likewise with transferring a node and pulling all of the things it references, recursively.

What about this?

dst.cloneSubTree(src.getRoot().listNodes()[2]);

elalish avatar Apr 25 '23 21:04 elalish

Yes, for any of these APIs I am assuming the process is recursive, and e.g. textures will be kept with the material. That's part of the motivation for an array parameter. With a single-argument API, I don't think I'd be able to avoid creating duplicates of any shared textures:

// duplicate textures!
dst.transfer(material1);
dst.transfer(material2); 

// ok
dst.transfer([material1, material2]);

donmccurdy avatar Apr 25 '23 22:04 donmccurdy

Ah, that makes sense, thanks. And I suppose if the dangling references in the src are just nulled out, then everything will still be in a good state.

elalish avatar Apr 25 '23 22:04 elalish

Another suggestion to this API: cloneExternal method on all PropertyTypes which takes buffer as an optional argument. If that returns a new accessor, we can attach it whatever document we want (which is associated with the passed buffer).

CITIZENDOT avatar Sep 14 '23 19:09 CITIZENDOT

I'm not sure I understand what you would like to happen with the buffer argument – would it be the same thing as finding the Document associated with that Buffer, and passing that Document in instead?

donmccurdy avatar Sep 14 '23 20:09 donmccurdy

I was talking about the argument passed to Accessor.setBuffer.

would it be the same thing as finding the Document associated with that Buffer, and passing that Document in instead

I think this works too. I was not aware this can be done.

CITIZENDOT avatar Sep 14 '23 21:09 CITIZENDOT

Also, just curious, what if we detach the property and all it's child properties and attach the parent property to the new document? That works too right?

CITIZENDOT avatar Sep 14 '23 21:09 CITIZENDOT

None of this is supported now, but that's the idea for the proposal here yes. 👍🏻

donmccurdy avatar Sep 15 '23 01:09 donmccurdy

Proposed solution:

  • https://github.com/donmccurdy/glTF-Transform/pull/1375

donmccurdy avatar Apr 27 '24 02:04 donmccurdy