пятница, 15 января 2016 г.

Resource collector for 3ds max

 Скрипт собирает все файлы в сцене.
 


Update - обновление путей в сцене
Move files - перемещение файлов
Simple collect - сборка в одну папку

Почти тоже самое, что архивация сцены, только с бонусами:
- умеет работать с "*.ifl" и "*.xml" -> "*.mc"
- возможность собирать по категориям - Proxy, PointCache, Bitmap
- возможность собирать только с выделенных объектов


------------------------------------------------------start
-- tested in 3DMax 2014
try destroyDialog ResourceCollector catch()
global ResourceCollector
global arrData = #(#(),#(),#(),#(),#(),#(),#())


--functions
--bitmaps
fn MakingDir FilePath PathForCollection = (
    local outData = false
    if PathForCollection != undefined do(
         if FilePath != undefined and doesFileExist FilePath then
         (
             arPath = filterString FilePath "\\"
             -- if other NetworkPath
              if pathIsNetworkPath FilePath do (
                  local NewPath = "\\"
                  for i = 3 to arPath.count-1 do NewPath +=  (arPath[i] + "\\")
                  if (makeDir (PathForCollection + NewPath) all:true) do outData = PathForCollection + NewPath
                  )
            -- if not NetworkPath     
              if pathIsNetworkPath FilePath == false do(
                  local NewPath = "\\"
                  for i = 2 to arPath.count-1 do NewPath +=  (arPath[i] + "\\")
                  if (makeDir (PathForCollection + NewPath) all:true) do outData = PathForCollection + NewPath
                  )
             )else append arrData[1] ("Wrong files: "+ (FilePath as string))
        )
    return outData
    )
   
fn arrBitMapSel =
(
    local arBitMap = #()
    for obj in selection  where obj.material != undefined do for bm in (getclassinstances bitmapTexture  target:obj) do appendIfUnique arBitMap bm
    return arBitMap
    )   

--proxy
fn selGoodProxy =(
    local theAllGoodProxy = #()
    for i in selection where (classOf i == VRayProxy or classOf i == CProxy) do if doesFileExist i.filename  do appendIfUnique theAllGoodProxy i
    theAllGoodProxy   
    )
   
fn allGoodProxy =(
    local theAllGoodProxy = #()
    for i in objects where(classOf i == VRayProxy or classOf i == CProxy) do if doesFileExist i.filename  do appendIfUnique theAllGoodProxy i
    theAllGoodProxy
    )

--pointcache
fn arrPointCacheSel =
(
    local arPC = #()
    for obj in selection  do for pc in (getclassinstances Point_Cache  target:obj) do appendIfUnique arPC pc
    for obj in selection  do for pc in (getclassinstances Point_CacheSpacewarpModifier  target:obj) do appendIfUnique arPC pc
    return arPC
    )   



