Перемещение материала из одного слота материалов объекта в другой в Blender

Для того чтобы переместить материал из одного слота материала в другой, мы можем в панели материалов объекта нажать на кнопку со стрелкой вверх или вниз. При этом материал в текущем выделенным слоте поднимется (или опуститься) на одну позицию. Такой способ сортировки и перемещения материалов очень медленный и не очень удобный.

При нажатии на кнопку со стрелкой для перемещения материала в “слот вверх” или в “слот вниз” вызывается оператор object.material_slot_move(), в параметрах которого передается направление перемещения UP (вверх) или DOWN (вниз).

К сожалению этот оператор не может перемещать материалы по слотам более чем на одно соседнее место.

В самом простом случае мы можем вызывать этот оператор в цикле несколько раз – столько, на сколько позиций нам нужно передвинуть материал в активном слоте.

Например, для того чтобы передвинуть текущий материал на два слота вверх, нужно вызвать оператор два раза, указывая в его параметре направление “UP”. Не забудем про необходимость переопределения контекста, если мы исполняем наш код из текстового редактора Text Edit.

В целом, такое решение работает, но мы можем немного его улучшить.

Для начала обратим внимание на то, что порядок расположения материалов по слотам идентичен порядку расположения материалов в списке материалов объекта.

Мы можем вывести список материалов для активного объекта до ручной перестановки.

После чего, например, поднять последний материал на один слот вверх, и снова посмотреть на этот список.

Порядок остается в прямом соответствии.

И вот, кажется очевидным решение, как можно быстро перекидывать материалы в слотах на нужное место – мы можем просто менять их местами в списке материалов.

Давайте попробуем переместить материал из последнего слота сразу в первый. Для этого поменяем местами последний материал с первым в списке, используя evaluation order.

И, у нас получилось.  Мы видим, что материалы с первом и последнем слотах действительно поменялись местами.

Однако, внимательно посмотрев на наш объект, мы замечаем, что у нас “что-то пошло не так”. Вместе с тем, что материалы поменялись в слотах, они заодно поменялись и на самом объекте – на полигонах, на которых у нас был назначен последний материал, теперь назначен первый, и наоборот. Такой вариант перемещения материалов в слотах нас, конечно, не устраивает.

Попробуем исправить ситуацию. Для этого нужно понять, каким образом материал назначается на полигоны объекта.

На самом деле все очень просто – каждый полигон объекта имеет свойство material_index, в котором хранится целое число. И это число как раз является порядковым индексом материала в списке материалов объекта.

Например, для первого полигона объекта:

Это означает, что на первый полигон (с индексом 0) назначен материал, расположенный на третьем месте (индекс 2) в списке материалов объекта.

Становится понятным, почему наш трюк с перекидыванием материалов сработал не так как ожидалось. Мы поменяли материалы в списке материалов объекта, что изменило их индексы, но на самих полигонах объекта остались отсылки к индексам материалов так, как было до замены.

Итак, чтобы у нас все получилось, нам нужно не только поменять местами материалы в списке, но также и поменять местами индексы материалов для каждого полигона объекта, на которые эти материалы назначены.

Мы можем до замены получить список полигонов объекта на которые назначен материал с нужным индексом, например – 2.

И после перекидывания материалов назначить этим полигонам новый индекс.

И как мы видим, после этого материал на объекте вернулся в свое исходное положение.

Давайте соберем все вместе и напишем функцию, которая будет менять местами два материала в слотах.

Определим функцию с тремя входными параметрами: объект, над которым мы проводим действия, индекс (порядковый номер) слота материала и второй индекс – номер слота, в который нужно поставить этот материал.

Сначала мы меняем материалы в списке материалов объекта.

Создадим два списка полигонов, с первым материалом, и со вторым.

И взаимно поменяем индексы материала у этих полигонов.

Все вместе:

Теперь, для того чтобы поставить последний материал, в слотах объекта на первое место, нам нужно просто вызвать нашу функцию.

Материал активного объекта из слота с индексом 2 (третий по порядку) переместится на первое место (индекс 0).

0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии