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

Выделение инстансных объектов.

 ------------------------------------------------------
arInst = #()
arSel = selection as array
if arSel.count != 0 do(
    for i in arSel do(
        InstanceMgr.GetInstances i &rptInstances
        join arInst rptInstances
        )
    select arInst
    )
 ------------------------------------------------------
Источники:
ersindemir
forums.cgsociety
forums.cgsociety
docs.autodesk.com

Декодирование mse скриптов.

1. Запустить quickbms.exe  и  выбрать Mse_Decrypter.txt

2. Выбрать mse

3. Указать путь для сохранения декодированного скрипта.

Источник:
http://www.scriptsays.com/2016/04/3dmax-mse-script-source-code-decryption-tool/

Правда этот способ подходит не для всех mse файлов. 
 

вторник, 13 сентября 2016 г.

Работа с именами текстур.

Бывает так, что, к примеру, в папке wood - куча текстур с непонятными названиями, вроде - 01, asdfasdf, и т.п. .Скрипт ниже переименовывает текстуры по названию папки + произвольное шестизначное число. Сразу обновляет путь битмапы. На примере папки wood текстуры будут иметь следующие имена  - wood_126523 и т.п.
-----------------------------------------------------------
 (
local albm = getclassinstances bitmapTexture, arPath = #()
  
fn randName num = (
local rN = ""
for i = 1 to num do rN+= (random 1 num) as string
rN
)

fn getFileFolderName pf = (
    fsp = filterString pf "\\"
    fsp[fsp.count-1]
    )

for n in albm do
(
    if n.filename != undefined do(
        if doesFileExist n.filename then(
                appendIfUnique arPath n.filename
                nn =(getFilenamePath  n.filename)+(getFileFolderName  n.filename)+"_"+(randName 6)+(getFilenameType n.filename)
                renameFile n.filename nn
                n.filename = nn
                appendIfUnique arPath n.filename
            ) else(
                if (findItem  arPath n.filename) != 0 do n.filename = arPath[(findItem  arPath n.filename)+1]
                )
        )
    )
)   
-----------------------------------------------------------

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

Поиск и замена одинаковых текстур с разными именами.

Иногда бывает так, что в сложных сценах могут появится битмапы с одинаковыми текстурами, но с разными путями к ним, соответственно 3ds max может при просчете несколько раз загружать одну и ту же текстуру, в пустую расходуя память. Чтобы этого избежать и был написан следующий скрипт.

  ---------------------------------------------------
(
arBMT = getclassinstances bitmapTexture
   
fn unicImageData w_bmp = (
            arData = #()
            unicAr = #()
            work_bmp = openbitmap w_bmp.filename
            bmp_w = work_bmp.width
            bmp_h = work_bmp.height
            for i = 0.1 to 0.9 by 0.1 do(
                for j = 0.1 to 0.9 by 0.1 do(
                    p = (getpixels work_bmp [(i*bmp_w) as  integer,(j*bmp_h) as  integer] 1)[1]
                    append unicAr p
                    )
                )
            close work_bmp       
            join arData  #(bmp_w, bmp_h, GetFileSize w_bmp.filename, unicAr, getFilenameType w_bmp.filename)
            arData
    )
   
fn CompareArrays a b = if a.count == b.count AND (for i = 1 to a.count where a[i]!=b[i] collect i).count == 0 then return true else return false
   
fn CompareImages bm1 bm2 =(
            local a = unicImageData bm1
            local b = unicImageData bm2
            if a[1] ==b[1] and a[2] == b[2] and a[3] == b[3] and CompareArrays a[4] b[4] == true and a[5] == b[5] then return true else return false
    )

progressstart "Search and replacement..."
num = 1
nc = arBMT.count
    for i in arBMT do(
        progressupdate (num*100.0/nc)
        num+=1
       
        for j in arBMT do(
            if i.filename != j.filename do(
                if i.filename != undefined and j.filename != undefined do(
                    if doesFileExist i.filename and doesFileExist j.filename do(
                        if CompareImages i j do (print (j.filename+"    --->    "+i.filename);j.filename = i.filename;)
                        )
                    )
                )
            ) -- for j in arBMT do
           
        )--for i in arBMT do
progressend ()    

)
---------------------------------------------------

Функция unicImageData получает информацию о текстуре в виде массива #(ширина, высота, размер текстуры, RGB 100 точек с шагом 10% , разрешение текстуры)

Функция CompareArrays просто сравнивает два массива. Источник.

Функция CompareImages сравнивает две битмапы.

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

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

Полуавтоматический способ импорта и подготовки чертежей

Это что-то вроде заготовки для импорта и подготовки чертежей. В теле скрипта необходимо указать путь к dwg файлам,  также можно удалить указанные слои.
Функция ObjLayerName выполняет роль фильтра - не рассматриваются сплайны из указанных в функции слоев.
 --------------------------------------------------------
--mP = "23"

importFile ("path.dwg") #noPrompt

delete (for o in objects where superclassOf o == shape and (o.layer.name == "name layer 01" or o.layer.name == "name layer 02") collect o)

fn ObjLayerName obj = (
    temp = true
    if obj.layer.name == "acad-K2-fas" then temp = false
    if obj.layer.name == "acad-K1-pl" then temp = false
    if obj.layer.name == "acad-K2-pl" then temp = false
    if obj.layer.name == "acad-K3-pl" then temp = false
    if obj.layer.name == "acad-K4-pl" then temp = false
    if obj.layer.name == "acad-K5-pl" then temp = false
    if obj.layer.name == "acad-K6-pl" then temp = false
    temp
    )

arrShape = for o in objects where superclassOf o == shape and ObjLayerName o 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]
    )
   
arrShape = for o in objects where superclassOf o == shape and ObjLayerName o collect o
arrShapeC = arrShape.count
ms = arrShape[1]

convertToSplineShape ms
for i = 2 to arrShapeC do(
        convertToSplineShape arrShape[i]
        addAndWeld ms arrShape[i] -1
            )
updateShape ms

--delete blocks           
delete (for o in objects where superclassOf o != shape collect o)

--delete empty layers
--set 0-layer to be current
(layermanager.getlayer 0).current = true
for i = Layermanager.count-1 to 1 by-1 do(
(layermanager.getLayer i).nodes &theNodes
if thenodes.count== 0 do LayerManager.deleteLayerbyname (layermanager.getLayer i).name
)

select ms
ms.name = "K6_floor_"+mP

------add newObj to layer
theLayer = layermanager.getLayerFromName $K6_floor_01.layer.name
theLayer.addNode ms
 --------------------------------------------------------

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"