rollout ResourceCollector "ResourceCollector"
(
--Interface   


checkbox theUpd "Update" checked:false align:#left   
checkbox delFile "Move files" checked:false align:#left   
checkbox simCol "Simple collect" checked:false align:#left   
checkbox theAll "All scene" checked:true align:#left
checkbox withProxy "Proxy" checked:false align:#left enabled:false   
checkbox withPointCache "PointCache" checked:false align:#left    enabled:false   
checkbox withBitmap "Bitmap" checked:false align:#left    enabled:false   
checkbox selObj "Selection objects" checked:false align:#left enabled:false   

button btn_browse "Browse--->" width:150  height:24 align:#left toolTip:"Please pick path for collections."
button do_it "Start collection" width:150  height:24 align:#left enabled:false   
--button stripPathes "Strip path" width:150  height:24 align:#left enabled:false   
   
local FolderPathForCollection = undefined
   
on theAll changed theState do(
    if theState then (
        withProxy.enabled = false
        withProxy.checked = false
        withPointCache.enabled = false
        withPointCache.checked = false
        withBitmap.enabled = false
        withBitmap.checked = false
        selObj.enabled = false
        selObj.checked = false
        ) else (
        withProxy.enabled = true
        withPointCache.enabled = true
        withBitmap.enabled = true
        withBitmap.enabled = true
        selObj.enabled = true
        )
    )

on btn_browse pressed do
    (
        FolderPathForCollection = getSavePath  caption: "Pick folder" initialDir:"\\\\fs\\projects\\"
        btn_browse.text = FolderPathForCollection as string
        btn_browse.toolTip = FolderPathForCollection as string
        if FolderPathForCollection != undefined then do_it.enabled = true else( do_it.enabled = false; btn_browse.text = "Browse--->")
        )       
on do_it pressed do(
    if FolderPathForCollection != undefined  do(
       
    if theAll.state then(
            tempAr = #()
            clearlistener()
            progressstart "Collecting..."
            -- refresh asset tracking files
            atsops.Refresh()

            -- collect all the assets
                origAssets = for i = 1 to AssetManager.GetNumAssets() collect (AssetManager.GetAssetByIndex i)
                sceneroot = (for r in (refs.dependents rootnode) where (classof r == Scene) collect r)[1]
                theNum =  origAssets.count
       
                for AUIO = 1 to theNum do(
                   
                    AFile = origAssets[AUIO].getfilename()

                                if simCol.state then(
                                                    NewPath = FolderPathForCollection+ "\\" + (filenameFromPath AFile)
                                                    if matchpattern AFile pattern:"*.ifl" do(
                                                                if doesFileExist NewPath == false do copyFile AFile NewPath                               
                                                                f = openFile AFile mode:"r"
                                                                while not eof f do
                                                                (
                                                                    newLine = readLine f
                                                                    NewPathIFL = FolderPathForCollection+ "\\" + newLine
                                                                    if doesFileExist NewPathIFL == false  do if copyFile ((getFilenamePath AFile) + newLine) NewPathIFL then(
                                                                        append tempAr #(origAssets[AUIO], ((getFilenamePath AFile) + newLine), NewPathIFL)
                                                                        if delFile.state do try(deleteFile newLine)catch()
                                                                        )
                                                                -- delete old files
                                                                    )
                                                                close f
                                                            )
                                                    if doesFileExist NewPath == false do if copyFile AFile NewPath do(
                                                        append tempAr #(origAssets[AUIO], AFile, NewPath)
                                                        if delFile.state do try(deleteFile  AFile)catch()
                                                        )
                                    )else (
                                                    crFolder = MakingDir AFile FolderPathForCollection
                                                    if crFolder != false do(
                                                        NewPath = crFolder + (filenameFromPath AFile)
                                                        if matchpattern AFile pattern:"*.ifl" do(
                                                                    f = openFile AFile mode:"r"
                                                                    while not eof f do
                                                                    (
                                                                        newLine = readLine f
                                                                        NewPathIFL = crFolder    + newLine
                                                                       
                                                                        if doesFileExist NewPathIFL == false  do if copyFile ((getFilenamePath AFile) + newLine) NewPathIFL then(
                                                                            append tempAr #(origAssets[AUIO], ((getFilenamePath AFile) + newLine), NewPathIFL)
                                                                            if delFile.state do try(deleteFile  ((getFilenamePath AFile) + newLine))catch()
                                                                            )
                                                                   
                                                                    -- delete old files
                                                                        )
                                                                    close f
                                                                )
                                                        if doesFileExist NewPath == false do if copyFile AFile NewPath do(
                                                            append tempAr #(origAssets[AUIO], AFile, NewPath)
                                                            if delFile.state do try(deleteFile  ((getFilenamePath AFile) + NewPath))catch()
                                                            )
                                                        )
                                                       
                                            )
                               
                progressupdate (AUIO*100.0/theNum)     
                )
               
                progressend ()

               
               
                --update pathes
                if theUpd.state do(
                        progressstart "Update pathes..."
                        nta = tempAr.count
                        for i = 1 to nta do(
                            try(atsops.RetargetAssets sceneroot tempAr[i][2] tempAr[i][3] CreateOutputFolder:false)catch()
                            progressupdate (i*100.0/nta)     
                            )
                        progressend ()
                    )                    

       
        ) else(
                                    local arBMTex_newPath=#()
                                    local arProxy_newPath=#()
                                    local arPC_newPath = #()
                                    -- bitmap collections
                                        if withBitmap.state do(
                                            arBitMapTexture = if selObj.state then arrBitMapSel() else  getclassinstances bitmapTexture
                                            if arBitMapTexture.count != 0 do(
                                                    progressstart "Collecting textures..."
                                                    local num = 1
                                                    local numAll = arBitMapTexture.count
                                                    for bm in arBitMapTexture do(
                                                                    if bm.filename != undefined do(
                                                                                    if simCol.state then(
                                                                                        NewPath = FolderPathForCollection+ "\\" + (filenameFromPath bm.filename)
                                                                                        --copy files
                                                                                        if getFilenameType bm.filename == ".ifl" then(
                                                                                                   
                                                                                                    if doesFileExist NewPath == false do if copyFile bm.filename NewPath do append arrData[2] ("Copied textures: " + bm.filename)
                                                                                           
                                                                                                    f = openFile bm.filename mode:"r"
                                                                                                   
                                                                                                    while not eof f do
                                                                                                    (
                                                                                                    newLine = readLine f
                                                                                                    NewPathIFL = FolderPathForCollection+ "\\" + newLine
                                                                                                    if doesFileExist NewPathIFL == false  do if copyFile ((getfilenamePath bm.filename) + newLine) NewPathIFL do(
                                                                                                        --append arBMTex_newPath #(bm,NewPathIFL,newLine)
                                                                                                        append arrData[2] ("Copied textures: " + ((getfilenamePath bm.filename) + newLine))
                                                                                                        )
                                                                                                   
                                                                                                    -- delete old files
                                                                                                    if delFile.state do try(deleteFile  ((getfilenamePath bm.filename) + newLine))catch(append arrData[3] ("Undeleted textures: " + ((getfilenamePath bm.filename) + newLine)))
                                                                                                        )
                                                                                                    close f
                                                                                                   
                                                                                            )else if doesFileExist NewPath == false do if copyFile bm.filename NewPath do append arrData[2] ("Copied textures: " + bm.filename)
                                                                                       
                                                                                       
                                                                                        -- delete old files
                                                                                       
                                                                                        --update
                                                                                        append arBMTex_newPath #(bm,NewPath,bm.filename)
                                                                                        progressupdate (num*100.0/numAll) 
                                                                                        num+=1
                                                                                           
                                                                            )else (
                                                                                            local crFolder = MakingDir bm.filename FolderPathForCollection
                                                                                            if crFolder != false do(
                                                                                               
                                                                                                NewPath = crFolder + (filenameFromPath bm.filename)
                                                                                                --copy files
                                                                                                if getFilenameType bm.filename == ".ifl" then(
                                                                                                            if doesFileExist NewPath == false do if copyFile bm.filename NewPath do append arrData[2] ("Copied textures: " + bm.filename)
                                                                                                            f = openFile bm.filename mode:"r"
                                                                                                            while not eof f do
                                                                                                            (
                                                                                                            newLine = readLine f
                                                                                                            NewPathIFL = crFolder    + newLine
                                                                                                            if doesFileExist NewPathIFL == false  do if copyFile ((getFilenamePath bm.filename) + newLine) NewPathIFL do(
                                                                                                                --append arBMTex_newPath #(bm,NewPathIFL,((getFilenamePath bm.filename) + newLine))
                                                                                                                append arrData[2] ("Copied textures: " + ((getFilenamePath bm.filename) + newLine))
                                                                                                                )
                                                                                                            -- delete old files
                                                                                                            if delFile.state do try(deleteFile  ((getFilenamePath bm.filename) + newLine))catch(append arrData[3] ("Undeleted textures: " + ((getFilenamePath bm.filename) + newLine)))
                                                                                                                )
                                                                                                            close f
                                                                                                           
                                                                                                    )else if doesFileExist NewPath == false do if copyFile bm.filename NewPath do append arrData[2] ("Copied textures: " + bm.filename)
                                                                                                append arBMTex_newPath #(bm,NewPath,bm.filename)
                                                                                                progressupdate (num*100.0/numAll) 
                                                                                                num+=1
                                                                                                )
                                                                            )
                                                                        )
                                                                )
                                                progressend ()
                                                )--end if arBitMapTexture.count != 0
                                            )--end if withBitmap.state do
                                           
                                    -- proxy collections
                                        if withProxy.state do(
                                            arProxy = if selObj.state then selGoodProxy() else allGoodProxy()
                                            if arProxy.count != 0 do(
                                                    progressstart "Collecting proxy..."
                                                    local num = 1
                                                    local numAll = arProxy.count
                                                   
                                                    for p in arProxy do(
                                                        if p.filename != undefined do(
                                                                        if simCol.state then(
                                                                                            NewPath = FolderPathForCollection+ "\\" + (filenameFromPath p.filename)
                                                                                            --copy files   
                                                                                            if doesFileExist NewPath == false do if copyFile p.filename NewPath do append arrData[4] ("Copied Proxy: " + p.filename)
                                                                                            -- delete old files
                                                                                            if delFile.state do try(deleteFile p.filename)catch(append arrData[5] ("Undeleted Proxy: " + p.filename))
                                                                                            --update
                                                                                            append arProxy_newPath #(p,NewPath,p.filename)
                                                                                            progressupdate (num*100.0/numAll) 
                                                                                            num+=1
                                                                            )else (
                                                                                        local crFolder = MakingDir p.filename FolderPathForCollection
                                                                                        if crFolder != false do(
                                                                                            NewPath = crFolder + (filenameFromPath p.filename)
                                                                                            --copy files   
                                                                                            if doesFileExist NewPath == false do if copyFile p.filename NewPath do append arrData[4] ("Copied Proxy: " + p.filename)
                                                                                            -- delete old files
                                                                                            if delFile.state do try(deleteFile p.filename)catch(append arrData[5] ("Undeleted Proxy: " + p.filename))
                                                                                            --update
                                                                                            append arProxy_newPath #(p, NewPath, p.filename)
                                                                                            progressupdate (num*100.0/numAll) 
                                                                                            num+=1
                                                                                            )
                                                                            )
                                                            )
                                                        )
                                                    progressend ()
                                                )--end if arProxy.count != 0
                                            )--end if withProxy.state do   
                                           
                                    -- pointcache collections
                                        if withPointCache.state do(
                                            arPC = if selObj.state then arrPointCacheSel() else(
                                                (getclassinstances Point_Cache)+(getclassinstances Point_CacheSpacewarpModifier)
                                                )
                                           
                                            if arPC.count != 0 do(
                                                    progressstart "Collecting Point Cache..."
                                                    local num = 1
                                                    local numAll = arPC.count
                                                    for pc in arPC do(
                                                        if pc.filename != undefined do(
                                                                    if simCol.state then(
                                                                                        NewPath = FolderPathForCollection+ "\\" + (filenameFromPath pc.filename)
                                                                                       
                                                                                        --copy files   
                                                                                        if (getFilenameType pc.filename) == ".xml" then(
                                                                                               
                                                                                                if doesFileExist NewPath == false do if copyFile pc.filename NewPath do append arrData[6] ("Copied PointCache: " + pc.filename)

                                                                                                allMC = getFiles ((getFilenamePath  pc.filename) + (getFilenameFile  pc.filename) +  "*.mc")
                                                                                                for i in allMC do if copyFile i (FolderPathForCollection + "\\" +  (filenameFromPath i)) do(
                                                                                                    --append arPC_newPath #(pc,(FolderPathForCollection + "\\" +  (filenameFromPath i)),i)   
                                                                                                    append arrData[6] ("Copied PointCache: " + i)
                                                                                                    )

                                                                                            )else if doesFileExist NewPath == false do if copyFile pc.filename NewPath do append arrData[6] ("Copied PointCache: " + pc.filename)
                                                                                        append arPC_newPath #(pc,NewPath,pc.filename)   
                                                                                        progressupdate (num*100.0/numAll) 
                                                                                        num+=1
                                                                        )else(
                                                                                    local crFolder = MakingDir pc.filename FolderPathForCollection
                                                                                    if crFolder != false do(
                                                                                        NewPath = crFolder + (filenameFromPath pc.filename)
                                                                                        --copy files   
                                                                                        if (getFilenameType pc.filename) == ".xml" then(
                                                                                                if doesFileExist NewPath == false do if copyFile pc.filename NewPath do append arrData[6] ("Copied PointCache: " + pc.filename)
                                                                                                allMC = getFiles ((getFilenamePath  pc.filename) + (getFilenameFile  pc.filename) +  "*.mc")
                                                                                                for i in allMC do if copyFile i (crFolder + (filenameFromPath i)) do(
                                                                                                    --append arPC_newPath #(pc,(crFolder + (filenameFromPath i)),i)
                                                                                                    append arrData[6] ("Copied PointCache: " + i)
                                                                                                    )
                                                                                            )else if doesFileExist NewPath == false do if copyFile pc.filename NewPath do append arrData[6] ("Copied PointCache: " + pc.filename)
                                                                                        append arPC_newPath #(pc,NewPath,pc.filename)   
                                                                                        progressupdate (num*100.0/numAll) 
                                                                                        num+=1
                                                                                        )
                                                                                )
                                                            )
                                                        )
                                                       
                                                )--end if arProxy.count != 0
                                            )--end if withProxy.state do   
                                           


                            --update pathes
                            if theUpd.state do(
                                for i in arBMTex_newPath do i[1].filename = i[2]
                                for i in arProxy_newPath do i[1].filename = i[2]
                                for i in arPC_newPath do i[1].filename = i[2]
                                )                
                            -- delete old files
                            if delFile.state do(
                                for i in arBMTex_newPath do try(deleteFile i[3])catch(append arrData[7] ("Undeleted Bitmap: " + i[3]))
                                for i in arProxy_newPath do try(deleteFile i[3])catch(append arrData[7] ("Undeleted Proxy: " + i[3]))
                                for i in arPC_newPath do try(deleteFile i[3])catch(append arrData[7] ("Undeleted PointCache: " + i[3]))
                                )        
                            clearlistener()       
                            progressend ()    
                            for i in arrData do print i
                               
                            arrData = #(#(),#(),#(),#(),#(),#(),#())    
                            arBMTex_newPath=#()
                            arProxy_newPath=#()
                            arPC_newPath = #()
            ) -- end else
            --stripPathes.enabled = true   
        )
    )   
/*
on stripPathes pressed do (
    ATSOps.SetPath ""
    ATSOps.Refresh()
    )   
    */
   
   
   
 )
createDialog ResourceCollector width:180
-- Created Alex Yakushev
------------------------------------------------------end

понедельник, 11 января 2016 г.

Cars by roads

Скрипт расставляет машины по дорогам.
- умеет менять плотность машин (с помощью omni lights -> Near Attenuation)
- проецировать машины на дороги со сложным рельефом
- умет работать с прилинкованными объектами к машинам (например люди в салоне и т.п.)

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


Пример работы (spline надо сконвертировать в editable spline):

Проецирование на поверхность



------------------------------start
-- tested in 3DMax 2014
--units:  1 Unit = 1 Centimeters
try destroyDialog CarsBySpline catch()

--global variables
global CarsBySpline
global LengthSeg = 0
global arrTrafficOmni = #()
global arrSplineData = #()
global theMainMesh = undefined
global theMainSelectionCars = #()
global TempArraysCarsForDelete = #()  

  
--functions  
fn filter_spline o = superclassof o == shape --filter only shapes
fn filter_Mesh o = superclassof o == GeometryClass --filter only shapes
  
fn NormPlanter ArrObj theRoad = (
  if ArrObj.count >0 and theRoad != undefined and superclassof theRoad == GeometryClass do( 
        tempMesh = snapshot theRoad
        for i in ArrObj do(  
            theObj = i
            theObjT = theObj.transform
            theIntRay = intersectRay tempMesh (Ray [theObjT[4].x, theObjT[4].y, theRoad.max.z + 1000] [0,0,-1])
            if theIntRay != undefined do(  
                NaprVecX = theObjT[1]
                NaprVecY = theObjT[2]

                x0 = theIntRay.pos.x
                y0 = theIntRay.pos.y
                z0 = theIntRay.pos.z
              
                x1 = theObjT[4][1]
                y1 = theObjT[4][2]
                z1 = theObjT[4][3]
              
                l = NaprVecX[1]
                m = NaprVecX[2]
                n = NaprVecX[3]
              
                A1 = y1*n-y0*n-z1*m+z0*m
                B1 = -x1*n+x0*n+z1*l-z0*l      
                C1 = x1*m-x0*m-y1*l+y0*l

                A2 = theIntRay.dir[1]
                B2 = theIntRay.dir[2]  
                C2 = theIntRay.dir[3]  

            --napravlayshiy vector peresecheniya dvuh ploskostey
                DirVX = [B1*C2 - B2*C1, C1*A2 - C2*A1, A1*B2 - A2*B1]
                DirVX =if (dot DirVX NaprVecX) > 0 then DirVX else -DirVX
                nDirVX = normalize DirVX
              
                DirVY = cross nDirVX theIntRay.dir
                DirVY = if (dot DirVY NaprVecY) > 0 then DirVY  else -DirVY
                nDirVY = normalize DirVY
              
                theNewX = nDirVX
                theNewY = nDirVY
                theNewZ = theIntRay.dir
                theNewPos = theIntRay.pos
              
                theObj.transform = (matrix3 theNewX theNewY theNewZ theNewPos)
                )--END if theIntRay != undefined do
            ) -- END for i in ArrObj do
            delete tempMesh
        ) -- END if ArrObj.count >0 and theGround != undefined do
    )

  
fn instanceCar FlipAxis theSh rb1_state distMin distMax densCars arrNum  =
(
    if FlipAxis then (tM1 = 1; tM2 = 0) else (tM1 = 0; tM2 = 1)
    LengthSeg += length(arrSplineData[arrNum] - arrSplineData[arrNum-1])
    if LengthSeg >= (random distMin distMax) do
    (
        LengthSeg = 0
        if (random 0 100) <= densCars do
        (
            --instance  new car
            GetRandomCar = theMainSelectionCars[random 1 theMainSelectionCars.count]
            maxops.clonenodes GetRandomCar cloneType:#instance expandHierarchy:true newNodes:&nnl
            new_car = nnl[1]
            join TempArraysCarsForDelete nnl
          
            --transform
            case rb1_state of
                (
                    1: (
                            theY = normalize (arrSplineData[arrNum - tM2] - arrSplineData[arrNum - tM1])
                            theZ = [0,0,1]
                            theX = cross theY theZ
                            new_car.transform = matrix3 theY theX theZ (arrSplineData[arrNum] + theY*(random -theSh theSh))
                        )
                    2: (
                            theY = normalize (arrSplineData[arrNum - tM2] - arrSplineData[arrNum - tM1])
                            theZ = [0,0,1]
                            theX = cross theY theZ
                            new_car.transform = matrix3 theX theY theZ (arrSplineData[arrNum] + theX*(random -theSh theSh))
                        )
                )
            -- planting to mesh
            if theMainMesh != undefined do NormPlanter #(new_car) theMainMesh
            )
        )
      
    )

fn getOmniByZone_Point mPoint arrOmni =
(
    local arrO = arrOmni
    local arrDataProc = #()
    for o in arrOmni do
    (
            local theDist = distance mPoint o.pos
            local procDist = (theDist - o.nearAttenStart)/(o.nearAttenEnd - o.nearAttenStart)
            append arrDataProc procDist
        )
    local NumOmni = findItem arrDataProc (amin arrDataProc)
    return arrO[NumOmni]  
    )
  
----END functions  


--Interface
rollout CarsBySpline "Cars by Spline"
(  
group "Selection:"
(
    listbox ListCars ""  height:10
    button addToListCars "Add cars to list" width:175

    listbox ListTraffic ""  height:2
    button addToListTraffic "Add OMNI as traffic light" width:175  
    label lbl1 ""
    pickbutton chooseShape "Select road spline" width:175 filter:filter_spline
    pickbutton chooseMesh "SelectRoadMesh(not necessarily)" width:175 filter:filter_Mesh
    )
group "Parameters:"
    (
    spinner DistCarsMin "DistanceCars-MIN:" range:[501,10000000, 550] type:#integer width:120 align:#right --across:2
    spinner DistCarsMax "DistanceCars-MAX:" range:[0,10000000, 4000] type:#integer width:120 align:#right
    spinner theShift "Shift:" range:[0,1000, 70] type:#integer width:70 align:#right
    spinner densityCars "Density of cars:" range:[0,100, 30] type:#float width:120 align:#right
    spinner AccurRead "Step of reading spline:"  range:[10,1000, 30] type:#float width:120 align:#right
    checkbox DelCars "Delete OLD"    checked:true align:#right
    label lbl2 "Direction objects by:"
    radiobuttons rb1  "" labels:#("X", "Y") default:2 across:2 align:#center
    checkbox theFlip "Flip"    checked:false align:#center
        )

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

on CarsBySpline open do
    (
        global LengthSeg = 0
        global arrTrafficOmni = #()
        global arrSplineData = #()
        global theMainMesh = undefined
        global theMainSelectionCars = #()
        global TempArraysCarsForDelete = #()
        )
      
      

      
on addToListTraffic pressed do(
    arrTrafficOmni = for i in selection where classOf i == Omnilight collect i
    local ListName = #()
    if arrTrafficOmni.count != 0 then(
            for i in arrTrafficOmni do append ListName i.name
            ListTraffic.items = ListName
            ) else ListTraffic.items = #()
    )  
  
 on addToListCars pressed do(
    theMainSelectionCars = for i in selection collect i
    local ListName = #()
    if theMainSelectionCars.count != 0 then(
            for i in theMainSelectionCars do append ListName i.name
            ListCars.items = ListName
            ) else ListCars.items = #()
     )

on chooseShape picked main_spl do
(
    chooseShape.text = main_spl.name

--reading data of shape  
    arrSplineData = #()
    for numS = 1 to (numSplines  main_spl) do
        (   
            progressstart "Reading splines..."  
            for k =0.0 to 1.0 by (
                if AccurRead.value/(getSegLengths main_spl numS)[(getSegLengths main_spl numS).count] < 0.0001 then 0.0001
                else AccurRead.value/(getSegLengths main_spl numS)[(getSegLengths main_spl numS).count]
                )    do (
                         append arrSplineData (pathInterp main_spl numS k)
                         progressupdate (k*100.0)
                            )
            progressend ()
        ) -- END for numS = 1 to (numSplines  theMainShape) do
)


on chooseMesh picked obj do (chooseMesh.text = obj.name; theMainMesh = obj)

on theGo pressed do
(
    max select none
    if DelCars.state do (try(delete TempArraysCarsForDelete)catch();TempArraysCarsForDelete = #())      
  
    if arrSplineData.count >= 2 and theMainSelectionCars.count > 0  then
    (
        if arrTrafficOmni.count > 0 then
        (
            for i = 2 to arrSplineData.count do
            (
                --vibor omni po velichine vliyaniya
                mainOmni = getOmniByZone_Point arrSplineData[i] arrTrafficOmni
          
                if (distance arrSplineData[i] mainOmni.pos) > mainOmni.nearAttenEnd do instanceCar theFlip.state theShift.value rb1.state DistCarsMin.value DistCarsMax.value densityCars.value i
                if (distance arrSplineData[i] mainOmni.pos) < mainOmni.nearAttenStart do instanceCar theFlip.state theShift.value rb1.state 500.0 650.0 100.0 i
              
                if (distance arrSplineData[i] mainOmni.pos) < mainOmni.nearAttenEnd and (distance arrSplineData[i] mainOmni.pos) > mainOmni.nearAttenStart do
                (
                    procDist = ((distance arrSplineData[i] mainOmni.pos) - mainOmni.nearAttenStart)/(mainOmni.nearAttenEnd - mainOmni.nearAttenStart)
                  
                    theMin = DistCarsMin.value + (DistCarsMin.value - 500)*procDist
                    theMax = DistCarsMax.value + (DistCarsMax.value - 650)*procDist
                    theDensity = 100.0 - (100.0 - densityCars.value)*procDist
                  
                    instanceCar theFlip.state theShift.value rb1.state theMin theMax theDensity i
                    )
                ) --END for i = 2 to arrSplineData.count do
            )else for i = 2 to arrSplineData.count do instanceCar theFlip.state theShift.value rb1.state DistCarsMin.value DistCarsMax.value densityCars.value i
        )else (print "No data")

)-- END on theGo pressed do


) --END rollout
createDialog CarsBySpline width:200
-- Created Alex Yakushev (alexander.yakushev@gmail.com, aly.work@mail.ru)

------------------------------end

пятница, 4 декабря 2015 г.

Настройка анимации ступеней эскалатора посредством maxscript

Имеем анимированную по сплайну ступеньку эскалатора. Задаем скорость движения ступеньки около 0.5 м/c.
Далее необходимо накопировать ступеньки по пути с заданным сдвигом:

------------------------------------------------------------
for i = 1 to 10 do
(
    asd = instance $
    moveKeys asd.pos.controller.percent.controller 20f
    select asd
    )
------------------------------------------------------------

Соответственно эта строчка регулирует количество копий(10 шт):

for i = 1 to 10 do

 А эта строка - сдвиг на 20 кадров:

moveKeys asd.pos.controller.percent.controller 20f

Величина 20f подбиралась опытным путем, таким образом, чтобы ступени были на максимально корректном расстоянии друг от друга. 
Можно и в другую сторону сдвигать: -20f



Тонкую настройку - подгонку ступеней можно провести небольшой реглировкой их скорости, т.е. углом наклона анимационной линии:
 Этой строчкой меняем угол наклона (работает только с выделенными ступенями):
-----------------------------------------------------------------------
for i in selection  do i.pos.controller.percent.controller.keys[2].value = i.pos.controller.percent.controller.keys[2].value - 0.001
------------------------------------------------------------------------
Смысл в том, что верхний ключ немного смещается вверх или вниз сразу для всех ступеней.
После, примерно, двадцатикратного применения этой строки (Ctrl+E) удалось точно подогнать ступени эскалатора.

Спасибо за внимание.

Поворот в локальных координатах вокруг выбранной оси.

for i in selection do i.transform = (rotateZmatrix (random 0 100))*i.transform

К примеру, таким образом, все эти окна  были открыты на угол от 0 до 100 градусов за время нажатия клавиш Ctrl+E.

пятница, 27 ноября 2015 г.

Один из способов анимации меха, например, гармошки.

 Есть некая заготовка мехов:
 Создаем FFD(Box) немного бОльших размеров, чем габариты заготовки. 
Create -> Space Warps -> Geometric/Deformable -> FFD(Box)
Подгонять надо именно по размерам FFD, а не подтягиванием вершин!
Далее создаем два хелпера для будущего управления мехами:
Выделяем нужные вершины на FFD и линкуем их к хелперу с помощью модификатора Linked XForm:
Также линкуем другие вершины(меняем выделение с помощью модификатора FFD Select ) к другому хелперу:




С помощью Bind to Space Warp привязываем нашу заготовку к FFD(Box):

Все готово. Это результат:
Таким же образом можно анимировать, например, сцепление поездов и т.п.:
Спасибо за внимание!

среда, 11 ноября 2015 г.

Простой и быстрый способ выравнивания чертежей с помощью Normal Align.

Это заимпортированные исходники:

 Выделяем ось и применяем экструд:
 Создаем вспомогательный объект, - box и, с помощью Normal Align, выравниваем по плоскости:


Осталось только привязать все чертежи к вспомогательному боксу и сбросить ему вращение на 0:



Наслаждаемся результатом и продожаем работать)

