Export tags GLTF

Hello!

I’m trying various ways to get tags from a downloaded GLTF file, but I’ve never been able to access them in BabylonJS.

I created a simple GLTF file in Blender, in the file I see the tags (test, lod) in the meshes section:

"meshes" : [
        {
            "extras" : {
                "tags" : "test lod",
                "prop" : 1
            },
            "name" : "Cube",
            "primitives" : [
                {
                    "attributes" : {
                        "POSITION" : 0,
                        "NORMAL" : 1,
                        "TEXCOORD_0" : 2
                    },
                    "indices" : 3,
                    "material" : 0
                }
            ]
        }
    ],

The last thing I tried was to create an extension for ImportMeshAsync. The extension is successfully registered and has access to resources:

import { IGLTFLoaderExtension } from '@babylonjs/loaders/glTF'
import { GLTFLoader } from '@babylonjs/loaders/glTF/2.0'
import { Tags, TransformNode } from '@babylonjs/core'

class TagsExtension implements IGLTFLoaderExtension {
  public readonly name = 'MyTagsExtension'
  public enabled = true
  
  constructor(private _loader: GLTFLoader) {}
  
  public loadNodeAsync(context: string, node: any, assign: (babylonMesh: any) => void): Promise<TransformNode> {
    return this._loader.loadNodeAsync(context, node, function (babylonMesh) {
      if (babylonMesh.id == 'BTLMN_Prop_RoadSign_A') {
        console.log(babylonMesh, node)
      }
 
      if (node.extras && node.extras.tags) {
        Tags.AddTagsTo(babylonMesh, node.extras.tags);
      }
      assign(babylonMesh);
    });
  }
  
  public dispose(): void {
    // Add code to dispose any resources used by the extension
  }
}

export default function RegisterTagsExtension () {
  GLTFLoader.RegisterExtension("MyTagsExtension", (loader: GLTFLoader) => {
    return new TagsExtension(loader)
  })
}

But babylonMesh.metadata and node.extras remain empty.

Tags are imported well and work with files .babylon, without additional extensions, but we need GLTF.

I’m looking for any working way to get tags from GLTF. Perhaps there is an example that I could not find? I will be glad of any help. Thanks!

hey @Rubaka not sure if it is helpful but I use Blender as well and make use of custom props. I noticed a difference. Here is a quick export:

{
	"asset":{
		"generator":"Khronos glTF Blender I/O v3.5.30",
		"version":"2.0"
	},
	"scene":0,
	"scenes":[
		{
			"name":"Scene",
			"nodes":[
				0
			]
		}
	],
	"nodes":[
		{
			"extras":{
				"prop":0.6200000047683716
			},
			"mesh":0,
			"name":"Cube"
		}
	],
	"meshes":[
		{
			"name":"Cube",
			"primitives":[
				{
					"attributes":{
						"POSITION":0,
						"TEXCOORD_0":1,
						"NORMAL":2
					},
					"indices":3
				}
			]
		}
	],
	"accessors"
//...


See that the extras property is under “nodes” not “meshes”. Could that be the issue here?

Hi! Thank you!

In my case, the export places all the properties in the section

{
    "asset" : {
        "generator" : "Khronos glTF Blender I/O v1.6.16",
        "version" : "2.0"
    },
    "scene" : 0,
    "scenes" : [
        {
            "name" : "Scene",
            "nodes" : [
                0
            ]
        }
    ],
    "nodes" : [
        {
            "extras" : {},
            "mesh" : 0,
            "name" : "BTLMN_Prop_RoadSign_A"
        }
    ],
    "meshes" : [
        {
            "extras" : {
                "tags" : "babylon_tag",
                "test" : "custom_tag",
                "autoPlaySound" : 0
            },
            "name" : "Cube",
            "primitives" : [
                {
                    "attributes" : {
                        "POSITION" : 0,
                        "NORMAL" : 1,
                        "TEXCOORD_0" : 2
                    },
                    "indices" : 3,
                    "material" : 0
                }
            ]
        }
    ],
//...

And when I try to create a custom property named Tags, Blender automatically replaces this property with Baylon tags. The cursor moves itself to the BabylonJS section.

Here are the export settings, if it helps in any way:

@babylonjs/loaders”: “^5.52.0”,
@babylonjs/core”: “^5.52.0”

Blender 2.93.8

cc @bghgary

The glTF scene structure is not a 1-to-1 mapping to Babylon scene structure. There is not a perfect place to store glTF extras for a glTF mesh because there is no equivalent object that represents a glTF mesh in Babylon.

If you can provide a playground of what you have so far with the custom loader extension, I can help you modify the code to make it work.

2 Likes

Hello! I created a sandbox. I will be glad of your help.

Code GLTF: test/test.gltf at main · wdda/test · GitHub

Here is one way to do it: https://playground.babylonjs.com/#XL1M1C#1

3 Likes

Thank you for your help!

1 Like

@bghgary This topic became interesting for us as well, as we got a request to import tags from Blender from our customer.

You mentioned the issue of the 1-to-1 mapping between Babylon and glTF meshes, which I understand to a certain extend, whereas I would say that a glTF node is quite close to a Babylon mesh, isn’t it?

I found the ExtrasAsMetadata glTF plugin, which IMO adresses the same topic as well.
=> extras are extracted from glTF node and added as metadata to a Babylon mesh.
So couldn’t we just do the same with tags?
=> extract extras.tags from glTF node and add as tags to Babylon mesh.

I’d be willing to contribute this code by myself.
Just let me know if this concept would work or if I am missing something here.

Sort of. I think I explained this in other threads already but let me know if something is not clear.

Maybe. It’s tricky because tags are not a concept in glTF. Anything in extras are considered application specific and is generic. Are tags something specific in Blender or is someone just putting this as a property that gets exported as extras? I think if we want this to be consistent and generic, it needs to be in a custom glTF extension. Barring that, it should just be a specific glTF loader extension customized to the specific scenario.

Hi @bghgary,
thx for the response, totally makes sense to me.
I was just curious if this is something that would benefit the framework in general.

Anyway, we decided to bypass the Babylon.js tags framework and use the Blender tags directly from metadata.gltf.extras, which also works for us.

1 Like