Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of duplicate URIs #115

Open
javagl opened this issue Jun 27, 2024 · 2 comments
Open

Handling of duplicate URIs #115

javagl opened this issue Jun 27, 2024 · 2 comments

Comments

@javagl
Copy link
Owner

javagl commented Jun 27, 2024

Right now, it is not clear how duplicate URIs should be handled.

For example:

  • one can create two ImageModel objects (and add them to a model/builder)
  • both can have the URI image.png
  • when writing this model, the result depends on the type of the asset:
    • for embedded and binary assets, the result will be fine
    • for 'default' assets, one image will be overwritten by the other one, due to the equal URI...

The latter is happening silently and certainly not desired.

Simply appending some _0 suffix to the file name might be a reasonable solution. But different mechanisms could be considered...

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import de.javagl.jgltf.model.ImageModel;
import de.javagl.jgltf.model.creation.GltfModelBuilder;
import de.javagl.jgltf.model.creation.ImageModels;
import de.javagl.jgltf.model.impl.DefaultGltfModel;
import de.javagl.jgltf.model.impl.DefaultSceneModel;
import de.javagl.jgltf.model.io.GltfModelWriter;

public class GltfModelBuilderImageUriDeduplicationTest
{
    public static void main(String[] args) throws IOException
    {
        BufferedImage bufferedImage =
            new BufferedImage(8, 8, BufferedImage.TYPE_INT_ARGB);
        ImageModel imageModel0 = ImageModels.createFromBufferedImage(
            "image.png", "image/png", bufferedImage);
        ImageModel imageModel1 = ImageModels.createFromBufferedImage(
            "image.png", "image/png", bufferedImage);

        GltfModelBuilder gltfModelBuilder = GltfModelBuilder.create();
        gltfModelBuilder.addSceneModel(new DefaultSceneModel());
        gltfModelBuilder.addImageModel(imageModel0);
        gltfModelBuilder.addImageModel(imageModel1);

        DefaultGltfModel gltfModel = gltfModelBuilder.build();
        GltfModelWriter w = new GltfModelWriter();
        w.write(gltfModel, new File("./data/temp.gltf"));
    }
    
}

(Note: The same might apply to buffers - to be verified - but for images, it is much more apparent)

@javagl
Copy link
Owner Author

javagl commented Jun 28, 2024

In many ways, I see glTF-Transform as ... "a source of inspiration" at least, but often as a reference for sensible ways of approaching things like this.

And I just tried it - i.e. creating a Document with two textures, and writing that out.

Now, the conceptual handling of images and textures in glTF-Transform is a bit special, and "structurally different" to a verbatim translation of glTF itself. There is no Image object, so to speak - the image is just "the data that is backing the texture". The user often will not explicitly assign a URI to a texture, even though this is possible:

texture0.setURI("test.png");
texture1.setURI("test.png");

Writing that out will also overwrite the "file" (resource) of the first texture with the data from the second.

Sooo... one could just say that this is the behavior that the user has to expect when doing something like this...

However: When no URIs are assigned explicitly, then they will be assigned automatically. And by default, the URIs are texture_1.png and texture_2.png.

(Now... glTF-Transform is doing many things right, but ... how can one start counting at 1? 😆 )


After seeing that, I followed my usual behavior of "being nasty", and tried

//texture0.setURI("test.png");
texture1.setURI("texture_1.png");

and this also causes the first texture to be called texture_1.png, and consequently, its data will be overwritten with the data from the second texture. That... is something that one might call a "bug"... but ... it's not worth arguing about that, I guess.


For JglTF, one overarching question is whether any deduplication should happen in the model, or only at the time of writing. Both could have undesired implications, so there might not be a silver bullet.

However, when using null as the URI when creating the ImageModel, then it will also generate the URIs when writing out the data, namely as image0.png and image1.png. (And before you ask: When assigning image0.png as the URI for the second one, then it will rename this to image1.png and not overwrite the existing data...)

Maybe I'll just close this...

@javagl
Copy link
Owner Author

javagl commented Sep 29, 2024

Just a back-pointer to a related question in the glTF repo: KhronosGroup/glTF#2446

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant