среда, 7 сентября 2016 г.

Wirecolor by Z


----------------------------------------------------------------
arPos = #()
arObj = selection as array

for i in arObj do append arPos i.pos.z
sort arPos

arData = #()
for i = 1 to arPos.count do (append arData ((arPos[i] - arPos[1])/(arPos[arPos.count] - arPos[1]));  append arData arPos[i])

for i in arObj do (
    fi = findItem arData i.pos.z
    if fi != 0 do i.wirecolor = (color 255 (arData[if fi != 1 then fi-1 else fi]*255) 0)
    )
-----------------------------------------------------------------

Варьируя параметрами "(color 255 (arData[fi-1]*255) 0)"  можно менять расцветку.
Этим параметром можно менять оси "i.pos.z"

среда, 31 августа 2016 г.

Аттачит сплайны по именам.

Если в сцене много сплайнов с одинаковыми именами и появилась необходимость их объединить в один, то этот скрипт как раз для этого:

-------------------------------------------------------
(
arrShape = for o in objects where superclassOf o == shape collect o
arrShapeC = arrShape.count

arByName = #()
for i = 1 to arrShapeC do if findItem arbyName arrShape[i].name ==  0 do append arByName arrShape[i].name
   
arSplineByName = #()
for n in arByName do(
    arNT = #()
    for j in arrShape do if j.name == n do append arNT j
    append arSplineByName arNT
    )
   
for s in arSplineByName do(
        convertToSplineShape s[1]
        for i=2 to s.count do(
            convertToSplineShape s[i]
            addAndWeld s[1] s[i] -1
            )
        updateShape s[1]
    )
)
-------------------------------------------------------

вторник, 30 августа 2016 г.

Один из способов найти неинстансные короновские прокси и сделать их инстансными.


 ----------------------------------------------
arCP = for i in objects where classOf i == CProxy collect i
arCPc = arCP.count
for i = 1 to arCPc do(
    for j = 1 to arCPc do(
        if i != j do (
            n1 = getFilenameFile (arCP[i].filename)
            n2 = getFilenameFile (arCP[j].filename)
            if arCP[i].filename != arCP[j].filename and n1 == n2 do instanceReplace arCP[i] arCP[j]
            )
        )
    )
 ----------------------------------------------

По идее, если  "CProxy " заменить на "VrayProxy", то должно сработать и для vray прокси.

вторник, 16 августа 2016 г.

Если необходимо переименовать сгруппированные объекты по названию группы.

Есть сгруппированные объекты с именем группы "Group_01". Необходимо каждому объекту присвоить следующее имя - "Group_01_######", где ###### - произвольное шестизначное число.
Скрипт работает только с выделенными группами.
------------------------------------------------------------------
 (
fn randName num = (
local arS = #("123456", "123456", "123456"), rN = ""
for i = 1 to num do rN+= arS[r = random 1 arS.count][random 1 arS[r].count]
rN
)
  
for i in selection do(
    if not (isgrouphead i) do(
        if i.parent != undefined do i.name = (i.parent).name + "_" + (randName 6)
        )
    )  
)
------------------------------------------------------------------

пятница, 10 июня 2016 г.

Вращение колес посредством maxscript.

Данный скрипт предназначен для анимации сразу большого массива колес!

Если Вам надо заригить колеса в одном авто, лучше пройти по ссылкам ниже.  Данный случай постараюсь рассмотреть позже.

Для корректной работы колесам необходимо применить ResetXForm.

Также, в зависимости от способа копирования колес (mirror или instance с разворотом), возможно понадобится отдельно настраивать вращение для левых и правых колес (по часовой стрелке или против).

Сразу про недостатки:
- покадровая анимация
- морока с настройкой колес
- наверняка можно оптимизировать, но такая задача не ставилась. Главное, что более менее корректно работал. 

---------------------------------------------------------------
-- tested in 3DMax 2014
try destroyDialog WheelAnimator catch()

global arrFrontWheel, arrBackWheel, arAllData = #()

--function
fn sumArData ar = (
    sum = 0
    for i in ar do  sum+=i
    sum
    )
   
fn wheelRotationFlipZ_180 arW fb = if arW.count != 0 do for i in arW do if fb then rotate i (angleaxis 180 [0,0,1]) else rotate i (angleaxis -180 [0,0,1])

    -- arWheel - array wheels, wheelRadius - value, theAxis - axis rotation(1 - "X" or 2-"Y"), AngFlip - clockwise(counterclockwise) (true or false)   
fn wheelWriteDataAnimation arW wheelRadius theAxis AngFlip FB = (
                if arWeel.count != 0 do(
                    arAllData = #()
                    for w in arW do(
                        case FB of(
                            ("FrontWheel"): (
                                            local arTransform = #(), arAng = #()
                                            --weelRadius
                                            if wheelRadius == 0 do wheelRadius =  (w.max.z - w.min.z)/2.0
                                            --delete old keys
                                            sliderTime =  animationRange.start
                                            deleteKeys w #allKeys
                                            --write data
                                            for t = animationRange.start to animationRange.end do (
                                                    at time t (
                                                            p0 = at time t w.position; p1 = at time (t+1) w.position;
                                                            dif = p1-p0; len = Length(dif); vec = normalize dif; v2 = normalize (cross vec [0,0,1]);
                                                           
                                                            theAng = (if AngFlip then 1 else -1)*(180.0*len)/(wheelRadius*pi) -- AngFlip +1 or -1
                                                            append arAng theAng; ang = sumArData arAng;
                                                           
                                                            cm = if theAxis == 1 then matrix3 v2 vec (cross v2 vec) p0 else matrix3 vec v2 (cross vec v2) p0
                                                            append arTransform ((rotateXmatrix ang)*cm)
                                                        )  -- end at time j
                                                    ) -- end for j = AnimStart to AnimEnd do
                                            append arAllData #(w, arTransform)
                                )
                            ("BackWheel"):(
                                            local arTransform = #(), arAng = #()
                                            --weelRadius
                                            if wheelRadius == 0 do wheelRadius =  (w.max.z - w.min.z)/2.0
                                            --delete old keys
                                            sliderTime =  animationRange.start
                                            deleteKeys w #allKeys
                                            --write data
                                            for t = animationRange.start to animationRange.end do (
                                                    at time t (
                                                            p0 = at time t w.position; p1 = at time (t+1) w.position;
                                                            dif = p1-p0; len = Length(dif); vec = normalize dif; v2 = normalize (cross vec [0,0,1]);
                                                           
                                                            theAng = (if AngFlip then 1 else -1)*(180.0*len)/(wheelRadius*pi) -- AngFlip +1 or -1
                                                            append arAng theAng; ang = sumArData arAng;
                                                           
                                                            cm = w.transform
                                                            append arTransform ((rotateXmatrix ang)*cm)
                                                        )  -- end at time j
                                                    ) -- end for j = AnimStart to AnimEnd do
                                            append arAllData #(w, arTransform)
                                )
                            )
                        )
                    )--end if arWeel.count != 0
    )
   
