From f084f925252e99b4d7cdd2b19b52918b5306504e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Dukai?= Date: Mon, 9 Jan 2023 14:41:55 +0100 Subject: [PATCH] Gltf triangulate argument --- CHANGELOG.md | 4 +++ cjio/cityjson.py | 4 +-- cjio/convert.py | 66 +++++++++++++++++++++++++++++++----------------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f39c7fe..553768a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ - Added the `translate` paramter to `cityjson.compress` to manually set the tranlation properties instead of computing from the data. - The `cityjson.cityjson_for_features` and `cityjson.generate_features` methods. +### Changed +- The glb converter (`to_glb`) sets a root transformation matrix for z-up to y-up, instead of swapping the vertex coordinates directly. +- The glb converter takes a `do_triangulate` argument to completely skip triangulation. + ## [0.8.0] – 2022-11-28 ### Added - added functions for reading/writing CityJSONL (CityJSONFeatures) from stdin/stdout, so cjio can be part of a pipeline of operators processing 3D city models 🚀 diff --git a/cjio/cityjson.py b/cjio/cityjson.py index 0c0589a..1476b53 100644 --- a/cjio/cityjson.py +++ b/cjio/cityjson.py @@ -1571,9 +1571,9 @@ def export2b3dm(self): return b3dm - def export2glb(self): + def export2glb(self, do_triangulate=True): self.decompress() - glb = convert.to_glb(self) + glb = convert.to_glb(self, do_triangulate=do_triangulate) return glb def export2jsonl(self): diff --git a/cjio/convert.py b/cjio/convert.py index 3b5c607..cfab167 100644 --- a/cjio/convert.py +++ b/cjio/convert.py @@ -96,7 +96,7 @@ def to_b3dm(cm, glb): return b3dm_bin -def to_glb(cm): +def to_glb(cm, do_triangulate=True): """Convert to Binary glTF (.glb) Adapted from CityJSON2glTF: https://github.com/tudelft3d/CityJSON2glTF @@ -188,35 +188,55 @@ def to_glb(cm): matid = 9 material_ids.append(matid) - # TODO: skip triangulation if already triangulated - for geom in cm.j['CityObjects'][theid]['geometry']: - poscount = poscount + 1 - if geom['type'] == "Solid": - triList = [] - for shell in geom['boundaries']: - for face in shell: + if do_triangulate: + for geom in cm.j['CityObjects'][theid]['geometry']: + poscount = poscount + 1 + if geom['type'] == "Solid": + triList = [] + for shell in geom['boundaries']: + for face in shell: + tri, success = geom_help.triangulate_face(face, vertexlist) + if success: + for t in tri: + triList.append(list(t)) + else: + # TODO: logging + print(f"Failed to triangulate face in CityObject {theid}") + trigeom = (flatten(triList)) + + elif (geom['type'] == 'MultiSurface') or (geom['type'] == 'CompositeSurface'): + triList = [] + for face in geom['boundaries']: tri, success = geom_help.triangulate_face(face, vertexlist) if success: for t in tri: - triList.append(list(t)) + triList.append(t) else: # TODO: logging print(f"Failed to triangulate face in CityObject {theid}") - trigeom = (flatten(triList)) - - elif (geom['type'] == 'MultiSurface') or (geom['type'] == 'CompositeSurface'): - triList = [] - for face in geom['boundaries']: - tri, success = geom_help.triangulate_face(face, vertexlist) - if success: - for t in tri: + trigeom = (flatten(triList)) + else: + # If the caller says it's triangulate, then we trust that it's + # triangulated. + for geom in cm.j['CityObjects'][theid]['geometry']: + poscount = poscount + 1 + if geom['type'] == "Solid": + triList = [] + for shell in geom['boundaries']: + for face in shell: + for t in face: + triList.append(list(t)) + trigeom = (flatten(triList)) + + elif (geom['type'] == 'MultiSurface') or ( + geom['type'] == 'CompositeSurface'): + triList = [] + for face in geom['boundaries']: + for t in face: triList.append(t) - else: - # TODO: logging - print(f"Failed to triangulate face in CityObject {theid}") - trigeom = (flatten(triList)) - flatgeom = trigeom - forimax.append(flatgeom) + trigeom = (flatten(triList)) + flatgeom = trigeom + forimax.append(flatgeom) #----- buffer and bufferView flatgeom = flatten(forimax)