VCityTeam / UD-Viz

UD-Viz is a javascript mono repository for creating web applications for visualizing and interacting with geospatial 3D urban data.
Other
36 stars 18 forks source link

Clean CityObject #594

Closed valentinMachado closed 1 year ago

valentinMachado commented 1 year ago

This class should be the first thing to discuss, as many of the other issue of #590 and thus #584 are related to it. Basically it's record an interval in the vertex array of the 3DTile (or a batch id) to attach some semantic to it (props which are stored in the batchtable)

For me it's not relevant but I might miss some use case so do not hesiate to expose your opinion over there.

References

EricBoix commented 1 year ago

Hints:

Refactoring CityObject

  1. Ditch CityObject code
  2. propose a 3DTile extension describing some "semantic annotation". Such an extension would announce that the tileset distinguishes between e.g. three types of BatchIDs: tree, building and road. The extension would then point to the field holding that information in the batchId (batchid numbere 14 is a tree). Note: this is a known issue
  3. As always for Extensions, one must code the client side (iTowns) extension. It will be up to the "semantic annotation" extension hook to propose where to store and in what form (for example is could create a CityGMLTree instance that would hold the gmlID in a 3DCityDB).
  4. propose a 3DTile extension describing some styles that could be base on Cesium 3DTiles extension or could be based on iTowns's Style (to be explored).
  5. propose a last 3DTiles extension, depending both of "semantic annotation" and style that proposes to attach a default style to sematic/category.
valentinMachado commented 1 year ago

Hints:

valentinMachado commented 1 year ago
  • IMHO The original notion for the creation of the CityObject class was to try to retrieve some CityGML semantics after the loss of that data source domain information when squeezing things into a 3DTile (that has no notion of CityGML or IFC data model).

In batchtable (which is the place to add semantics related to a batch id) a gml_id can be attached to a batch_id which I presume point to this CityGML semantics (geometry <== batch id ==> gml_id <==> city_gml ??).

A question could be what are suppose to do CityObject that batch id cannot ? In other word a CityObject could be something else that a geometry + data in the batchtable ?

valentinMachado commented 1 year ago

Here it's writed that you can also attached a batch id to a cityobject.database_id (pointing to the one you mentioned I guess/hope) via batchtable. If that's the case, since this data (cityobject.database_id) is optional in batchtable (it could be empty or point to a gml_id) calling a batch id a CityObject in ud-viz is confusing.

LorenzoMarnat commented 1 year ago

About B3DM

With Py3DTilers, the 3DTiles we create are Batched 3D Models (B3DM). The B3DM file contains a binary glTF part. For rendering purposes, in a B3DM file each glTF mesh can contain several models (instead of having one mesh per model). If the mesh has more than one model, we associate a batch ID to each vextex:

batchId:  [0,   0,   0,   ..., 1,   1,   1,   ..., 2,   2,   2,   ...]
position: [xyz, xyz, xyz, ..., xyz, xyz, xyz, ..., xyz, xyz, xyz, ...]
normal:   [xyz, xyz, xyz, ..., xyz, xyz, xyz, ..., xyz, xyz, xyz, ...]

We can use those batch IDs to find all the vertices of a model and to split the batched models of the glTF mesh. We can also use those batch IDs to associate semantic data to the models. The semantic data is in the Batch Table and is written (with Py3DTilers) as JSON:

{
"prop1":  ["A", "B", "C", "A", ...],
"prop2": [1, 2, 2, 3, ...],
"prop3":   ["BLUE", "RED", "GREEN", "YELLOW", ...]
}

If the model has a batch ID equal to 1, it means that its semantic data will be at the index 1 of each property ("B", 2, "RED").

About CityObject

When iTowns loads B3DM 3DTiles, the batch IDs are in the attributes of the THREE mesh (as well as normals and positions). iTowns implements a method to find the semantic data associated to a batch ID by raycasting: since the raycast hits a (THREE) triangle, you can find the batch ID in the attributes of the vertices of this triangle.

BUT, iTowns doesn't split the batched models of a tile and has no method to find all the vertices corresponding to a model/batch ID. We've created the CityObject class to be able to easily 'split' a model from the rest of the mesh (for example by applying a color only on a sub-part of the vertices). If we want to delete the CityObject class, we need iTowns to implement methods which:

clementcolin commented 1 year ago

A question could be what are suppose to do CityObject that batch id cannot ? In other word a CityObject could be something else that a geometry + data in the batchtable ?

I do not recall a specific use of a GMLID in UD-Viz (as we never created a widget to retrieve semantic data from a 3DCityDB). CityObject was created when we were working only with CityGML data, transformed in 3DTiles. Now that we work with more data models, I think that it would be best to make this concept in UD-Viz more generic, are directly in Itowns, by completing C3DTileset class and C3Tiles Layer

Usually, what is done on 2D Geometry is to call each object a Feature, and give him attributes, such as it's Id. Itowns created a few months ago a FeatureGeometryLayer, that follows this mechanism : it creates a 3D Object from 2D Vector Data and a batch table if needed to retrieve each individual object from the batched geometry. Extending some methods of this type of layer (style and event) to the existing C3DTiles Layer would actually meet some of our need.

clementcolin commented 1 year ago

More specifically and functionally, the CityObject concept in UD-Viz was used to :

valentinMachado commented 1 year ago
  • iTowns implements a method to find the semantic data associated to a batch ID by raycasting: since the raycast hits a (THREE) triangle, you can find the batch ID in the attributes of the vertices of this triangle.

You can directly find the semantics with the batchtable, i guess what you mean is when you raycast the THREE.Object3D you can retrieve batch id and so the semantics associated to it

  • can find all the vertices corresponding to a model (without iterating on the whole mesh each time)

Storing indexStart and indexEnd can be used to retrieve directly the part of the vertex array needed (and avoid to iterate on the whole mesh geometry buffer each time). But I think we should prioritize readability over performance in the first place (and in fact I think this is not a performance gap and there are many other performance topic to deal with first).

  • can create groups in the mesh geometry
  • can associate a material to each group

These methods sounds like THREE.js static methods since nothing justify to create a class and are proper to THREE.js, we could just implement them as THREEUtil for now and then when it come to contribute with itowns, discuss with them the need of thoses methods

valentinMachado commented 1 year ago
  • Style CityObject (or traditionally, Feature) in a 3DTiles tileset. 3DObject styling still need further research and experimentation, but it can be made generic and only associated to the 3DTiles concept (i.e free from the CityObject class)

itowns has a Style class what we could do is a function that apply this style to batch id (a first implementation could be the color of the material is the fill color) in the futur it could be a bit more complex (if we handle outline and so on)

From what you said every functionalities seems to be already in itowns (except maybe for some stateless util methods, that should be easy to contribute).

So CityObject class + CityObjectStyle #595 should go home