Python для 3D моделирования: от простых фигур до сложных сцен
В данной статье рассматриваются различные способы создания трёхмерных моделей с использованием языка программирования Python. Для каждого подхода приведены примеры кода, пояснения и типичные ошибки.
Основные библиотеки и подходы к созданию 3D моделей на Python
Библиотека trimesh – универсальное решение для работы с мешами
Библиотека trimesh предоставляет широкие возможности для создания, загрузки, обработки и экспорта трёхмерных сеток (mesh). Она основана на numpy и поддерживает множество форматов: OBJ, STL, PLY, GLTF и другие. Это основной инструмент, если требуется программно генерировать геометрию.
Как создать простую 3D модель (куб и сфера) с помощью trimesh?
import trimesh
import numpy as np
# Создание единичного куба
cube = trimesh.creation.box(extents=[1, 1, 1])
# Создание сферы радиусом 0.5
sphere = trimesh.creation.icosphere(subdivisions=2, radius=0.5)
# Перемещение сферы на (1, 0, 0)
sphere.apply_translation([1, 0, 0])
# Объединение двух мешей
combined = trimesh.util.concatenate([cube, sphere])
# Экспорт в OBJ
combined.export('combined.obj')Python 3d модели (создание 3d моделей на python)
Пояснение: сначала импортируем trimesh и numpy. С помощью метода box создаём куб с заданными размерами. icosphere создаёт сферу с указанным числом подразделений (чем больше subdivisions, тем выше детализация). apply_translation перемещает сферу. concatenate объединяет два меша в один. export сохраняет результат.
Типичные проблемы:
- При экспорте в OBJ текстуры не сохраняются, если их не задавать.
- Большие модели могут потребовать много памяти и времени.
- Не все форматы экспорта поддерживают цвета вершин – следует обращаться к документации.
Как визуализировать математическую поверхность в 3D с помощью matplotlib?
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
x = np.linspace(-2, 2, 50)
y = np.linspace(-2, 2, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap='viridis')
plt.show()
Библиотека matplotlib с модулем mplot3d позволяет строить 3D поверхности, но не предназначена для создания экспортируемых моделей. Это скорее визуализация данных.
Полученную поверхность сложно экспортировать в формат меша без дополнительных усилий (например, через сохранение координат вершин).
Как быстро создать интерактивную сцену с помощью VPython?
from vpython import sphere, box, vector
sphere(pos=vector(0,0,0), radius=1, color=vector(1,0,0))
box(pos=vector(2,0,0), size=vector(1,1,1), color=vector(0,1,0))
VPython (vpython) предоставляет простые функции для создания 3D объектов в реальном времени. Подходит для обучения и демонстрации, но не для промышленного моделирования.
Нет поддержки экспорта в стандартные 3D форматы; объекты примитивные.
Как использовать полный функционал Blender из Python (bpy)?
import bpy
# Удалить всё по умолчанию
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# Создать куб
bpy.ops.mesh.primitive_cube_add(size=1, location=(0,0,0))
# Создать сферу
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.5, location=(1,0,0))
Blender Python API (bpy) – самый мощный способ, но требует установленного Blender и запуска скриптов внутри него. Позволяет создавать сложные модификаторы, анимацию, материалы.
Не работает как обычная библиотека Python; требуется использовать интерпретатор Blender.
Как сделать собственную 3D сцену с низкоуровневой графикой через Pyglet/OpenGL?
import pyglet
from pyglet.gl import *
window = pyglet.window.Window(width=800, height=600)
@window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glBegin(GL_TRIANGLES)
glVertex3f(0.0, 0.5, 0.0)
glVertex3f(-0.5, -0.5, 0.0)
glVertex3f(0.5, -0.5, 0.0)
glEnd()
pyglet.app.run()
Если требуется полный контроль над рендерингом, можно использовать OpenGL через pyglet. Однако такой подход требует глубоких знаний графических конвейеров и не предназначен для быстрого создания моделей.
Необходимо самостоятельно управлять вершинами, шейдерами, буферами. Высок порог входа.
Расширенные примеры создания 3D моделей
Пример 1: Генерация спиралевидного меша с помощью trimesh и numpy
Следующий пример создаёт сетку спирали из треугольников на основе математической кривой. Это демонстрирует, как формировать произвольную геометрию.
import trimesh
import numpy as np
def spiral_mesh(n_turns=3, n_points=500, radius=1.0, height=2.0):
theta = np.linspace(0, 2 * np.pi * n_turns, n_points)
r = np.linspace(0, radius, n_points)
z = np.linspace(0, height, n_points)
x = r * np.cos(theta)
y = r * np.sin(theta)
points = np.column_stack([x, y, z])
# Создаём секции (например, трубчатую поверхность)
# Для простоты используем ленту из треугольников
# Здесь опущено построение полной топологии – в реальном коде требуется задать треугольники
vertices = points
faces = np.array([[i, i+1, i+2] for i in range(len(points)-2)])
mesh = trimesh.Trimesh(vertices=vertices, faces=faces)
return mesh
mesh = spiral_mesh()
mesh.export('spiral.stl')
print('Спираль сохранена в spiral.stl')
Спираль сохранена в spiral.stl
Примечание: генерация правильной топологии для трубчатой поверхности сложнее – в примере используется упрощённая лента, которая может дать некорректную трёхмерную фигуру. Для более реалистичного результата необходимо строить сегменты с радиальными слоями.
Пример 2: Создание сложной модели с помощью Blender Python API и импорт SVG
Blender позволяет импортировать SVG-контуры и превращать их в 3D с помощью экструдирования. Этот скрипт загружает файл SVG, создаёт крышку и экспортирует результат.
import bpy
import os
# Удаляем объекты по умолчанию
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# Импорт SVG (предполагается, что файл 'logo.svg' лежит рядом)
svg_path = os.path.join(os.path.dirname(__file__), 'logo.svg')
bpy.ops.import_curve.svg(filepath=svg_path)
# Выбираем все импортированные кривые
bpy.ops.object.select_by_type(type='CURVE')
# Преобразуем кривые в меш
bpy.ops.object.convert(target='MESH')
# Выбираем новый меш
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
# Экструдируем по оси Z на 0.2
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value": (0, 0, 0.2)})
bpy.ops.object.editmode_toggle()
# Экспорт в OBJ
bpy.ops.export_scene.obj(filepath='logo.obj')
Объект экспортирован как logo.obj
Этот пример требует установленного Blender и корректного пути к SVG. Ошибки часто возникают из-за неправильной активации объекта перед редактированием.