вторник, 18 октября 2016 г.

Расстановка книг.

Возникла задача расставить большое количество книг в книжном магазине. Как обычно, руками оказалось слишком долго. Разбираться в готовых решениях тоже долго. Быстрее оказалось написать простой скрипт для расстановки по сплайнам, что называется без изысков.

Ниже сам скрипт с небольшим описанием:
Заготовка из книг
Расположение пивота(точки опоры) книги
Сплайны по которым будет расстановка книг
При выделенном сплайне выполняем этот код:
-----------------------------
main_spl = $
arrSplineData = #()
for numS = 1 to (numSplines  main_spl) do
    (     arS = #()
        for k =0.0 to 1.0 by  0.0001 do append arS (pathInterp main_spl numS k)
        append arrSplineData arS
    )
-----------------------------
Происходит считывание позиций со сплайна с шагом 0.0001 от длины элемента сплайна. Запись данных в массив происходит также поэлементно.
После записи arrSplineData = #(#(pos1, pos2, pos3),#(pos1, pos2, pos3),#(pos1, pos2, pos3).....)
Затем выделяем заготовку книг и выполняем запись книг в массив:

--------------------------------
arrBooks = selection as array
--------------------------------
Далее с помощью функции newBook из массива книг arrBooks выбираем произвольную книгу и определяем ее габариты, в моем случае, по оси Y! 
------------------------------
fn newBook arB =  #(theB = arB[random 1 arB.count], theB.max.y - theB.min.y)
NB = newBook arrBooks    
------------------------------

С помощью следующей части кода определяем массив newBooks - куда будут записаны все созданные книги и обращаясь к уже созданному массиву arrSplineData производим расстановку книг:
------------------------------
 newBooks = #()
for k = 1 to arrSplineData.count do(
    s = 0
    thePos = arrSplineData[k][1]
    for i = 2 to arrSplineData[k].count do(
        if s == 0 do thePos = arrSplineData[k][i-1]
        s = s + (distance arrSplineData[k][i-1] arrSplineData[k][i])
        if s >= NB[2] do (
            nbi = instance NB[1]
            nbi.wirecolor = NB[1].wirecolor
            theY = normalize (arrSplineData[k][i-1] - arrSplineData[k][i])
            theZ = [0,0,1]
            theX = cross theY theZ
            nbi.transform = matrix3 theX theY theZ thePos
          
            append newBooks nbi
            NB = newBook arrBooks  
            s = 0
            )
        )
    )
------------------------------

После первой расстановки возможно понадобится сделать реверс некоторым элементам сплайна.

Для этого удалим массив newBooks:
--------------------------------
delete newBooks
--------------------------------

Получается сырой, полуавтоматический способ расстановки для больших библиотек без изысков.
Ниже целиком весь код:
---------------------------------
 main_spl = $
arrSplineData = #()
for numS = 1 to (numSplines  main_spl) do
    (     arS = #()
        for k =0.0 to 1.0 by  0.0001 do append arS (pathInterp main_spl numS k)
        append arrSplineData arS
    ) -- END for numS = 1 to (numSplines  theMainShape) do
      
arrBooks = selection as array

fn newBook arB =  #(theB = arB[random 1 arB.count], theB.max.y - theB.min.y)
NB = newBook arrBooks  

newBooks = #()
for k = 1 to arrSplineData.count do(
    s = 0
    thePos = arrSplineData[k][1]
    for i = 2 to arrSplineData[k].count do(
        if s == 0 do thePos = arrSplineData[k][i-1]
        s = s + (distance arrSplineData[k][i-1] arrSplineData[k][i])
        if s >= NB[2] do (
            nbi = instance NB[1]
            nbi.wirecolor = NB[1].wirecolor
            theY = normalize (arrSplineData[k][i-1] - arrSplineData[k][i])
            theZ = [0,0,1]
            theX = cross theY theZ
            nbi.transform = matrix3 theX theY theZ thePos
          
            append newBooks nbi
            NB = newBook arrBooks  
            s = 0
            )
        )
    )

delete newBooks
---------------------------------

Это финальный результат:

Похожие скрипты:
bookmanager на scriptspot
bookscatter на scriptspot



пятница, 7 октября 2016 г.

Сложное копирование.

--------------------------------------------
arZamenit = selection as array
arNaEto = selection as array

for i in arZamenit do(
    maxops.clonenodes arNaEto[random 1 arNaEto.count] cloneType:#instance expandHierarchy:true newNodes:&nnl
    nnl[1].transform = i.transform
     )
delete arZamenit
--------------------------------------------

Функция  maxops.clonenodes позволяет копировать объекты с прилинкованными объектами.
Например, если надо боксы-заготовки поменять на машины с людьми. При этом машины  в виде группы, то данный способ подойдет как нельзя кстати.