除了格雷迪网格丛中,还有其他/更好的体素网格划分算法吗
对于我正在工作的项目,我有大量的体素数据,需要在网格中可视化。
在搜索时,我迅速找到了在Minecraft游戏中/a>文章,由Mikolalysenko撰写,早在2012年,根据我的研究,每个人似乎都提到每个人都在回答这个问题。 他描述了解决这个问题的三种算法:愚蠢的,被淘汰和贪婪。
这两个首先是不高效的,所以我为我为我的项目提供的代码制作了Python版本:
- 我使用 numba 为了加快计算,
- 我直接计算三角顶点,而不是四边形,以获取我们的网格释放函数实现,
@njit()
def greedy_mesh(volume, dims):
def f(i, j, k):
return(volume[i + dims[0] * (j + dims[1] * k)])
points = []
# Sweep over 3-axes
for d in range(3):
u = (d + 1) % 3
v = (d + 2) % 3
x = [0, 0, 0]
q = [0, 0, 0]
mask = [0] * (dims[u] * dims[v])
q[d] = 1
x[d] = -1
while x[d] < dims[d]:
n = 0
x[v] = 0
x[u] = 0
# Compute mask
while x[v] < dims[v]:
while x[u] < dims[u]:
a = f(x[0], x[1], x[2]) if x[d] >= 0 else False
b = f(x[0] + q[0], x[1] + q[1], x[2] + q[2]) if x[d] < (dims[d] - 1) else False
mask[n] = a != b
n += 1
x[u] += 1
x[u] = 0
x[v] += 1
x[d] += 1
n = 0
# Generate mesh for mask using lexicographic ordering
for j in range(0, dims[v]):
i = 0
while i < dims[u]:
if (n < len(mask)) and mask[n]:
w = 1
# Compute width
while (n + w < len(mask)) and (mask[n + w] and ((i + w) < dims[u])):
w += 1
done = False
h = 1
# Compute height (slighty awkward according to the autor)
while (j + h) < dims[v]:
for k in range(0, w):
if not mask[n + k + h * dims[u]]:
done = True
break
if done:
break
h += 1
# New quad
x[u] = i;
x[v] = j;
du = [0, 0, 0]
dv = [0, 0, 0]
du[u] = w
dv[v] = h
# Triangles
A = (x[0],
x[1],
x[2])
B = (x[0] + du[0],
x[1] + du[1],
x[2] + du[2])
C = (x[0] + du[0] + dv[0],
x[1] + du[1] + dv[1],
x[2] + du[2] + dv[2])
D = (x[0] + dv[0],
x[1] + dv[1],
x[2] + dv[2])
points.extend([A, B, C])
points.extend([A, C, D])
# Zero-out mask
for l in range(0, h):
for k in range(0, w):
mask[n + k + l * dims[u]] = False
i += w
n += w
else:
i += 1
n += 1
# Unique set of points
vertices = [i for i in set(points)]
# Points
indices = []
for p in points:
indices.append(vertices.index(p))
return np.array(vertices), np.array(indices).reshape(-1, 3)
我使用示例测试了我的代码,Mikolalysenko再次提供了我的代码,并且运行良好。 但是后来我尝试从我们的项目(〜300x300x300)中加载更大的体素数据,现在该算法运行约5s来处理数据。老实说,我很快,但不足以使用,并且我们的数据集更大。
经过一点点的概况,并且没有任何惊喜,大多数计算时间都是由于最终创建了顶点及其索引。不幸的是,这是创建与之使用的Meshing函数的方式,我无法更改此功能。
终于使我的问题引起了我的问题:今天是否有一种比贪婪的网格划分更好的体素网际算法可以帮助我满足自己的要求?
即使我认为没有针对此类任务的最佳解决方案(看起来有点像p = np问题),即使在寻找科学论文时,我也无法在网上找到其他算法。
您对我的问题有任何建议或参考吗?
For the project I'm working, I have large voxel data I need to visualize within a mesh.
While searching I rapidly find the Meshing in a Minecraft Game article article, written by mikolalysenko back in 2012, and according to my research seems to only source everyone is referring to answer this question.
He describes three algorithm to solving this problem: the Stupid, the Culled and the Greedy.
The two first are really non efficient, so I made a Python version of the code he provides for my project with two tweaks:
- I use Numba to speed up computations
- I directly compute the triangle vertices instead of quadrilaterals, to mach to our meshing function implementation
@njit()
def greedy_mesh(volume, dims):
def f(i, j, k):
return(volume[i + dims[0] * (j + dims[1] * k)])
points = []
# Sweep over 3-axes
for d in range(3):
u = (d + 1) % 3
v = (d + 2) % 3
x = [0, 0, 0]
q = [0, 0, 0]
mask = [0] * (dims[u] * dims[v])
q[d] = 1
x[d] = -1
while x[d] < dims[d]:
n = 0
x[v] = 0
x[u] = 0
# Compute mask
while x[v] < dims[v]:
while x[u] < dims[u]:
a = f(x[0], x[1], x[2]) if x[d] >= 0 else False
b = f(x[0] + q[0], x[1] + q[1], x[2] + q[2]) if x[d] < (dims[d] - 1) else False
mask[n] = a != b
n += 1
x[u] += 1
x[u] = 0
x[v] += 1
x[d] += 1
n = 0
# Generate mesh for mask using lexicographic ordering
for j in range(0, dims[v]):
i = 0
while i < dims[u]:
if (n < len(mask)) and mask[n]:
w = 1
# Compute width
while (n + w < len(mask)) and (mask[n + w] and ((i + w) < dims[u])):
w += 1
done = False
h = 1
# Compute height (slighty awkward according to the autor)
while (j + h) < dims[v]:
for k in range(0, w):
if not mask[n + k + h * dims[u]]:
done = True
break
if done:
break
h += 1
# New quad
x[u] = i;
x[v] = j;
du = [0, 0, 0]
dv = [0, 0, 0]
du[u] = w
dv[v] = h
# Triangles
A = (x[0],
x[1],
x[2])
B = (x[0] + du[0],
x[1] + du[1],
x[2] + du[2])
C = (x[0] + du[0] + dv[0],
x[1] + du[1] + dv[1],
x[2] + du[2] + dv[2])
D = (x[0] + dv[0],
x[1] + dv[1],
x[2] + dv[2])
points.extend([A, B, C])
points.extend([A, C, D])
# Zero-out mask
for l in range(0, h):
for k in range(0, w):
mask[n + k + l * dims[u]] = False
i += w
n += w
else:
i += 1
n += 1
# Unique set of points
vertices = [i for i in set(points)]
# Points
indices = []
for p in points:
indices.append(vertices.index(p))
return np.array(vertices), np.array(indices).reshape(-1, 3)
I test out my code using the examples provides once again by mikolalysenko and it run perfectly fine.
But then I tried to load bigger voxel data from our project (~ 300x300x300), and now the algorithm run for about 5s to process the data. Honestly I quite fast but not enough for usage, and we have much larger data sets.
After a bit of profile, and without really any surprise, most of computation time is due to creation of the vertices and their indices at the end. Unfortunetly, this is the way the meshing function was created to work with and I'm not able to change this feature.
That's finally leads my to my question: Is there today a voxel meshing algorithm better than Greedy Meshing that could helps me fulfill my requirements?
Even if I believe there is no optimal solution for this kind of task (looks a bit like a P = NP problem), I cannot find alternative algorithms online even while looking for scientific papers.
Do you have any suggestions or references regarding my problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论