marcomusy / vedo

A python module for scientific analysis of 3D data based on VTK and Numpy
https://vedo.embl.es
MIT License
1.98k stars 257 forks source link

Obtaining boundary points #1061

Closed DeepaMahm closed 2 weeks ago

DeepaMahm commented 4 months ago

Hi @marcomusy ,

For a geometry like the following

image

I would like to get all the boundaries (please refer to the lines marked with black and indicated with arrows).

Using,

b = pts.generate_delaunay2d(mode='xy').c('w').lc('o').lw(1)
b.add_ids()
#vplt.show(pts, labels, dly, __doc__, bg="Mint").close()
b.compute_normals().clean().linewidth(0.1)
boundary_pts = Points(b.points()[pids], r=10, c='red5')

I could obtain the points marked with red dots as boundaries.

Could you please help me with obtaining all the boundary points (i.e. including boundaries inside the domain)?

The original geometry is added here (image) for your kind reference and I would like to get the boundary points of all the vessel branches. The pointcloud of the geometry is included here (pointcloud), kindly see.

marcomusy commented 4 months ago

Hi @DeepaMahm long time no see :)

After:

pip install -U git+https://github.com/marcomusy/vedo.git

Try this:

from vedo import *

pts = Points("fig_4b_collacation_points.txt")

msh = pts.generate_delaunay2d(mode='xy', alpha=0.0035)
msh.keep_cell_types(["triangle"])  # to remove lines
print(msh)

bmsh = msh.boundaries()
lines = [b.lw(3) for b in bmsh.split()]
show([pts, lines], N=2)
Screenshot 2024-03-01 at 00 43 15

(note that the lines are a bit rounded at intersections.. but this is kind of difficult to achieve without generating holes .. not sure if vedo is the best tool to use in this case!)

Or this completely different approach:

from vedo import *
img = Image("https://github.com/DeepaMahm/misc/blob/master/Bagah.jpeg")
msh = img.bw().tomesh().threshold("RGBA", above=10)
qmsh = msh.boundaries().c("red5").lw(2)
show([img, [msh, qmsh]], N=2, axes=1)
Screenshot 2024-03-01 at 00 42 15
DeepaMahm commented 4 months ago

Hello @marcomusy ,

bmsh = msh.boundaries() lines = [b.lw(3) for b in bmsh.split()]

gives the bounding lines. Can we get the points formed by these lines?

Alternately, can we use inside_points?

I tried,

msh = pcloud2.generate_delaunay2d(mode='xy').c('w').lc('o').lw(1)
msh.add_ids()
msh.keep_cell_types(["triangle"])  # to remove lines

# method 1
msh.compute_normals().clean().linewidth(0.1)
pids = msh.boundaries(return_point_ids=True)
boundary_pts = Points(msh.points()[pids], r=10, c='red5')

# method 2
bmsh = msh.boundaries()
lines = [b.lw(3) for b in bmsh.split()]
print(type(lines[0]))

# method 3
msh.inside_points(pts=pcloud2, return_ids=True)
inside_pts = msh.pointdata["IsInside"]

Unfortunately, this is not working for me.

marcomusy commented 4 months ago

Sorry I don't understand the question. The lines are made of points, which you can read as eg:

bmsh.split()[0].coordinates  # numpy array
DeepaMahm commented 2 months ago

Hi @marcomusy

I managed to get the boundaries using a software. The corresponding point cloud is uploaded here for your kind reference (data)

image

I would like to know if it is possible to load these boundary points in vedo and create a bmsh object. I would like to detect the edges and split/partition the edges for calculating the slope and intercept of the lines forming the edges.

bmsh = msh.boundaries()
lines = [b.lw(3) for b in bmsh.split()]
marcomusy commented 2 months ago

Difficult problem as you do not have a concept of "inside" and "outside" .. maybe this can help:

from vedo import *
pts = Points("data/points_edges.txt")
x0, x1, y0,y1, z0,z1 = pts.bounds()
z0,z1 = -0.1, 0.1
msh = pts.reconstruct_surface(dims=(200,200,40), radius=0.004, bounds=(x0,x1,y0,y1,z0,z1))
msh.lighting('off')
msh.mark_boundaries().cmap("viridis_r", "BoundaryPoints")
show(pts, msh, N=2, axes=1)

Screenshot from 2024-04-09 20-18-21