From 4d5bf8cf7fbe2560f25bd6e1db976a47dbbe69ac Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 10:31:08 +0200 Subject: [PATCH 1/8] use correct index --- src/compas/topology/orientation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compas/topology/orientation.py b/src/compas/topology/orientation.py index 4593a58e816..09f7abd9ae3 100644 --- a/src/compas/topology/orientation.py +++ b/src/compas/topology/orientation.py @@ -88,7 +88,7 @@ def _face_adjacency(vertices, faces, nmax=10, radius=10.0): found.add(nbr) break - adjacency[face] = nbrs + adjacency[index] = nbrs return adjacency From 8aad5dddd3e3a4f4ec31524cde07649e4b0c52e5 Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 10:31:24 +0200 Subject: [PATCH 2/8] use the orientation function with a bit of preprocessing --- src/compas/datastructures/mesh/mesh.py | 62 ++++++++++++-------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/src/compas/datastructures/mesh/mesh.py b/src/compas/datastructures/mesh/mesh.py index 250e6a8dace..31b3cb8b59c 100644 --- a/src/compas/datastructures/mesh/mesh.py +++ b/src/compas/datastructures/mesh/mesh.py @@ -58,6 +58,7 @@ from compas.topology import breadth_first_traverse from compas.topology import face_adjacency from compas.topology import connected_components +from compas.topology import unify_cycles from compas.datastructures.datastructure import Datastructure from compas.datastructures.attributes import VertexAttributeView @@ -2953,45 +2954,26 @@ def unify_cycles(self, root=None): The mesh is modified in place. """ - - def unify(node, nbr): - # find the common edge - for u, v in self.face_halfedges(nbr): - if u in self.face[node] and v in self.face[node]: - # node and nbr have edge u-v in common - i = self.face[node].index(u) - j = self.face[node].index(v) - if i == j - 1 or (j == 0 and u == self.face[node][-1]): - # if the traversal of a neighboring halfedge - # is in the same direction - # flip the neighbor - self.face[nbr][:] = self.face[nbr][::-1] - return - - if root is None: - root = self.face_sample(size=1)[0] - + vertex_index = {vertex: index for index, vertex in enumerate(self.vertices())} + index_vertex = {index: vertex for index, vertex in enumerate(self.vertices())} index_face = {index: face for index, face in enumerate(self.faces())} - points = self.vertices_attributes("xyz") - faces = [self.face_vertices(face) for face in self.faces()] - - adj = face_adjacency(points, faces) - adjacency = {} - for face in adj: - adjacency[index_face[face]] = [index_face[nbr] for nbr in adj[face]] - visited = breadth_first_traverse(adjacency, root, unify) + vertices = self.vertices_attributes('xyz') + faces = [[vertex_index[vertex] for vertex in self.face_vertices(face)] for face in self.faces()] - if len(list(visited)) != self.number_of_faces(): - raise Exception("Not all faces were visited.") + unify_cycles(vertices, faces) self.halfedge = {key: {} for key in self.vertices()} - for fkey in self.faces(): - for u, v in self.face_halfedges(fkey): - self.halfedge[u][v] = fkey + for index, vertices in enumerate(faces): + face = index_face[index] + vertices = [index_vertex[vertex] for vertex in vertices] + self.face[face] = vertices + for u, v in pairwise(vertices + vertices[:1]): + self.halfedge[u][v] = face if u not in self.halfedge[v]: self.halfedge[v][u] = None + # -------------------------------------------------------------------------- # Components # -------------------------------------------------------------------------- @@ -4413,6 +4395,11 @@ def face_flatness(self, fkey, maxdev=0.02): float The flatness. + Raises + ------ + Exception + If the face has more than 4 vertices. + Notes ----- Flatness is computed as the ratio of the distance between the diagonals @@ -4426,6 +4413,12 @@ def face_flatness(self, fkey, maxdev=0.02): """ vertices = self.face_vertices(fkey) f = len(vertices) + + if f == 3: + return 0.0 + if f > 4: + raise Exception("Computing face flatness for faces with more than 4 vertices is not supported.") + points = self.vertices_attributes("xyz", keys=vertices) or [] lengths = [distance_point_point(a, b) for a, b in pairwise(points + points[:1])] length = sum(lengths) / f @@ -5075,8 +5068,8 @@ def thickened(self, thickness=1.0, both=True): raise ValueError("Thickness should be a positive number.") if both: - mesh_top = self.offset(+0.5 * thickness) - mesh_bottom = self.offset(-0.5 * thickness) + mesh_top = self.offset(+0.5 * thickness) # type: Mesh + mesh_bottom = self.offset(-0.5 * thickness) # type: Mesh else: mesh_top = self.offset(thickness) mesh_bottom = self.copy() @@ -5085,7 +5078,8 @@ def thickened(self, thickness=1.0, both=True): mesh_bottom.flip_cycles() # join parts - thickened_mesh = mesh_top.join(mesh_bottom) + thickened_mesh = mesh_top.copy() # type: Mesh + thickened_mesh.join(mesh_bottom) # close boundaries n = thickened_mesh.number_of_vertices() / 2 From 0d50a8f8c303a23b09d54a58f7ada732cb6d1a5a Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 10:33:10 +0200 Subject: [PATCH 3/8] log --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf9dcdaab07..647ea2c660c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Changed and updated the `compas_view2` examples into `compas_viewer`. * Changed `compas.scene.Scene` to inherent from `compas.datastructrues.Tree`. * Changed `compas.scene.SceneObject` to inherent from `compas.datastructrues.TreeNode`. +* Changed to implementation of `Mesh.unify_cycles` to use the corresponding function of `compas.topology.orientation`. +* Fixed bug in `compas.topology.orientation.unify_cycles`. ### Removed From d7bd1e81b442e9cd5fd6424fa2e7dc980c36b36d Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 10:35:37 +0200 Subject: [PATCH 4/8] log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 647ea2c660c..4225897c627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Changed `compas.scene.SceneObject` to inherent from `compas.datastructrues.TreeNode`. * Changed to implementation of `Mesh.unify_cycles` to use the corresponding function of `compas.topology.orientation`. * Fixed bug in `compas.topology.orientation.unify_cycles`. +* Fixed bug in `Mesh.thickened`. ### Removed From 505d0f1305c1c5973a136c9663429fee24e3cb45 Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 10:38:17 +0200 Subject: [PATCH 5/8] lint --- src/compas/datastructures/mesh/mesh.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compas/datastructures/mesh/mesh.py b/src/compas/datastructures/mesh/mesh.py index 31b3cb8b59c..614482b35b1 100644 --- a/src/compas/datastructures/mesh/mesh.py +++ b/src/compas/datastructures/mesh/mesh.py @@ -56,7 +56,6 @@ from compas.utilities import window from compas.topology import breadth_first_traverse -from compas.topology import face_adjacency from compas.topology import connected_components from compas.topology import unify_cycles @@ -2958,7 +2957,7 @@ def unify_cycles(self, root=None): index_vertex = {index: vertex for index, vertex in enumerate(self.vertices())} index_face = {index: face for index, face in enumerate(self.faces())} - vertices = self.vertices_attributes('xyz') + vertices = self.vertices_attributes("xyz") faces = [[vertex_index[vertex] for vertex in self.face_vertices(face)] for face in self.faces()] unify_cycles(vertices, faces) @@ -2966,14 +2965,13 @@ def unify_cycles(self, root=None): self.halfedge = {key: {} for key in self.vertices()} for index, vertices in enumerate(faces): face = index_face[index] - vertices = [index_vertex[vertex] for vertex in vertices] + vertices = [index_vertex[vertex] for vertex in vertices] self.face[face] = vertices for u, v in pairwise(vertices + vertices[:1]): self.halfedge[u][v] = face if u not in self.halfedge[v]: self.halfedge[v][u] = None - # -------------------------------------------------------------------------- # Components # -------------------------------------------------------------------------- From 0c3ebc06824cdc45f9d77e981afc33e3fce95273 Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 11:13:57 +0200 Subject: [PATCH 6/8] update docs --- src/compas/topology/orientation.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compas/topology/orientation.py b/src/compas/topology/orientation.py index 09f7abd9ae3..20a1f3c8712 100644 --- a/src/compas/topology/orientation.py +++ b/src/compas/topology/orientation.py @@ -98,8 +98,10 @@ def face_adjacency(points, faces): Parameters ---------- - mesh : :class:`compas.datastructures.Mesh` - A mesh object. + points : list[point] + The vertex locations of the faces. + faces : list[list[int]] + The faces defined as list of indices in the points list. Returns ------- From 8b7067445410ee6c046902ea74e965df856d6af9 Mon Sep 17 00:00:00 2001 From: Tom Van Mele Date: Mon, 22 Apr 2024 11:34:22 +0200 Subject: [PATCH 7/8] Update src/compas/datastructures/mesh/mesh.py Co-authored-by: Gonzalo Casas --- src/compas/datastructures/mesh/mesh.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compas/datastructures/mesh/mesh.py b/src/compas/datastructures/mesh/mesh.py index 614482b35b1..72343fec862 100644 --- a/src/compas/datastructures/mesh/mesh.py +++ b/src/compas/datastructures/mesh/mesh.py @@ -2953,8 +2953,11 @@ def unify_cycles(self, root=None): The mesh is modified in place. """ - vertex_index = {vertex: index for index, vertex in enumerate(self.vertices())} - index_vertex = {index: vertex for index, vertex in enumerate(self.vertices())} + vertex_index = {} + index_vertex = {} + for index, vertex in enumerate(self.vertices()): + vertex_index[vertex] = index + index_vertex[index] = vertex index_face = {index: face for index, face in enumerate(self.faces())} vertices = self.vertices_attributes("xyz") From 056a048f338b8fb5f71d37ad0a37e19cde776679 Mon Sep 17 00:00:00 2001 From: tomvanmele Date: Mon, 22 Apr 2024 11:36:38 +0200 Subject: [PATCH 8/8] fix indentation --- src/compas/datastructures/mesh/mesh.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compas/datastructures/mesh/mesh.py b/src/compas/datastructures/mesh/mesh.py index 72343fec862..7be50338ef7 100644 --- a/src/compas/datastructures/mesh/mesh.py +++ b/src/compas/datastructures/mesh/mesh.py @@ -2956,8 +2956,8 @@ def unify_cycles(self, root=None): vertex_index = {} index_vertex = {} for index, vertex in enumerate(self.vertices()): - vertex_index[vertex] = index - index_vertex[index] = vertex + vertex_index[vertex] = index + index_vertex[index] = vertex index_face = {index: face for index, face in enumerate(self.faces())} vertices = self.vertices_attributes("xyz")