{"id":399549,"date":"2024-06-29T14:44:29","date_gmt":"2024-06-29T14:44:29","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=399549"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=399549","title":{"rendered":"<span>3D \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Python<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/7o\/la\/oc\/7olaocvqltjf9qgmxe-rpbhftva.png\" width=\"4214\" height=\"2107\" data-src=\"https:\/\/habrastorage.org\/webt\/7o\/la\/oc\/7olaocvqltjf9qgmxe-rpbhftva.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0432\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f python, \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u0438\u043b\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u043f\u0435\u0447\u0430\u0442\u0438 \u043d\u0430 3D \u043f\u0440\u0438\u043d\u0442\u0435\u0440\u0435. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0449\u0438\u0445 \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u044d\u0442\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0442\u043e\u0447\u0435\u043a, \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u0432 python. \u041a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0435 \u043f\u0440\u0438\u0435\u043c\u044b 3D \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u0432\u043e\u0440\u043e\u0442, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>numpy-stl<\/p>\n<\/li>\n<li>\n<p>pymesh<\/p>\n<\/li>\n<li>\n<p>pytorch3d<\/p>\n<\/li>\n<li>\n<p>SolidPython<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b &#8212;<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%93%D1%83%D0%B1%D0%BA%D0%B0_%D0%9C%D0%B5%D0%BD%D0%B3%D0%B5%D1%80%D0%B0\" rel=\"noopener noreferrer nofollow\"> <u>\u0413\u0443\u0431\u043a\u0443 \u041c\u0435\u043d\u0433\u0435\u0440\u0430<\/u><\/a> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Menger_sponge\" rel=\"noopener noreferrer nofollow\"><u>Menger sponge<\/u><\/a>), \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0432 stl \u0444\u0430\u0439\u043b \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u043f\u0443\u0442\u043d\u043e, \u043a\u0440\u0430\u0442\u043a\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043c\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<a href=\"https:\/\/github.com\/format37\/python3d\" rel=\"noopener noreferrer nofollow\"> <u>\u043d\u0430 GitHub<\/u><\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0441\u0440\u0435\u0434\u044b<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.docker.com\/engine\/install\/\" rel=\"noopener noreferrer nofollow\"><u>Docker<\/u><\/a> \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 Pymesh:<\/p>\n<\/li>\n<\/ul>\n<p><code>curl -fsSL https:\/\/get.docker.com -o get-docker.sh<\/code><\/p>\n<p><code>sudo sh get-docker.sh<\/code><\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 g++ \u0434\u043b\u044f PyTorch3d:<\/p>\n<\/li>\n<\/ul>\n<p><code>sudo apt update<\/code><\/p>\n<p><code>sudo apt install g++<\/code><\/p>\n<ul>\n<li>\n<p>\u041a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a:<\/p>\n<\/li>\n<\/ul>\n<p><code>git clone https:\/\/github.com\/format37\/python3d.git<\/code><\/p>\n<p><code>cd python3d<\/code><\/p>\n<p><code>pip install -r requirements.txt<\/code><\/p>\n<p><code>pip install \"git+https:\/\/github.com\/facebookresearch\/pytorch3d.git\"<\/code><\/p>\n<ul>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 OpenScad:<\/p>\n<\/li>\n<\/ul>\n<p><code>sudo apt-get install openscad<\/code><\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"numpy_overview\" id=\"numpy_overview\"><\/a><\/p>\n<h2>Numpy-stl: \u041e\u0431\u0437\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p><a href=\"https:\/\/pypi.python.org\/pypi\/numpy-stl\" rel=\"noopener noreferrer nofollow\"><u>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/a><\/p>\n<p><a href=\"https:\/\/numpy-stl.readthedocs.io\" rel=\"noopener noreferrer nofollow\"><u>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/u><\/a><\/p>\n<p><a href=\"https:\/\/github.com\/WoLpH\/numpy-stl\" rel=\"noopener noreferrer nofollow\"><u>Github<\/u><\/a><\/p>\n<p>\u0421\u0442\u0440\u043e\u0435\u043d\u0438\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B0\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438<\/u><\/a>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/vw\/kl\/rp\/vwklrpj8lp8bomlojmf5qcyq6qs.png\" alt=\"\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438\" title=\"\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438\" width=\"720\" height=\"271\" data-src=\"https:\/\/habrastorage.org\/webt\/vw\/kl\/rp\/vwklrpj8lp8bomlojmf5qcyq6qs.png\"\/><figcaption>\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/figcaption><\/figure>\n<p><strong>Vertices (\u0432\u0435\u0440\u0448\u0438\u043d\u044b)<\/strong> &#8212; \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u0447\u0435\u043a. \u041a\u0430\u0436\u0434\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0442\u0440\u0435\u043c\u044f \u0447\u0438\u0441\u043b\u0430\u043c\u0438 &#8212; \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0432 3-\u0445 \u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 Jupyter notebook<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/thecode.media\/jupyter\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 jupyter-\u043d\u043e\u0443\u0442\u0431\u0443\u043a \u0438 \u0437\u0430\u0447\u0435\u043c \u043e\u043d \u043d\u0443\u0436\u0435\u043d<\/a><\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_01.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_01.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">import numpy as np from myplot import plot_verticles  vertices = np.array(     [         [-3, -3, 0],         [+3, -3, 0],         [+3, +3, 0],         [-3, +3, 0],         [+0, +0, +3]     ] )  plot_verticles(vertices = vertices, isosurf = False)<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/k3\/dz\/uv\/k3dzuvmjw1tj_ukifsgez_fr-jc.png\" alt=\"\u0412\u0435\u0440\u0448\u0438\u043d\u044b \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b\" title=\"\u0412\u0435\u0440\u0448\u0438\u043d\u044b \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b\" width=\"263\" height=\"242\" data-src=\"https:\/\/habrastorage.org\/webt\/k3\/dz\/uv\/k3dzuvmjw1tj_ukifsgez_fr-jc.png\"\/><figcaption>\u0412\u0435\u0440\u0448\u0438\u043d\u044b \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b<\/figcaption><\/figure>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043a\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c, \u0435\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430\u043c\u0438:<\/p>\n<pre><code class=\"python\">plot_verticles(vertices = vertices, isosurf = True)<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/bn\/tf\/ys\/bntfysalvm3z0s9jakzpygv-rjw.png\" alt=\"\u0418\u0437\u043e\u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b\" title=\"\u0418\u0437\u043e\u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b\" width=\"263\" height=\"242\" data-src=\"https:\/\/habrastorage.org\/webt\/bn\/tf\/ys\/bntfysalvm3z0s9jakzpygv-rjw.png\"\/><figcaption>\u0418\u0437\u043e\u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b<\/figcaption><\/figure>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0431\u0443\u0434\u0442\u043e \u0433\u0440\u0430\u043d\u0438 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442. \u041d\u043e \u043f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b. \u0427\u0442\u043e\u0431\u044b \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c stl \u0444\u0430\u0439\u043b, \u043e\u043f\u0438\u0448\u0435\u043c \u0433\u0440\u0430\u043d\u0438, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0440\u0430\u0431\u043e\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/generated\/scipy.spatial.ConvexHull.html\" rel=\"noopener noreferrer nofollow\"><u>spatial.ConvexHull <\/u><\/a>\u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/\" rel=\"noopener noreferrer nofollow\"><u>scipy<\/u><\/a><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_02.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_02.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">import numpy as np from scipy import spatial from stl import mesh from myplot import plot_mesh  vertices = np.array(     [         [-3, -3, 0],         [+3, -3, 0],         [+3, +3, 0],         [-3, +3, 0],         [+0, +0, +3]     ] )  hull = spatial.ConvexHull(vertices) faces = hull.simplices<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435, \u043c\u0430\u0441\u0441\u0438\u0432 faces \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043d\u0435\u0439:<\/p>\n<pre><code class=\"python\">array([[4, 1, 0],        [4, 2, 1],        [3, 4, 0],        [3, 4, 2],        [3, 2, 1],        [3, 1, 0]], dtype=int32)<\/code><\/pre>\n<p><strong>faces<\/strong> <strong>(\u0433\u0440\u0430\u043d\u0438)<\/strong> &#8212; \u0441\u043f\u0438\u0441\u043e\u043a \u0433\u0440\u0430\u043d\u0435\u0439. \u041a\u0430\u0436\u0434\u0430\u044f \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0430\u043d\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0442\u0440\u0435\u043c\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438, \u0438\u043b\u0438 \u0442\u043e\u0447\u043a\u0430\u043c\u0438. \u0410 \u0442\u043e\u0447\u043d\u0435\u0435, \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u0442\u043e\u0447\u0435\u043a \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 vertices.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0433\u0440\u0430\u043d\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0447\u0438\u0441\u043b\u0430 3, 1, 0. \u0417\u043d\u0430\u0447\u0438\u0442 \u0433\u0440\u0430\u043d\u044c \u0441\u043e\u0431\u0440\u0430\u043d\u0430 \u0438\u0437 \u0442\u043e\u0447\u0435\u043a 0-\u0433\u043e, 1-\u0433\u043e \u0438 3-\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 vertices:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/zx\/1i\/xs\/zx1ixspulzbw1ug-adfcl1hcgno.png\" alt=\"\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\" title=\"\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\" width=\"1274\" height=\"367\" data-src=\"https:\/\/habrastorage.org\/webt\/zx\/1i\/xs\/zx1ixspulzbw1ug-adfcl1hcgno.png\"\/><figcaption>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d<\/figcaption><\/figure>\n<p><strong>Mesh (\u0441\u0435\u0442\u043a\u0430) <\/strong>&#8212; \u041d\u0430\u0431\u043e\u0440 \u0432\u0435\u0440\u0448\u0438\u043d \u0438 \u0433\u0440\u0430\u043d\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u0444\u043e\u0440\u043c\u0443 \u043c\u043d\u043e\u0433\u043e\u0433\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<pre><code class=\"python\">myramid_mesh = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces):     for j in range(3):         myramid_mesh.vectors[i][j] = vertices[f[j],:] plot_mesh(myramid_mesh)<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ia\/aj\/ix\/iaajixa6kvglnaa3ncdtgnvgxhg.png\" alt=\"\u0413\u0440\u0430\u043d\u0438 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b\" title=\"\u0413\u0440\u0430\u043d\u0438 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b\" width=\"311\" height=\"307\" data-src=\"https:\/\/habrastorage.org\/webt\/ia\/aj\/ix\/iaajixa6kvglnaa3ncdtgnvgxhg.png\"\/><figcaption>\u0413\u0440\u0430\u043d\u0438 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b<\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u0440\u0438\u0441\u0443\u043d\u043a\u0430, \u043e\u0434\u043d\u0430 \u0433\u0440\u0430\u043d\u044c \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u0430. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445, \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u043e\u0432, \u043c\u0435\u0442\u043e\u0434 ConvexHull \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u0433\u0440\u0430\u043d\u0438 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0433\u0440\u0430\u043d\u0435\u0439.<\/p>\n<pre><code class=\"python\">myramid_mesh.save('numpy_stl_example_02.stl')<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 stl \u0444\u0430\u0439\u043b\u043e\u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u041e\u0434\u043d\u0430 \u0438\u0437 \u043d\u0438\u0445 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.blender.org\" rel=\"noopener noreferrer nofollow\"><u>Blender<\/u><\/a>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u043f\u043b\u0430\u0442\u044b \u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/gb\/dp\/hp\/gbdphpl7lsqk88chsnjgay0ygtq.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_02.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_02.stl\" width=\"752\" height=\"604\" data-src=\"https:\/\/habrastorage.org\/webt\/gb\/dp\/hp\/gbdphpl7lsqk88chsnjgay0ygtq.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_02.stl<\/figcaption><\/figure>\n<p>\u041c\u0435\u0442\u043e\u0434 spatial.ConvexHull \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u0443\u043a\u043b\u043e\u0439 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0438 \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u043e\u0439 \u0438 \u043a\u0443\u0431\u043e\u043c. \u041d\u043e \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445, \u0438\u043c\u0435\u044e\u0449\u0438\u0445 \u0432\u043f\u0430\u0434\u0438\u043d\u044b, \u0447\u0430\u0441\u0442\u044c \u0442\u043e\u0447\u0435\u043a \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u0430 \u0438 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 stl \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430 \u0438\u0437-\u0437\u0430 \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0433\u0440\u0430\u043d\u0435\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0442\u043e\u0447\u0435\u043a.<\/p>\n<p>\u042d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432 \u0434\u0432\u0443\u0445 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u0445: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_03.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_03.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">import matplotlib.pyplot as plt from scipy import spatial import numpy as np   points = np.array([     [0,0],     [-2,0],     [-2,2],     [0,1.5],     [2,2],     [2,0] ])  hull = spatial.ConvexHull(points)<\/code><\/pre>\n<p>\u0412 hull.simplices \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043d\u0435\u0439:<\/p>\n<pre><code class=\"python\">array([[2, 1],        [2, 4],        [5, 1],        [5, 4]], dtype=int32)<\/code><\/pre>\n<p>\u041e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0438 \u0433\u0440\u0430\u043d\u0438 \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435:<\/p>\n<pre><code class=\"python\">plt.plot(points[:,0], points[:,1], 'o') for simplex in hull.simplices:     plt.plot(points[simplex, 0], points[simplex, 1], 'k-')<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ys\/mf\/yr\/ysmfyr94j59btacq1wuhd0gsxqa.png\" alt=\"\u0426\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0433\u0440\u0430\u043d\u044f\u043c\u0438\" title=\"\u0426\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0433\u0440\u0430\u043d\u044f\u043c\u0438\" width=\"378\" height=\"248\" data-src=\"https:\/\/habrastorage.org\/webt\/ys\/mf\/yr\/ysmfyr94j59btacq1wuhd0gsxqa.png\"\/><figcaption>\u0426\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0433\u0440\u0430\u043d\u044f\u043c\u0438<\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443 ConvexHull, \u0438\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e:<\/p>\n<pre><code class=\"python\">faces = np.array([     [0, 1],     [1, 2],     [2, 3],     [3, 4],     [4, 5],     [5, 0] ])  plt.plot(points[:,0], points[:,1], 'o') for simplex in faces:     plt.plot(points[simplex, 0], points[simplex, 1], 'k-')<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/iz\/ye\/ky\/izyekyl0v3c0jwthdh_xscuokhc.png\" alt=\"\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u0432\u0435 \u0433\u0440\u0430\u043d\u0438: \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438, \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0439\" title=\"\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u0432\u0435 \u0433\u0440\u0430\u043d\u0438: \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438, \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0439\" width=\"378\" height=\"248\" data-src=\"https:\/\/habrastorage.org\/webt\/iz\/ye\/ky\/izyekyl0v3c0jwthdh_xscuokhc.png\"\/><figcaption>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u0432\u0435 \u0433\u0440\u0430\u043d\u0438: \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438, \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0439<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"numpy_menger_sponge\" id=\"numpy_menger_sponge\"><\/a><\/p>\n<h3>Numpy-stl: \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/h3>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0444\u0440\u0430\u043a\u0442\u0430\u043b. \u0412 numpy-stl \u043d\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u043b\u0435\u0432\u0430 \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 Menger Sponge \u043f\u043e\u0439\u0434\u0435\u043c \u043e\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e. \u0412 \u043d\u0430\u0448\u0435\u043c \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u0438 \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u043e\u0433\u043e mesh \u043a\u0443\u0431\u0430. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e voxel.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 voxel \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 mesh.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0438\u0437 \u043a\u0443\u0431\u0438\u043a\u043e\u0432, \u043a\u0430\u043a \u0438\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043e\u0433\u043e\u0432\u043e\u0438\u043c\u0441\u044f \u0447\u0442\u043e \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0433\u0440\u0430\u043d\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 &#8212; \u0435\u0434\u0438\u043d\u0438\u0446\u0430. \u0413\u043b\u0443\u0431\u0438\u043d\u0430 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 \u044d\u0442\u043e, \u0433\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439. \u0414\u043b\u0438\u043d\u0430 \u0432\u043e\u043a\u0441\u0435\u043b\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430, \u043e\u043d\u0430 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 3 \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u043d\u043e\u0432\u044b\u043c \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u0433\u043b\u0443\u0431\u0438\u043d\u044b.<\/p>\n<p>\u041d\u0430\u0439\u0434\u0435\u043c \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0432\u043e\u043a\u0441\u0435\u043b\u044f \u043d\u0430 \u0433\u043b\u0443\u0431\u0438\u043d\u0430\u0445 1 \u0438 2.\u00a0\u0423\u043f\u0440\u043e\u0441\u0442\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u0441\u0432\u0435\u0440\u043d\u0443\u0432 \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0441 3-\u0445 \u0434\u043e 1-\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/xa\/lb\/rr\/xalbrr-2y0ukyaaaqpic-lchdsq.png\" width=\"1472\" height=\"576\" data-src=\"https:\/\/habrastorage.org\/webt\/xa\/lb\/rr\/xalbrr-2y0ukyaaaqpic-lchdsq.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u0443\u0431\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442 1\/(3**2) \u0438\u043b\u0438 1\/9. \u0421\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430\u0431\u043e\u0440 \u043a\u0443\u0431\u043e\u0432 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u043e\u0438\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043e\u043d\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u0443\u0431. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%92%D0%BE%D0%BA%D1%81%D0%B5%D0%BB\" rel=\"noopener noreferrer nofollow\"><u>\u0432\u043e\u043a\u0441\u0435\u043b\u044c\u043d\u044b\u0439<\/u><\/a> \u043a\u0443\u0431. \u0412\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439. \u0418\u0441\u043a\u043b\u044e\u0447\u0438\u043c \u0432\u043e\u043a\u0441\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439. \u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0432\u043e\u043a\u0441\u0435\u043b\u0438 \u0432 \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_04.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_04.ipynb<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from stl import mesh import numpy as np import datetime  time_start = datetime.datetime.now()   def create_voxel(side, tx, ty, tz):     vertices = np.array([        [tx + 0,     ty + 0,      tz + 0],        [tx + side,  ty + 0,      tz + 0],        [tx + side,  ty + side,   tz + 0],        [tx + 0,     ty + side,   tz + 0],        [tx + 0,     ty + 0,      tz + side],        [tx + side,  ty + 0,      tz + side],        [tx + side,  ty + side,   tz + side],        [tx + 0,     ty + side,   tz + side]     ])      faces = np.array([         [3, 2, 1],         [3, 1, 0],         [0, 1, 5],#         [5, 4, 0],         [7, 3, 0],         [0, 4, 7],#         [1, 2, 6],#         [6, 5, 1],         [2, 3, 6],#         [3, 7, 6],#         [4, 5, 6],#         [6, 7, 4]      ])     voxel = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))     for i, f in enumerate(faces):         for j in range(3):             voxel.vectors[i][j] = vertices[f[j],:]     return voxel       def voxel_in_hole(holes, x, y):     comp_error = 0     for hole in holes:         if  x + comp_error >= hole['x'][0] and x - comp_error &lt; hole['x'][1] and \\             y + comp_error >= hole['y'][0] and y - comp_error &lt; hole['y'][1]:             return True     return False       depth = 3 side = 1\/(3**depth)  # holes holes = [] side = 1 round_factor = 14 for d in range(1, depth+1):     side \/= 3     for x in range(1,3**d,3):         for y in range(1,3**d,3):                        holes.append({                 'x':[round(side*x,round_factor), round(side*x+side,round_factor)],                 'y':[round(side*y,round_factor), round(side*y+side,round_factor)]             })              sponge = None for x in range(3**depth):     for y in range(3**depth):         for z in range(3**depth):             rx = round(x\/(3**depth),round_factor)             ry = round(y\/(3**depth),round_factor)             rz = round(z\/(3**depth),round_factor)             if  voxel_in_hole(holes, ry, rz) or \\                 voxel_in_hole(holes, rx, ry) or \\                 voxel_in_hole(holes, rx, rz):                 continue             if sponge is None:                 sponge = create_voxel(side, x\/(3**depth), y\/(3**depth), z\/(3**depth))             else:                 new_voxel = create_voxel(side, x\/(3**depth), y\/(3**depth), z\/(3**depth))                 sponge = mesh.Mesh(np.concatenate([sponge.data, new_voxel.data]))                  sponge.save('numpy_stl_example_04.stl')   time_end = datetime.datetime.now() print('spent', (time_end - time_start).seconds, 'seconds') <\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/wd\/cx\/-l\/wdcx-ljjdtbvjsaln2u9974uonq.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_04.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_04.stl\" width=\"749\" height=\"741\" data-src=\"https:\/\/habrastorage.org\/webt\/wd\/cx\/-l\/wdcx-ljjdtbvjsaln2u9974uonq.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_04.stl<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"numpy_rendering\" id=\"numpy_rendering\"><\/a><\/p>\n<h3>Numpy-stl: \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0414\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0432\u043e\u0434\u0430 <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/myplot.py\" rel=\"noopener noreferrer nofollow\"><em>plot_mesh<\/em><\/a>, \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c mesh, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 stl \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_05.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_05.ipynb<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from myplot import plot_mesh from stl import mesh import datetime import imageio import math import os  sponge = mesh.Mesh.from_file('numpy_stl_example_04.stl')  gif_half_size = 14 filenames = [] imageio_images = [] for i in range(gif_half_size):     sponge.rotate([1, 0.0, 1], math.radians(1))     filename = 'solidpython_example_03_'+str(i)+'.png'     filenames.append(filename)     plot_mesh(sponge, filename = filename)     print(datetime.datetime.now(), filename)      print('forward rendering..') for i in range(gif_half_size):     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1      print('reverse rendering..') i = gif_half_size-1 while i>0:     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1      # save gif imageio.mimsave('solidpython_example_03.gif', imageio_images)      # remove images for filename in filenames:     os.remove(filename)      print('job complete!')<\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/uy\/9y\/xg\/uy9yxg3j1eqbxgwhiohzuklvliu.png\" alt=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" title=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" width=\"816\" height=\"816\" data-src=\"https:\/\/habrastorage.org\/webt\/uy\/9y\/xg\/uy9yxg3j1eqbxgwhiohzuklvliu.png\"\/><figcaption>\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/kz\/fh\/q6\/kzfhq6y_wnkd4lxmuhmxsfw-30c.gif\" alt=\"\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f: solidpython_example_03.gif\" title=\"\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f: solidpython_example_03.gif\" width=\"800\" height=\"800\" data-src=\"https:\/\/habrastorage.org\/webt\/kz\/fh\/q6\/kzfhq6y_wnkd4lxmuhmxsfw-30c.gif\"\/><figcaption>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f: solidpython_example_03.gif<\/figcaption><\/figure>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"pymesh_overview\" id=\"pymesh_overview\"><\/a><\/p>\n<h2>PyMesh: \u041e\u0431\u0437\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p><a href=\"https:\/\/pymesh.readthedocs.io\/en\/latest\/\" rel=\"noopener noreferrer nofollow\"><u>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/u><\/a><\/p>\n<p><a href=\"https:\/\/github.com\/PyMesh\/PyMesh\" rel=\"noopener noreferrer nofollow\"><u>Github<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 PyMesh \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0430\u0441\u044c \u0443 \u043c\u0435\u043d\u044f \u043d\u0438 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 PIP (\u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438), \u043d\u0438 \u0447\u0435\u0440\u0435\u0437 Anaconda. \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438.<\/p>\n<ol>\n<li>\n<p>\u0421\u043b\u0435\u0434\u0443\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440. \u0412\u044b\u0431\u0435\u0440\u0435\u043c \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u0430\u043a \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439. \u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438. \u041f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u0430\u043f\u043a\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u041f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u0441\u043a\u0440\u0438\u043f\u0442. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d. \u0415\u0441\u043b\u0438 Docker \u0432\u044b \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438, \u0431\u043e\u043b\u0435\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<\/li>\n<\/ol>\n<p>\u0415\u0441\u043b\u0438 Docker \u0432\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0439\u0442\u0435 PyMesh, \u0441\u043b\u0435\u0434\u0443\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u0422\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a\u0443\u0431\u0430. \u0412 \u043f\u0430\u043f\u043a\u0435 <em>pymesh_examples<\/em> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043a\u0440\u0438\u043f\u0442 <em>pymesh_example_01<\/em>.py. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0437 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pymesh_examples\/pymesh_example_01.py\" rel=\"noopener noreferrer nofollow\"><u>pymesh_example_01.py<\/u><\/a><\/p>\n<pre><code class=\"python\">import pymesh  box_a = pymesh.generate_box_mesh([0,0,0], [1,1,1]) filename = \"\/pymesh_examples\/pymesh_example_01.stl\" pymesh.save_mesh(filename, box_a, ascii=False)<\/code><\/pre>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043d\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440:<\/p>\n<pre><code class=\"bash\">sh pymesh_example_01.sh<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0427\u0442\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442?<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 pymesh. \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d \u043e\u0431\u0440\u0430\u0437, \u044d\u0442\u043e \u0437\u0430\u0439\u043c\u0451\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u043f\u043a\u0430 <em>pymesh_examples<\/em> \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f python \u0441\u043a\u0440\u0438\u043f\u0442 \/<em>pymesh_examples<\/em>\/<em>pymesh_example_01.py<\/em><\/p>\n<\/li>\n<li>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 pymesh<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u044f <a href=\"https:\/\/pymesh.readthedocs.io\/en\/latest\/api_procedural_mesh_generation.html?highlight=generate_box_mesh#pymesh.generate_box_mesh\" rel=\"noopener noreferrer nofollow\"><u>generate_box_mesh<\/u><\/a> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043a\u0443\u0431 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0432\u0443\u0445 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u044b\u0445 \u0432\u0435\u0440\u0448\u0438\u043d \u0432 \u0442\u043e\u0447\u043a\u0430\u0445 [0,0,0] \u0438 [1,1,1]<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u044f <a href=\"https:\/\/pymesh.readthedocs.io\/en\/latest\/api_meshio.html?highlight=save_mesh#pymesh.meshio.save_mesh\" rel=\"noopener noreferrer nofollow\"><u>save_mesh<\/u><\/a> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 stl \u0444\u0430\u0439\u043b.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0432 \u043f\u0430\u043f\u043a\u0435 <em>pymesh_examples<\/em> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b <em>pymesh_example_01<\/em>.stl<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/9y\/tv\/wb\/9ytvwbrdazkgpfkpfvtixdrvd7q.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_01.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_01.stl\" width=\"898\" height=\"770\" data-src=\"https:\/\/habrastorage.org\/webt\/9y\/tv\/wb\/9ytvwbrdazkgpfkpfvtixdrvd7q.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_01.stl<\/figcaption><\/figure>\n<p>\u041a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u043e\u0435 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0431\u0443\u043b\u0435\u0432\u0430 \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u044f. \u0421\u0442\u0440\u043e\u0438\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0435\u043f\u0438\u043f\u0435\u0434 \u0438 \u0432\u044b\u0447\u0438\u0442\u0430\u0435\u043c \u0435\u0433\u043e \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u0443\u0431\u0430.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pymesh_examples\/pymesh_example_02.py\" rel=\"noopener noreferrer nofollow\"><u>pymesh_example_02.py<\/u><\/a><\/p>\n<pre><code class=\"python\">import pymesh  box_a = pymesh.generate_box_mesh([0,0,0], [1,1,1]) box_b = pymesh.generate_box_mesh([0.4,0.4,0], [0.6,0.6,1]) box_c = pymesh.boolean(box_a, box_b, operation='difference', engine=\"igl\")  filename = \"\/pymesh_examples\/pymesh_example_02.stl\" pymesh.save_mesh(filename, box_c, ascii=False)<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a:<\/p>\n<pre><code class=\"bash\">sh pymesh_example_02.sh<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/jv\/l5\/by\/jvl5byacrheodcwux0dcg5g_2oy.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_02.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_02.stl\" width=\"900\" height=\"724\" data-src=\"https:\/\/habrastorage.org\/webt\/jv\/l5\/by\/jvl5byacrheodcwux0dcg5g_2oy.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_02.stl<\/figcaption><\/figure>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <a href=\"https:\/\/pymesh.readthedocs.io\/en\/latest\/mesh_boolean.html\" rel=\"noopener noreferrer nofollow\">boolean<\/a> \u043f\u0440\u043e\u0441\u0442\u0430. \u041f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0442\u0430\u0435\u043c. \u0412\u0442\u043e\u0440\u044b\u043c &#8212; \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0447\u0438\u0442\u0430\u0435\u043c. \u0421\u043b\u0435\u0434\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0438 \u0434\u0432\u0438\u0436\u043e\u043a.\u00a0<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c boolean \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u044f. \u0412\u0441\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e 4 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>Intersection: <em>A<\/em>\u2229<em>B<\/em><\/p>\n<\/li>\n<li>\n<p>Union: <em>A<\/em>\u222a<em>B<\/em><\/p>\n<\/li>\n<li>\n<p>Difference: <em>A<\/em>\u2216<em>B (\u0434\u0432\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430)<\/em><\/p>\n<\/li>\n<li>\n<p>Symmetric difference: <em>A<\/em> XOR <em>B (\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e)<\/em><\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/qf\/x_\/wj\/qfx_wj6kuzjvk_y1gtdao7rmft0.png\" alt=\"\u0418\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 boolean \u043d\u0430 \u0441\u0444\u0435\u0440\u0435 \u0438 \u043a\u0443\u0431\u0435\" title=\"\u0418\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 boolean \u043d\u0430 \u0441\u0444\u0435\u0440\u0435 \u0438 \u043a\u0443\u0431\u0435\" width=\"2214\" height=\"665\" data-src=\"https:\/\/habrastorage.org\/webt\/qf\/x_\/wj\/qfx_wj6kuzjvk_y1gtdao7rmft0.png\"\/><figcaption>\u0418\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 boolean \u043d\u0430 \u0441\u0444\u0435\u0440\u0435 \u0438 \u043a\u0443\u0431\u0435<\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0438 \u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u0431\u044b\u0432\u0430\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e Difference \u043d\u0430 Union.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0435 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0435, \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u043c \u0438 \u043f\u043e\u0432\u0435\u0440\u043d\u0435\u043c \u0435\u0433\u043e.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pymesh_examples\/pymesh_example_03.py\" rel=\"noopener noreferrer nofollow\"><u>pymesh_example_03.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import pymesh import numpy as np import math  def mesh_trans(mesh, x, y, z):    return pymesh.form_mesh(mesh.vertices + [[x, y, z]], mesh.faces)  def mesh_rotate(mesh, x, y, z, angle):    rot = pymesh.Quaternion.fromAxisAngle(np.array([x, y, z]), math.pi*2*angle\/360)    return pymesh.form_mesh(np.dot(rot.to_matrix(), mesh.vertices.T).T, mesh.faces)  sponge = pymesh.generate_box_mesh([0,0,0], [1,1,1]) bool_box = pymesh.generate_box_mesh([0.4,0.4,-0.1], [0.6,0.6,1.1]) sponge = pymesh.boolean(sponge, bool_box, operation='difference', engine=\"igl\")  bool_box = mesh_rotate(mesh = bool_box, x = 1, y = 0, z = 0, angle = 90) bool_box = mesh_trans(mesh = bool_box, x = 0, y = 1, z = 0) sponge = pymesh.boolean(sponge, bool_box, operation='difference', engine=\"igl\")  filename = \"\/pymesh_examples\/pymesh_example_03.stl\" pymesh.save_mesh(filename, sponge, ascii=False)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a:<\/p>\n<pre><code class=\"bash\">sh pymesh_example_03.sh<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 mesh \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0445 \u0432\u0435\u0440\u0448\u0438\u043d \u0438 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0414\u043b\u044f \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"https:\/\/pymesh.readthedocs.io\/en\/latest\/api_misc.html?highlight=Quaternion#quaternion\" rel=\"noopener noreferrer nofollow\"><u>Quaternion<\/u><\/a>, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u043e\u0440\u043e\u0442, \u0430 \u0437\u0430\u0442\u0435\u043c, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0441\u043b\u0443\u0447\u0430\u044e \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e, \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d \u0438 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430.<\/p>\n<blockquote>\n<p><a href=\"http:\/\/ru.wikipedia.org\/wiki\/%D0%9A%D0%B2%D0%B0%D1%82%D0%B5%D1%80%D0%BD%D0%B8%D0%BE%D0%BD\" rel=\"noopener noreferrer nofollow\"><u>\u041a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u044b<\/u><\/a> &#8212; \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0433\u0438\u043f\u0435\u0440\u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b, \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0449\u0430\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u0447\u0435\u0442\u044b\u0440\u0435 \u043d\u0430\u0434 \u043f\u043e\u043b\u0435\u043c \u0432\u0435\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<\/blockquote>\n<p>\u041e \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u0430\u0445 \u0435\u0441\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f:<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/426863\/\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043e \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u0430\u0445 \u0438 \u0438\u0445 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445<\/a><\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043a\u0443\u0431 \u0441 \u0434\u0432\u0443\u043c\u044f \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u044f\u043c\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/iz\/yv\/bp\/izyvbpevgh5gi9awayb6krlwhto.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_03.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_03.stl\" width=\"711\" height=\"677\" data-src=\"https:\/\/habrastorage.org\/webt\/iz\/yv\/bp\/izyvbpevgh5gi9awayb6krlwhto.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_03.stl<\/figcaption><\/figure>\n<p>\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430.<\/p>\n<p><a class=\"anchor\" name=\"pymesh_menger_sponge\" id=\"pymesh_menger_sponge\"><\/a><\/p>\n<h3>PyMesh: \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/h3>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pymesh_examples\/pymesh_example_04.py\" rel=\"noopener noreferrer nofollow\"><u>pymesh_example_04.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import datetime import pymesh import math import sys  time_start = datetime.datetime.now()  depth = int(sys.argv[1])  def mesh_trans(mesh, x, y, z):    return pymesh.form_mesh(mesh.vertices + [[x, y, z]], mesh.faces)  def mesh_rotate(mesh, x, y, z, angle):    rot = pymesh.Quaternion.fromAxisAngle(np.array([x, y, z]), math.pi*2*angle\/360)    return pymesh.form_mesh(np.dot(rot.to_matrix(), mesh.vertices.T).T, mesh.faces)  def menger_sponge(depth):    mesh_fractal = pymesh.generate_box_mesh([0,0,0], [1,1,1])    z = [-0.1,1.1]    side = 1    for d in range(1, depth+1):       side \/= 3       for x in range(1,3**d,3):          for y in range(1,3**d,3):                print(datetime.datetime.now(), d, x, y, '\/', depth, ':', 3**d)                box_a = pymesh.generate_box_mesh([side*x,side*y,z[0]], [side*x+side,side*y+side,z[1]])                             box_b = mesh_rotate(mesh = box_a, x = 1, y = 0, z = 0, angle = 90)                box_b = mesh_trans(mesh = box_b, x = 0, y = 1, z = 0)                 box_c = mesh_rotate(mesh = box_a, x = 0, y = 1, z = 0, angle = 90)                box_c = mesh_trans(mesh = box_c, x = 0, y = 0, z = 1)                 mesh_fractal = pymesh.boolean(mesh_fractal, box_a, operation='difference', engine=\"igl\")                mesh_fractal = pymesh.boolean(mesh_fractal, box_b, operation='difference', engine=\"igl\")                mesh_fractal = pymesh.boolean(mesh_fractal, box_c, operation='difference', engine=\"igl\")                return mesh_fractal  mesh_fractal = menger_sponge(depth)  pymesh.save_mesh(\"\/pymesh_examples\/pymesh_example_04_\"+str(depth)+\".stl\", mesh_fractal, ascii=False)  time_end = datetime.datetime.now() print('spent', (time_end - time_start).seconds, 'seconds')<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0435\u043f\u0438\u043f\u0435\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0434\u0432\u0430\u0436\u0434\u044b \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u0441\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e 3 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0435\u043f\u0438\u043f\u0435\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u0443\u0431\u0430. \u041f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u0433\u0440\u0430\u043d\u044c. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f x \u0438 y \u0440\u0430\u0437, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0433\u0440\u0430\u043d\u0438. \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u0438\u0437 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430:<\/p>\n<pre><code class=\"bash\">sh pymesh_example_04.sh 3<\/code><\/pre>\n<p>\u0418\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u043d \u0431\u0443\u0434\u0435\u0442 5-15 \u043c\u0438\u043d\u0443\u0442. \u041f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0432 \u043f\u0430\u043f\u043a\u0435 pymesh_examples \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f stl \u0444\u0430\u0439\u043b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/g_\/ae\/l3\/g_ael35hczajf025c9hno8cntm0.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_04_3.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_04_3.stl\" width=\"897\" height=\"800\" data-src=\"https:\/\/habrastorage.org\/webt\/g_\/ae\/l3\/g_ael35hczajf025c9hno8cntm0.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_04_3.stl<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0444\u0440\u0430\u043a\u0442\u0430\u043b 4-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0437\u0430\u0439\u043c\u0435\u0442 \u043e\u043a\u043e\u043b\u043e 4-\u0445 \u0447\u0430\u0441\u043e\u0432, \u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442 73 \u043c\u0431:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/4u\/if\/dd\/4uifddiphckpmtrgmd4a1e2qk6i.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_04_4.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_04_4.stl\" width=\"742\" height=\"716\" data-src=\"https:\/\/habrastorage.org\/webt\/4u\/if\/dd\/4uifddiphckpmtrgmd4a1e2qk6i.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pymesh_example_04_4.stl<\/figcaption><\/figure>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/pi\/ro\/rd\/pirordukfelh---4mfkmqtnecx8.jpeg\" alt=\"Menger sponge 4-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 3D \u043f\u0440\u0438\u043d\u0442\u0435\u0440\u0435\" title=\"Menger sponge 4-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 3D \u043f\u0440\u0438\u043d\u0442\u0435\u0440\u0435\" width=\"4000\" height=\"1868\" data-src=\"https:\/\/habrastorage.org\/webt\/pi\/ro\/rd\/pirordukfelh---4mfkmqtnecx8.jpeg\" data-blurred=\"true\"\/><figcaption>Menger sponge 4-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 3D \u043f\u0440\u0438\u043d\u0442\u0435\u0440\u0435<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"pymesh_rendering\" id=\"pymesh_rendering\"><\/a><\/p>\n<h3>PyMesh: \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>Mesh \u043c\u044b \u0443\u0436\u0435 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043b\u0438, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u043e\u0432\u0435\u0440\u043d\u0451\u043c \u043a\u0430\u043c\u0435\u0440\u0443.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pymesh_examples\/pymesh_example_05.py\" rel=\"noopener noreferrer nofollow\"><u>pymesh_example_05.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import pymesh from myplot_vf import plot_vf import imageio import os import datetime  gif_half_size = 16  sponge = pymesh.meshio.load_mesh('\/pymesh_examples\/pymesh_example_04_3.stl')  filenames = [] imageio_images = []  # rendering for i in range(gif_half_size):     vertices = sponge.vertices     faces = sponge.faces     filename = '\/pymesh_examples\/pymesh_example_05_3_'+str(i)+'.png'     print(filename)     filenames.append(filename)         plot_vf(vertices, faces, cam_x=i, cam_y=i, filename = filename)  print('forward rendering..') for i in range(gif_half_size):     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1  print('reverse rendering..') i = gif_half_size-1 while i>0:     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1  # save gif imageio.mimsave('\/pymesh_examples\/pymesh_example_05_3.gif', imageio_images)  # remove images for filename in filenames:     os.remove(filename)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a:<\/p>\n<pre><code class=\"bash\">sh pymesh_example_05.sh<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/7i\/l2\/fo\/7il2fow-jhalj2fmhqjv3aqbz1c.png\" alt=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" title=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" width=\"795\" height=\"663\" data-src=\"https:\/\/habrastorage.org\/webt\/7i\/l2\/fo\/7il2fow-jhalj2fmhqjv3aqbz1c.png\"\/><figcaption>\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/-c\/hr\/zq\/-chrzqyavbe-xepwt6vtwdth0u8.gif\" alt=\"\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f: pymesh_example_05_3.gif\" title=\"\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f: pymesh_example_05_3.gif\" width=\"800\" height=\"800\" data-src=\"https:\/\/habrastorage.org\/webt\/-c\/hr\/zq\/-chrzqyavbe-xepwt6vtwdth0u8.gif\"\/><figcaption>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f: pymesh_example_05_3.gif<\/figcaption><\/figure>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"pytorch3d_overview\" id=\"pytorch3d_overview\"><\/a><\/p>\n<h2>PyTorch3d: \u041e\u0431\u0437\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p><a href=\"https:\/\/pytorch3d.org\" rel=\"noopener noreferrer nofollow\"><u>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/a><\/p>\n<p><a href=\"https:\/\/pytorch3d.org\/docs\/why_pytorch3d.html\" rel=\"noopener noreferrer nofollow\"><u>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/u><\/a><\/p>\n<p><a href=\"https:\/\/github.com\/facebookresearch\/pytorch3d\/blob\/master\/INSTALL.md\" rel=\"noopener noreferrer nofollow\"><u>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/u><\/a><\/p>\n<p><a href=\"https:\/\/github.com\/facebookresearch\/pytorch3d\" rel=\"noopener noreferrer nofollow\"><u>Github<\/u><\/a><\/p>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b. \u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pytorch3d_examples\/pytorch3d_example_01.py\" rel=\"noopener noreferrer nofollow\"><u>pytorch3d_example_01.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import torch from pytorch3d.io import save_obj from scipy import spatial import numpy as np  if torch.cuda.is_available():     device = torch.device(\"cuda:0\")     torch.cuda.set_device(device) else:     device = torch.device(\"cpu\")  with_grad = False  verts = torch.tensor(     [         [-3, -3, 0],         [+3, -3, 0],         [+3, +3, 0],         [-3, +3, 0],         [+0, +0, +3]     ],     device=device,     dtype=torch.float32,     requires_grad=with_grad, )  hull = spatial.ConvexHull(verts.cpu().numpy()) faces_data = hull.simplices  faces = torch.tensor(     faces_data,     device=device,     dtype=torch.int64, )  save_obj('pytorch3d_example_01.obj', verts, faces)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u0445\u043e\u0434 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0432 numpy-stl. \u041d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043d\u0430 GPU, \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u0445\u043e\u0441\u0442\u0430 \u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. \u0425\u043e\u0441\u0442 &#8212; \u043d\u0430\u0448 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440. \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e &#8212; GPU \u043a\u0430\u0440\u0442\u0430. \u0415\u0441\u043b\u0438 \u043a\u0430\u0440\u0442\u044b \u043d\u0435\u0442, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e, \u0442\u043e\u0433\u0434\u0430 \u0432 \u0440\u043e\u043b\u0438 GPU \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c CPU. \u0423 \u0445\u043e\u0441\u0442\u0430 \u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0441\u0432\u043e\u044f \u043f\u0430\u043c\u044f\u0442\u044c. \u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0445\u043e\u0441\u0442\u0430 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0438\u0442\u0443\u0430\u043b.\u00a0<\/p>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0438\u0436\u0435, \u0441\u0440\u0430\u0437\u0443 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0438\u0445 \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u0445\u043e\u0441\u0442. \u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0433\u0440\u0430\u043d\u0438. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442. \u0424\u0430\u0439\u043b \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 obj \u043c\u043e\u0436\u043d\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 blender:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fr\/c1\/p_\/frc1p_hvt-fft5df-h-vthny36a.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_01.obj\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_01.obj\" width=\"739\" height=\"770\" data-src=\"https:\/\/habrastorage.org\/webt\/fr\/c1\/p_\/frc1p_hvt-fft5df-h-vthny36a.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_01.obj<\/figcaption><\/figure>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 verts.cpu().numpy()<\/p>\n<p>\u0412\u0435\u0440\u0448\u0438\u043d\u044b \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u0445\u043e\u0441\u0442. \u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435 \u0441 GPU, \u043a\u0430\u0436\u0434\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430. \u0412 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0445\u043e\u0441\u0442\u043e\u043c \u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c, \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043b\u0443\u0447\u0448\u0435 \u0441\u0432\u0435\u0441\u0442\u0438 \u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0438\u043c\u0435\u044f \u043d\u0430 \u0445\u043e\u0441\u0442\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0435\u0440\u0448\u0438\u043d, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u0438, \u043d\u0435 \u043f\u0440\u0438\u0431\u0435\u0433\u0430\u044f \u043a \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0432\u0435\u0440\u0448\u0438\u043d \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u0445\u043e\u0441\u0442, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pytorch3d_examples\/pytorch3d_example_02.py\" rel=\"noopener noreferrer nofollow\"><u>pytorch3d_example_02.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import torch from pytorch3d.io import IO from pytorch3d.structures.meshes import Meshes from pytorch3d.structures import join_meshes_as_scene from pytorch3d.transforms import RotateAxisAngle from pytorch3d.transforms import Translate from scipy import spatial import numpy as np  if torch.cuda.is_available():    device = torch.device(\"cuda:0\")    torch.cuda.set_device(device) else:    device = torch.device(\"cpu\")  with_grad = False  host_verts = [        [-3, -3, 0],        [+3, -3, 0],        [+3, +3, 0],        [-3, +3, 0],        [+0, +0, +3]    ]  verts = torch.tensor(    host_verts,    device=device,    dtype=torch.float32,    requires_grad=with_grad, )  hull = spatial.ConvexHull(host_verts) faces = torch.tensor(    hull.simplices,    device=device,    dtype=torch.int64, )  mesh_a = Meshes(verts=[verts], faces=[faces])  rot = RotateAxisAngle(180,'X', device=device) verts_b = rot.transform_points(mesh_a.verts_list()[0])  trans = Translate(0,0,5, device=device) verts_b = trans.transform_points(verts_b)  mesh_b = Meshes(verts=[verts_b], faces=[faces])  mesh = join_meshes_as_scene([mesh_a, mesh_b]) IO().save_mesh(mesh, 'pytorch3d_example_02.obj')<\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/y1\/of\/ec\/y1ofec-d-h34f9uvm6h73haypw0.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_02.obj\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_02.obj\" width=\"749\" height=\"669\" data-src=\"https:\/\/habrastorage.org\/webt\/y1\/of\/ec\/y1ofec-d-h34f9uvm6h73haypw0.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_02.obj<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"pytorch3d_menger_sponge\" id=\"pytorch3d_menger_sponge\"><\/a><\/p>\n<h3>PyTorch3d: \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 GPU \u0434\u0430\u0451\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0440\u043e\u0441\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pytorch3d_examples\/pytorch3d_example_03.py\" rel=\"noopener noreferrer nofollow\"><u>pytorch3d_example_03.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import torch from pytorch3d.io import IO from pytorch3d.structures.meshes import Meshes from pytorch3d.structures import join_meshes_as_scene from pytorch3d.transforms import Translate from scipy import spatial import numpy as np import sys import datetime  batch_size = 10  time_start = datetime.datetime.now()  def log(message):    print(datetime.datetime.now().strftime('%Y.%m.%d %H:%M:%S'), message)  if torch.cuda.is_available():    device = torch.device(\"cuda:0\")    torch.cuda.set_device(device) else:    device = torch.device(\"cpu\")  depth = 3 side = 1\/(3**depth) with_grad = False  # vertices vertices_base = [        [0,     0,      0],        [side,  0,      0],        [side,  side,   0],        [0,     side,   0],        [0,     0,      side],        [side,  0,      side],        [side,  side,   side],        [0,     side,   side]    ] vertices = torch.tensor(    vertices_base,    device=device,    dtype=torch.float32,    requires_grad=with_grad, )  # faces #hull = spatial.ConvexHull(vertices_base) faces_data = [     [3, 2, 1],     [3, 1, 0],     [0, 1, 5],#     [5, 4, 0],     [7, 3, 0],     [0, 4, 7],#     [1, 2, 6],#     [6, 5, 1],     [2, 3, 6],#     [3, 7, 6],#     [4, 5, 6],#     [6, 7, 4]  ] faces = torch.tensor(    faces_data,    device=device,    dtype=torch.int64, )  # holes holes = [] side = 1 round_factor = 14 for d in range(1, depth+1):    side \/= 3    for x in range(1,3**d,3):        for y in range(1,3**d,3):                       holes.append({                'x':[round(side*x,round_factor), round(side*x+side,round_factor)],                'y':[round(side*y,round_factor), round(side*y+side,round_factor)]                })  def voxel_in_hole(holes, x, y):    comp_error = 0    for hole in holes:        if  x + comp_error >= hole['x'][0] and x - comp_error &lt; hole['x'][1] and \\            y + comp_error >= hole['y'][0] and y - comp_error &lt; hole['y'][1]:            return True    return False  # voxels voxels = [] batch = 0 mesh = None for x in range(3**depth):    log('x '+ str(x)+' in '+str(3**depth))    for y in range(3**depth):        for z in range(3**depth):            if  voxel_in_hole(holes, round(y\/(3**depth),round_factor), round(z\/(3**depth),round_factor)) or \\                voxel_in_hole(holes, round(x\/(3**depth),round_factor), round(y\/(3**depth),round_factor)) or \\                voxel_in_hole(holes, round(x\/(3**depth),round_factor), round(z\/(3**depth),round_factor)):                continue            voxel_translate = Translate(x\/(3**depth), y\/(3**depth), z\/(3**depth), device=device)            voxel_vertices_translated = voxel_translate.transform_points(vertices)            voxels.append(Meshes(verts=[voxel_vertices_translated], faces=[faces]))    batch += 1    if batch > batch_size:        if not mesh is None:            log('append mesh')            voxels.append(mesh)        log('join')        mesh = join_meshes_as_scene(voxels)        voxels = []        batch = 0   log('join') if len(voxels):    if not mesh is None:        voxels.append(mesh)    mesh = join_meshes_as_scene(voxels) log('save') IO().save_mesh(mesh, 'pytorch3d_example_03.obj') log('end')  time_end = datetime.datetime.now() print('spent', (time_end - time_start).seconds, 'seconds')<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0432\u043e\u043a\u0441\u0435\u043b\u044f. \u041f\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u043e\u043c\u0443 \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439 \u0432 \u0434\u0432\u0443\u0445 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u0445. \u0417\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u0443\u0431 \u0432\u043e\u043a\u0441\u0435\u043b\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439.<\/p>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/6u\/62\/yb\/6u62yb4tpzst1wd1ofvttvhzjxa.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_03.obj\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_03.obj\" width=\"752\" height=\"714\" data-src=\"https:\/\/habrastorage.org\/webt\/6u\/62\/yb\/6u62yb4tpzst1wd1ofvttvhzjxa.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: pytorch3d_example_03.obj<\/figcaption><\/figure>\n<p>C\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u0430\u0441\u044c \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0437\u0430 5 \u0447\u0430\u0441\u043e\u0432 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0444\u0440\u0430\u043a\u0442\u0430\u043b 5 \u0443\u0440\u043e\u0432\u043d\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/yw\/oy\/41\/ywoy41nayiuh2pd1p5ujnhd_guq.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender Menger Sponge 5 lvl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender Menger Sponge 5 lvl\" width=\"751\" height=\"680\" data-src=\"https:\/\/habrastorage.org\/webt\/yw\/oy\/41\/ywoy41nayiuh2pd1p5ujnhd_guq.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender Menger Sponge 5 lvl<\/figcaption><\/figure>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 stl \u0444\u0430\u0439\u043b\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b 1.9 \u0413\u0411. \u041f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 5-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u043b\u0430\u0441\u044c \u0438\u0437-\u0437\u0430 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u044b. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438. \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e 10 \u0441\u043b\u043e\u0435\u0432 \u201c\u0434\u0432\u0443\u043c\u0435\u0440\u043d\u044b\u0445\u201d \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u043e\u0432, \u0437\u0430\u0442\u0435\u043c \u043e\u043d\u0438 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u043b\u0438\u0441\u044c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443, \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u0444\u0440\u0430\u043a\u0442\u0430\u043b.<\/p>\n<p><a class=\"anchor\" name=\"pytorch3d_rendering\" id=\"pytorch3d_rendering\"><\/a><\/p>\n<h3>PyTorch3d: \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e plotly \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439, pytorch3d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u0442 <a href=\"https:\/\/pytorch3d.org\/docs\/renderer\" rel=\"noopener noreferrer nofollow\"><u>\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433<\/u><\/a> \u0438 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435\u043c\u0443 \u0442\u0443\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439, \u0441 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430\u043c\u0438 \u0438 \u0448\u0435\u0439\u0434\u0435\u0440\u0430\u043c\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/pytorch3d_examples\/pytorch3d_example_04.py\" rel=\"noopener noreferrer nofollow\"><u>pytorch3d_example_04.py<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import torch from pytorch3d.structures.meshes import Meshes from pytorch3d.io import IO, load_obj from pytorch3d.renderer import (     FoVPerspectiveCameras, look_at_view_transform,     RasterizationSettings, BlendParams,     MeshRenderer, MeshRasterizer, HardPhongShader, TexturesVertex ) import matplotlib.pyplot as plt import imageio import os  gif_half_size = 30  if torch.cuda.is_available():    device = torch.device(\"cuda:0\")    torch.cuda.set_device(device) else:    device = torch.device(\"cpu\")  # Load object verts, faces, aux = load_obj('pytorch3d_example_03.obj')  # init texture verts_list = [] faces_list = [] texts_list = []  verts = torch.as_tensor(verts, dtype=torch.float32, device=device) faces = torch.as_tensor(faces.verts_idx, dtype=torch.float32, device=device) texts = torch.rand((len(verts), 3), dtype=torch.float32, device=device) verts_list.append(verts) faces_list.append(faces) texts_list.append(texts)  # create textures tex = TexturesVertex(texts_list)  # Initialise the mesh with textures mesh = Meshes(verts=[verts], faces=[faces], textures=tex)[0]  filenames = [] imageio_images = []  # rendering for i in range(gif_half_size):      filename = 'pytorch3d_example_'+str(i)+'.png'     print(filename)     filenames.append(filename)      # Select the viewpoint using spherical angles       distance = 3.5   # distance from camera to the object     elevation = 0.0 + i   # angle of elevation in degrees     azimuth = 0.0 + i  # No rotation so the camera is positioned on the +Z axis.      # Get the position of the camera based on the spherical angles     R, T = look_at_view_transform(distance, elevation, azimuth, device=device)      # Initialize an OpenGL perspective camera.     cameras = FoVPerspectiveCameras(device=device, R=R, T=T)      # Define the settings for rasterization and shading. Here we set the output image to be of size     # 512x512. As we are rendering images for visualization purposes only we will set faces_per_pixel=1     # and blur_radius=0.0. Refer to rasterize_meshes.py for explanations of these parameters.     raster_settings = RasterizationSettings(         image_size=512,         blur_radius=0.0,         faces_per_pixel=1,     )      # Create a phong renderer by composing a rasterizer and a shader. Here we can use a predefined     # PhongShader, passing in the device on which to initialize the default parameters     renderer = MeshRenderer(         rasterizer=MeshRasterizer(cameras=cameras, raster_settings=raster_settings),         shader=HardPhongShader(device=device, cameras=cameras)     )      images = renderer(mesh)     plt.figure(figsize=(10, 10))     plt.imshow(images[0, ..., :3].cpu().numpy())     plt.savefig(filename)     plt.axis(\"off\")     imageio_images.append(imageio.imread(filename))       # reverse rendering i = gif_half_size-1 while i>0:     print(filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1  # save gif imageio.mimsave('pytorch3d_example_03.gif', imageio_images)  # remove images for filename in filenames:     os.remove(filename)<\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/sp\/uy\/n_\/spuyn_vtca3jk0jorz29hzr-dpq.png\" alt=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" title=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" width=\"636\" height=\"631\" data-src=\"https:\/\/habrastorage.org\/webt\/sp\/uy\/n_\/spuyn_vtca3jk0jorz29hzr-dpq.png\"\/><figcaption>\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/lu\/hb\/rn\/luhbrnspu0ep1saufkpl7servzw.gif\" width=\"1000\" height=\"1000\" data-src=\"https:\/\/habrastorage.org\/webt\/lu\/hb\/rn\/luhbrnspu0ep1saufkpl7servzw.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"solidpython_overview\" id=\"solidpython_overview\"><\/a><\/p>\n<h2>SolidPython: \u041e\u0431\u0437\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p><a href=\"https:\/\/solidpython.readthedocs.io\/en\/latest\/\" rel=\"noopener noreferrer nofollow\"><u>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f SolidPython<\/u><\/a><\/p>\n<p><a href=\"https:\/\/github.com\/SolidCode\/SolidPython\" rel=\"noopener noreferrer nofollow\"><u>Github<\/u><\/a><\/p>\n<p><a href=\"https:\/\/openscad.org\/cheatsheet\/\" rel=\"noopener noreferrer nofollow\"><u>Openscad cheatsheet<\/u><\/a><\/p>\n<p><a href=\"https:\/\/en.wikibooks.org\/wiki\/OpenSCAD_User_Manual\" rel=\"noopener noreferrer nofollow\"><u>Wiki<\/u><\/a><\/p>\n<p>SolidPython \u0421\u0430\u043c\u0430\u044f \u0431\u043e\u0433\u0430\u0442\u0430\u044f \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0441\u0440\u0435\u0434\u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445. 3D \u0441\u0446\u0435\u043d\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 python, \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0435\u043c \u043d\u0430 openscad, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f openscad \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 scad \u0444\u0430\u0439\u043b \u0438 \u0434\u0430\u043b\u0435\u0435 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 openscad \u0438\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 stl.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/solidpython_examples\/solidpython_example_01.ipynb\" rel=\"noopener noreferrer nofollow\"><u>solidpython_example_01.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">from solid import *  d = difference()(     cube(size = 10, center = True),     sphere(r = 6.5, segments=300) ) path = scad_render_to_file(d, 'solidpython_example_01.scad')<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0441\u0444\u0435\u0440\u044b, \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0433\u043e \u0434\u043b\u044f openscad \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 $fn, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043b\u043e\u0432\u043e segments.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ln\/il\/hf\/lnilhfl--6f5ib_df8mm0sxw0ie.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_01.scad\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_01.scad\" width=\"698\" height=\"715\" data-src=\"https:\/\/habrastorage.org\/webt\/ln\/il\/hf\/lnilhfl--6f5ib_df8mm0sxw0ie.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_01.scad<\/figcaption><\/figure>\n<p>solidpython \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c. \u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442 scad \u0444\u0430\u0439\u043b, \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 jupyter notebook. \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 <em>scad_render_to_file \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0432 openscad \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f.<\/em><\/p>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u0435\u043d stl, openscad \u0443\u043c\u0435\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u044d\u0442\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/en.wikibooks.org\/wiki\/OpenSCAD_User_Manual\/Using_OpenSCAD_in_a_command_line_environment\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/u><\/a> \u043a\u043e\u043d\u0441\u043e\u043b\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u0437 jupyter notebook:<\/p>\n<pre><code class=\"python\">!openscad solidpython_example_01.scad -o solidpython_example_01.stl<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/nb\/26\/zu\/nb26zulkx-swb3rvsk-tv6qkx7g.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: solidpython_example_01.stl\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: solidpython_example_01.stl\" width=\"752\" height=\"610\" data-src=\"https:\/\/habrastorage.org\/webt\/nb\/26\/zu\/nb26zulkx-swb3rvsk-tv6qkx7g.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: solidpython_example_01.stl<\/figcaption><\/figure>\n<p>\u041e\u0431\u0449\u0438\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0442\u0430\u043a\u043e\u0439: \u041b\u044e\u0431\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442. \u0415\u0441\u043b\u0438 \u043d\u0430\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043e\u0431\u044a\u0435\u043a\u0442 (\u0438\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432) \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0440\u0443\u0433\u043b\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/solidpython_examples\/solidpython_example_02.ipynb\" rel=\"noopener noreferrer nofollow\"><u>solidpython_example_02.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">from solid import *  c = circle(r = 1) t = translate([2, 0, 0]) (c) e = linear_extrude(height = 10, center = True, convexity = 10, twist = -500, slices = 500) (t) col = color('lightgreen') (e) path = scad_render_to_file(col, 'solidpython_example_02.scad')<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c slices.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/tj\/bj\/ak\/tjbjakjrhqsg8f7jahx2-i7xnw8.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_02.scad\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_02.scad\" width=\"557\" height=\"659\" data-src=\"https:\/\/habrastorage.org\/webt\/tj\/bj\/ak\/tjbjakjrhqsg8f7jahx2-i7xnw8.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_02.scad<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"solidpython_menger_sponge\" id=\"solidpython_menger_sponge\"><\/a><\/p>\n<h3>SolidPython: \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/h3>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/solidpython_examples\/solidpython_example_03.ipynb\" rel=\"noopener noreferrer nofollow\"><u>solidpython_example_03.ipynb<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from solid import * from IPython.display import Image import datetime  depth = 3 sponge = cube([1,1,1], center = True) z = 1.1 side = 1 for d in range(1, depth+1):     side \/= 3     for x in range(1,3**d,3):         for y in range(1,3**d,3):             box_a = cube([side,side,z], center = True)             box_a = translate([side*x-0.5+side\/2, side*y-0.5+side\/2, 0]) (box_a)                         box_b = rotate([90,0,0]) (box_a)             box_c = rotate([0,90,0]) (box_a)             sponge -= box_a             sponge -= box_b             sponge -= box_c path = scad_render_to_file(sponge, 'solidpython_example_03.scad')  # export to stl !openscad solidpython_example_03.scad -o solidpython_example_03.stl  time_end = datetime.datetime.now() print('spent', (time_end - time_start).seconds, 'seconds')<\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/p3\/dg\/l6\/p3dgl62d4xqpm82akshpusnbymo.png\" alt=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_03.scad\" title=\"\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_03.scad\" width=\"719\" height=\"718\" data-src=\"https:\/\/habrastorage.org\/webt\/p3\/dg\/l6\/p3dgl62d4xqpm82akshpusnbymo.png\"\/><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Openscad: solidpython_example_03.scad<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"solidpython_rendering\" id=\"solidpython_rendering\"><\/a><\/p>\n<h3>SolidPython: \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0421\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0440\u0438\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0446\u0435\u043d\u044b, \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044f \u043a\u0430\u043c\u0435\u0440\u0443 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/solidpython_examples\/solidpython_example_04.ipynb\" rel=\"noopener noreferrer nofollow\"><u>solidpython_example_04.ipynb<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from solid import * import subprocess import datetime import imageio import os  gif_half_size = 30 filenames = [] imageio_images = [] for i in range(gif_half_size):     filename = 'solidpython_example_03_'+str(i)+'.png'     filenames.append(filename)     # export to png with camera params     # camera parameters when exporting png:      # =translate_x,y,z,rot_x,y,z,dist or      # =eye_x,y,z,center_x,y,z     rot_x = str(i-20)     rot_y = str(i-20)     rot_z = str(i-20)     dist = str(5+i\/10)     cmd = \"openscad solidpython_example_03.scad --camera '0,0,0,\"+\\         rot_x+\",\"+rot_y+\",\"+rot_z+\",\"+dist+\"' -o \"+filename     MyOut = subprocess.Popen(         cmd,          shell=True,          stdout=subprocess.PIPE,          stderr=subprocess.PIPE,          stdin=subprocess.PIPE     )     stdout,stderr = MyOut.communicate()     imageio_images.append(imageio.imread(filename))     print(datetime.datetime.now(), filename)         print('stdout', stdout)     print('stderr', stderr)      print('reverse rendering..') i = gif_half_size-1 while i>0:     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1      # save gif imageio.mimsave('solidpython_example_03.gif', imageio_images)      # remove images for filename in filenames:     os.remove(filename)      print('job complete!')<\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/gi\/c-\/4v\/gic-4voe2nhe4zudn2kzqbvnayk.png\" alt=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" title=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438\" width=\"505\" height=\"504\" data-src=\"https:\/\/habrastorage.org\/webt\/gi\/c-\/4v\/gic-4voe2nhe4zudn2kzqbvnayk.png\"\/><figcaption>\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/m9\/f3\/oj\/m9f3ojaysevcjpqoohud7drifzs.gif\" width=\"512\" height=\"512\" data-src=\"https:\/\/habrastorage.org\/webt\/m9\/f3\/oj\/m9f3ojaysevcjpqoohud7drifzs.gif\"\/><figcaption><\/figcaption><\/figure>\n<\/div>\n<\/details>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, solidpython \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 openscad. \u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u0435\u0441\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 <a href=\"https:\/\/solidpython.readthedocs.io\/en\/latest\/#animation\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0437\u0434\u0435\u043b<\/a> \u0441 <a href=\"https:\/\/github.com\/SolidCode\/SolidPython\/blob\/master\/solid\/examples\/animation_example.py\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c<\/a>.<\/p>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u044b \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/solidpython_examples\/solidpython_example_05.ipynb\" rel=\"noopener noreferrer nofollow\">solidpython_example_05.ipynb<\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import solid as scad import subprocess import os  # sponge depth = 3 sponge = scad.cube([1,1,1], center = True) z = 1.1 side = 1 for d in range(1, depth+1):     side \/= 3     for x in range(1,3**d,3):         for y in range(1,3**d,3):             box_a = scad.cube([side,side,z], center = True)             box_a = scad.translate([side*x-0.5+side\/2, side*y-0.5+side\/2, 0]) (box_a)                         box_b = scad.rotate([90,0,0]) (box_a)             box_c = scad.rotate([0,90,0]) (box_a)             sponge -= box_a             sponge -= box_b             sponge -= box_c  sponge = scad.translate([3.3, 0.5, 0.5]) (sponge)  # text text = scad.text('Pyth   n 3d', size = 1) text_gray = scad.linear_extrude(height = 0.9) (text) text_gray = scad.color('gray', 0.5) (text_gray)  text_white = scad.linear_extrude(height = 0.1) (text) text_white = scad.color('white', 0.8) (text_white) text_white = scad.translate([0, 0, 0.9]) (text_white)  text_blue = scad.linear_extrude(height = 0.1) (text) text_blue = scad.color('blue', 0.2) (text_blue) text_blue = scad.translate([0, 0, 0.9]) (text_blue)  # merge objects = text_gray + text_white + text_blue for i in range(0,10):     sponge_entity = scad.color('magenta', 0.5\/(i**2+1)) (sponge)     sponge_entity = sponge_entity + scad.color('blue', 0.5\/(i**2+1)) (sponge)     objects += scad.translate([0, 0, i*2]) (sponge_entity)     if i>0:         objects += scad.translate([0, 0, -i*2]) (sponge_entity)         objects += scad.translate([0, i*2, 0]) (sponge_entity)         objects += scad.translate([0, -i*2, 0]) (sponge_entity)          # render filename = 'solidpython_example_05' render = scad.scad_render_to_file(objects, filename+'.scad') # camera parameters when exporting png:  #                                 =translate_x,y,z,rot_x,y,z,dist or  #                                 =eye_x,y,z,center_x,y,z  #  =colorscheme: *Cornfield | Metallic | Sunset |  #                                 Starnight | BeforeDawn | Nature | DeepOcean |  #                                 Solarized | Tomorrow | Tomorrow 2 | Tomorrow  #                                 Night | Monotone cmd = \"openscad \"+filename+\".scad --camera '3,2,2,20,5,-70,30' --imgsize=10000,3000 --colorscheme='Tomorrow' -o \"+filename+\".png\" MyOut = subprocess.Popen(     cmd,      shell=True,      stdout=subprocess.PIPE,      stderr=subprocess.PIPE,      stdin=subprocess.PIPE ) MyOut.stdout, MyOut.stderr<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/6g\/pe\/an\/6gpeans9u0ifehnafwu6kbdjtdi.png\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\" width=\"4500\" height=\"1332\" data-src=\"https:\/\/habrastorage.org\/webt\/6g\/pe\/an\/6gpeans9u0ifehnafwu6kbdjtdi.png\"\/><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/figcaption><\/figure>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"comparing\" id=\"comparing\"><\/a><\/p>\n<h3>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a<\/h3>\n<p>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u0445. \u0412 Pymesh \u0438 SolidPython \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0432 Numpy-stl \u0438 Pytorch3d \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 mesh.<\/p>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\">\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/p>\n<\/td>\n<td>\n<p>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/p>\n<p>(\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 3-\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443)<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0424\u043e\u0440\u043c\u0430\u0442\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0424\u043e\u0440\u043c\u0430\u0442\u044b \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u041e\u0442\u043b\u0438\u0447\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"center\">Numpy-stl<\/p>\n<\/td>\n<td>\n<p align=\"center\">24<\/p>\n<\/td>\n<td>\n<p align=\"center\">stl<\/p>\n<\/td>\n<td>\n<p align=\"center\">stl<\/p>\n<\/td>\n<td>\n<p align=\"center\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"center\">Pymesh<\/p>\n<\/td>\n<td>\n<p align=\"center\">823<\/p>\n<\/td>\n<td>\n<p align=\"center\">obj, off, ply, stl, mesh, msh, node, face, ele<\/p>\n<\/td>\n<td>\n<p align=\"center\">obj, off, ply, stl, mesh, msh, node, face, ele<\/p>\n<\/td>\n<td>\n<p align=\"center\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"center\">Pytorch3d<\/p>\n<\/td>\n<td>\n<p align=\"center\">12<\/p>\n<\/td>\n<td>\n<p align=\"center\">obj, ply, npz<\/p>\n<\/td>\n<td>\n<p align=\"center\">obj, ply<\/p>\n<\/td>\n<td>\n<p align=\"center\">GPU \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435, \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 <a href=\"https:\/\/pytorch3d.org\/tutorials\/render_colored_points\" rel=\"noopener noreferrer nofollow\"><u>\u043e\u0431\u043b\u0430\u043a\u0430 \u0442\u043e\u0447\u0435\u043a<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"center\">SolidPython<\/p>\n<\/td>\n<td>\n<p align=\"center\">347<\/p>\n<\/td>\n<td>\n<p align=\"center\">scad (\u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/en.wikibooks.org\/wiki\/OpenSCAD_User_Manual\/Using_OpenSCAD_in_a_command_line_environment\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043d\u0441\u043e\u043b\u044c<\/u><\/a>: stl, 3mf, off, amf, dxf, svg, csg)<\/p>\n<\/td>\n<td>\n<p align=\"center\">scad (\u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/en.wikibooks.org\/wiki\/OpenSCAD_User_Manual\/Using_OpenSCAD_in_a_command_line_environment\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043d\u0441\u043e\u043b\u044c<\/u><\/a>: stl, 3mf, off, amf, dxf, svg, csg, png, stl, off, echo, ast, term, nef3, nefdbg)<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0411\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u044b\u0431\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<details class=\"spoiler\">\n<summary>\u0425\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>Ubuntu 20.04.2 LTS<\/p>\n<\/li>\n<li>\n<p>Python 3.7.3<\/p>\n<\/li>\n<li>\n<p>Intel(R) Core(TM) i3-7350K CPU @ 4.20GHz<\/p>\n<\/li>\n<li>\n<p>RAM 35.2Gb<\/p>\n<\/li>\n<li>\n<p>GPU GeForce GTX 1080 Ti 11175 MB<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/itmai\/blog\/503358\/\" rel=\"noopener noreferrer nofollow\"><u>3D ML. \u0427\u0430\u0441\u0442\u044c 1: \u0444\u043e\u0440\u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f 3D-\u0434\u0430\u043d\u043d\u044b\u0445<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/itmai\/blog\/504416\/\" rel=\"noopener noreferrer nofollow\"><u>3D ML. \u0427\u0430\u0441\u0442\u044c 2: \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0442\u0435\u0440\u044c \u0432 \u0437\u0430\u0434\u0430\u0447\u0430\u0445 3D ML<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/itmai\/blog\/516404\/\" rel=\"noopener noreferrer nofollow\"><u>3D ML. \u0427\u0430\u0441\u0442\u044c 3: \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u044b \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0432 3D ML<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/itmai\/blog\/520268\/\" rel=\"noopener noreferrer nofollow\"><u>3D ML. \u0427\u0430\u0441\u0442\u044c 4: \u0434\u0438\u0444\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/itmai\/blog\/533746\/\" rel=\"noopener noreferrer nofollow\"><u>3D ML. \u0427\u0430\u0441\u0442\u044c 5: \u0421\u0432\u0435\u0440\u0442\u043a\u0438 \u043d\u0430 \u0433\u0440\u0430\u0444\u0430\u0445<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/itmai\/blog\/534036\/\" rel=\"noopener noreferrer nofollow\"><u>3D ML. \u0427\u0430\u0441\u0442\u044c 6: \u041e\u0431\u0437\u043e\u0440 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043e\u0431\u043b\u0430\u043a\u0430 \u0442\u043e\u0447\u0435\u043a<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/medium.com\/applied-data-science\/pytorch3d-robolove-2138d84a425e\" rel=\"noopener noreferrer nofollow\"><u>PyTorch3D : RoboLove<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/trimsh.org\" rel=\"noopener noreferrer nofollow\"><u>trimesh &#8212; \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/552948\/\" rel=\"noopener noreferrer nofollow\"><u>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 3D \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0432 Python \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 OpenMesh<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/hmeyer\/openscadpy\" rel=\"noopener noreferrer nofollow\"><u>openscadpy &#8212; \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/443140\/\" rel=\"noopener noreferrer nofollow\"><u>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u0433\u043e 3\u0434 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f ZenCad<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/mirmik.github.io\/zencad\/ru\/index.html\" rel=\"noopener noreferrer nofollow\"><u>zenscad &#8212; \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/analyticsindiamag.com\/hands-on-guide-to-pytorch3d-a-library-for-deep-learning-with-3d-data\/\" rel=\"noopener noreferrer nofollow\"><u>Hands-on Guide to PyTorch 3D \u2013 A Library for Deep Learning with 3D Data<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.unrealengine.com\/4.26\/en-US\/ProductionPipelines\/ScriptingAndAutomation\/Python\/\" rel=\"noopener noreferrer nofollow\"><u>Scripting the Unreal Editor using Python<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/developer.nvidia.com\/nvidia-kaolin\" rel=\"noopener noreferrer nofollow\"><u>Nvidia kaolin<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/analyticsindiamag.com\/nvidias-kaolin-3d-deep-learning-library\/\" rel=\"noopener noreferrer nofollow\"><u>Guide To NVIDIA\u2019s Kaolin: A 3D Deep Learning Library<\/u><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/matplotlib.org\/stable\/tutorials\/toolkits\/mplot3d.html\" rel=\"noopener noreferrer nofollow\"><u>3D \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 matplotlib<\/u><\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/572760\/\"> https:\/\/habr.com\/ru\/articles\/572760\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0432\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f python, \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u0438\u043b\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u043f\u0435\u0447\u0430\u0442\u0438 \u043d\u0430 3D \u043f\u0440\u0438\u043d\u0442\u0435\u0440\u0435. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0449\u0438\u0445 \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u044d\u0442\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0442\u043e\u0447\u0435\u043a, \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u0432 python. \u041a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0435 \u043f\u0440\u0438\u0435\u043c\u044b 3D \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u0432\u043e\u0440\u043e\u0442, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>numpy-stl<\/p>\n<\/li>\n<li>\n<p>pymesh<\/p>\n<\/li>\n<li>\n<p>pytorch3d<\/p>\n<\/li>\n<li>\n<p>SolidPython<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b &#8212;<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%93%D1%83%D0%B1%D0%BA%D0%B0_%D0%9C%D0%B5%D0%BD%D0%B3%D0%B5%D1%80%D0%B0\" rel=\"noopener noreferrer nofollow\"> <u>\u0413\u0443\u0431\u043a\u0443 \u041c\u0435\u043d\u0433\u0435\u0440\u0430<\/u><\/a> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Menger_sponge\" rel=\"noopener noreferrer nofollow\"><u>Menger sponge<\/u><\/a>), \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0432 stl \u0444\u0430\u0439\u043b \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u043f\u0443\u0442\u043d\u043e, \u043a\u0440\u0430\u0442\u043a\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043c\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<a href=\"https:\/\/github.com\/format37\/python3d\" rel=\"noopener noreferrer nofollow\"> <u>\u043d\u0430 GitHub<\/u><\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0441\u0440\u0435\u0434\u044b<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.docker.com\/engine\/install\/\" rel=\"noopener noreferrer nofollow\"><u>Docker<\/u><\/a> \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 Pymesh:<\/p>\n<\/li>\n<\/ul>\n<p><code>curl -fsSL https:\/\/get.docker.com -o get-docker.sh<\/code><\/p>\n<p><code>sudo sh get-docker.sh<\/code><\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 g++ \u0434\u043b\u044f PyTorch3d:<\/p>\n<\/li>\n<\/ul>\n<p><code>sudo apt update<\/code><\/p>\n<p><code>sudo apt install g++<\/code><\/p>\n<ul>\n<li>\n<p>\u041a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a:<\/p>\n<\/li>\n<\/ul>\n<p><code>git clone https:\/\/github.com\/format37\/python3d.git<\/code><\/p>\n<p><code>cd python3d<\/code><\/p>\n<p><code>pip install -r requirements.txt<\/code><\/p>\n<p><code>pip install \"git+https:\/\/github.com\/facebookresearch\/pytorch3d.git\"<\/code><\/p>\n<ul>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 OpenScad:<\/p>\n<\/li>\n<\/ul>\n<p><code>sudo apt-get install openscad<\/code><\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"numpy_overview\" id=\"numpy_overview\"><\/a><\/p>\n<h2>Numpy-stl: \u041e\u0431\u0437\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p><a href=\"https:\/\/pypi.python.org\/pypi\/numpy-stl\" rel=\"noopener noreferrer nofollow\"><u>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/a><\/p>\n<p><a href=\"https:\/\/numpy-stl.readthedocs.io\" rel=\"noopener noreferrer nofollow\"><u>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/u><\/a><\/p>\n<p><a href=\"https:\/\/github.com\/WoLpH\/numpy-stl\" rel=\"noopener noreferrer nofollow\"><u>Github<\/u><\/a><\/p>\n<p>\u0421\u0442\u0440\u043e\u0435\u043d\u0438\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B0\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438<\/u><\/a>:<\/p>\n<figure class=\"full-width\"><figcaption>\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/figcaption><\/figure>\n<p><strong>Vertices (\u0432\u0435\u0440\u0448\u0438\u043d\u044b)<\/strong> &#8212; \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u0447\u0435\u043a. \u041a\u0430\u0436\u0434\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0442\u0440\u0435\u043c\u044f \u0447\u0438\u0441\u043b\u0430\u043c\u0438 &#8212; \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0432 3-\u0445 \u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 Jupyter notebook<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/thecode.media\/jupyter\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 jupyter-\u043d\u043e\u0443\u0442\u0431\u0443\u043a \u0438 \u0437\u0430\u0447\u0435\u043c \u043e\u043d \u043d\u0443\u0436\u0435\u043d<\/a><\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_01.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_01.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">import numpy as np from myplot import plot_verticles  vertices = np.array(     [         [-3, -3, 0],         [+3, -3, 0],         [+3, +3, 0],         [-3, +3, 0],         [+0, +0, +3]     ] )  plot_verticles(vertices = vertices, isosurf = False)<\/code><\/pre>\n<figure class=\"\"><figcaption>\u0412\u0435\u0440\u0448\u0438\u043d\u044b \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b<\/figcaption><\/figure>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043a\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c, \u0435\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430\u043c\u0438:<\/p>\n<pre><code class=\"python\">plot_verticles(vertices = vertices, isosurf = True)<\/code><\/pre>\n<figure class=\"\"><figcaption>\u0418\u0437\u043e\u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b<\/figcaption><\/figure>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0431\u0443\u0434\u0442\u043e \u0433\u0440\u0430\u043d\u0438 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442. \u041d\u043e \u043f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b. \u0427\u0442\u043e\u0431\u044b \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c stl \u0444\u0430\u0439\u043b, \u043e\u043f\u0438\u0448\u0435\u043c \u0433\u0440\u0430\u043d\u0438, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0440\u0430\u0431\u043e\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/generated\/scipy.spatial.ConvexHull.html\" rel=\"noopener noreferrer nofollow\"><u>spatial.ConvexHull <\/u><\/a>\u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/\" rel=\"noopener noreferrer nofollow\"><u>scipy<\/u><\/a><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_02.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_02.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">import numpy as np from scipy import spatial from stl import mesh from myplot import plot_mesh  vertices = np.array(     [         [-3, -3, 0],         [+3, -3, 0],         [+3, +3, 0],         [-3, +3, 0],         [+0, +0, +3]     ] )  hull = spatial.ConvexHull(vertices) faces = hull.simplices<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435, \u043c\u0430\u0441\u0441\u0438\u0432 faces \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043d\u0435\u0439:<\/p>\n<pre><code class=\"python\">array([[4, 1, 0],        [4, 2, 1],        [3, 4, 0],        [3, 4, 2],        [3, 2, 1],        [3, 1, 0]], dtype=int32)<\/code><\/pre>\n<p><strong>faces<\/strong> <strong>(\u0433\u0440\u0430\u043d\u0438)<\/strong> &#8212; \u0441\u043f\u0438\u0441\u043e\u043a \u0433\u0440\u0430\u043d\u0435\u0439. \u041a\u0430\u0436\u0434\u0430\u044f \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0430\u043d\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0442\u0440\u0435\u043c\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438, \u0438\u043b\u0438 \u0442\u043e\u0447\u043a\u0430\u043c\u0438. \u0410 \u0442\u043e\u0447\u043d\u0435\u0435, \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u0442\u043e\u0447\u0435\u043a \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 vertices.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0433\u0440\u0430\u043d\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0447\u0438\u0441\u043b\u0430 3, 1, 0. \u0417\u043d\u0430\u0447\u0438\u0442 \u0433\u0440\u0430\u043d\u044c \u0441\u043e\u0431\u0440\u0430\u043d\u0430 \u0438\u0437 \u0442\u043e\u0447\u0435\u043a 0-\u0433\u043e, 1-\u0433\u043e \u0438 3-\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 vertices:<\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d<\/figcaption><\/figure>\n<p><strong>Mesh (\u0441\u0435\u0442\u043a\u0430) <\/strong>&#8212; \u041d\u0430\u0431\u043e\u0440 \u0432\u0435\u0440\u0448\u0438\u043d \u0438 \u0433\u0440\u0430\u043d\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u0444\u043e\u0440\u043c\u0443 \u043c\u043d\u043e\u0433\u043e\u0433\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<pre><code class=\"python\">myramid_mesh = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces):     for j in range(3):         myramid_mesh.vectors[i][j] = vertices[f[j],:] plot_mesh(myramid_mesh)<\/code><\/pre>\n<figure class=\"\"><figcaption>\u0413\u0440\u0430\u043d\u0438 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b<\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u0440\u0438\u0441\u0443\u043d\u043a\u0430, \u043e\u0434\u043d\u0430 \u0433\u0440\u0430\u043d\u044c \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u044b \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u0430. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445, \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u043e\u0432, \u043c\u0435\u0442\u043e\u0434 ConvexHull \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u0433\u0440\u0430\u043d\u0438 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0433\u0440\u0430\u043d\u0435\u0439.<\/p>\n<pre><code class=\"python\">myramid_mesh.save('numpy_stl_example_02.stl')<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 stl \u0444\u0430\u0439\u043b\u043e\u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u041e\u0434\u043d\u0430 \u0438\u0437 \u043d\u0438\u0445 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.blender.org\" rel=\"noopener noreferrer nofollow\"><u>Blender<\/u><\/a>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u043f\u043b\u0430\u0442\u044b \u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/p>\n<figure class=\"full-width\"><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_02.stl<\/figcaption><\/figure>\n<p>\u041c\u0435\u0442\u043e\u0434 spatial.ConvexHull \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u0443\u043a\u043b\u043e\u0439 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0438 \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438\u0434\u043e\u0439 \u0438 \u043a\u0443\u0431\u043e\u043c. \u041d\u043e \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445, \u0438\u043c\u0435\u044e\u0449\u0438\u0445 \u0432\u043f\u0430\u0434\u0438\u043d\u044b, \u0447\u0430\u0441\u0442\u044c \u0442\u043e\u0447\u0435\u043a \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u0430 \u0438 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 stl \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430 \u0438\u0437-\u0437\u0430 \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0433\u0440\u0430\u043d\u0435\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0442\u043e\u0447\u0435\u043a.<\/p>\n<p>\u042d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432 \u0434\u0432\u0443\u0445 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u0445: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_03.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_03.ipynb<\/u><\/a><\/p>\n<pre><code class=\"python\">import matplotlib.pyplot as plt from scipy import spatial import numpy as np   points = np.array([     [0,0],     [-2,0],     [-2,2],     [0,1.5],     [2,2],     [2,0] ])  hull = spatial.ConvexHull(points)<\/code><\/pre>\n<p>\u0412 hull.simplices \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043d\u0435\u0439:<\/p>\n<pre><code class=\"python\">array([[2, 1],        [2, 4],        [5, 1],        [5, 4]], dtype=int32)<\/code><\/pre>\n<p>\u041e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0438 \u0433\u0440\u0430\u043d\u0438 \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435:<\/p>\n<pre><code class=\"python\">plt.plot(points[:,0], points[:,1], 'o') for simplex in hull.simplices:     plt.plot(points[simplex, 0], points[simplex, 1], 'k-')<\/code><\/pre>\n<figure class=\"\"><figcaption>\u0426\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0433\u0440\u0430\u043d\u044f\u043c\u0438<\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443 ConvexHull, \u0438\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e:<\/p>\n<pre><code class=\"python\">faces = np.array([     [0, 1],     [1, 2],     [2, 3],     [3, 4],     [4, 5],     [5, 0] ])  plt.plot(points[:,0], points[:,1], 'o') for simplex in faces:     plt.plot(points[simplex, 0], points[simplex, 1], 'k-')<\/code><\/pre>\n<figure class=\"\"><figcaption>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u0432\u0435 \u0433\u0440\u0430\u043d\u0438: \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438, \u043e\u0434\u043d\u0430 \u0434\u043b\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0439<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"numpy_menger_sponge\" id=\"numpy_menger_sponge\"><\/a><\/p>\n<h3>Numpy-stl: \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/h3>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0444\u0440\u0430\u043a\u0442\u0430\u043b. \u0412 numpy-stl \u043d\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u043b\u0435\u0432\u0430 \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 Menger Sponge \u043f\u043e\u0439\u0434\u0435\u043c \u043e\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e. \u0412 \u043d\u0430\u0448\u0435\u043c \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u0438 \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u043e\u0433\u043e mesh \u043a\u0443\u0431\u0430. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e voxel.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 voxel \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 mesh.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0438\u0437 \u043a\u0443\u0431\u0438\u043a\u043e\u0432, \u043a\u0430\u043a \u0438\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043e\u0433\u043e\u0432\u043e\u0438\u043c\u0441\u044f \u0447\u0442\u043e \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0433\u0440\u0430\u043d\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 &#8212; \u0435\u0434\u0438\u043d\u0438\u0446\u0430. \u0413\u043b\u0443\u0431\u0438\u043d\u0430 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 \u044d\u0442\u043e, \u0433\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439. \u0414\u043b\u0438\u043d\u0430 \u0432\u043e\u043a\u0441\u0435\u043b\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430, \u043e\u043d\u0430 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 3 \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u043d\u043e\u0432\u044b\u043c \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u0433\u043b\u0443\u0431\u0438\u043d\u044b.<\/p>\n<p>\u041d\u0430\u0439\u0434\u0435\u043c \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0432\u043e\u043a\u0441\u0435\u043b\u044f \u043d\u0430 \u0433\u043b\u0443\u0431\u0438\u043d\u0430\u0445 1 \u0438 2.\u00a0\u0423\u043f\u0440\u043e\u0441\u0442\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u0441\u0432\u0435\u0440\u043d\u0443\u0432 \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0441 3-\u0445 \u0434\u043e 1-\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u0443\u0431\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442 1\/(3**2) \u0438\u043b\u0438 1\/9. \u0421\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430\u0431\u043e\u0440 \u043a\u0443\u0431\u043e\u0432 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u043e\u0438\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043e\u043d\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u0443\u0431. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%92%D0%BE%D0%BA%D1%81%D0%B5%D0%BB\" rel=\"noopener noreferrer nofollow\"><u>\u0432\u043e\u043a\u0441\u0435\u043b\u044c\u043d\u044b\u0439<\/u><\/a> \u043a\u0443\u0431. \u0412\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439. \u0418\u0441\u043a\u043b\u044e\u0447\u0438\u043c \u0432\u043e\u043a\u0441\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0440\u0441\u0442\u0438\u0439. \u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0432\u043e\u043a\u0441\u0435\u043b\u0438 \u0432 \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_04.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_04.ipynb<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from stl import mesh import numpy as np import datetime  time_start = datetime.datetime.now()   def create_voxel(side, tx, ty, tz):     vertices = np.array([        [tx + 0,     ty + 0,      tz + 0],        [tx + side,  ty + 0,      tz + 0],        [tx + side,  ty + side,   tz + 0],        [tx + 0,     ty + side,   tz + 0],        [tx + 0,     ty + 0,      tz + side],        [tx + side,  ty + 0,      tz + side],        [tx + side,  ty + side,   tz + side],        [tx + 0,     ty + side,   tz + side]     ])      faces = np.array([         [3, 2, 1],         [3, 1, 0],         [0, 1, 5],#         [5, 4, 0],         [7, 3, 0],         [0, 4, 7],#         [1, 2, 6],#         [6, 5, 1],         [2, 3, 6],#         [3, 7, 6],#         [4, 5, 6],#         [6, 7, 4]      ])     voxel = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))     for i, f in enumerate(faces):         for j in range(3):             voxel.vectors[i][j] = vertices[f[j],:]     return voxel       def voxel_in_hole(holes, x, y):     comp_error = 0     for hole in holes:         if  x + comp_error >= hole['x'][0] and x - comp_error &lt; hole['x'][1] and \\             y + comp_error >= hole['y'][0] and y - comp_error &lt; hole['y'][1]:             return True     return False       depth = 3 side = 1\/(3**depth)  # holes holes = [] side = 1 round_factor = 14 for d in range(1, depth+1):     side \/= 3     for x in range(1,3**d,3):         for y in range(1,3**d,3):                        holes.append({                 'x':[round(side*x,round_factor), round(side*x+side,round_factor)],                 'y':[round(side*y,round_factor), round(side*y+side,round_factor)]             })              sponge = None for x in range(3**depth):     for y in range(3**depth):         for z in range(3**depth):             rx = round(x\/(3**depth),round_factor)             ry = round(y\/(3**depth),round_factor)             rz = round(z\/(3**depth),round_factor)             if  voxel_in_hole(holes, ry, rz) or \\                 voxel_in_hole(holes, rx, ry) or \\                 voxel_in_hole(holes, rx, rz):                 continue             if sponge is None:                 sponge = create_voxel(side, x\/(3**depth), y\/(3**depth), z\/(3**depth))             else:                 new_voxel = create_voxel(side, x\/(3**depth), y\/(3**depth), z\/(3**depth))                 sponge = mesh.Mesh(np.concatenate([sponge.data, new_voxel.data]))                  sponge.save('numpy_stl_example_04.stl')   time_end = datetime.datetime.now() print('spent', (time_end - time_start).seconds, 'seconds') <\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><figcaption>\u0421\u043d\u0438\u043c\u043e\u043a \u044d\u043a\u0440\u0430\u043d\u0430. Blender: numpy_stl_example_04.stl<\/figcaption><\/figure>\n<p><a class=\"anchor\" name=\"numpy_rendering\" id=\"numpy_rendering\"><\/a><\/p>\n<h3>Numpy-stl: \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0414\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0432\u043e\u0434\u0430 <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/myplot.py\" rel=\"noopener noreferrer nofollow\"><em>plot_mesh<\/em><\/a>, \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c mesh, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 stl \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: <a href=\"https:\/\/github.com\/format37\/python3d\/blob\/main\/numpy_stl_examples\/numpy_stl_example_05.ipynb\" rel=\"noopener noreferrer nofollow\"><u>numpy_stl_example_05.ipynb<\/u><\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from myplot import plot_mesh from stl import mesh import datetime import imageio import math import os  sponge = mesh.Mesh.from_file('numpy_stl_example_04.stl')  gif_half_size = 14 filenames = [] imageio_images = [] for i in range(gif_half_size):     sponge.rotate([1, 0.0, 1], math.radians(1))     filename = 'solidpython_example_03_'+str(i)+'.png'     filenames.append(filename)     plot_mesh(sponge, filename = filename)     print(datetime.datetime.now(), filename)      print('forward rendering..') for i in range(gif_half_size):     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1      print('reverse rendering..') i = gif_half_size-1 while i>0:     print(datetime.datetime.now(), filenames[i])     imageio_images.append(imageio.imread(filenames[i]))     i-=1      # save gif imageio.mimsave('solidpython_example_03.gif', imageio_images)      # remove images for filename in filenames:     os.remove(filename)      print('job complete!')<\/code><\/pre>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><figcaption>\u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption>\u0410\u043d\u0438\u043c<\/figcaption><\/figure>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-399549","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/399549","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=399549"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/399549\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=399549"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=399549"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=399549"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}