JDS
JDS

Reputation: 16978

Python 3d analysis (vedo): find largest spheres that can fit inside of a mesh?

I am using vedo to visualize and work with 3D models taken from a Lidar scan; they are .obj files that I open up.

In my application, I want to find the largest spheres the can 'fit inside' of my scanned object, if that makes sense. Imagine I have a room or hallway - basically I am trying to measure the amount of free space available.

So I want to fit in a bunch of spheres, and then see how big those spheres are. It's important that I can automate this process for whatever .obj file I load in, otherwise I would manually measure things...

Here is an example .obj file I open up, a crudely scanned hallway:

enter image description hereenter image description here

I'm not sure how to go about this with vedo, the closest example I found was 'Fit a Sphere' from the example website, which inspired my solution idea: enter image description here https://vedo.embl.es/#quick_start https://github.com/marcomusy/vedo/blob/master/examples/advanced/fitspheres1.py

But then how would I define constraints on the spheres that they "fit inside" the mesh (hallway / room)?

For reference, here is my starter code, all it really does is read and display the mesh:

import vedo
import numpy as np

# https://vedo.embl.es/#quick_start

mesh_str = 'meshes/mesh1_indoor_scene_1.obj'

# Load a polygonal mesh, make it white and glossy:
scene = vedo.Mesh(mesh_str)
scene.c('white').lighting('glossy')

# Create two points:
p1 = vedo.Point([ 1,0,1], c='yellow')
p2 = vedo.Point([-1,0,2], c='red')
# Add colored light sources at the point positions:
l1 = vedo.Light(p1, c='yellow')
l2 = vedo.Light(p2, c='red')

# Show everything in one go:
vedo.show(scene, l1, l2, p1, p2, mesh_str, axes=True)

Appreciate any help, and open to thinking about other feasible solutions that can be implemented in python code.

Upvotes: 1

Views: 646

Answers (1)

mmusy
mmusy

Reputation: 1337

If you can reconstruct a surface from the point cloud you can directly use surf.volume() or maybe generate a grid of points and use insidePoints() (instead of fitting spheres), e.g.:

from vedo import *
import numpy as np

surf = Mesh(dataurl+'cow.vtk').wireframe()
printc("true volume: ", surf.volume())

pts = []
step = 0.05
b = surf.bounds()
for x in np.arange(b[0], b[1], step):
    for y in np.arange(b[2], b[3], step):
        for z in np.arange(b[4], b[5], step):
            pts.append([x,y,z])
pts = np.array(pts)

ipts = surf.inside_points(pts)
printc("approx volume:", ipts.npoints*step**3)

show(surf, ipts, N=2, axes=1)

enter image description here

true volume:  0.8346111674784022
approx volume: 0.8287500000000002

You can also post an issue here.

Upvotes: 1

Related Questions