EXT_mesh_features: Features and Properties for structured data#2082
EXT_mesh_features: Features and Properties for structured data#2082donmccurdy wants to merge 12 commits intoKhronosGroup:mainfrom
Conversation
|
Some earlier context on the use cases this extension addresses: |
|
Talked with @wallabyway and others today and there were some interesting interesting takeways. There is a strong need for global feature IDs. In some systems these are 64-bit uints; after all 32-bit uints can only represent up to 4,294,967,295 discrete features and collisions could start to occur for a variety of reasons. The In order to support 64-bit IDs you'd need to store these in a property table with the An example of this might be worth including in the extension writeup. |
|
Good point on the UINT24 (safe float)... We render to a target buffer RGBA (using MRT) to get UINT32 featureID (equivalent), but that complicates implementation for others. Hmmm🤔 what to do? |
|
RE: The section in the spec on 'Schema-definitions' Is it possible to limit this spec to just a featureID and not define how the ID is used? Currently, the spec has a schema requirement, which is a bit too limiting for our AEC use-cases. Having just an featureID requirement, and not a schema definition, broadens the use for this extension. Or perhaps I mis-interpreted the "Schema-definitions" section of the spec. |
The schema definition itself is not required in the top-level extension object
I think that the case that you are referring to is already covered in the "Specifying Feature IDs" section. It says
So it is valid to say to assign Feature IDs to the triangles of a primitive, without specifying property tables, and therefore without assigning any internal meaning to these IDs. These IDs could then be picked up and resolved externally by an application. (Maybe I overlooked some other requirement - so if there is a reason why this wouldn't be possible based on the specification, then this should indeed be clarified). |
|
@javagl - Ah, thank you ! I think this is worth explicitly mentioning "what you said" somewhere in the spec. ie. Basically "What you said" 'verbatim', along with your json example. |
FWIW my understanding of the spec is that this only works for un-indexed geometry. |
|
Yeah, if you assign a unique feature ID to each triangle like with But more often groups of triangles will have the same feature ID and you can still benefit from indexed geometry. Maybe the example should be |
|
@lilleyse Hmm I'd like to clarify this to make sure we're on the same page. My understanding is that using offset/repeat doesn't actually make all vertices unique by itself. What I meant is that typically in indexed geometry, there's no obvious mapping between the vertices and triangles (well, short of the index buffer). When you specify offset=0 repeat=3, my understanding of the spec is that you're taking the existing vertices - whatever the number and order - and assigning feature ids to vertices, the same one to each 3 consecutive ones. If the geometry is not indexed, this in effect will result in all 3 vertices of each triangle having a unique feature id. If the geometry is indexed, you're going to get the same mesh with the same indexing, but the feature ids are not going to map to triangles. As a positive example, imagine a tool that batches N instances of the same mesh together by transforming each instance, generating a new vertex buffer, concatenating all vertex buffers and index buffers together. E.g. gltfpack does that on request. In this case, if each mesh had V vertices and T triangles, you can specify |
|
@zeux yes exactly, everything you wrote is my understanding too. |
ptrgags
left a comment
There was a problem hiding this comment.
Just wanted to cross-link a couple relevant issues/PRs from our end for better visibility.
| } | ||
| }, | ||
| { | ||
| "description": "Implicit feature ID. Both 'offset' and 'repeat' are optional; 'attribute' is disallowed.", |
There was a problem hiding this comment.
Note that we've had some back-and-forth about the best way to describe the different types of feature IDs in JSON schema, see CesiumGS/3d-tiles#508.
The issue is that this very flexible definition of implicit feature IDs causes problems when used in this oneOf clause, as a valid featureIdTexture is valid here as well.
|
The latest update that has been integrated here separates the definition of feature IDs for elements of a glTF asset from the actual storage and structure of metadata. This extension now focusses on the definition of feature IDs for vertices and texels in a glTF asset. The definition of the structure and storage of metadata is covered with the |
|
This extension is already in use by published software, right? Is this ready to be merged? |
|
(Disclosure: I'm an independent Khronos contributor, but have been involved in the development of this extension as part of contracted (freelancer) work for Cesium. I do not speak on behalf of Khronos or Cesium here, but just try to summarize the state) Support for reading the extension is implemented in CesiumJS. Basic structures for the extension are part of I think that further reviews could be worthwhile. But as for all extension PRs, there's the question: Who of the WG could allocate the time that is necessary for that...? |
Change integer to glTFid
|
Excellent idea! If you don't mind me asking, what is the rationale against using XMP/JSON-LD like the There are at least 2 reasons for using XMP/JSON-LD:
|
|
Given that there is the same comment in another PR, I think that it could make sense to address some of that with first, high level answer in one place (and split the discussion in the PRs only when necessary). And I'll have to start with a disclaimer: I know that there are many, many, MANY standards for metadata, schemas, taxonomies, ontologies, with everything that falls under the umbrella of "semantic web" and beyond. But I don't have a clue about all that. If someone claims to be able to give an executive summary that covers everything that is relevant here, drop me a note 😉 On a high level, the main differences between this proposal (and the Specifically: The the For example, consider a Building on top of that, these IDs can be associated with metadata using the |
It is the sole purpose of my question actually. I'm the main author/designer of the tech behind https://smartshape.com/. Wich we are rebuilding from scratch using glTF 2.0 as the representation layer. When I "discovered" the only way to support metadata on a per object basis was
So I started wondering: maybe the XMP/JSON-LD extension (and it's added complexity) has its purpose. And I started reviewing each of those requirements: do they have an existing W3C/ISO standard that can be leveraged by XMP/JSON-LD? And the answer is yes. I mentioned ORDL and Web Annotations. But surely there are others. And since glTF aims at being 1. standard and 2. a transmission format, I now think those standards apply.
I think I understand that. That's one of the challenges when we're dealing with (for example):
So IMHO I think I understand why those extensions proposal exist. And I want them to exist. Actually I want to implement them!
My understanding is that the schema is JSON cf https://github.com/CesiumGS/glTF/tree/proposal-EXT_structural_metadata/extensions/2.0/Vendor/EXT_structural_metadata#class) but the actual data (matching that schema) is binary (in a So my question is: why a custom JSON format and not XMP/JSON-LD? For example, "classes" sounds a lot like an RDF definition. XMP/JSON-LD already has namespaces to avoid class name collisions. {
"@context": {
"mv": "http://example.org/movement/1.0#",
"xmp": "http://ns.adobe.com/xap/1.0/",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"@type": "mv:PointCloudMovement",
"mv:schema": {
"@id": "mv:Movement",
"@type": "rdfs:Class",
"rdfs:label": "Movement",
"rdfs:comment": "The movement of points in a point cloud",
"mv:properties": [
{
"@id": "mv:direction",
"@type": "rdf:Property",
"rdfs:label": "direction",
"rdfs:comment": "The movement direction, as a normalized 3D vector",
"mv:datatype": "mv:Vec3",
"mv:componentType": "xsd:float",
"mv:required": true
},
{
"@id": "mv:magnitude",
"@type": "rdf:Property",
"rdfs:label": "magnitude",
"rdfs:comment": "The magnitude of the movement",
"mv:datatype": "mv:Scalar",
"mv:componentType": "xsd:float",
"mv:required": true
}
]
},
"mv:propertyMappings": {
"@type": "mv:AttributeMapping",
"mv:namespace": "mv",
"mv:mappings": {
"mv:direction": {
"mv:attribute": "_DIRECTION"
},
"mv:magnitude": {
"mv:attribute": "_MAGNITUDE"
}
}
}
}Now it sounds like a lot of efforts for just a different JSON. But really it's not. For example JSON-LD supports composition: {
"@context": {
"mv": "http://example.org/movement/1.0#",
"schema": "http://schema.org/",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"pc": "http://example.org/pointcloud/1.0#"
},
"@graph": [
{
"@id": "pc:AnimatedPointCloud",
"@type": ["schema:Dataset", "pc:PointCloudDataset"],
"schema:name": "Animated Point Cloud with Movement Data",
"schema:description": "A point cloud dataset composed of geometry and movement information",
"schema:hasPart": [
{"@id": "pc:GeometryComponent"},
{"@id": "mv:MovementComponent"},
{"@id": "pc:ColorComponent"}
],
"schema:isPartOf": {
"@id": "pc:LargerDatasetCollection"
}
},
{
"@id": "pc:GeometryComponent",
"@type": "pc:PointCloudGeometry",
"schema:name": "Point Geometry",
"pc:schema": {
"@id": "pc:Position",
"@type": "rdfs:Class",
"rdfs:label": "Position",
"rdfs:comment": "3D position of points",
"pc:properties": [
{
"@id": "pc:coordinates",
"@type": "rdf:Property",
"rdfs:label": "coordinates",
"pc:datatype": "pc:Vec3",
"pc:componentType": "xsd:float",
"pc:required": true
}
]
},
"pc:propertyMappings": {
"@type": "pc:AttributeMapping",
"pc:mappings": {
"pc:coordinates": {
"pc:attribute": "_POSITION"
}
}
}
},
{
"@id": "mv:MovementComponent",
"@type": "mv:PointCloudMovement",
"schema:name": "Movement Data",
"mv:schema": {
"@id": "mv:Movement",
"@type": "rdfs:Class",
"rdfs:label": "Movement",
"rdfs:comment": "The movement of points in a point cloud",
"mv:properties": [
{
"@id": "mv:direction",
"@type": "rdf:Property",
"rdfs:label": "direction",
"rdfs:comment": "The movement direction, as a normalized 3D vector",
"mv:datatype": "mv:Vec3",
"mv:componentType": "xsd:float",
"mv:required": true
},
{
"@id": "mv:magnitude",
"@type": "rdf:Property",
"rdfs:label": "magnitude",
"rdfs:comment": "The magnitude of the movement",
"mv:datatype": "mv:Scalar",
"mv:componentType": "xsd:float",
"mv:required": true
}
]
},
"mv:propertyMappings": {
"@type": "mv:AttributeMapping",
"mv:namespace": "mv",
"mv:mappings": {
"mv:direction": {
"mv:attribute": "_DIRECTION"
},
"mv:magnitude": {
"mv:attribute": "_MAGNITUDE"
}
}
}
},
{
"@id": "pc:ColorComponent",
"@type": "pc:PointCloudColor",
"schema:name": "Color Information",
"pc:schema": {
"@id": "pc:Color",
"@type": "rdfs:Class",
"rdfs:label": "Color",
"rdfs:comment": "RGB color values for points",
"pc:properties": [
{
"@id": "pc:rgb",
"@type": "rdf:Property",
"rdfs:label": "rgb",
"rdfs:comment": "RGB color values",
"pc:datatype": "pc:Vec3",
"pc:componentType": "xsd:unsignedByte",
"pc:required": true
}
]
},
"pc:propertyMappings": {
"@type": "pc:AttributeMapping",
"pc:mappings": {
"pc:rgb": {
"pc:attribute": "_COLOR"
}
}
}
},
{
"@id": "pc:LargerDatasetCollection",
"@type": "schema:DataCatalog",
"schema:name": "Time-Series Point Cloud Collection"
}
]
}or inheritance: {
"@context": {
"mv": "http://example.org/movement/1.0#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"@graph": [
{
"@id": "mv:Motion",
"@type": "rdfs:Class",
"rdfs:label": "Motion",
"rdfs:comment": "Base class for any kind of motion"
},
{
"@id": "mv:LinearMotion",
"@type": "rdfs:Class",
"rdfs:subClassOf": {"@id": "mv:Motion"},
"rdfs:label": "Linear Motion",
"rdfs:comment": "Motion along a straight line"
},
{
"@id": "mv:RotationalMotion",
"@type": "rdfs:Class",
"rdfs:subClassOf": {"@id": "mv:Motion"},
"rdfs:label": "Rotational Motion",
"rdfs:comment": "Motion around an axis"
},
{
"@id": "mv:ComplexMotion",
"@type": "rdfs:Class",
"rdfs:subClassOf": [
{"@id": "mv:LinearMotion"},
{"@id": "mv:RotationalMotion"}
],
"rdfs:label": "Complex Motion",
"rdfs:comment": "Motion combining linear and rotational components (multiple inheritance)"
}
]
}What if I want to filter a CAD file using metadata? RDF and JSON-LD already has query languages like SPARQL. So with XMP/JSON-LD the metadata would follow the same logic as the existing per-object metadata, re-use the same definitions, leverage composition/inheritance, leverage the whole existing standard ecosystem such as querying. |
That is correct.
That's a good question, and I cannot give a definite answer right now. Some possible reasons that I could come up with, on a high level:
Maybe some of the developers of the XMP extension and the metadata extensions can chime in here with additional thoughts and details. |
|
I think this extension is in a pretty good state, but there's a few things I've been thinking about:
|
|
|
|
Notes from meeting with @lexaknyazev, @abwood, and @weegeekps
|
|
And some next steps:
|
Also Option 0: keep the schema as-is and specify that if |
|
|


EXT_mesh_featuresdefines a means of storing structured metadata associated with geometry and subcomponents of geometry within a glTF 2.0 asset.In most realtime 3D contexts, performance requirements demand minimizing the number of nodes and meshes in an asset. These requirements compete with interactivity, as applications may wish to merge static objects while still supporting interaction or inspection on those objects. Common performance optimizations for GPU rendering — like merging geometry or GPU instancing to reduce CPU overhead — may destroy references to distinct objects, their attributes, and their behaviors.
By defining a representation of conceptual objects ("features") distinct from rendered geometry, and a means of associating structured metadata ("properties") with those features, this extension allows applications to preserve important details of 3D assets for inspection and interaction without compromising runtime performance and draw calls.
This extension will be used by embedded glTF content in 3D Tiles for loading large, tiled geospatial datasets. The extension's design is intended to be similarly useful for individual glTF 2.0 assets outside of geospatial use cases, like large AEC designs, CAD models, or photogrammetry captures.
Markdown Preview: