vedo icon indicating copy to clipboard operation
vedo copied to clipboard

Feature Request: Mesh thickening

Open JeffreyWardman opened this issue 2 years ago • 13 comments

I'd like to be able to thicken the mesh within vedo such that the pointdata is retained.

For inspiration: https://pymadcad.readthedocs.io/en/latest/_modules/madcad/generation.html#thicken

JeffreyWardman avatar Nov 13 '23 22:11 JeffreyWardman

isn't it already possible with extrude():

from vedo import *
letter = Text3D("A") #can be any Mesh
letter.pointdata["mydata"] = range(letter.npoints)
letter.cmap("Set1")
eletter = letter.clone().extrude(0.1)
eletter.cmap("Set1")
eletter.print()
show(letter, eletter, N=2, axes=1)
Screenshot 2023-11-14 at 16 07 30

marcomusy avatar Nov 14 '23 15:11 marcomusy

The extrusions are made based on the normals of the points rather than in a constant direction. It should also handle overlapping regions when the points collapse on top of each other. You can do a contour offset in equal amounts in both the positive and negative directions of the normal so the centre of the thickened object remains the same.

JeffreyWardman avatar Nov 15 '23 00:11 JeffreyWardman

this is only available in the forthcoming release:

git clone https://github.com/marcomusy/vedo.git
cd vedo
git checkout restruct_mem
pip install -e .
from vedo import *
letter = Text3D("A")
letter.pointdata["mydata"] = range(letter.npoints)
letter.cmap("Set1")
eletter = letter.clone().extrude(0.3, direction=(1, 1))
print(eletter)
show(letter, eletter, N=2, axes=1)
Screenshot 2023-11-15 at 03 34 22

marcomusy avatar Nov 15 '23 02:11 marcomusy

The thickening is moreso like inflating and deflating a balloon by a centimetre. Unless the point normals can be passed into direction? This visualisation might help: https://pymadcad.readthedocs.io/en/latest/reference/generation.html#madcad.generation.thicken

JeffreyWardman avatar Nov 15 '23 03:11 JeffreyWardman

oh for that i see 2 options:

  • use https://vedo.embl.es/autodocs/content/vedo/vedo/pointcloud.html#Points.implicit_modeller
  • compute_normals(cells=False) then manually move the vertices along the normals. To avoid self collisions I would move them by averaging the normals over a region of the mesh (by 3d closeness with closest_point(), or better by looking at the connecting vertices with connected_vertices()).

(this madcad is pretty cool btw!)

marcomusy avatar Nov 15 '23 09:11 marcomusy

The link you shared doesn't seem to point to anything. I couldn't see implicit_modeller.

For the second option, it'll be too computationally slow in Python for dense meshes. The normal approach is to do the contour offsetting and merge points that collapse into each other to my knowledge.

A third option (that I haven't explored yet) could be supporting madcad (glad you like it, it's been quite nifty!). I'm not sure if it's possible to include attributes and collect them back after the operation is done within madcad.

JeffreyWardman avatar Nov 15 '23 23:11 JeffreyWardman

Ops sorry, another miss in my release docs.. it's: https://vedo.embl.es/autodocs/content/vedo/vedo/pointcloud.html#Points.generate_surface_halo

How "dense" is dense for you? I would say it should be ok up to 100k vertices.

Third option, would be cool to explore, i'm also sure it should be possible (it's just a bunch of numpy arrays in the end).

marcomusy avatar Nov 16 '23 09:11 marcomusy

Thanks. The surface halo is in all directions rather than just the normal so it doesn't fit the particular use case (which is to extrude a flat mesh boundary and then thicken it).

In terms of density, most cases I'm working with will be probably 120-200k but I also need to be able to accommodate for the outliers.

I've created a feature request for madcad. I'm not too familiar with it under the hood but happy to give it a go in a week or two.

JeffreyWardman avatar Nov 16 '23 23:11 JeffreyWardman

Moving vertices along the normal is very fast even for meshes of 438k:

from vedo import *
msh = Mesh("https://www.dropbox.com/scl/fi/l28380iuhudaanl5uajf4/dragon.ply")
msh.compute_normals(cells=False, points=True)
for i in progressbar(10):
    normals = msh.pointdata["Normals"]
    msh.vertices += normals*0.0005
show(msh)
Screenshot 2023-11-17 at 01 22 49

the problem is to deal with self collisions..

marcomusy avatar Nov 17 '23 00:11 marcomusy

@marcomusy do you want to assign this to me? I'll have a go at implementing a VTK native version of it that handles collisions.

JeffreyWardman avatar Dec 01 '23 12:12 JeffreyWardman

Hi @marcomusy! Finally working on this now. Just writing it with vedo itself. All that's left is to copy across the cell and point data to the new mesh (or to update the points, edges, faces on the existing one. Is there a simple/recommended way to do that?

JeffreyWardman avatar Jan 10 '24 01:01 JeffreyWardman

Hey, in principle you don't even need to do anything if you just replace/modify the vertex coordinates, all data stays the same.

marcomusy avatar Jan 10 '24 13:01 marcomusy

Because we're offsetting the vertices in both directions, there will be double the number of vertices, so there will also be new ones (and new faces) [will be less than double for intersecting offsets].

JeffreyWardman avatar Jan 10 '24 22:01 JeffreyWardman