Для того чтобы быстро вписать всю UV-развертку, или отдельный выделенный остров, в границы области UV при помощи Blender Python API можно сделать несложный скрипт.
Добавим в сцену куб, сделаем для него развертку и случайным образом сдвинем и отмасштабируем ее. Теперь нам нужно вписать ее в границы UV-области, т.е. сделать так, чтобы координаты всех точек развертки лежали в пределах от 0.0 до 1.0 по осям X и Y.
Работать с координатами развертки нужно из объектного режима.
|
1 |
bpy.ops.object.mode_set(mode='OBJECT') |
Получим указатель на текущий активный слой UV-развертки.
|
1 2 3 |
uv_layer = bpy.context.object.data.uv_layers.active # <bpy_struct, MeshUVLoopLayer("UVMap") at 0x000001F95F9E0EF8> |
И отфильтруем только выделенные точки.
|
1 2 3 |
points = [point for point in uv_layer.data if point.select] # [bpy.data.meshes['Cube'].uv_layers["UVMap"].data[0], ...] |
Мы можем получить координаты всех выделенных точек развертки через их свойство “uv”.
|
1 2 3 |
[(point.uv.x, point.uv.y) for point in points] # [(0.644528865814209, 0.0), ...] |
Для начала сдвинем все выделенные точки до левой и нижней границ UV-области.
Для этого нам нужно найти точки с минимальными координатами по X и Y осям.
|
1 2 3 4 5 |
min_x = min((point.uv.x for point in points)) min_y = min((point.uv.y for point in points)) # 0.39864683151245117 # 0.108274444937706 |
И вычесть найденные значения из координат каждой выделенной точки. Это сдвинет их все до упора вниз и влево в области UV.
|
1 2 3 |
for point in points: point.uv.x -= min_x point.uv.y -= min_y |
Теперь нам нужно растянуть развертку вправо и вверх так, чтобы хотя бы по одной оси (X или Y) развертка занимала всю область UV.
Найдем теперь точки с максимальными координатами по этим осям.
|
1 2 3 4 5 |
max_x = max((point.uv.x for point in points)) max_y = max((point.uv.y for point in points)) # 0.4475545883178711 # 0.5212229490280151 |
Чтобы развертка растянулась так, чтобы занимать область от 0.0 до 1.0 по каждой оси, нам нужно умножить координаты всех точек на отношение 1 к текущей максимальной координате.
|
1 2 |
x_scale_factor = 1 / max_x y_scale_factor = 1 / max_y |
Остается произвести умножение.
|
1 2 3 |
for point in points: point.uv.x *= x_scale_factor point.uv.y *= y_scale_factor |
Однако если мы это сделаем так, развертка будет искажена.
Если мы хотим избежать искажения развертки, нам нужно умножать координаты точек на минимальное из двух значений по X и Y осям.
|
1 |
scale_factor = min(x_scale_factor, y_scale_factor) |
И вот теперь мы можем произвести умножение.
|
1 2 3 |
for point in points: point.uv.x *= scale_factor point.uv.y *= scale_factor |
Вернувшись в режим редактирования меша,
|
1 |
bpy.ops.object.mode_set(mode='EDIT') |
мы увидим, что теперь развертка, или ее выделенная часть, четко вписана в область UV с координатами от 0.0 до 1.0.

.blend file on Patreon