пятница, 6 ноября 2015 г.

Возможности float script


-----------------------------------------------------------------
delete objects
b = box height:0.5 length:5 width:5
for i = 0 to 30 do(
    for j = 0 to 30 do(
        instance b pos: [b.length*i, b.length*j, 0]
        )
    )
s = sphere radius:5 name:"ms" pos:[-10,-10,0] wirecolor:red

for i in $box* do(
        i.rotation.controller.X_Rotation.controller = float_script ()
        i.rotation.controller.X_Rotation.controller.script =     "dependsOn $ms.transform.controller\n" +
                                            "dependsOn $"+i.name+".transform.controller\n"+
                                            "p1 = $ms.transform.controller.Position\n" +
                                            "p2 = $"+i.name+".transform.controller.Position\n" +
                                            "if (length (p1 - p2)) < 50 then degtorad ((length (p1 - p2))*3.6) else degtorad 180"
    )           
for i in $box* do(
        i.visibility = bezier_float()
        i.visibility.controller = float_script ()
        i.visibility.controller.script =     "dependsOn $ms.transform.controller\n" +
                                            "dependsOn $"+i.name+".transform.controller\n"+
                                            "p1 = $ms.transform.controller.Position\n" +
                                            "p2 = $"+i.name+".transform.controller.Position\n" +
                                            "if (length (p1 - p2)) < 100 then ((length (p1 - p2))/100.0) else 1"
    )   
   
   
/*    --return
for i in $box* do(
    i.visibility.controller = bezier_float()
    i.rotation.controller.X_Rotation.controller = bezier_float()
    )        
-----------------------------------------------------------------

Если немного доработать код, то можно поменять ось вращения зависимых объектов следующим образом:
--------------------------------------------------------------------
for i in $box* do(
        i.rotation.controller = rotation_script ()
        i.rotation.controller.script =     "dependsOn $ms.transform.controller\n" +
                                            "dependsOn $"+i.name+".transform.controller\n"+
                                            "p1 = $ms.transform.controller.Position\n" +
                                            "p2 = $"+i.name+".transform.controller.Position\n" +
    "dirVec = normalize(p1-p2)\n"+
    "rotax = cross dirVec [0, 0, 1]\n"+
    "quat (720.0/(length (p1 - p2))) rotax"
    --"if (length (p1 - p2)) < 50 then (quat (720.0/(length (p1 - p2))/3.6) rotax) else (quat 0 0 0 1)"
    )    

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