From c9b9c8b38db2ff018a6dcc09a4c62364730e8533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Sun, 26 Nov 2017 13:03:26 +0100 Subject: [PATCH] make sure triangulate_rings does not create triangles with no area --- src/c3nav/mapdata/render/engines/wavefront.py | 4 ++-- src/c3nav/mapdata/utils/mesh.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/c3nav/mapdata/render/engines/wavefront.py b/src/c3nav/mapdata/render/engines/wavefront.py index 33b8ba98..2b6dd9c2 100644 --- a/src/c3nav/mapdata/render/engines/wavefront.py +++ b/src/c3nav/mapdata/render/engines/wavefront.py @@ -20,7 +20,7 @@ class WavefrontEngine(Base3DEngine): vertices_lookup = {vertex: i for i, vertex in enumerate(vertices, start=1)} normals = np.cross(facets[:, 1] - facets[:, 0], facets[:, 2] - facets[:, 1]).reshape((-1, 3)) - normals = normals / np.maximum(1, np.amax(np.absolute(normals), axis=1)).reshape((-1, 1)) + normals = normals / np.amax(np.absolute(normals), axis=1).reshape((-1, 1)) normals = tuple(set(tuple(normal) for normal in normals)) normals_lookup = {normal: i for i, normal in enumerate(normals, start=1)} @@ -50,7 +50,7 @@ class WavefrontEngine(Base3DEngine): if not facets.size: continue normals = np.cross(facets[:, 1] - facets[:, 0], facets[:, 2] - facets[:, 1]).reshape((-1, 3)) - normals = normals / np.maximum(1, np.amax(np.absolute(normals), axis=1)).reshape((-1, 1)) + normals = normals / np.amax(np.absolute(normals), axis=1).reshape((-1, 1)) normals = tuple(normals_lookup[tuple(normal)] for normal in normals) result += ((b'g %s_%d_%d\n' % (subgroup.encode(), i, j)) + (b'usemtl %s\n' % subgroup.encode()) + diff --git a/src/c3nav/mapdata/utils/mesh.py b/src/c3nav/mapdata/utils/mesh.py index 120a2787..6481d7aa 100644 --- a/src/c3nav/mapdata/utils/mesh.py +++ b/src/c3nav/mapdata/utils/mesh.py @@ -44,7 +44,16 @@ def triangulate_rings(rings, holes=None): info.set_holes(np.rint(np.array(holes)*1000)) mesh = triangle.build(info, quality_meshing=False) - return np.rint(np.array(mesh.points)).astype(np.int32), np.array(mesh.elements, dtype=np.uint32) + + mesh_points = np.rint(np.array(mesh.points)).astype(np.int32) + mesh_elements = np.array(mesh.elements, dtype=np.uint32) + + # remove triangles with no area + facets = np.dstack((np.zeros(mesh_elements.shape), mesh_points[mesh_elements])) + ok_index = np.cross(facets[:, 1] - facets[:, 0], facets[:, 2] - facets[:, 1]).max(axis=1) != 0 + mesh_elements = mesh_elements[ok_index] + + return mesh_points, mesh_elements def _triangulate_polygon(polygon: Polygon, keep_holes=False):