tudelft3d/val3dity

Potentially valid object is stated as invalid by val3dity

Closed this issue ยท 9 comments

Since I don't come closer to a solution I post this as a question.

I have this simple object in CityJSON and it validates correctly with cjio. But I'am not able to convince val3dity to do so. Maybe someone could have look at it?

Thanks in advance.

Happy new year!

{"type":"CityJSON","version":"1.0","metadata":{"datasetReferenceDate":"2020-01-07","referenceSystem":"urn:ogc:def:crs:EPSG::2056","geographicalExtent":[2609482.573,1262755.868,307.460,2609487.330,1262760.514,311.870]},"CityObjects":{"17087":{"type":"Building","geographicalExtent":[2609482.573,1262755.868,307.460,2609487.330,1262760.514,311.870],"attributes":{"LOD":2,"capacity":40.12,"capacity_ag":38.63,"eaves_z":310.36,"max_z":311.87,"mean_z":310.40,"min_z":307.46,"meas_height":4.41,"slope":0.00,"aspect":0.00,"egid":245030995,"projektiert":0},"geometry":[{"type":"Solid","lod":2.0,"boundaries":[[[[0,1,2,3,4,5]],[[6,7,0,5]],[[7,8,1,0]],[[9,6,5,4]],[[10,11,3,2]],[[11,12,4,3]],[[12,13,9]],[[8,14,15]],[[15,10,2,1]],[[6,9,13,14,8,7]],[[10,15,14,13,12,11]]]],"semantics":{"values":[[0,1,1,1,1,1,1,1,1,2,2]],"surfaces":[{"type":"GroundSurface"},{"type":"WallSurface"},{"type":"RoofSurface"}]}}]}},"vertices":[[87329,58449,7459],[86468,57220,7459],[85519,55868,7459],[82572,57932,7459],[83721,59569,7459],[84383,60513,7459],[84383,60513,10433],[87329,58449,10459],[86468,57220,11582],[83721,59569,11296],[85519,55868,10358],[82572,57932,10382],[83721,59569,11870],[83623,59170,11584],[86425,57246,11585],[86468,57220,11587]],"transform":{"scale":[0.001,0.001,0.001],"translate":[2609400.0,1262700.0,300.0]}}

Edit:
The announced points in question seems to be outside the building.

Report from val3dity:

{
  "errors_dataset": null,
  "features": [
    {
      "errors_feature": null,
      "id": "17087",
      "primitives": [
        {
          "errors": [
            {
              "code": 302,
              "description": "SHELL_NOT_CLOSED",
              "id": "",
              "info": "Location hole: (2.60949e+06, 1.26276e+06, 311.582)",
              "type": "Error"
            },
            {
              "code": 302,
              "description": "SHELL_NOT_CLOSED",
              "id": "",
              "info": "Location hole: (2.60948e+06, 1.26276e+06, 307.459)",
              "type": "Error"
            }
          ],
          "id": "17087(0)",
          "numberfaces": 11,
          "numbershells": 1,
          "numbervertices": 16,
          "type": "Solid",
          "validity": false
        }
      ],
      "type": "Building",
      "validity": false
    }
  ],
  "input_file": "17087.json",
  "invalid_features": 1,
  "invalid_primitives": 1,
  "overlap_tol": -1.0,
  "overview_errors": [
    302
  ],
  "overview_features": [
    "Building"
  ],
  "overview_primitives": [
    "Solid"
  ],
  "planarity_d2p_tol": 0.01,
  "planarity_n_tol": 20.0,
  "snap_tol": 0.001,
  "time": "Thu Jan  9 09:39:46 2020 UTC",
  "total_features": 1,
  "total_primitives": 1,
  "type": "val3dity report",
  "val3dity_version": "2.1.1",
  "valid_features": 0,
  "valid_primitives": 0
}

On the first look I can see that the reported "Location hole" is in the models, since those are vertices of the object (5th and 9th I think). I checked this on the decompressed file.
building_uncompressed.zip

I tried to visually find the location in Blender but without success yet.

But converting to OBJ and checking the topology with Meshlab reports two holes, so those holes are there somehow.
building2.zip

Meshlab report:

V: 16 E: 42 F: 26
Unreferenced Vertices 0
Boundary Edges 6
Mesh is composed by 1 connected component(s) 
Mesh is two-manifold 
Mesh has 2 holes
Genus is 0

Hi,
I did some further tests - I imported the OBJ in Meshlab, used the "close holes" filter, and exported the data again as OBJ. Meshlab inserted two vertical faces/triangles without area (same x,y coordinates, three different z coordinates). After the export the coordinates of the vertices are slightly mangled, but the 16 vertices can be mapped back to the 16 original ones.

Newly added faces by meshlab's 'close holes':

2,9,16
v 2609486.500000 1262757.250000 307.459015
v 2609486.500000 1262757.250000 311.582001
v 2609486.500000 1262757.250000 311.587006

10,5,13
v 2609483.750000 1262759.625000 311.295990
v 2609483.750000 1262759.625000 307.459015
v 2609483.750000 1262759.625000 311.869995

corresponding vertices in original obj:

v 2609486.468 1262757.22 307.459
v 2609486.468 1262757.22 311.582
v 2609486.468 1262757.22 311.587

v 2609483.721 1262759.569 311.296
v 2609483.721 1262759.569 307.459
v 2609483.721 1262759.569 311.87

After some discussions I think we found the reason why those two triangles were inserted - they are required to make the mesh topologically consistent. Have a look at my small sketch:

missing_vertex

The wall on the right is missing the vertex on its left edge where the left wall is touching. This vertex is currently not inserted due to how our building reconstruction algorithm works.

Seems like a borderline case - not sure if this make the model really "not watertight". But we will try to change our implementation in order to avoid such cases.

Best regards,
Volker

Thanks everyone for digging. We can close that and state: val3dity is always right ๐Ÿ‘

We can close that and state: val3dity is always right ๐Ÿ‘

To this I say halleluiah!

Seems like a borderline case - not sure if this make the model really "not watertight". But we will try to change our implementation in order to avoid such cases.

ISO 19107 is not really clear on that case indeed (since point-set topology is used to describe the cases, and not a graph-based approach). I decided that it's invalid in val3dity because otherwise the work involved to validate would have been more complex and the process slower.

I've just fixed this in our algorithm, now both val3dity and Meshlab report "valid" for this building model. So the suspicion has been confirmed :-)

@vwichmann I need to understand correctly please.
Your saying; that if I have a .obj with a similar challenge as your sketch above (missing vertices); the Meshlab 'close holes' filter will place additional faces? Why would the result not be a 'water-tight' surface?

I just used the Meshlab "close holes" filter for debugging and error detection. The meshing done by their algorithm adds two vertical triangles (without area) to fix the topology at the position where the vertex is missing.

The "is a surface water-tight?" discussion was more general - the object can also be seen as being "water-tight" without the missing vertex, there is no hole in the geometry. So the model would be "water-tight" in both cases. But from a geometric perspective it is clearly favorable if the vertex is inserted.