Создавая новую геометрию в Blender при помощи Python API очень часто нужно не просто создавать новые полигоны, а еще и сразу присваивать им правильные координаты UV-развертки. При работе через объект BMesh это делается через связку точек геометрии с точками развертки мешлупами.
Возьмем для примера любой объект в сцене в Blender, тот же дефолтный куб, создадим внутри него новый полигон и сразу же назначим точкам этого полигона требуемые координаты на UV-развертке.
Если куб был в режиме редактирования, переключимся в объектный режим.
|
1 |
bpy.ops.object.mode_set(mode = 'OBJECT') |
Создадим объект BMesh и сбросим в него данные геометрии текущего активного объекта.
|
1 2 |
bm = bmesh.new() bm.from_mesh(bpy.context.object.data) |
Создадим четыре новых точки для дальнейшего создания по ним нового полигона. Пусть они располагаются квадратом 1 на 1 в плоскости XY, в нулевой точки сцены.
Сразу выделим их. Выделять не обязательно, это нужно просто для того, чтобы сразу увидеть их на плоскости развертки.
|
1 2 3 4 5 6 7 |
v0 = bm.verts.new((0.0, 0.0, 0.0)) v1 = bm.verts.new((1.0, 0.0, 0.0)) v2 = bm.verts.new((1.0, 1.0, 0.0)) v3 = bm.verts.new((0.0, 1.0, 0.0)) for v in [v0, v1, v2, v3]: v.select = True |
По этим точкам построим новый полигон.
|
1 |
face = bm.faces.new((v0, v1, v2, v3)) |
Получим указатель на текущий активный слой UV-развертки. Если развертки нет, она будет создана этой же командой.
|
1 |
uv_layer = bm.loops.layers.uv.verify() |
Зададим координаты для точек нашего полигона на UV-развертке. Пусть они образуют трапецию от начала координат.
|
1 2 3 4 5 6 |
uv_coords = [ (0.0, 0.0), (0.5, 0.0), (0.4, 0.5), (0.1, 0.5) ] |
Теперь пройдем по точкам мешлупа созданного нами полигона. Через них мы можем получить связку точек полигона с точками на UV. Порядок следования по точкам мешлупа соответствует порядку точек как полигона, так и точек на UV-развертке.
|
1 2 |
for loop, co in zip(face.loops, uv_coords): loop[uv_layer].uv = co |
Теперь нам осталось вернуть обновленную геометрию в исходный объект — куб, и очистить более не нужный объект BMesh.
|
1 2 |
bm.to_mesh(bpy.context.object.data) bm.free() |
Переключимся в режим редактирования для просмотра изменений на UV.
|
1 |
bpy.ops.object.mode_set(mode = 'EDIT') |
Как мы видим, внутри самого объекта в сцене создался еще один полигон, а его точки на UV-раввертке получили заданные нами координаты.

.blend file on Patreon