Доступ к активной развертке:
1 |
bpy.context.active_object.data.uv_layers.active |
Доступ к развертке по имени:
1 |
bpy.context.active_object.data.uv_layers['UVMap'] |
Один полигон меша всегда соответствует одному полигону на развертке. Однако для ребер и вертексов это не так. Ребро меша, если по нему проходит шов, будет разделено в развертке на два отдельных ребра. Вертекс меша будет разделен на столько точек в развертке, сколько швов его пересекает. Поэтому для того, чтобы точно соотносить точки развертки и меша используются так называемые “мешлупы” (MeshLoop).
По сути, “мешлуп” это логическая комбинация “ребро + вертекс”. Основное отличие от обычных ребер и вертексов в том, что если два прилегающих полигона имеют одно общее ребро и два общих вертекса, “мешлупы” у каждого из них свои. Так у отдельного четырехугольного полигона (квада) 4 вертекса, 4 ребра и 4 “мешлупа”. А у дефолтного куба 8 вертексов, 12 ребер и 24 “мешлупа” – 6 полигонов в каждом из которых по 4 “мешлупа”.
Для того, чтобы различать “мешлупы” на меше и в развертке, они по-разному типизируются. MeshLoop – для меша, MeshUVLoop – для развертки.
Одной из особенностей API Blender является то, что данные “мешлупов” доступны только в объектном режиме. Перед началом работы нужно проверять или принудительно выставлять нужный режим:
1 |
bpy.ops.object.mode_set(mode = 'OBJECT') |
Получить доступ ко всем “мешлупам” меша можно через индексы его полигонов. Через них же можно получить доступ к “мешлупам” развертки.
Список всех “мешлупов” развертки с координатами их точек можно получить следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import bpy bpy.ops.object.mode_set(mode = 'OBJECT') meshdata = bpy.context.active_object.data for i, polygon in enumerate(meshdata.polygons): print('polygon: ', i) for i1, loopindex in enumerate(polygon.loop_indices): print('meshloop: ', i1, ' index: ',loopindex) meshloop = meshdata.loops[i1] meshvertex = meshdata.vertices[meshloop.vertex_index] meshuvloop = meshdata.uv_layers.active.data[loopindex] print('meshuvloop coords: ', meshuvloop.uv, ' selected: ', meshuvloop.select) |
Если при построении развертки ребро меша не было разделено швом, “мешлупы” развертки для этого ребра расположены в одной точке и при выделении кликом мышки выделяются сразу все. Все манипуляции (например перемещение) соответственно производятся со всеми совпадающими “мешлупами” сразу. Такой подход удобен для сшивания – достаточно совместить “мешлупы” развертки, соответствующие одному ребру меша, чтобы шов был сшит. Однако из-за этого “мешлупы” развертки сложно разделить.
Для разделения выбранных на развертке “мешлупов” можно использовать следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import bpy import mathutils def centroid(vertexes): x_list = [vertex[0] for vertex in vertexes] y_list = [vertex[1] for vertex in vertexes] length = len(vertexes) x = sum(x_list) / length y = sum(y_list) / length return(mathutils.Vector((x, y))) bpy.ops.object.mode_set(mode = 'OBJECT') meshdata = bpy.context.active_object.data for polygon in meshdata.polygons: # Get uv polygon center polygondata = () for i in polygon.loop_indices: polygonvert = meshdata.uv_layers.active.data[i].uv[:] # Vector -> tuple polygondata += polygonvert, polygoncenter = centroid(polygondata) # Move MeshUVLoop if selected to polydon center for i in polygon.loop_indices: meshuvloop = meshdata.uv_layers.active.data[i] if meshuvloop.select: moveto = (meshuvloop.uv - polygoncenter) * 0.8 + polygoncenter meshuvloop.uv.x = moveto.x meshuvloop.uv.y = moveto.y |
Функция centroid высчитывает координаты центра полигона по координатам его вершин.
Скрипт просматривает все выделенные точки развертки. Все “мешлупы” для выделенной точки немного сдвигаются на развертке по направлению к центру полигона, которому они принадлежат.
Здравствуйте. Я импортирую в blender большую модель с разверткой из rizom uv, которая содержит 2 udim’а. В блендере же я хочу полигонам левого uv квадрата назначить один материал, а полигонам правого uv квадрата – другой, чтоб фактически каждый меш модели имел два материала, для облегченного нанесения материалов в unity. Я хотел автоматизировать этот процесс при помощи скриптинга, но столкнулся с проблемой, что у меня не получается оператором bpy.ops.uv.select_box (и прочими вариациями select) выделить полигоны именно левого или правого uv квадрата. Оператор либо выдает ошибку context is incorrect, либо (видимо из-за mesh-loop’ов) выделяет все полигоны.
Вручную я просто в режиме uv sync selection мышкой выделяю области каждого uv квадрата и назначаю им материалы, все получается. Как я могу повторить это действие при помощи скриптинга?
Здравствуйте!
По ошибке контекста смотрите здесь https://b3d.interplanety.org/pereopredelenie-konteksta-v-blender-versii-3-2-i-bolee-pozdnih/
По выделению полигонов по развертке, я думаю вам поможет эта статья https://b3d.interplanety.org/perenos-vydeleniya-s-uv-razvertki-na-mesh/