-- animation wheel by array data
fn wheelAnimation =(
        if arAllData.count != 0 do(
            for w in arAllData do(
                local num = 0
                with animate on(
                    for t = animationRange.start to animationRange.end do at time t w[1].transform = w[2][num+=1]
                    )
            --deleting unnecessary keys       
            selectKeys w[1].pos.controller animationRange.start animationRange.end
            deleteKeys w[1].pos.controller #selection   
            selectKeys w[1].scale.controller animationRange.start animationRange.end
            deleteKeys w[1].scale.controller #selection   

            )--for i in arWeel do
        )--if arWeel.count != 0 do(
    )--fn weelAnimation w arW =(

--Interface
rollout WheelAnimator "WheelAnimator"
(   
group "Selection:"
(
    listbox ListFrontWheel ""  height:5
    button addToListFrontWheel "Add front wheels" width:175
    listbox ListBackWheel ""  height:5
    button addToListBackWheel "Add back wheels" width:175
    )
group "Parameters:"
    (
    spinner radW "Wheel radius:" range:[0,100000, 0] type:#float width:100 offset:[30,0] enabled:false across:2
    checkbox theAuto "Auto" checked:true align:#center offset:[10,0]
    label lbl1 "Orientation: " align:#left across:2
    radiobuttons rb1  "" labels:#("X", "Y") default:1 align:#left  offset:[-15,0] --across:2
    checkbox theFlip "Flip (turn 180 deg around Z-ax)" checked:true align:#left
    checkbox theCW "Clockwise (or not)" checked:true align:#left
        )

button theGo "Animate" width:175 height:30  align:#left  --across:2

on theAuto changed theState do(
    radW.enabled = not theAuto.state
    if radW.enabled == false do radW.value = 0
    ) 
   
on addToListFrontWheel pressed do(
    local SelFW = selection as array, ListName = #()
    arrFrontWheel = #()
    if SelFW.count != 0 then(
            for i in SelFW do (append ListName i.name; append arrFrontWheel i;)
            ListFrontWheel.items = ListName
            ) else ListFrontWheel.items = #()
     )
   
 on addToListBackWheel pressed do(
    local SelFW = selection as array, ListName = #()
    arrBackWheel = #()
    if SelFW.count != 0 then(
            for i in SelFW do(append ListName i.name; append arrBackWheel i;)
            ListBackWheel.items = ListName
            ) else ListBackWheel.items = #()
     )

on theFlip changed theState do (wheelRotationFlipZ_180 arrFrontWheel theFlip.state; wheelRotationFlipZ_180 arrBackWheel theFlip.state;)   
   
on rb1 changed state do (
    wheelWriteDataAnimation arrFrontWheel radW.value rb1.state theCW.state "FrontWheel"
    wheelAnimation()
    wheelWriteDataAnimation arrBackWheel radW.value rb1.state theCW.state "BackWheel"
    wheelAnimation()
    )
on theGo pressed do (
    wheelWriteDataAnimation arrFrontWheel radW.value rb1.state theCW.state "FrontWheel"
    wheelAnimation()
    wheelWriteDataAnimation arrBackWheel radW.value rb1.state theCW.state "BackWheel"
    wheelAnimation()
    )
on theCW changed theState do    (
    wheelWriteDataAnimation arrFrontWheel radW.value rb1.state theCW.state "FrontWheel"
    wheelAnimation()
    wheelWriteDataAnimation arrBackWheel radW.value rb1.state theCW.state "BackWheel"
    wheelAnimation()
    )
) --END rollout
createDialog WheelAnimator width:200
---------------------------------------------------------------
 

Ссылки по теме:
MAXScript Tutorials: Quaternions 1/2
Rolling Ball
111_carWheel_v0.3
3DS MAX - CG Academy - The Matrix Continued
CGTalk - Wheel rig script!
Rotating the Wheels


Если необходимо просто провращать колеса без подруливания, то это можно сделать этим скриптом:

------------------------------------------------------------
 -- tested in 3DMax 2014
try destroyDialog SimpleWheelAnimator catch()
--fn
fn swa arW wr st cw rb  = ( -- arW: array wheels [#()], wr: wheel radius[float], st: step [integer], cw: Clockwise[false-true], rb: radiobuttons [integer]
    if arW.count != 0 do(
        for w in arW do(
            deleteKeys w #allKeys
                for t = animationRange.start to animationRange.end by st do(
                    p0 = at time (t-st) w.position; p1 = at time t w.position; d = length (p1-p0); u += (if cw then 1 else -1)*180.0*d/(wr*pi);
                    case rb of(
                        (1):(addnewkey w.rotation.controller.X_Rotation.controller t).value = u
                        (2):(addnewkey w.rotation.controller.Y_Rotation.controller t).value = u
                        (3):(addnewkey w.rotation.controller.Z_Rotation.controller t).value = u
                        )
                    )
            )--for w in ws do(
        )--if ws.count != 0 do(
    )-- end fn
--Interface
rollout SimpleWheelAnimator "SimpleWheelAnimator"(  
group "Parameters:"(
    label lbl1 "Rotation axis   - " align:#left across:2; radiobuttons rb1  "" labels:#("X", "Y", "Z") default:1 align:#left    columns:3;
    checkbox theCW "Clockwise" checked:true align:#left across:2; spinner sf "Step:" range:[1,100000, 20] type:#integer width:60  align:#left;  
    spinner radW "Wheel radius:" range:[0,100000, 40] type:#float width:100 align:#left  --enabled:false across:2; checkbox theAuto "Auto" checked:true align:#center offset:[10,0]
        )
button theGo "Animate selection!" width:175 height:30  align:#left  --across:2
on theAuto changed theState do(
    radW.enabled = not theAuto.state
    if radW.enabled == false do radW.value = 0
    )
on theGo pressed do swa (selection as array) radW.value sf.value theCW.state rb1.state
on theCW changed theState do    swa (selection as array) radW.value sf.value theCW.state rb1.state
on rb1 changed state do swa (selection as array) radW.value sf.value theCW.state rb1.state
) --END rollout
createDialog SimpleWheelAnimator width:200
------------------------------------------------------------

Clear undefined Bitmaps

----------------------------------------------------

fn clearUndefinedBitMaps mm = (
  numSTM = getNumSubTexmaps  mm
  if numSTM != undefined and numSTM != 0 do  (
   for i = 1 to numSTM do  (
    BMAP = getSubTexmap  mm i
       if BMAP != undefined do(
                                        bm =  getclassinstances Bitmaptexture target:BMAP
                                        getUnd = false
                                        if bm.count != 0 do for t in bm do if t.filename == "" or t.filename == undefined  do getUnd = true
                                          
                                        if getUnd do(
                                            format "%, % - clear\n" mm.name BMAP.name
                                            setSubTexmap mm i undefined
                                            )
                                    )
                                )  
                            )
 )


fn theAllMat = (
  local allMat = #()
  join allMat (getclassinstances CoronaMtl)
  join allMat (getclassinstances VRayMtl)
  join allMat (getclassinstances Standardmaterial)
   allMat
 )

for m in theAllMat() do clearUndefinedBitMaps m
for m in sceneMaterials do clearUndefinedBitMaps m
for i = 1 to meditmaterials.count do if classOf meditmaterials[i] == BitmapTexture do if meditmaterials[i].filename == "" or meditmaterials[i].filename == undefined do (mn = meditmaterials[i].name; format "% - replase Standardmaterial in meditmaterials\n" mn; meditmaterials[i] = Standardmaterial name:mn;)
----------------------------------------------------

четверг, 9 июня 2016 г.

Выделить задублированные объекты в сцене.

Если вдруг выяснилось, что по ошибке произошло задвоение объектов в сцене и объекты абсолютно идентичные, с одним материалом  и т.п.. В общем, единственный способ их убрать - это вручную "протыкивать" , то  на помощь может прийти этот скрипт:

------------------------------------------------------------
 fn round_to val n =
(
    local mult = 10.0 ^ n
        (floor ((val * mult) + 0.5)) / mult
)
arPos = #()
arObj = #()

ar = selection as array

for i in ar do(
    rp = [round_to i.pos.x 1,round_to i.pos.y 1, round_to i.pos.z 1]
  
    if findItem arPos rp == 0 do(
        append arPos rp
        append arObj i
        )
    )
select arObj
------------------------------------------------------------


Функция округления взята отсюда: http://forums.cgsociety.org - Rounding a number, How?
 Похожие скрипты: http://www.scriptspot.com/ - Duplicate object finder/selecter