用于分析3D表面的复杂网格类。
项目描述
Motmot
Motmot是一个用于分析无色多边形网格(例如STL文件)的复杂网格类,它提供了一个无缝的抽象层,在原始向量网格或更高效的(顶点 + 面积)(也称为(顶点 + 多边形))形式之间。
- 自由软件:MIT许可证
- 源代码: https://github.com/bwoodsend/motmot/
- 发行版: https://pypi.ac.cn/project/motmot/
- 文档: https://bwoodsend.github.io/motmot/index.html
相关项目
这个库几乎完全专注于分析网格。您很可能需要使用其他库来读取/写入特定格式或简化现有网格。
-
网格读写
-
网格分析
-
网格清理
- quad_mesh_simplify:减少(折叠冗余或近似冗余顶点)网格,以大幅度减小文件大小,同时对质量的影响微乎其微。
- Py_Fast-Quadric-Mesh-Simplification:另一个网格缩减器。这个版本速度更快,但尚未在 PyPI 上发布。
使用方法
motmot
的基本API模仿了 numpy-stl 的API,并进行了一些修改。
初始化
网格可以是
-
从头开始使用单个 向量 数组构建。这个数组应该是3D的,形状为
(n, k, 3)
,其中n
是网格中的多边形数量,k
是每个多边形具有的角的数量,3
对应于3个轴。即x
、y
和z
。
# vectors is a (n, 3, 3) numpy array. triangle_mesh = Mesh(vectors) # vectors is a (n, 4, 3) numpy array. square_mesh = Mesh(vectors)
-
或使用更高效的 顶点+面 形式。
# `vertices` is an array of points. It should contain no duplicates. # `faces` is an integer array indicating which vertices are used to construct # each polygon. mesh = Mesh(vertices, faces)
-
从STL文件读取。这使用 numpy-stl 作为底层。目前,STL是
motmot
能够隐式读取的唯一文件格式from motmot import Mesh mesh = Mesh("some-file.stl")
-
从lzma、gzip或bzip2压缩的STL文件读取
from motmot import Mesh # An lzma compressed STL file. Create using `xz some-file.stl` in bash. mesh = Mesh("some-file.stl.xz") # A gzip compressed STL file. Create using `gzip some-file.stl` in bash. mesh = Mesh("some-file.stl.gz") # A bzip2 compressed STL file. Create using `bzip2 some-file.stl` in bash. mesh = Mesh("some-file.stl.bz2")
-
从任何
io.RawIOBase
的子类流式传输。从这里,您可以读取任意来源,例如嵌入式文件、流、归档或其他伪文件。例如,以下代码直接从Web请求中读取STL:from urllib import request from motmot import Mesh # Pull an STL file from the internet and load it without an intermediate # temporary file. url = "https://raw.githubusercontent.com/bwoodsend/vtkplotlib/master/" \ "vtkplotlib/data/models/rabbit/rabbit.stl" with request.urlopen(url) as req: mesh = Mesh(req)
顶点+面网格与向量网格
网格有两种形式。
-
一个 向量 网格本质上是一个多边形列表,其中每个多边形是一个点列表(它的角),每个点是
(x, y, z)
三元组。这种形式很简单,但很浪费,因为出现在多个多边形中的点被多次写入,浪费内存和渲染时间。 -
一个 顶点+面 网格从 向量 网格中提取所有唯一的点,称它们为 顶点,然后将 向量 中的每个点替换为其从 顶点 中的索引,称这个为 面。请注意,面 通常也称为 面片 或 多边形。
Motmot 使两种形式可以互换。每个 向量、顶点 和 面 都可以作为所有网格的属性,但根据网格是如何构建的,向量 可能是从 顶点 和 面 内部推导出来的,反之亦然。
import numpy as np
from motmot import Mesh
# Define the 8 vertices in a cuboid.
vertices = np.array([
[0., 0., 0.],
[3., 0., 0.],
[0., 5., 0.],
[3., 5., 0.],
[0., 0., 9.],
[3., 0., 9.],
[0., 5., 9.],
[3., 5., 9.],
])
# Define the 6 sides of a cube or cuboid.
faces = np.array([
# Draw a square using vertices[6], vertices[2], vertices[0] and vertices[4]
[6, 2, 0, 4],
# Draw a square using vertices[0], vertices[1], vertices[5] and vertices[4]
[0, 1, 5, 4],
# And so on...
[0, 2, 3, 1],
[5, 1, 3, 7],
[3, 2, 6, 7],
[4, 5, 7, 6],
])
# Construct a vertices+faces mesh.
mesh = Mesh(vertices, faces)
# This attribute is set to True to signify that this was originally a faces mesh.
mesh.is_faces_mesh
# Although `vectors` can still be derived automatically.
mesh.vectors
# Construct a vectors mesh.
mesh = Mesh(vertices[faces])
# This attribute is set to False to signify that this was originally a vectors
# mesh.
mesh.is_faces_mesh
# But `vertices` and `faces` can still be derived automatically.
mesh.vertices, mesh.faces
网格属性
这只是一个简要的总结。有关每个属性的更多信息,请参阅 API参考。
# Outward normal to each polygon:
>>> mesh.normals
array([[-45., 0., 0.],
[ -0., -27., -0.],
[ -0., -0., -15.],
[ 45., 0., -0.],
[ -0., 27., 0.],
[ 0., 0., 15.]])
# Normalised (magnitude of 1.0) outward normal to each polygon:
>>> mesh.units
array([[-1., 0., 0.],
[ 0., -1., 0.],
[ 0., 0., -1.],
[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
# Area of each polygon.
>>> mesh.areas
array([45., 27., 15., 45., 27., 15.])
# Total surface area (just a sum of mesh.areas).
>>> mesh.area
174.0
# The number of times each vertex is used (which admittedly
# isn't particularly interesting for a cuboid):
>>> mesh.vertex_counts
array([3, 3, 3, 3, 3, 3, 3, 3], dtype=int32)
# A mapping of which other vertices each vertex is directly connect to.
>>> mesh.vertex_map
RaggedArray.from_nested([
[1, 7, 3], # vertices[0] connects to vertices[[1, 7, 3]].
[2, 6, 0], # vertices[1] connects to vertices[[2, 6, 0]].
[4, 1, 3], # and so on...
[5, 0, 2],
[5, 6, 2],
[4, 7, 3],
[1, 4, 7],
[0, 5, 6],
])
# Because this mesh's vertices appear the same number of times,
# this example slightly trivialises the problem. Consider instead
# a mesh with only the first three faces. Not all vertices have
# the same number of neighbours.
>>> mesh[:3].vertex_map
RaggedArray.from_nested([
[1, 3],
[2, 6, 0],
[4, 1, 3],
[0, 2, 5],
[5, 2, 6],
[3, 4],
[4, 1],
])
# If you prefer to use raw vertices rather than vertex IDs then
# use the connected_vertices() method.
>>> mesh.connected_vertices(mesh.vertices[0])
array([[0., 5., 0.],
[3., 5., 9.],
[0., 0., 9.]])
# Similarly, `polygon_map` maps every polygon to each of its neighbours.
# Read the first line of the following as *polygon 0 shares an edge each with
# polygons 4, 2, 1 and 5*.
>>> mesh.polygon_map
array([[4, 2, 1, 5],
[2, 3, 5, 0],
[0, 4, 3, 1],
[1, 2, 4, 5],
[2, 0, 5, 3],
[1, 3, 4, 0]])
顶点查找
motmot
利用两个库来查找顶点。
精确查找
将顶点ID转换为真实顶点很容易。只需将它们作为索引传递给 mesh.vertices
即可。
>>> ids = [0, 4, 5, 2]
>>> points = mesh.vertices[ids]
>>> points
array([[0., 0., 0.],
[0., 0., 9.],
[3., 0., 9.],
[0., 5., 0.]])
通过索引 vertex_table
属性进行反向操作。
>>> mesh.vertex_table[points]
array([0, 4, 5, 2], dtype=int64)
需要注意的一些事项
-
查询点的
dtype
必须与mesh.dtype
匹配。 -
与常规Python
dict
中的常规浮点数一样,即使是最小的偏差也会导致查找失败。>>> mesh.vertex_table[[3., 0., 9.]] 5 >>> mesh.vertex_table[[3., 0, 9.00000000001]] KeyError: 'key = array([3., 0., 9.]) is not in this table.'
模糊查找
为了找到 最近点,motmot
使用 KDTree。这里的API非常简单,你很可能希望直接创建和使用 KDTree
而不是使用 motmot
的方法。
将KDTree拟合到mesh.centers
(每个多边形的中心),可以在mesh.kdtree
属性中找到。
给定一组点定义为
points = np.array([[2., 3.5, 4.2], [2.3, 4.2, 1.1]], mesh.dtype)
找到每个点在网格表面上的最近点
>>> mesh.closest_point(points)
array([[3. , 3.5, 4.2],
[2.3, 4.2, 0. ]])
或者限制输出仅包含mesh.centers
,而不在它们之间进行插值
>>> mesh.closest_point(points, interpolate=False)
array([[3. , 2.5, 4.5],
[1.5, 2.5, 0. ]])
对于其他任何情况,直接使用mesh.kdtree
。
惰性
motmot.Mesh
使用@functools.cached_property的后端口惰性加载其属性。这允许它们仅在需要时进行计算,从而不会浪费计算您未使用的内容的时间。以mesh.normals为例。在mesh = Mesh(vertices, faces)
上不会进行任何计算,因此如果法线从未被使用,则它们永远不会被计算。访问属性mesh.normals
会初始化并返回它们,使mesh.normals
在外部看起来像是一个常规属性。值被缓存,以确保计算不会运行多次。即mesh.normals is mesh.normals
。
在修改网格后应重置缓存。大部分操作都是自动完成的。网格修改方法,如rotate()
、translate()
或crop(in_place=True)
都会自行使受影响的缓存失效。同样,设置任何vertices
、faces
或vectors
属性都会重置所有缓存。但是,以原地方式写入这些数组(例如mesh.vectors[:] = x
)对motmot
来说是不可检测的。在完成原地修改后,请调用mesh.reset()
。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源分布
构建分布
motmot-0.3.2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2363dd96da15739c2cc17882fc641a7b53b0913aaf10285bb2693c8e28999c13 |
|
MD5 | a184215619246104db58f04a53e8fcef |
|
BLAKE2b-256 | e5f1094ebce2f0fb8c7a26f76ff55b101f251e47f15765ced915d9c9889a0e60 |
motmot-0.3.2-py3-none-win_amd64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8e6282135e84c075965109f3ae6c9750764e664ede90e03b4185c9a68e68c239 |
|
MD5 | aa3803a63552a02b469dae6a6485a837 |
|
BLAKE2b-256 | 97a0537533982be608558038aae9c3e09d8e2bdec5c025fb6bb122848d12fd86 |
motmot-0.3.2-py3-none-win32.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | da7985e85924b66d7f4f3b403bf58569f3a8339ae7127111bbd1b4becc58eb79 |
|
MD5 | 825b407b56860a2dd71045b1b9849fb6 |
|
BLAKE2b-256 | b3b7191f7dee59c9031d58ac653fa3ac6c3628524a41d8cf628b295d3e54e9a2 |
motmot-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | f6b958ebef0a3f2ed966005ef5c825aa7f42c2581ed0cb3df7fd0a7355baac98 |
|
MD5 | e8076bf03f75fd9bb6124b88329c70e4 |
|
BLAKE2b-256 | 649849a643bc508b807ce8f126d1564d87b74830946805cecc76dca861263062 |
motmot-0.3.2-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9b2a0abfd54e9e115b594a182438a1c3f1b8c9dbc38c4352b26e8c72fbce2ecc |
|
MD5 | 03ea96d4e07217898f5575d0bdbc6bbb |
|
BLAKE2b-256 | 888620090192a65119568ec1e916160b865f29459f5a280a38d6d8a2c4ee8d9c |
motmot-0.3.2-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6111cd07bd738a72cf657f5ed7295080b836b26a7f129e6935bb081e0315cc38 |
|
MD5 | ad6d7e98a0f62c33fa60c4473634ddb7 |
|
BLAKE2b-256 | 53999675ed8de93891d8cd72372f1ae63c85818a78f295b98b3ef6644a95a0ca |
哈希值 用于 motmot-0.3.2-py3-none-manylinux_2_5_i686.manylinux1_i686.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d5203224e9719213103121e4fe90afd4e77116f90780b4c1fac818f75407a578 |
|
MD5 | 792becde1cb284430c1222cfc3e35ff3 |
|
BLAKE2b-256 | 6c2f29a7807e2560c5770d9e49117f7313056c168b346eb442165d485f984cea |