Closed valentinMachado closed 1 year ago
Hints:
CityObject
is one of the core classes of CityGML-3.0 (refer to e.g. AbstractCityObject
within the core module overview or to its textual definition). CityObject
is defined as being the base class of all thematic classes within the CityGML conceptual model [...] that provide CityGML objects with location, geometry and boundary properties. In order to visualize CityGML objects within iTwons one needs to format the corresponding information with one of the iTowns supported formats. When choosing 3DTiles for this encoding, the semantics of CityGML source is lost (since 3DTiles focuses on geometry). Once the data is on the client side (and fit for visualization) the original semantics are lost: there is no way to know that this triangle-soup is either a tree, a building or a river. Re-introducing some semantics (or introducing them back) in the visualization model (i.e. in ITowns) is of course the occasion to add advanced features (on the client side). For example it allows to apply some rendering styling that can now be expressed as 'display the buildings in blue).
- 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 ?
- py3dTilers has an equivalent notion of citym_cityobject
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.
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").
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:
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.
More specifically and functionally, the CityObject concept in UD-Viz was used to :
Create CityObject (or traditionally, Feature) from a 3DTiles tileset
Associate / Reference its batch table data and geometry from a tile (the UD-Viz tile class
Getters to retrieve a CityObject (or traditionally, Feature) using semantic data in the batch (typically it's ID) Those functionalities can live (if not already the case) in itowns.
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 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
- 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
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