最近使用了numpy-stl,现在对numpy-stl进行深入总结学习。 写这个文档的时候有些地方的理解还是不到位,姑且看之。

numpy-stl中文文档

  • 0 3D基础和相关概念
    • 0.1 顶点、多边形、网格
    • 0.2 材质、纹理、光源
    • 0.3 向量、矩阵
    • 0.4 相机、透视、视口、投影
    • 0.5 着色器(shader)
  • 1 相关链接
  • 2 依赖
  • 3 安装
  • 4 初始使用
  • 5 贡献
  • 6 快速开始
  • 7 使用 *matplotlib* 绘制同样简单
  • 8 修改网格对象
  • 9 继承扩展Mesh对象
  • 10 用一个顶点和面的集合列表创建Mesh对象
  • 11 获取mesh对象相关参数(体积、重心、惯量)
  • 12 组合多个stl文件
  • 13 已知限制
  • 参考文献

numpy-stl 是一个可以让你简单快捷地处理STL(和普通的3D对象)文件的简单库。
由于 numpy-stl 的所有操作都是重度依赖于 numpy 的,所以它是Python可使用的最快的用于STL编辑的库之一。

0 3D基础和相关概念

0.1 顶点、多边形、网格

顶点(vertex)一个点在空间中的位置,描述具有x、y、z坐标的空间位置。顶点就是在一个三维坐标系中的点。
多边形3个以上的顶点连接形成多边形。在3DMAX中,常见的概念是三角形面(triangle),也就是3个顶点形成的三角形区域。
网格(mesh)提供3D模型的底层结构。通常,网格看起来是由成千上万个单独的多边形框架结构组成的线框。3D模型通常至少包含一个网格,也可能包含多个网格。

3D图形是由3D网格构成的,网格也被称为模型。

0.2 材质、纹理、光源

光有网格模型看上去就是一个物品的轮廓,为了让模型具有真实感,我们就要为模型赋予材质和纹理。

纹理(texture)物体表面绘制的图案。
材质(materal)物体表面各可视属性的集合,可以看出物体是由什么材料组成的。这些可视属性是指表面的色彩、纹理、光滑度、透明度、反射率、折射率、发光度等。
光源(light)材质的表现必然依赖光源,光源不同,表现也会不同,没有光源就看不到物体,也就没有材质。

0.3 向量、矩阵

向量(vector)我们说一个模型就是一个对象。对象都有其位置和方向,在3D空间由x、y、z三个值来定义,在这里位置和方向都是向量。
矩阵(matrix)对象有了方向和位置后,要对其进行移动、缩放、旋转等处理就需要用到矩阵。

0.4 相机、透视、视口、投影

相机(camera)相当于在3D场景中的人的眼睛。
透视相机的一种显示效果,比如物体远小近大。
视口视觉窗口,由浏览器窗口或canvans决定。
投影(projection)3D坐标系列到2D渲染坐标的映射,影子。

0.5 着色器(shader)

承担着将顶点、变换、材质、光源、相机等相互作用生成最终图像的任务。

1 相关链接

  • 源码: https://github.com/WoLpH/numpy-stl
  • 项目页面: https://pypi.python.org/pypi/numpy-stl
  • bug报告: https://github.com/WoLpH/numpy-stl/issues
  • 文档: http://numpy-stl.readthedocs.org/en/latest/
  • 作者博客: https://wol.ph/

2 依赖

  • numpy 任意最近版本
  • python-utils 1.6及以上版本

3 安装

pip install numpy-stl

4 初始使用

在安装完这个模块后,我们可以像使用pip命令一样,使用下面的这些命令。

$ stl2bin your_ascii_stl_file.stl new_binary_stl_file.stl
$ stl2ascii your_binary_stl_file.stl new_ascii_stl_file.stl
$ stl your_ascii_stl_file.stl new_binary_stl_file.stl

5 贡献

作者欢迎大家积极多做贡献,根据指引开始贡献。

6 快速开始

import numpy
from stl import mesh# 读取一个本地已经存在的stl文件
your_mesh = mesh.Mesh.from_file('some_file.stl')# 或者创建一个新的 mesh (确保引入的‘mesh’不被自定义的mesh重写覆盖):
VERTICE_COUNT = 100
data = numpy.zeros(VERTICE_COUNT, dtype=mesh.Mesh.dtype)
your_mesh = mesh.Mesh(data, remove_empty_areas=False)# The mesh normals (自动计算)
your_mesh.normals
# mesh向量
your_mesh.v0, your_mesh.v1, your_mesh.v2
# Accessing individual points (concatenation of v0, v1 and v2 in triplets)
assert (your_mesh.points[0][0:3] == your_mesh.v0[0]).all()
assert (your_mesh.points[0][3:6] == your_mesh.v1[0]).all()
assert (your_mesh.points[0][6:9] == your_mesh.v2[0]).all()
assert (your_mesh.points[1][0:3] == your_mesh.v0[1]).all()# 保存为stl文件
your_mesh.save('new_stl_file.stl')

7 使用 matplotlib 绘制同样简单

使用matplotlib辅助显示3D模型和我们对其的处理结果。如下图,加载了一个俺私人珍藏的一个狗头。

from stl import mesh
from mpl_toolkits import mplot3d
from matplotlib import pyplot# 创建一个plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)# 加载stl文件并将向量加载到 plot
your_mesh = mesh.Mesh.from_file('dog.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))# 自动缩放网格尺寸
scale = your_mesh.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)# 在屏幕上显示这个plot
pyplot.show()

8 修改网格对象

from stl import mesh
import math
import numpy# Create 3 faces of a cube
data = numpy.zeros(6, dtype=mesh.Mesh.dtype)# Top of the cube
data['vectors'][0] = numpy.array([[0, 1, 1],[1, 0, 1],[0, 0, 1]])
data['vectors'][1] = numpy.array([[1, 0, 1],[0, 1, 1],[1, 1, 1]])
# Front face
data['vectors'][2] = numpy.array([[1, 0, 0],[1, 0, 1],[1, 1, 0]])
data['vectors'][3] = numpy.array([[1, 1, 1],[1, 0, 1],[1, 1, 0]])
# Left face
data['vectors'][4] = numpy.array([[0, 0, 0],[1, 0, 0],[1, 0, 1]])
data['vectors'][5] = numpy.array([[0, 0, 0],[0, 0, 1],[1, 0, 1]])# Since the cube faces are from 0 to 1 we can move it to the middle by
# substracting .5
data['vectors'] -= .5# Generate 4 different meshes so we can rotate them later
meshes = [mesh.Mesh(data.copy()) for _ in range(4)]# Rotate 90 degrees over the Y axis
meshes[0].rotate([0.0, 0.5, 0.0], math.radians(90))# Translate 2 points over the X axis
meshes[1].x += 2# Rotate 90 degrees over the X axis
meshes[2].rotate([0.5, 0.0, 0.0], math.radians(90))
# Translate 2 points over the X and Y points
meshes[2].x += 2
meshes[2].y += 2# Rotate 90 degrees over the X and Y axis
meshes[3].rotate([0.5, 0.0, 0.0], math.radians(90))
meshes[3].rotate([0.0, 0.5, 0.0], math.radians(90))
# Translate 2 points over the Y axis
meshes[3].y += 2# Optionally render the rotated cube faces
from matplotlib import pyplot
from mpl_toolkits import mplot3d# Create a new plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)# Render the cube faces
for m in meshes:axes.add_collection3d(mplot3d.art3d.Poly3DCollection(m.vectors))# Auto scale to the mesh size
scale = numpy.concatenate([m.points for m in meshes]).flatten()
axes.auto_scale_xyz(scale, scale, scale)# Show the plot to the screen
pyplot.show()

9 继承扩展Mesh对象

from stl import mesh
import math
import numpy# 创建立方体的3个面
data = numpy.zeros(6, dtype=mesh.Mesh.dtype)# 立方体顶部
data['vectors'][0] = numpy.array([[0, 1, 1],[1, 0, 1],[0, 0, 1]])
data['vectors'][1] = numpy.array([[1, 0, 1],[0, 1, 1],[1, 1, 1]])
# 前面
data['vectors'][2] = numpy.array([[1, 0, 0],[1, 0, 1],[1, 1, 0]])
data['vectors'][3] = numpy.array([[1, 1, 1],[1, 0, 1],[1, 1, 0]])
# 左面
data['vectors'][4] = numpy.array([[0, 0, 0],[1, 0, 0],[1, 0, 1]])
data['vectors'][5] = numpy.array([[0, 0, 0],[0, 0, 1],[1, 0, 1]])# Since the cube faces are from 0 to 1 we can move it to the middle by
# substracting .5
data['vectors'] -= .5cube_back = mesh.Mesh(data.copy())
cube_front = mesh.Mesh(data.copy())# Rotate 90 degrees over the X axis followed by the Y axis followed by the
# X axis
cube_back.rotate([0.5, 0.0, 0.0], math.radians(90))
cube_back.rotate([0.0, 0.5, 0.0], math.radians(90))
cube_back.rotate([0.5, 0.0, 0.0], math.radians(90))cube = mesh.Mesh(numpy.concatenate([cube_back.data.copy(),cube_front.data.copy(),
]))# Optionally render the rotated cube faces
from matplotlib import pyplot
from mpl_toolkits import mplot3d# 创建一个 plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)# 提供立方体
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(cube.vectors))# 自动缩放尺寸
scale = cube_back.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)# 显示
pyplot.show()

10 用一个顶点和面的集合列表创建Mesh对象

import numpy as np
from stl import mesh# 定义立方体的8个顶点
vertices = np.array([\[-1, -1, -1],[+1, -1, -1],[+1, +1, -1],[-1, +1, -1],[-1, -1, +1],[+1, -1, +1],[+1, +1, +1],[-1, +1, +1]])
# 定义一个由12个三角面构成的立方体
faces = np.array([\[0,3,1],[1,3,2],[0,4,7],[0,7,3],[4,5,6],[4,6,7],[5,1,2],[5,2,6],[2,3,6],[3,7,6],[0,1,5],[0,5,4]])# 创建mesh
cube = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
for i, f in enumerate(faces):for j in range(3):cube.vectors[i][j] = vertices[f[j],:]# 将mesh 写入文件"cube.stl"
cube.save('cube.stl')

11 获取mesh对象相关参数(体积、重心、惯量)

import numpy as np
from stl import mesh# Using an existing closed stl file:
your_mesh = mesh.Mesh.from_file('some_file.stl')volume, cog, inertia = your_mesh.get_mass_properties()
print("体积                                  = {0}".format(volume))
print("重心                            (COG) = {0}".format(cog))
print("Inertia matrix at expressed at the COG  = {0}".format(inertia[0,:]))
print("                                          {0}".format(inertia[1,:]))
print("                                          {0}".format(inertia[2,:]))

12 组合多个stl文件

import math
import stl
from stl import mesh
import numpy# find the max dimensions, so we can know the bounding box, getting the height,
# width, length (because these are the step size)...
def find_mins_maxs(obj):minx = obj.x.min()maxx = obj.x.max()miny = obj.y.min()maxy = obj.y.max()minz = obj.z.min()maxz = obj.z.max()return minx, maxx, miny, maxy, minz, maxzdef translate(_solid, step, padding, multiplier, axis):if 'x' == axis:items = 0, 3, 6elif 'y' == axis:items = 1, 4, 7elif 'z' == axis:items = 2, 5, 8else:raise RuntimeError('Unknown axis %r, expected x, y or z' % axis)# _solid.points.shape == [:, ((x, y, z), (x, y, z), (x, y, z))]_solid.points[:, items] += (step * multiplier) + (padding * multiplier)def copy_obj(obj, dims, num_rows, num_cols, num_layers):w, l, h = dimscopies = []for layer in range(num_layers):for row in range(num_rows):for col in range(num_cols):# skip the position where original being copied isif row == 0 and col == 0 and layer == 0:continue_copy = mesh.Mesh(obj.data.copy())# pad the space between objects by 10% of the dimension being# translatedif col != 0:translate(_copy, w, w / 10., col, 'x')if row != 0:translate(_copy, l, l / 10., row, 'y')if layer != 0:translate(_copy, h, h / 10., layer, 'z')copies.append(_copy)return copies# Using an existing stl file:
main_body = mesh.Mesh.from_file('ball_and_socket_simplified_-_main_body.stl')# rotate along Y
main_body.rotate([0.0, 0.5, 0.0], math.radians(90))minx, maxx, miny, maxy, minz, maxz = find_mins_maxs(main_body)
w1 = maxx - minx
l1 = maxy - miny
h1 = maxz - minz
copies = copy_obj(main_body, (w1, l1, h1), 2, 2, 1)# I wanted to add another related STL to the final STL
twist_lock = mesh.Mesh.from_file('ball_and_socket_simplified_-_twist_lock.stl')
minx, maxx, miny, maxy, minz, maxz = find_mins_maxs(twist_lock)
w2 = maxx - minx
l2 = maxy - miny
h2 = maxz - minz
translate(twist_lock, w1, w1 / 10., 3, 'x')
copies2 = copy_obj(twist_lock, (w2, l2, h2), 2, 2, 1)
combined = mesh.Mesh(numpy.concatenate([main_body.data, twist_lock.data] +[copy.data for copy in copies] +[copy.data for copy in copies2]))combined.save('combined.stl', mode=stl.Mode.ASCII)  # save as ASCII

13 已知限制

  • 启用加速后,STL名会自动转为小写。

参考文献

  • [1] 3D的基本概念
  • [2] numpy-stl
  • [3] 3D基本概念

numpy-stl中文文档相关推荐

  1. Python爱好者周知:Scikit-Learn中文文档正式发布

    整理 | 费棋 出品 | AI科技大本营(公众号ID:rgznai100) 近日,Scikit-Learn 中文文档已由开源组织 ApacheCN 完成校对.该中文文档依然包含了 Scikit-Lea ...

  2. source insight3.5显示中文_Doxygen 中文文档

    Doxygen 中文文档 原文:http://doxygen.nl/manual 本文档摘取重点进行了介绍. Getting started doxygen是解析源文件和生成文档的主要程序.详细使用方 ...

  3. aspose excel中文文档_除了VBA,还有哪些编程语言可以操作Excel文件?

    Excel(Microsoft office)是现在最常用的办公软件,主要涉及电子表格制作.数据处理.报表输出展示以及更高端的还有金融建模等:我们知道,在需要批处理多个Excel工作表以及工作簿的时候 ...

  4. 【Scikit-Learn 中文文档】支持向量机 - 监督学习 - 用户指南 | ApacheCN

    中文文档: http://sklearn.apachecn.org/cn/0.19.0/modules/svm.html 英文文档: http://sklearn.apachecn.org/en/0. ...

  5. PyTorch 1.4 中文文档校对活动正式启动 | ApacheCN

    一如既往,PyTorch 1.4 中文文档校对活动启动了! 认领须知 请您勇敢地去翻译和改进翻译.虽然我们追求卓越,但我们并不要求您做到十全十美,因此请不要担心因为翻译上犯错--在大部分情况下,我们的 ...

  6. PyTorch 1.2 中文文档校对活动 | ApacheCN

    整体进度:https://github.com/apachecn/pytorch-doc-zh/issues/422 贡献指南:https://github.com/apachecn/pytorch- ...

  7. PlantCV中文文档

    PlantCV中文文档 1. 简介 1. 欢迎来到PlantCV文档 总览 开始 教程 贡献 版本 2. PlantCV Namespace 2.1 PlantCV 2.1.1 分析颜色 2.1.2 ...

  8. MoviePy - 中文文档2-快速上手-创建和导出video clips

    回到目录 创建和导出video clips video 和 audio clips是moviepy中的核心的对象.这篇博文,我们会介绍不同的短clip,展示如何创建他们,以及如何将它们导出到文件中.关 ...

  9. 【Scikit-Learn 中文文档】数据集加载工具 - 用户指南 | ApacheCN

    中文文档: http://sklearn.apachecn.org/cn/stable/datasets/index.html 英文文档: http://sklearn.apachecn.org/en ...

  10. Scikit-Learn 中文文档】数据集加载工具 - 用户指南 | ApacheCN

    中文文档: http://sklearn.apachecn.org/cn/stable/datasets/index.html 英文文档: http://sklearn.apachecn.org/en ...

最新文章

  1. OKR 落地需要相关工具的辅助吗?
  2. python 爬取图片_使用python爬取英雄联盟官方英雄皮肤图片
  3. oc09--NSString
  4. Swift 与 Objective-C混合编程
  5. 手把手教你安装Flutter(Flutter起步之安装)
  6. Mac版钉钉之一个新的技术electron
  7. PyTorch 1.0 中文文档:torch.distributions
  8. JQuery中淡出和淡入动画效果
  9. cmd查看所有数据库 db2_db2 cmd命令操作
  10. xshell 自动断开解决方法
  11. 此博客不再更新,新博客地址https://xsamsara.tk/
  12. (原创)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)
  13. Container的限制
  14. SAP GUI 一些实用技巧分享
  15. windows设置自动获取IP地址
  16. Q3D之多视图(左视图,正视图等)
  17. MATLAB读取10bit的raw格式图片代码
  18. 爱上调试:div初探,参照物的重要性!
  19. 数商云电子元器件B2B商城系统
  20. 记录一下自己爬虎牙LOL主播的爬虫思路

热门文章

  1. 国内搜索引擎技术现状 zZ
  2. 密码生成器(字母+数字+特殊字符)
  3. VBA 字典 键值为二维数组并不断增加行
  4. html视频怎么添加封面,快影视频封面怎么添加文字标题
  5. volatile能保持线程安全吗_volatile变量能保证线程安全性吗?为什么?
  6. raspbain系统连接家庭wifi的配置方法
  7. excel打乱各行的顺序,实现无序随机排列
  8. HashMap HashTable和CurrentHashMap的区别
  9. 条件语句的if语句的5种替代方法
  10. 窗体泄露 WindowManager: android.view.WindowLeaked: Activity com.XXX.XXX.activity.XXXActivity has leaked