ПрограммированиеПодсказкиГрафика

Экспорт моделей из 3D Studio Max в свой формат при помощи MaxScript.

Автор:

Как написать скрипт для экспорта объектов из 3D Studio Max в свой формат.

В этой подсказке я расскажу как сделать скрипт на 3D Studio Max для экспорта моделей.

Для начала пару слов о синтаксисе скриптов. В 3D Studio Max к сожалению нет распознавания строчных букв. Т.е.  переменные с именем  positon_x и с именем POSITION_X  одно и то же.

Комментарии в скриптах прописываются двойным минусом (--)
Например

      widht = 1
      height = 2
      -- коментарий
      -- еще один комментарий
      size = width*height

А в общем синтаксис примерно похож на C++.  Операции деления и умножения такие же (даже сравнение такое (через двойное равно ==)). Различие в том что элементы массива начинают отчет с единицы, а не с нуля, и каждый элемент массива может иметь свой тип данных. Потом фигурные скобки заменены на обычные, а при вызове функций перечень переменных идет через пробел, а не через запятую. Т.е. чтоб вызвать функцию создания сферы надо ввести:

Sphere “Sphere01” radius:10 pos:[0,0,0]

Выберите в меню  “MAXScript” “NewScript”. Для удобства использования нашего скрипта  сначала пропишем окно.

    rollout roll_expmesh "Export Mesh"
    (
      edittext edt_path "Path" pos:[10,10] width:300  -- Это
                              -- путь к файлу для экспорта
      button btn_Browse "Browse" pos:[320,10] width:50   -- Кнопка для
                                -- удобного выбора файла
      button btn_exp "Export"          --Кнопка экспорта

      --Дальше пропишем пункты для выбора 
      --того что нам нужно экспортировать в файл
      --т.е. (списки вершин, списки нормалей вершин, списки фейсов,
      -- и координаты текстур)
      checkbox chk_v "Vertex" checked:true  
      checkbox chk_n "Normal" checked:true
      checkbox chk_f "Face" checked:true
      checkbox chk_t "Texture" checked:true
      
      on roll_expmesh open do  
      (
        --Это функция которая запускается при открытии окна

        s=selection[1].name as string
        edt_path.text=(GetDir #Export)+"\\"+s+".msh"
      )
      on btn_browse pressed do
      (
        --Здесь открывается окно для выбора пути к сохранению файла
        s=GetSaveFileName types:"Mesh file (*.msh)|*.msh|All files (*.*)|*.*"
        if s!=undefined do
        (
          edt_path.text=s
        )
      )
      on btn_exp pressed do
      (
        --А здесь происходит сам экспорт объекта и запись в файл
        
        --Прописываем флаги для дальнейшего экспорта
        local bV=0      --флаг вершин
        local bN=0      --флаг нормалей
        local bF=0      --флаг фейсов
        local bT=0      --флаг текстур
        
        --дальще устанавливаем эти флаги
        if chk_v.checked==true then bV=1
        if chk_n.checked==true then bN=1
        if chk_f.checked==true then bF=1
        if chk_t.checked==true then bT=1
        
          --Проверяем выбран ли путь
          if edt_path.text!=undefined do
          (
            --Создаем файл
            file01=createFile edt_path.text

            --Записываем наши флаги в файл чтобы потом при чтении этого
            --файла можно было узнать что в нем записано а что нет
            format "% " bV to:file01
            format "% " bN to:file01
            format "% " bF to:file01
            format "%\n" bT to:file01
        
            --Находим количество вершин в объекте
            local vnum=getNumVerts selection[1].mesh

            --Находим количество фейсов
            local fnum=getNumFaces selection[1].mesh

            --Находим количество вершин текстур в объекте
            local tnum=getNumTVerts selection[1].mesh

            --И записываем все это в файл
            format "% " vnum to:file01
            format "% " fnum to:file01
            format "%\n" tnum to:file01
            
            --Дальше всю информацию о выделенном объекте
            --записываем в переменную mesh01 (так надо чтоб не было глюков)
            --но только эта функция работает в шестом 3d max
            -- (в 4-ом и 5-ом не проверял но в 3-ем точно не работает)
            --так что если что можно обойтись
            --и без нее используя selection[1].mesh
            mesh01=snapshotasmesh selection[1]

            
            if chk_v.checked==true do
            (
              --Записываем вершины объекта  
              format "vertex \n"  to:file01
              for j=1 to vnum do
              (
                local p01=[0,0,0]
                p01=GetVert mesh01 j
                format "% " p01.x to:file01
                format "% " p01.y to:file01
                format "%\n" p01.z to:file01
              )
            )
            if chk_n.checked==true do
            (
              --Записываем нормали вершин объекта  
              format "normals \n"  to:file01
              for j=1 to vnum do
              (
                local p01=[0,0,0]
                p01=GetNormal selection[1].mesh j
                format "% " p01.x to:file01
                format "% " p01.y to:file01
                format "%\n" p01.z to:file01
              )
            )
            if chk_f.checked==true do
            (
              --Здесь идет запись фейсов
              --Каждый фейс содержит три вершины
              --и здесь идет запись id этих вершин
               format "Faces \n" fnum to:file01
              for j=1 to fnum do
              (
                local p01=[0,0,0]
                p01=GetFace selection[1].mesh j
                --Так как в 3D max элементы массивов начинаются с 1-го
                --а не с нулевого элемента как это принято
                --во всех языках
                --то будем отнимать единицу
                x01=(p01.x-1) as integer
                y01=(p01.y-1) as integer
                z01=(p01.z-1) as integer
                format "% " x01 to:file01
                format "% " y01 to:file01
                format "%\n" z01 to:file01
              )
            )
            if chk_t.checked==true do
            (
              --Запись координат текстур идет по такому принцыпу
              --Сначала записываются вершины а потом 
              --для каждого фейса id этой вершмны
              format "texture_vertex \n"  to:file01
              for j=1 to tnum do
              (
                local p01=[0,0,0]
                p01=GetTVert selection[1].mesh j
                format "% " p01.x to:file01
                format "% " p01.y to:file01
                format "%\n" p01.z to:file01
              )
              format "texture_face \n" fnum to:file01
              for j=1 to fnum do
              (
                local p01=[0,0,0]
                p01=GetTVFace selection[1].mesh j
                x01=(p01.x-1) as integer
                y01=(p01.y-1) as integer
                z01=(p01.z-1) as integer
                format "% " x01 to:file01
                format "% " y01 to:file01
                format "%\n" z01 to:file01
              )
            )            
            close file01
          )
      )
    )
    --Дальше будем использовать ограничение на выделение объектов
    --т.е. запускать макрос только если выделен один объект
    if selection.count<1 then MessageBox "Select object"
    if selection.count==1 do
    (
      --создаем главное окно
      m_roll=newrolloutfloater "JSD Exporter" 400 600
      --и к нему добавляем вкладку которую создали в самом начале скрипта
      addrollout roll_expmesh m_roll
    )

#3D Studio MAX, #MAX Script

26 марта 2006