вторник, 10 ноября 2015 г.

Слои скриптами в SculptRoom

Есть, есть работа с воксельными слоями в скриптах 3D-Coat!) Сейчас и расскажу, и покажу...

Чтобы быстрее запомнить названия методов (мы ведь хотим результат, а не вечную тягу к документации), объясню чем руководствовался, создавая их. Но вначале посмотрите на это дерево:

Голова (Head), тело (Body), руки (* arm), ноги( * leg) - почти человек) 3D-Коут позволяет создавать множество слоёв. И каждый из них способен содержать... ну, Вы поняли: даже сложное дерево можно нарисовать в Коуте.

В первой заметке обещал быть кратким. Поэтому, сразу код:
// Работа со "слоями объёма" (volume layers, сокр. v-layers)
void main() {

    // подготавливаем сцену
    Vox  v;
    v.clearScene();

    // строим дерево v-слоёв
    v
      .appendToParent( "Head" )
      .appendToParent( "Body" )
        .append(         "Neck" )
        .appendToParent( "Left arm" )
        .appendToParent( "Right arm" )
        .appendToParent( "Heart" )
        .appendToParent( "Left leg" )
        .appendToParent( "Right leg" )

      // возвращаемся к слою "Head", переводим его
      // в "Режим поверхности" и аттачим новые
      .to( "Head" ).toSurface()
        .append( "Eye" )
        .appendToParent( "Lamps" )
      // Заметили как добавились последние?
      // Верно: `S`, не `V`.
    ;

    // удаляем первый (пустой) слой со сцены
    v.firstForRoot().remove();
}

Видите группы методов? `append()`, `appendToParent()`, `appendToRoot()`, `forEach()`, `forRootEach()`, ... - говорящие названия, если понимать, что "parent" по англ. "родитель", "root" - "корень", а "for each" - "для каждого". Сравнивая код с результатом-картинкой, Вы без документации без труда разберётесь кто что творит.

Пересмотрев библиотеки для работы с деревьями, я нашёл, что наиболее естественно это дело реализовано в JQuery. Знакомы? Ну, значит точно объяснять ничего не надо!) Единственное что пришлось учесть при разработке: класс `Vox` работает с UI 3D-Coat, поэтому представленные в коде Vox-методы выделяют слои прежде чем что-то с ними делать. Понимая это и порисовав в Коуте (бесплатно или нет), Вы не будете бомбардировать меня вопросами: "А зачем было создавать Root-методы!?" К прочим вопросам открыт!

Так, обход слоёв:
void main() {

    // создание дерева - см. выше
    // ...

    // #1
    // проходим все слои и вызываем для каждого функцию invert()
    // см. ф. ниже
    v.forRootEach( "invert" );

    // #2
    // перемещаемся на слой "Body" и invert() для него и его деток
    v.to( "Body" ).call( "invert" ).forEach( "invert" );
}


// функция, о которой глаголилось выше
void invert() {
    Vox  v;
    v.isSurface() ? v.toVoxel() : v.toSurface();
    // добавил паузу, чтобы видеть движение в UI
    Wait( 50 );
}

Я считаю, что методов выше достаточно для обхода любого дерева. Но Андрей Шпагин убеждает, что нет. Тогда вот ещё вариант:
    // доступ по индексу для всех деток слоя "Head"
    v.to( "Head" ).call( "invert" );
    for ( int i = 0; i < v.count(); ++i ) {
        v.at( i ).call( "invert" ).parent();
        Wait( 100 );
    }

Также, из скриптов для класса `Vox` доступны все возможности из меню, которое выпадает при щелчке правой кнопки мыши на слое:

Что ещё хочу добавить, так это более лаконичный конструктор. Позже. Сейчас надо в скриптах поднять работу с примитивами, а их - ох как много... Вот буквально сегодня Виталик показывал горы болтов-шайб-гаек - ждите в новых версиях!

P.S. Кстати, рассматриваемое дерево имеет "живой прототип":

Комментариев нет: