Классы Editable_Mesh и TriMesh

Editable_Mesh это класс объектов, которые получаются после сворачивания стэка модификаторов в объект редактируемой сетки (editable mesh object). Множество операторов работы с сеткой в MAXScript работают только с объектами Editable_Mesh.

Класс TriMesh (triangular mesh - треугольная сетка) это специальная оболочка в MAXScript для хранения низкоуровневых значений класса Mesh из 3ds Max SDK. Этот класс низкоуровневых значений широко используется в объектах и модификаторах, работающих или основанных на сетках. В треугольной сетке хранятся действительные массивы вершин, граней и другие важные данные. Сетки, созданные посредством MAXScript являются величинами triMesh. Все методы и свойства, описанные в данном разделе, применимы и к объектам Editable_Mesh и к величинам TriMesh (тип величины <mesh> для обоих)


Конструкторы (Editable_Mesh)
editable_mesh...
Создает пустую сетку

mesh [ length:<integer> ] [ width:<integer> ] \
[ lengthsegs:<integer> ] [ widthsegs:<integer> ]
Создает плоскую прямоугольную сетку с заданным размером и числом сегментов. Длина и ширина по умолчанию равны по 50, число сегментов равно 5.

mesh [ numverts:<number> ] [ numfaces:<number> ]
Создает сетку с заданным числом вершин и граней, но без топологии, т.е. без граней или ребер.
После чего вы должны вручную поставить вершины и создать из них грани. Число вершин и граней по умолчанию 36 и 50 соответственно.

mesh [ mesh:<TriMesh> ]
Создает сетку на основе указанной величины TriMesh.

mesh vertices:<array_of_point3s> \
faces:<array_of_point3s> \
[ materialIDs:<array_of_integers> ] \
[ tverts:<array_of_point3s> ]
Создает сетку из массива вершин и граней. Каждая величина Point3 в массиве вершин указывает координаты вершины в текущей СК.
Каждая величина Point3 в массиве граней указывает три индекса вершин, которые формируют грань. Массив параметра materialIDs указывает ID материала, назначенный на каждую грань. И наконец массив величин Point3 в параметре tverts задает UVW-координаты текстурных вершин.

Пример
mesh vertices:#([0,0,0],[10,0,0],[0,10,0],[10,10,0]) \
faces:#([1,2,3],[2,4,3]) materialIDS:#(1,2)
 
snapshot <node> -- mapped
Функция работает аналогично инструменту SnapShot (снимок) в 3ds Max.
Она создает новый объект, содержащий копию сетки исходного объекта <node> на тот момент времени, в который запущена (т.е. сделан снимок). Все существующие модификаторы сворачиваются для нового объекта, также на снимок сетки влияют все примененные на данный момент пространственные деформации (space warps).

convertToMesh <node> -- mapped
Переводит допустимые объекты сцены в редактируемые сетки. Метод подобен операции collapseStack(), он также удаляет все существующие в пространстве объекта модификаторы, но отличается тем, что всегда заменяет базовый объект его версией редактируемой сетки даже в том случае, когда на объекте вообще нет модификаторов.
Метод можно применить к любому объекту, с которым будет работать модификатор Edit Mesh, например к объектам geometry и shapes, но не к объектам helpers, space warps, lights, и т.п.

convertTo <node> [ TriMeshGeometry | Mesh ] -- mapped
Переводит допустимые объекты сцены в редактируемые сетки. Работает аналогично методу convertToMesh().

Операторы
Следующие операторы выполняют на сетках булевы операции. Они разрушают и изменяют сетку первого операнда для хранения в ней булевого результата.
<mesh> + <mesh> -- union (ОБЪЕДИНЕНИЕ)
<mesh> - <mesh> -- difference (ВЫЧИТАНИЕ)
<mesh> * <mesh> -- intersection (ПЕРЕСЕЧЕНИЕ)

Свойства сеток
<mesh>.numverts Integer
Получает или задает число вершин. При задании числа вершин с помощью данного свойства или метода setNumVerts, новые вершины инициализируются в [0.,0.,0.]

<mesh>.numfaces Integer
Получает или задает число граней (аналогично методу setNumFaces).

Пример:
$.numfaces=300
--ЭТО ЭКВИВАЛЕНТ СЛЕДУЮЩЕМУ
setNumFaces $ 300 false
--АРГУМЕНТ false ОЗНАЧАЕТ, ЧТО НЕ НУЖНО СОХРАНЯТЬ СУЩЕСТВУЮЩУЮ ТОПОЛОГИЮ

Для всех новых граней происходит следующее:
Группа сглаживания устанавливается в 1
Вершины устанавливаются в [1,1,1]
ID материала устанавливается в 1

