本文主要是实现将一个网格模型体素化,实现不同分辨率的体素化效果,并且可视化输出为obj文件!首先利用trimesh对mesh进行采样,然后根据采样点得到各个体素点的占有值。

效果

通过调整分辨率以及采样率(当分辨率变高时建议适量提高采样率)得到以下的效果!

代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author: Matthieu Zins
"""import trimesh
import numpy as np
import os
import argparse"""======   Voxelize the surface of a mesh   ======
"""def create_if_needed(folder):if not os.path.isdir(folder):os.mkdir(folder)parser = argparse.ArgumentParser(description='Pass object name')
parser.add_argument('input_mesh', type=str)
parser.add_argument('--output_folder', type=str, default="")
parser.add_argument('--resolution', type=int, nargs=3, default=[50, 50, 50], help="resolution_X resolution_Y resolution_Z")
parser.add_argument('--sampling', type=int, default="100000",help="number of points sampled on the mesh")
args = parser.parse_args()input_mesh_filename = args.input_mesh
object_name = os.path.splitext(os.path.basename(input_mesh_filename))[0]
output_folder = args.output_folder
if len(output_folder) == 0: output_folder = object_name
RES_X, RES_Y, RES_Z = args.resolution
sample_points_count = args.samplingcreate_if_needed(output_folder)mesh = trimesh.exchange.load.load(input_mesh_filename)# Uniform Points Sampling
pts, _ = trimesh.sample.sample_surface_even(mesh, sample_points_count )# Save sample points
sampled_points_mesh = trimesh.Trimesh(vertices=pts)
sampled_points_mesh.export(os.path.join(output_folder, object_name + "_resampled_points.ply"))# Adjust the grid origin and voxels size
origin = pts.min(axis=0)
dimensions = pts.max(axis=0) - pts.min(axis=0)
scales = np.divide(dimensions, np.array([RES_X-1, RES_Y-1, RES_Z-1]))
scale = np.max(scales)# Voxelizepts -= origin
pts /= scale
pts_int = np.round(pts).astype(int)grid = np.zeros((RES_X, RES_Y, RES_Z), dtype=int)
gooRES_X = np.where(np.logical_and(pts_int[:, 0] >= 0, pts_int[:, 0] < RES_X))[0]
gooRES_Y = np.where(np.logical_and(pts_int[:, 1] >= 0, pts_int[:, 1] < RES_Y))[0]
gooRES_Z = np.where(np.logical_and(pts_int[:, 2] >= 0, pts_int[:, 2] < RES_Z))[0]
goods = np.intersect1d(np.intersect1d(gooRES_X, gooRES_Y), gooRES_Z)
pts_int = pts_int[goods, :]
grid[pts_int[:, 0], pts_int[:, 1], pts_int[:, 2]] = 1# Save voxels
voxel_pts = np.array([[-0.5, 0.5, -0.5],[0.5, 0.5, -0.5],[0.5, 0.5, 0.5],[-0.5, 0.5, 0.5],[-0.5, -0.5, -0.5],[0.5, -0.5, -0.5],[0.5, -0.5, 0.5],[-0.5, -0.5, 0.5]])
voxel_faces = np.array([[0, 1, 2, 3],[1, 5, 6, 2],[5, 4, 7, 6],[4, 0, 3, 7],[0, 4, 5, 1],[7, 3, 2, 6]])def get_voxel(i, j, k):global voxel_pts, voxel_facesv = np.array([i, j, k], dtype=float) * scalev += originpoints = voxel_pts * scale + vreturn points, voxel_faces.copy()points = []
faces = []
fi = 0
for i in range(RES_X):for j in range(RES_Y):for k in range(RES_Z):if grid[i, j, k]:p, f = get_voxel(i, j, k)points.append(p)f += fifaces.append(f)fi += 8points = np.vstack(points)
faces = np.vstack(faces)
# Write obj mesh with quad faces
with open(os.path.join(output_folder, object_name + "_voxels.obj"), "w") as fout:for p in points:fout.write("v " + " ".join(map(str, p)) + "\n")for f in faces+1:fout.write("f " + " ".join(map(str, f)) + "\n")print(object_name, "done.")

运行
Dependencies

  • numpy
  • trimesh
## Usagepython voxelize_surface.py example/chair.obj --output_folder output --resolution 30 30 30 --sampling 10000

The optional parameters are:

  • output_folder (string): folder where the result is saved
  • resolution (list): the resolution of the grid [res_x, res_y, res_z]
  • sampling (int): number of points sampled on the mesh surface before voxelization
  • :输入的类型可以时obj也可以是off以及ply格式!

注意:若出现如下情况,可将采样点数(sampling)提高!出现此种情况的原因是采样间隔太大,而体素尺寸太小(分辨太高),所以导致在有些体素的占有值进行判断的时候出现错误。所以也可以通过降低分辨率来改善此种情况!

Reference

声明: 本文的代码并非原创,来自GitHub中zinsmatt的Surface_Voxels一作!若有侵权请联系撤文!

https://github.com/zinsmatt/Surface_Voxels

Python 三维网格体素化相关推荐

  1. python文本结构化处理_在Python中标记非结构化文本数据

    python文本结构化处理 Labelled data has been a crucial demand for supervised machine learning leading to a n ...

  2. Voxelization 三维模型体素化

    Voxelization 三维模型体素化 导入mesh文件,以obj文件为例: 一般文件mesh文件内容有顶点与面,可以用三维设计软件生成,生成的时候注意mesh文件只保存三角形面片,以便后面读取 o ...

  3. 在Unity中实现体素化

    在Unity中实现体素化 博客链接:在Unity中实现体素化 体素化 类似与用网格存储二维平面,将三维空间划分成大量尺寸相同的小方块的过程就称之为体素化. 为什么要体素化 以下是个人理解 当场景中多边 ...

  4. matlab体素化,教程|如何使用Matlab制造GrabCAD体素打印切片

    想必大家对Stratasys最近推出的Voxel Print解决方案已经并不感到陌生了,但你是否已经知道如何使用Matlab制造GrabCAD体素打印切片了呢? 本教程面向已熟悉Matlab及J750 ...

  5. Open3D Voxelization 体素化

    Voxelization 体素化 点云和三角形网格是非常灵活但不规则的几何类型.体素网格(voxel grid)是在 3D 网格上定义的 3D 中的另一种几何类型,体素可以被视为 2D 中像素(pix ...

  6. matlab体素化,一种三维激光点云数据快速体素化处理方法与流程

    本发明涉及一种三维激光点云数据快速体素化处理方法. 背景技术: 目前,三维激光扫描系统快速发展,由于研究的需要,往往需要把不具有空间长度信息的点数据转为具有三维空间信息的立方体,如何使用软件进行快速. ...

  7. Voxelization——体素化模型

    上周部门内部进行分享知识讲座时讲到一个词Voxelization,也就是体素化,也就是用某些东西充满一个物体的内部,如下面这两张图,用小方块充满圆环和锥体. 其主要算法也有多种,我这里采用的是用bou ...

  8. 基于ROS2开发的点云体素化

    0. 简介 最近在收到了很多读者的消息后,我觉得有必要开这个坑,来给大家阐述下如何对激光雷达点云以及图像点云去做栅格化以及体素化的操作.这部分需要各位读者拥有PCL,octomap,ROS2,C++的 ...

  9. Navmesh研究(二)体素化过程

    本文翻译自:http://critterai.org/projects/nmgen_study/voxelization.html 体素化过程 构建导航网格的第一步是使用体素化创建一个实体高度域 创建 ...

最新文章

  1. linux设置脚本开机启动centos7,centos7设置开机启动
  2. CBU计算机硕士申请难度,电脑开机后CBU百分只百是什么问题
  3. 我的图床设置PicGo
  4. PHP操作mongodb数据库操作类
  5. Go与PHP区别:类型 引用 语法 错误 性能 应用 生态
  6. Centos7.6环境Docker安装Oracle19c企业版
  7. Guava学习笔记:EventBus(转)
  8. Purus系统常见使用问题及解决方式FAQ 1
  9. Clr编写Insert Triggr
  10. delphi延时 4种方法
  11. 【POJ 3320】【尺取法】Jessica's Reading Problem【暑期 No.2】
  12. Chango的数学Shader世界(十八)RayTrace三维分形(三)—— 完善,距离场软阴影
  13. vue插槽面试题_vue面试题(一)
  14. c#获取文件的MD5值
  15. 路由模式和桥接模式的区别
  16. 读书印记 - 《我们人类的基因:全人类的历史和未来》
  17. win10 输入法 删除
  18. 人工智能“剧透”《权游》大结局,第一个“领便当”的居然是ta
  19. 炫酷的 loding效果(canvas)
  20. URL 重写就是把URL地址重新改写(汗^_^)。

热门文章

  1. 关于go命令下载工具终端提示找不到工具
  2. C语言计算三角形的面积
  3. IDEA 数据库驱动下载失败解决方法
  4. 每天记账,是穷人才会做的事?
  5. matlab怎么复数相位,怎么求复数相位
  6. 复数加减java_用java实现复数的加减乘除运算
  7. MTK之Flash篇二---如何调整Flash中FAT的配置
  8. 【公众号技能+】添加白名单,允许其他公众号转载文章
  9. 混合波束成形| 通过天线空间方向图理解波束成形的物理意义
  10. (附源码)计算机毕业设计SSM智慧工地管理系统