Skip to content

Compatability of FaceView/expand_faceviews() with vertex attribute updates #223

@ffreyer

Description

@ffreyer

This is sort of a future TODO.

The current version of expand_faceviews() isn't really compatible with varying vertex attributes.

Let's consider a mesh without vertex attributes first. Here we simply just change an element of a vertex attribute after creating the mesh.

m = normal_mesh(Sphere(Point3f(0), Vec3f(0))
m = GeometryBasics.mesh( m, color = fill(RGBf(1,0,0), length(coordinates(m))) )
m.color[7] = RGBf(0,1,0)
# m.color now has a green vertex

With some Observable structure this change could be passed down.

When expand_faceviews() is called on a mesh with FaceViews a new mesh is generated. Currently, it does not refer back to the original mesh, so any updates to the original mesh are not visible there.

m = normal_mesh(Rect3f(Point3f(0), Vec3f(1))
m = GeometryBasics.mesh( m, color = FaceView(fill(RGBf(1,0,0), 6), QuadFace.(1:6)) )
vm = expand_faceviews(m)
m.color[1] = RGBf(0,1,0)
vm.color # all red

You can of course rerun expand_faceviews(m) to get a new vm containing the new, expanded m.color. This is however rather costly and unnecessary (unless lengths change). A better option would be to dig a bit deeper to avoid recalculating the data remapping:

new_faces, indices = GeometryBasics.merge_vertex_indices(faces(m), faces(m.normal), faces(m.color))
# This may only work conceptually...
vm = GeometryBasics.Mesh(
    new_faces, 
    position = view(m.position, indices[1]), 
    normal = view(values(m.normal), indices[2]),
    color = view(values(m.color), indices[3])
)

For a (view-free) Observable structure this becomes more complicated because you need to use indices in the opposite direction inv_indices. Since data gets duplicated by indices, inv_indices[old] can contain multiple target indices [new1, new2, new3, ...].

For meshes that do not get modified, this would also be pure overhead. If the vertex attributes get read multiple times the view needs to be resolved multiple times, and the view requires more memory than collected array.

Note as well that the view() example above ignores mesh.views. That doesn't break anything, but it does potentially throw away some information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions