Mesh.vertex_attribute doesn't work ass expected
See original GitHub issueDescribe the bug I might be tired, or stupid… While looping through all vertices of a mesh and updating a vertex attribute of one vertex, all the vertices in the loop also get that value.
To Reproduce Run the following code:
from compas.geometry import Box
from compas.datastructures import Mesh
# make a simple compas mesh
mesh = Mesh.from_shape(Box.from_width_height_depth(2, 2, 2))
# add a new vertex attribute to all vertices
mesh.update_default_vertex_attributes({"new_attr": []})
# add a value to this new attribute only to some vertices
for index, v_attributes in enumerate(mesh.vertices(data=True)):
print("------", index)
v_key, v_data = v_attributes
attribute = mesh.vertex_attribute(v_key, 'new_attr')
print('before', attribute)
if index % 2 == 0:
attribute.append('why_{}'.format(index))
print('after', mesh.vertex_attribute(v_key, 'new_attr'))
The output I get is:
------ 0
before []
after ['why_0']
------ 1
before ['why_0']
after ['why_0']
------ 2
before ['why_0']
after ['why_0', 'why_2']
------ 3
before ['why_0', 'why_2']
after ['why_0', 'why_2']
------ 4
before ['why_0', 'why_2']
after ['why_0', 'why_2', 'why_4']
------ 5
before ['why_0', 'why_2', 'why_4']
after ['why_0', 'why_2', 'why_4']
------ 6
before ['why_0', 'why_2', 'why_4']
after ['why_0', 'why_2', 'why_4', 'why_6']
------ 7
before ['why_0', 'why_2', 'why_4', 'why_6']
after ['why_0', 'why_2', 'why_4', 'why_6']
Expected behavior I’m expecting to change the attribute only of the desired vertex/vertices. An output like the following:
------ 0
before []
after ['why_0']
------ 1
before []
after []
------ 2
before []
after ['why_2']
------ 3
before []
after []
------ 4
before []
after ['why_4']
------ 5
before []
after []
------ 6
before []
after ['why_6']
------ 7
before []
after []
Desktop (please complete the following information):
- OS: macOS Catalina
- Python version: 3.7.6
- Python package manager: Conda
- Compas: 0.19.1
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (9 by maintainers)
Top Results From Across the Web
Problems with Advanced Mesh API to optimize Vertex Attributes
The idea is to optimize some meshes data at runtime using the Advanced Mesh API. But I'm having issues after I try it....
Read more >Mesh data - Unity - Manual
This vertex attribute is required for all meshes. ... Note: The Points topology doesn't create faces; instead, Unity renders a single point at...
Read more >List of Filters — PyMeshLab documentation - Read the Docs
Given a Mesh M and a Pointset P, The filter project each vertex of P over M and color M according to the...
Read more >Vertex Specification - OpenGL Wiki - Khronos Group
The index list is a way of reordering the vertex attribute array data ... OpenGL (and Direct3D, if you're wondering) does not allow...
Read more >meshUtils | API Reference | ArcGIS Maps SDK for JavaScript ...
Various utilities and convenience functions for working with Mesh objects. ... The elevation sampler uses a snapshot of the Mesh geometry and will...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
random idea: would it make sense to allow setting a function as default value, which acts as the constructor for complex types? Eg.
this would make the behavior requested in this issue possible without convoluting the client code (at the expense of a bit of extra complexity in the internals of attribute views, having to type-check and execute functions when a default is requested).
This is actually expected behavior from python. The empty list you pass as default is a reference. It’s the same assigned to all attributes effectively (the attributes are getting the memory reference to that list, not copies of the list).
Despite this being somewhat confusing, I would be tempted to leave as is because it’s also what happens when you use an empty list as the default value of a function argument.