Для каждого используемого канала карты:
вершины маппинга грани устанавливаются в [1,1,1]
если параметр keep равен false, число вершин маппинга устанавливается в 1, вершины в [1,1,1]

<mesh>.numtverts Integer
Получает или задает число текстурных вершин. При задании числа текстурных вершин с помощью данного свойства или метода setNumTVerts, новые вершины инициализируются в [0.,0.,0.]

<mesh>.numcpvverts Integer
Получает или задает число цветовых (color-per-vertex) вершин. При задании числа цветовых вершин с помощью данного свойства или метода setNumCPVVerts, новые вершины инициализируются в [0.,0.,0.]

<mesh>.mesh TriMesh
Чтение этого свойства создает копию сетки, берущуюся после применения всех модификаторов, но перед применением пространственных деформаций, если таковые имеются. Изменение этого свойства устанавливает сетку в заданное значение TriMesh.
Вы можете использовать данное свойство совместно с методом copy() и свойством <node_or_baseobject>.mesh, для создания TriMesh значения из сеток объектов.

Основные методы
update <mesh> [ geometry:<boolean> ] [ topology:<boolean> ] [ normals:<boolean> ] -- mapped
Обновляет сетку. Метод необходимо вызывать всякий раз после редактирования сетки и перед примением к ней различных трансформаций. Три дополнительных ключевых параметра контролируют варианты обновления сетки.
Если параметр geometry: истинен, то стек геометрии перестраивается (список нормалей и ребер) и габаритный контейнер сетки становится недействительным. Если параметр topology: истинен, то данные о ребрах и границах (strip) будут перестроены.
Если истинен параметр normals:, то будут вычислены нормали граней.
По умолчанию все параметры истинны, так что обычный вызов функции update() приводит к полной реконструкции всех данных сетки.

attach <mesh> <node>
Метод аналогичен кнопке attach для Editable Mesh на панели Modify и позволяет вам конструировать сетку путем добавления к ней сществующих объектов. Метод извлекает сетку из объекта <node> (сперва конвертируя его в сетку при необходимости), добавляет его к сетке <mesh>, которая должна быть объектом Editable Mesh, и потом удаляет <node>.
Материалы и ID материалов объекта <node> внедряются в сетку, используя настройки по умолчанию для операции attach на панели Modify над объектом Editable Mesh. Данный метод неприменим к значениям TriMesh.

meshop.attach {<target_editable_mesh_node> | <target_mesh>} \
{<source_node> | <source_mesh>} \
targetNode:<node=unsupplied> \
sourceNode:<node=unsupplied> \
attachMat:<{#neither | #MatToID | #IDToMat}=#neither> \
condenseMat:<boolean=true> \
deleteSourceNode:<boolean=true>

Присоединяет исходную сетку к целевой сетке. Если цель или исходник задан как сетка а не объект, сетка присоединяется используя локальную СК и никакой коррекции материалов не производится. Чтобы данный факт обойти, в случае, если цель или исходник является сеткой, задаются соответствующие параметры targetNode или sourceNode и проверяется, если объект задан, то его трансформации и материал используются.
Если исходник или цель заданы как объекты, соответствующие параметры targetNode или sourceNode не проверяются.
Параметры attachMat и condenseMat аналогичны соответствующим настройкам attach для editable mesh.
Параметр condenseMat применим только в том случае, когда задан параметр attachMat:#IDToMat
Если параметр deleteSourceNode: не ложен и исходник был задан как объект или как сетка с установленным параметром sourceNode, то исходник после присоединения будет удален.

Примеры:
meshop.attach $.baseobject $sphere02 targetNode:$
meshop.attach $box01 $box02 attachMat:#IDToMat
condenseMat:true deleteSourceNode:false


Ну и в заключение приведу два фрагмента кода из справки MAXScript: запись данных сетки объекта в текстовый файл и чтение данных из файла с последующим построением сетки.

--ЗАПИСЬ
tmesh = snapshotAsMesh selection[1]
out_file = createfile ((GetDir #export)+"/testmesh.dat")
format "%,%\n" tmesh.numverts tmesh.numfaces to:out_file
for v = 1 to tmesh.numverts do
format "%," (getVert tmesh v) to:out_file
format "\n" to:out_file
for f = 1 to tmesh.numfaces do
format "%," (getFace tmesh f) to:out_file
close out_file

--ЧТЕНИЕ
vert_array = #()
face_array = #()
in_file = openFile ((GetDir #export)+"/testmesh.dat")
if in_file != undefined then
(
num_verts = readValue in_file
num_faces = readValue in_file
vert_array.count = num_verts
face_array.count = num_faces
for v = 1 to num_verts do vert_array[v] = (readValue in_file)
for f = 1 to num_faces do face_array[f] = (readValue in_file)
close in_file
new_mesh = mesh vertices:vert_array faces:face_array
)