-
Notifications
You must be signed in to change notification settings - Fork 112
CellNetwork.cell_neighbors() modification #1449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
hi, thanks for this. we will automate this in the future, but for now this needs to be done locally... thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i (think i) understand what you're trying to do, but (if i understood correctly) i think we should do it differently.
with what you propose, the cell network will not care about the welding of vertices in some cases while it does care in others. this will lead to very confusing results.
we should perhaps rather change the behaviour wrt welding, and/or include a setting wrt this behaviour on a global level...
def add_mesh(self, input_mesh: Mesh): | ||
if input_mesh.is_manifold(): | ||
# mesh.unify_cycles() | ||
unpacked_mesh = input_mesh.to_vertices_and_faces() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vertices, faces = ...
if self._max_vertex == -1: | ||
vertex_diff = 0 | ||
else: | ||
vertex_diff = self._max_vertex + 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be simplified to
vertex_offset = self._max_vertex + 1
vertex_diff = self._max_vertex + 1 | ||
|
||
for vertex in unpacked_mesh[0]: | ||
self.add_vertex(attr_dict = {"x": vertex[0], "y": vertex[1], "z":vertex[2]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.add_vertex(x=vertex[0], y=vertex[1], z=vertex[2])
@@ -728,6 +728,32 @@ def add_cell(self, faces, ckey=None, attr_dict=None, **kwattr): | |||
|
|||
return ckey | |||
|
|||
|
|||
def add_mesh(self, input_mesh: Mesh): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have the felling this already exists but under a different name, no @romanarust ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, this does not yet exist
@@ -4033,7 +4059,7 @@ def cell_face_neighbors(self, cell, face): | |||
return nbrs | |||
|
|||
def cell_neighbors(self, cell): | |||
"""Find the neighbors of a given cell. | |||
"""Find the neighbors of a given cell based on common vertices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this should be a different function because it does something else than what was intended by the original one...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I was even thinking about proposing one more datastructure like Mesh Network. Something more practice oriented, because that's not common to have a building represented as masses or adjacent rooms only. Moreover some parts in a model can have clashes, or be adjacent on a face to face level only, or can have common vertices.
So briefly the initial functionality:
- analyzing meshes adjacency (including collision etc)
- storing some metadata on a mesh level (attr dict but for meshes)
- mesh network to graph conversion (each node is a mesh centroid, edge could have some metadata about type of adjacency like collision or face adjacency)
- graph algorithms
- integration with compas viewer
Basically all of these could be added to CellNetwork as well, if it has no clashes with initial idea of a CellNetwork
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what you describe is already under development here
https://github.com/BlockResearchGroup/compas_model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this should be a different function because it does something else than what was intended by the original one...
Agree. Additionally, heavy processing tasks like clash detection shouldn't be tied to the CellNetwork, as they fall under mesh processing. Identifying nearby meshes for clash detection (which I assume is the goal of this function) would be better handled with something like KDtree for spatial awareness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal of this function is to convert meshes to a topologic spatial graph. Clashes were just a thing to consider, the general assumption is that the model is relatively clean with required openings etc. But now I see that maybe CellNetwork should remain more lightweight, especially considering the compas_model developments. I'll have a look at compas_model and investigate how it could be used for this task
|
||
for face in unpacked_mesh[1]: | ||
new_face = [vertex + vertex_diff for vertex in face] | ||
self.add_face(new_face) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fkey = self.add_face(new_face)
for face in unpacked_mesh[1]: | ||
new_face = [vertex + vertex_diff for vertex in face] | ||
self.add_face(new_face) | ||
faces_lst.append(self._max_face) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
faces_lst.append(fkey)
Hi @2twenity! Thank you for the PR! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review! I've modified add_mesh function and reverted back cell_neighbors method, because I find it more appropriate for compas_model. Method itself should be further developed as well. Also I've added add_mesh test
What type of change is this?
Checklist
Put an
x
in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.CHANGELOG.md
file in theUnreleased
section under the most fitting heading (e.g.Added
,Changed
,Removed
).invoke test
).invoke lint
).compas.datastructures.Mesh
.Some description.
CellNetwork.cell_neighbors
I've been trying to analyze connections between building elements using CellNetwork.cell_neighbors method and found out that simple common faces search could not work, because faces can point at the vertices with same coordinates, but which have different indexes, because there's no duplicate vertex check in CellNetwork.add_vertex method. Therefore I've modified the comparison logic to simple common vertices search. If 2 cells have more than 2 vertices in common, they might be adjacent. (Maybe a condition that points don't lie on the same line should be considered as well). This method performed quite well in a graph construction process of an HVAC received from Speckle.
I've added this particular CellNetwork to tests/compas/datastructures/fixtures folder.
CellNetwork.add_mesh
Also I've implemeted add_mesh method to CellNetwork which simple decomposes mesh to vertices and faces, checks if it's manifold and adds as a Cell to CellNetwork