-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Voxelize non-uniformly gridded points #41
Comments
Can you also include the point set that you are working with? (Attach as a file here) |
I would prefer not to share the files, is this a problem @banesullivan ? Thank you. |
I'm not sure I can track down this issue without seeing your data - perhaps you could email them to me and I'll delete the file when finished testing |
@banesullivan email sent. |
Thanks, @laserman781 - The I'm not sure if this is what you want, but here's a go at it: import pyvista as pv
import PVGeo
import pandas as pd
df = pd.read_csv(filename)
point_cloud = PVGeo.points_to_poly_data(df)
voxelizer = PVGeo.filters.VoxelizePoints()
voxelizer.set_deltas(5, 5, 2) # Your block sizes in dx, dy, dz
voxelizer.set_estimate_grid(False) # This is crucial for this point cloud
grid = voxelizer.apply(point_cloud)
grid.plot(notebook=False) |
From looking at your dataset, it appears to be a slice/threshold through a structured grid. If possible, I'd recommend trying to figure out where that data came from and if there is an original grid that you could use instead. If you do acquire that additional info, you could follow appoaches similar to those in the examples in #16 and #28 |
@banesullivan In this case, each point represents a block centroid, so since the grid is non-uniform, the blocks will not be all the same sizes, some will be larger or smaller than others. But, they should all be touching... How can we accomplish this? Thank you so much! |
Do you know the block sizes? Because the |
All you would need are three arrays: the X, Y, and Z sizes for each voxel |
@banesullivan that is an unknown and is based on the distances between the points, the goal is to be able to plot the blocks for any grid, whether the blocks all be the same size or have several different sizes. I attempted this with a regular grid and it was able to determine automatically the recovered cell size and recovered angle but only if they are in a regular grid. Is it possible to do the same thing with several different block sizes depending on the different block centroid distance? |
That's good to hear as the
Perhaps - but the How would you compute the block centroid distance? |
So I've been experimenting with this and I don't have an immediate solution - I did, however, fix a few bugs with the In the meantime, I think PyntCloud might have some features that could help recover the grid from the point cloud. I'd recommend checking out that library. FYI, I built some interoperability between PyntCloud and PyVista a while back, but we might need to add in a few additional features if PyntCloud can properly recreate the grid to be able to put that grid into a PyVista object @daavoo, would you be able to chime in here? Using code above: from pyntcloud import PyntCloud
cloud = PyntCloud.from_pyvista(point_cloud)
# Now leverage PyntCloud on the `cloud` object |
If you can find a way to compute the size sizes then all you would need to do is this (leverage version import pyvista as pv
import PVGeo
import pandas as pd
import numpy as np
df = pd.read_csv('sub_blocks.csv')
point_cloud = PVGeo.points_to_poly_data(df)
# Replace this with some sort of way to compute size of each voxel
x_cell_sizes = np.random.randint(3, 6, point_cloud.n_points)
y_cell_sizes = np.random.randint(3, 6, point_cloud.n_points)
z_cell_sizes = np.random.randint(3, 6, point_cloud.n_points)
voxelizer = PVGeo.filters.VoxelizePoints(unique=True, estimate=False)
voxelizer.set_deltas(x_cell_sizes, y_cell_sizes, z_cell_sizes)
grid = voxelizer.apply(point_cloud)
p = pv.Plotter(notebook=False)
p.add_mesh(grid)
p.show_grid()
p.add_axes()
p.show() |
Upon revising the thread, when you mentioned "A recovered connected grid with proper geometry". This is what is needed. The block point data is based on their centroids and the goal is to recover their proper geometry. They are all touching in reality and should, in general, be the same size. Although, that is not always the case and in some areas, the blocks can become smaller and in more quantity (denser) as we have seen in the point when they were displayed. Does the solution change if we want to recover the original geometry of the blocks instead of simply Voxelize them? |
Well, sort of. What changes is how we estimate the cell sizes which has to be done in the X, Y, and Z directions separately for every cell/voxel. Once you have a way to calculate what the cell sizes should be for every point, then we can use the Computing those cell sizes is a lot easier said than done. I've tried to develop an algorithm to do this in the past with no luck - even for just rectilinear grids like this: import pyvista as pv
import numpy as np
x = np.array([0, 2, 2.5, 2.75, 3.0, 4, 6])
y = np.array([0, 1, 1.5, 1.75, 2, 2.5, 4.5])
z = np.array([0])
grid = pv.RectilinearGrid(x, y, z)
p = pv.Plotter()
p.add_mesh(grid, show_edges=True, )
p.add_mesh(grid.cell_centers(), color='black')
p.show_grid()
p.enable_parallel_projection()
p.show(cpos='xy') Trying to recover the original cell sizes given just the cell centers is incredibly challenging because the cell edges are not directly in the middle of two nodes. The solver would have to account for almost all the nodes on a mesh in order to make a decision about the size of a single cell. If someone has an idea of how to implement an algorithm that can solve that problem, I will very happily code it up! |
The mesh type you emailed me, @laserman781, is more like a TreeMesh or UnstructuredGrid so solving that kind of geometry is a whole other beast that I'm not sure how to approach |
I am currently taking a stab at an algorithm that can solve this. But if I already have the incrementation between blocks (the block sizes), will we be able to produce the result? |
Yes, just pass those cell sizes into arrays as I do in #41 (comment) |
After trying to pass the x,y,z cell sizes as an array to the voxelizer I keep receiving this error: Code:
How can I fix this? |
Make sure you have the latest version of PVGeo and don't call x_cell_sizes = df[['XINC']].values
y_cell_sizes = df[['YINC']].values
z_cell_sizes = df[['ZINC']].values
voxelizer = PVGeo.filters.VoxelizePoints()
voxelizer.set_deltas(x_cell_sizes , y_cell_sizes, z_cell_sizes)
voxelizer.set_estimate_grid(False) # This is crucial for this point cloud
grid = voxelizer.apply(vtkpoints)
grid.plot(notebook=False) |
Same error occurs for me |
Is vtkpoint.GetNumberOfPoints() == len(x_cell_sizes) == len(y_cell_sizes) == len(z_cell_sizes) |
Something is wrong with your code - Try restarting your kernel and running in sequential order. It looks like something modified the cell sizes arrays between when you print the lengths and when you ran the conditional |
I figured out the problem, turns out the points data frame had had fewer points than the size data frame. It now plots exactly the way I want it to. Thank you so much for your help! |
Use opacity=0.5 or whatever suits in plots |
HI @RichardScottOZ. thanks for the tip. I tried it with opaciy=05 and 0.1 but the plot makes the solid face of the voxel transparent but the point clouds occupied inside the voxel are still invisible |
You are saying each voxel has something inside it? |
Yes, you can see from the first image that i have plotted. As these are the point clouds with intensity values. After that, I have applied a grid structure for generating voxels in the 3D scene. |
#482 might be of interest? |
Still not sure I see, what does one of your voxels and cloud inside look like? |
Thanks - so the plot above is just the point clouds? |
Now possibly - voxelise them as above Add that to a plot (with transparent opacity) |
Yes absolutely |
Thanks for the tip really appreciate that. I will give it a try as you suggested |
Yep - specifically, you may want to use |
I would like to voxelize non-uniformly gridded points. This is the code I have written so far:
How would I go about doing this?
This is the error I am receiving:
The text was updated successfully, but these errors were encountered: