суббота, 1 сентября 2007 г.

Методическое пособие "Введение в MAXScript". Часть 1.


  Предисловие.

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

  Методическое пособие содержит материал для самостоятельного изучения языка сценариев MAXScript. Цель пособия – научить пользователя самостоятельно расширять инструментарий 3D Studio Max.

  Уровень изложения рассчитан на людей, имеющих опыт работы с программой 3D Studio Max. Для более тщательного изучения материал сопровождается листингами с примерами программного кода. Также изложенная теория будет полезна преподавателям и студентам информационных специальностей.

Содержание:

Вступление
1. Понятие MAXScript
2. Первые шаги
3. Инструменты MAXScript
  3.1. Меню MAXScript
  3.2. Окно MAXScript Listener
  3.3. Окно редактора MAXScript
4. Синтаксис сценариев MAXScript
5. Основы программирования сценариев MAXScript
  5.1. Переменные
  5.2. Операторы
    5.2.1. Операторы присваивания
    5.2.2. Операторный приоритет
    5.2.3. Оператор If
    5.2.4. Оператор Case Of
    5.2.5. Оператор цикла For
  5.3. Функции
  5.4. Коллекции и массивы
  5.5. Создание функций
  5.6. Работа со строками
6. Инструменты для мыши

  Введение.


  В программе 3D Studio Max для художника предоставляется огромное количество различных инструментов, однако некоторые возможности, наверняка, не предусмотрены разработчиками. К счастью, данная проблема решена с помощью средства MAXScript, позволяющего добавить программе новые функции и возможности под конкретные запросы пользователя. Многие, кто работают в 3D Studio Max, даже не знают о существовании инструмента MAXScript. Это и объяснимо, инструмент специфичный и литературы для него не так много. Это и послужило поводом написания статьи о MAXScript.

  При изучении MAXScript проще будет тем, кто занимается программированием или хотя бы имеет какое-нибудь представление о нём. Но, не смотря на это, я постараюсь ознакомить Вас как с фундаментальными сведениями данного средства, так и с более сложными, но, на мой взгляд, интересными и полезными. Для этого необходимо иметь опыт работы с программой 3D Studio Max, знать его основы. Вам не обязательно читать абсолютно все разделы. Изучайте то, что считаете нужным и интересным для вас. Но листинги с примерами рекомендую не пропускать.

  Хотелось бы отметить, что в моих целях является не только помочь освоить MAXScript, но и показать возможности программирования в приложениях, рассчитанных на работу с трёхмерной графикой, в частности 3D Studio Max. Помимо теории я постарался разместить как можно больше листингов с аргументированными примерами сценариев для более тщательного изучения материала, по возможности старался, чтобы исходный текст был практичен и имел функциональную нагрузку. На практике материал будет усваиваться лучше, быстрее, а, главное, интересней. Итак, начнём.

  1. Понятие MAXScript

  Первый и вполне нормальный вопрос, возникающий у новичка – “Что же такое MAXScript?”. MAXScript – это встроенный в 3D Studio Max язык сценариев. Впервые он появился в 3-й версии 3ds max. Сложным языком его назвать трудно, но недооценивать его тоже нельзя. Впрочем, всё зависит от того, насколько сложная задача перед Вами стоит. Какие возможности открывает MAXScript, перечислить трудно ввиду своей обширности, часть из них Вы найдёте в разделах статьи. Всё сводится к автоматизации работы с объектами, анимацией, материалами, текстурами, эффектами и другими единицами 3ds max.

  Что касается поставленной Вами задачи перед инструментом MAXScript, стоит спросить себя, нужно ли к нему вообще обращаться. Иногда лучше лишний раз поискать нужный Вам модификатор или инструмент, чем писать плагин, выполняющий функции данного модификатора (инструмента). Думаю, вы со мной согласитесь: хорошее знание программы - это не только знание большинства её возможностей, но и рациональное использование этих возможностей.

  Имеет смысл затронуть понятие плагин (подключаемые приложения, отвечающие за конкретные задачи). Написать плагин для 3ds max можно с помощью MAXScript или С++. Если необходимо писать крупные сценарии с множеством различных операций, то C++ более предпочтительный, так как написанные на нем приложения работают быстрее. Явным преимуществом MAXScript является практически неограниченный и в свою очередь простой доступ к работе с 3ds max. В данной статье мы научимся писать плагины на MAXScript.

  Если говорить о принципах работы средства MAXScript, то тут аналогичная ситуация, как, к примеру, у макросов офисного пакета Microsoft (в частности, Microsoft Word, Microsoft Excel и т.д.): можно “записывать” и “воспроизводить” те или иные последовательности действий. Соответственно, для создания сценариев MAXScript также предусмотрено несколько инструментов, отвечающих за “запись” и “воспроизведение”, речь о которых пойдёт далее.


2. Первые шаги


  Давайте начнём не с нагрузки теорией, а с практики. Попробуем создать систему из нескольких примитивных объектов, имитирующую часы при помощи MAXScript. Сейчас наша задача – не просто создать часы, но и “оживить” механизм при помощи макроязыка. Предложенный пример может показать, насколько нестандартные задачи может решать инструмент MAXScript. Я не буду комментировать какие-либо фрагменты кода, заострять на чём-либо внимание, так как сейчас наша задача – просто ознакомиться с инструментом, понять принцип работы.

  Найдите в меню раздел MAXScript и щёлкните на New Script (рис. 1), появится текстовый редактор, в который необходимо ввести текст сценария (программный код), указанный в листинге 1.


Рис. 1. Щёлкните на New Script

Листинг 1. Создание механизма часов и их работы

rollout showtime "time" width:224 height:88
(
timer tmrSecond "Timer" pos:[63,79] width:24 height:24 interval:1000 active:false
button btnStart "Start" pos:[128,48] width:88 height:24
label lblTime "" pos:[40,8] width:160 height:24
label lbl5 "Time:" pos:[8,8] width:24 height:24
button btnStop "Stop" pos:[32,48] width:88 height:24

on tmrSecond tick do

select objects
max delete 

s = stringstream localtime 
seek s 11; table = readchars s 8
text size:50 text:table pos: [0,60,0]

seek s 11; hour = readchars s 2
seek s 14; minute = readchars s 2
seek s 17; second = readchars s 2

torus name: "watch" pos: [0,0,0] radius1: 250 segs: 12

--Создание секундных стрелок
ChamferCyl radius: 10 height: 10 sides: 15 fillet: 1 pos: [0, 0, 0] name: "cSecond"
ChamferBox length: 200 pos: [0, 100, 0] Width: 5 Height: 3 name: "bSecond"

$bSecond.parent = $cSecond
rotate $cSecond (angleaxis -(6 * second as integer) [0,0,1])

--Создание минутных стрелок
ChamferCyl radius: 10 height: 10 sides: 15 fillet: 1 pos: [0, 0, 10] name: "cMinute"
ChamferBox length: 150 pos: [0, 75, 10] Width: 5 Height: 3 name: "bMinute"
$bMinute.parent = $cMinute
rotate $cMinute (angleaxis -(6 * minute as integer) [0,0,1])

--Создание часовых стрелок
ChamferCyl radius: 10 height: 10 sides: 15 fillet: 1 pos: [0, 0, 20] name: "cHour"
ChamferBox length: 100 pos: [0, 50, 20] Width: 5 Height: 3 name: "bHour"
$bHour.parent = $cHour
rotate $cHour (angleaxis -(30 * hour as integer) [0,0,1])

select objects
$.material = meditMaterials[1]

lblTime.caption = localtime

)
on btnStart pressed do
(
meditMaterials[1].diffuse = color 288 0 0
select objects
max delete 

tmrSecond.active = true
)
on btnStop pressed do tmrSecond.active = false

)createdialog showtime width:244 height:88


В результате выполнения (<CTR+E> в окне редактора) введённого сценария появится форма time с двумя кнопками Start и Stop (рис. 2). Далее щелкните на Start, и вот Вам часы, показывающие реальное время (рис. 3). Можете теперь гордиться своим первым опытом работы в MAXScript. Поздравляю!

Рис. 2. Форма time

Рис. 3. Часы, созданные в MAXScript

3. Инструменты MAXScript

  Для работы с MAXScript нужно знать его инструментарий и уметь с ним обращаться. В данной главе будет изложен необходимый для этого материал.

3.1. Меню MAXScript

  Для работы с MAXScript часто потребуется вызывать его меню (рис. 4). Меню MAXScript содержит следующие команды: 

1. New Script (создать новый сценарий): открывает текстовый редактор для написания и редактирования сценария;
2. Open Script (открыть сценарий): открывает диалоговое окно Choose Editor File (Выбор файла), выбранный пользователем файл (расширения *.ms или *.mcr) открывается в окне редактора MAXScript;
3. Run Script (выполнить сценарий): открывает и сразу выполняет сценарий (горячие клавиши выполнения сценария в окне редактора – Ctrl+E);
4. MAXScript Listener (слушатель MAXScript): открывает окно для записи и выполнения команд, для вывода отчётов;
5. Macro Recorder (запись макроса): активирует или дезактивирует запись макроса;
6. Visual MAXScript Editor (редактор интерфейса): открывает инструмент для создания и расположения элементов управления;


Рис. 4. Меню MAXScript

  Итак, зная меню MAXScript, можно выделить три основные рабочие области: текстовый редактор, окно MAXScript Listener, окно Visual MAXScript Editor. В данной главе мы ознакомимся пока с первыми двумя рабочими областями, последняя будет разобрана чуть позже.

3.2. Окно MAXScript Listener

  Основная функция данного окна – это “общение” с программой 3D Studio Max при помощи команд MAXScript. В данном окне есть два текстовых поля: розовое и белое. Рассмотрим подробно, для чего они нужны. Использование большинства операций 3D Studio Max (перетаскивание объекта в сцене, изменение параметров, открытие окон и т.д.) сопровождается построчным выводом команд в розовом поле. Таким образом, можно узнать, как выглядит команда MAXScript для той или иной операции. Откройте окно MAXScript Listener и попробуйте создать в сцене сферу, в результате чего в розовом поле появится команда MAXScript для создания сферы. Теперь разберём нижнее текстовое поле. Оно позволяет получить отчёт выполненного сценария (вывод численных или текстовых значений, вывод текста об ошибках и т.д.). В обоих окнах можно самому вводить команды, выполнение которых происходит после нажатия <Enter>. Текстовые поля MAXScript Listener также расположены в нижним левом углу программы (рис. 5). Щелкнув в любом из полей правой кнопкой мыши, вы можете вызвать окно MAXScript Listener.


Рис. 5. Текстовые поля MAXScript Listener


  Каким же образом осуществляется “диалог” при помощи окна MAXScript Listener? Рассмотрим несколько примеров. Для начала попробуйте ввести какое-нибудь математическое выражение, после чего нажмите <Enter>. В результате MAXScript Listener выдаст Вам отчёт в нижнем поле (рис. 6). Кстати, после того как вы нажали на <Enter>, MAXScript сохранил результат в отведённую специально ячейку, в которой хранится только последний результат. К данной ячейке можно обратиться при помощи символа <?> (после ввода данного символа и нажатия <Enter> MAXScript Listener выведет последней сохранённый результат).


Рис. 6. Пример вычисления математических операций


  Давайте теперь поработаем с объектами с помощью окна MAXScript Listener. Создайте примитивный объект (например, сферу) и выберите его, затем введите в окне команду Showproperties $ (знак $ хранит в себе имя выбранного Вами объекта в сцене), выберите созданный Вами объект и нажмите на <Enter>. Если Вы всё сделали верно, ниже обнаружите список свойств объекта (рис.7).


Рис. 7. Свойства объекта Sphere 

  Теперь я Вам предлагаю создать сферу при помощи MAXScript. Что бы сделать это, необходимо знать команды для создания сферы. Поэтому создадим в сцене сферу вручную, скопируем получившуюся команду в розовом окне и откинув лишнее (ненужные свойства), выполним её, задав значения для радиуса, количества сегментов и положения (рис. 8). Чтобы создать объект со всеми заданными по умолчанию параметрами, достаточно вместо всех свойств написать <()>, например: sphere(), box(), plane() и т.д.


Рис. 8. Создание объекта Sphere при помощи макроязыка


  Как видите, я присвоил созданному мной объекту имя Earth, теперь я могу “обращаться” (обращение к любому объекту в сцене начинается со знака <gt;, затем следует имя объекта) к данному объекту, а именно, я могу в любой момент получить любое свойство или поменять свойство самому. Обращение к свойству объекта в сцене имеет следующий вид:


lt;имя объекта>.<название свойства>


  Чтобы уменьшить количество сегментов у сферы, к примеру, на 5, введите нижеуказанную строчку: 

$Earth.segs = $Earth.segs - 5 

  До этого были рассмотрены выражения из команд, входящих в состав MAXScript. Если же ввести, например, выражение hello there, он выдаст сообщение с ошибкой Type error (Ошибка ввода) (рис. 9). Это говорит о том, что MAXScript не знает подобных команд или выражений. Любое выражение в сценарии, которое не может быть выполнено в MAXScript влечет за собой оповещение об ошибки.


Рис. 9. Ошибка ввода

3.3. Окно редактора MAXScript

  Мы не будем ограничиваться “однострочным программированием”, ведь мы учимся писать сценарии. В окне MAXScript Listener писать сценарии мы не целесообразно, поскольку для этого существует специально отведенное окно редактора, речь о котором пойдет в этом пункте. А окно MAXScript Listener будем использовать, в основном, в трех случаях: для выполнения простых однострочных команд, для анализа отчёта и отладки сценариев, для получения команд некоторых операций 3D Studio Max.

  Окно редактора MAXScript – это текстовый редактор для редактирования файлов сценария. В нём можно открывать любой текстовый файл. В редакторе MAXScript, выберете команду MAXScript->New Script, в результате чего откроется область для редактирования сценариев (рис. 10).

Риc. 10. Редактор MAXScript

  Если есть необходимость проверить фрагмент кода в редакторе, выделите его, после чего нажмите <Shift+Enter> (или на <Enter> на цифровой клавиатуре). Выбранный фрагмент сценария будет автоматически скопирован в окно MAXScript Listener и, непосредственно, выполнен.

  Как Вы уже заметили редактор MAXScript и окно MAXScript Listener схожи по функциональности, не удивительно, что и большинство команд в меню совпадают. Так, например, команды меню File, Search и Help совпадают, за исключением команды Evaluate All (выполнить всё). Данная команда предназначена для выполнения всего сценария, а не одной строчки, как это делается в окне MAXScript Listener. Команды меню Edit предназначены для текстового редактирования, так что думаю, на этом останавливаться не буду, за исключением команд New Rollout и Edit Rollout (о них речь пойдёт в следующих разделах).

4. Синтаксис сценариев MAXScrip

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

R = 7; S = R + 5

  Во-вторых, многие команды имеют “рамки”, хранящие содержимое (тело), над которым работают данные команды. Эти “рамки” можно установить символами: <(> - для открытия, <)> - для закрытия. Чтобы понять значимость обособления, рассмотрим следующую задачу: необходимо вывести в окне MAXScript Listener квадраты чисел от одного до десяти. Что бы прогнать все необходимые нам значения, потребуется оператор цикла. На каждом этапе нужно вычислить квадрат i-го значения и вывести его в окне MAXScript Listener, т.е. данные две операции должны быть внутри цикла, что делается обособлением:

for i=1 to 10 do (k=i^2; print k as string)

  После выполнения вышеуказанной строчки, получили то, что и требовалось от поставленной нами задачи. Теперь рассмотрим тот же сценарий, но без обособления:

for i=1 to 10 do k=i^2; print k as string

  В результате в окне MAXScript Listener выведется только одно значение 100. Дело в том, что цикл работал только с математической операцией, а операция вывода произошла после окончания работы цикла и вывела последнее значение, заложенное в переменной k. 

  При написании того или иного сценария, необходимо учитывать то, что вы можете ни раз обратиться к нему снова, вспомнив о некоторых допустимых просчётах. Если код громоздкий, то помимо исправления сценария, необходимо сначала потратить время на поиск ошибки. Во избежание этой проблемы полезно аргументировать некоторые фрагменты сценария, и сделать это можно примечаниями. Их использование значительно облегчит ориентирование в больших сценариях. Более того с их помощью, можно временно закомментировать какой-либо фрагмент кода. Обозначение, с которого должно начинаться примечание – <-->. Например:

render frame:15 –- визуализация 15-го кадра 

  Данное обозначение рассчитано на выделения примечанием целой строки. Если необходимо обособить, допустим, только часть строки, для этого существуют обозначения: /* - для открытия, */ - для закрытия. Текст примечаний идентифицируется зелёным цветом. 

  В синтаксисе сценариев также важно учитывать следующее: прописные и строчные символы воспринимаются одинаково (слова SO, so, So для MAXScript означает одно и то же). 

  В языке сценариев применяется цветовое выделение программного кода. В состав входят 4 цвета: зелёным выделяется примечания, синим – операторы языка сценариев, коричневым – текст, идущий в кавычках и, соответственно, чёрным – всё остальное.


5. Основы программирования сценариев MAXScript

  В данном разделе будет изложен основной материал по программированию сценариев MAXScript: процедуры, выражения, переменные и т.д. В дебри лезть мы не будем, поскольку это уже является задачей целой книги, а не статьи. Изучив изложенный по основам программирования материал, у вас будет некий “фундамент” знаний MAXScript. Без подобного “фундамента”, поверьте, писать сценарии не имеет никакого смысла. Если Вы занимаетесь программированием, Вы, наверняка, встретите знакомые операторы, функции и т.д., что не удивительно, ибо MAXScript – это тот же язык программирования, только рассчитанный на решение несколько иного спектра задач.

5.1. Переменные и типы данных

  В процессе программирования Вы неоднократно встречаетесь с таким понятием, как переменная. Переменная (variable) – это ячейка памяти, предоставляемая тем или иным языком программирования (в нашем случае языком сценариев MAXScript) для хранения информации.

  В MAXScript существует несколько типов переменных: Integer (хранит целые числа), Float (хранит числа с плавающей точкой), String (хранит текстовую информацию). Чтобы ваш программный код был приятно читабельным и разборчивым, рекомендую, чтобы имя, объявляемое Вами переменной, начиналось с префикса, состоящего из 1-4 букв, который будет определять принадлежность сохраняемых данных к определённому типу. Вот некоторые из вариантов префиксов: bln отвечает за тип Boolean (булевский), int отвечает за тип Integer (целое число), str – за тип String (строка), obj – за тип Object (объект) и т.д. Использование префиксов целесообразно в случае больших сценариев, когда используется более 10 переменных – будет легче ориентироваться в типах переменных.

  В работе с переменными существуют следующие ограничения:
1. Имя переменной не должно быть ключевым словом (ключевым или служебным словами называются слова, используемые для работы с какими-либо операторами, относящиеся к синтаксису MAXScript);
2. В имени не должно быть точек, запятых и других символов;
3. В состав имени не должны входить русские буквы;
4. Имя переменной не должно совпадать с именами констант (это может быть число π (3.14159), синтаксис которого pi или основание натурального логарифма e (2.71828) и т.д.);
5. Имя переменно не должно начинаться с цифр.

  Но перед тем как работать с переменными, их необходимо объявить (создать ячейку и дать ей имя). Объявляется переменная следующим образом: сначала идёт присвоенное вами имя переменной, затем знаком <=> присваивается некоторое значение, после чего идут служебное слово As и тип переменной. Нижеуказанный листинг кода говорит о том, что мы объявляем переменную strCount типа String и присваиваем ему значение 15 (сли мы не укажем тип переменной, то переменная будет хранить число, а не текст):

strCount = 15 as String

  Говоря о типах данных, мы затронули текстовую и числовую информацию, однако этим перечень типов не ограничивается. Следующий тип данных характеризуется как множество 2-3 численных значений Point2 (2D-точка), Point3 (3D-точка). Явным примером данного типа информации является положение объекта в сцене (координаты X, Y, Z). На рисунке 11 представлен пример работы с данными типа Point3, проследите результаты выполнения в окне MAXScript Listener.


Рис. 11. Пример использования типа данных Point3

  Последний тип данных должен быть вам, наверняка, знаком. Любой созданный вами объект в сцене также относится к определённому типу данных, только более сложному в плане своей структуры, так как содержит множество других типов данных (свойства объекта). Объект, например, Sphere – это один из сложных типов данных, содержащий множество свойств: Name типа String, Radius типа Float, Segments типа Integer, Position типа Point3 и т.д. Изучая MAXScript, полезно воспринимать объект в сцене, как отдельную структуру данных, а не изображение в сцене.

5.2. Операторы

  Операторы (operator) – это выражения, заставляющие провести ту или иную работу с переменной, объектом и т.д. Многие операторы Вам уже известны: математические (сложение, вычитание, отрицание, умножение, деление, возведение в степень), логические («равно», «больше», «меньше», «больше или равно», «меньше или равно» «или», «и»). Напомню, что логические операторы при сравнении двух значений возвращают или истина (true) или ложь (false). Но это далеко не все операторы, другие мы разберём в следующих пунктах.

5.2.1. Операторы присваивания

  Пожалуй, один из самых простых операторов – оператор присваивания. Что касается, назначения, так название говорит само за себя: присваивать значения. Знаком присваивания, как Вы уже догадались, является <=>. В нижеуказанном примере переменной r присваивается значение 15, после чего радиусу объекта sphere01 устанавливается значение переменной r, т.е. 15.

r = 15; $sphere01.radius = r

  А здесь случай аналогичен, только мы работаем уже с текстовой информацией:

n = "My sphere"; $sphere01.name = n

  В этих примерах свойствам объекта sphere01 присваиваются значения переменных r и n, можно сделать наоборот: присвоить переменным значения свойств объекта. Например:

s = $sphere01.segs -- количество сегментов

  Ранее было сказано, что любой объект в сцене относится к конкретному типу данных. Поэтому любой объект в сцене можно заложить в ячейку, например:

obj = $ -- сохранение в ячейке obj выбранного в сцене объекта

5.2.2. Операторный приоритет

  Вам знакома шутка “Сколько будет два плюс два, и умножить на два”? Не знаю как Вы, а я и многие мои знакомые ловились на ней, отвечая 8. Ясно, что первой выполняется операция умножения, затем только сложение, и правильный ответ тогда 6. Я не зря вспомнил эту шутку, так как она яркий тому пример, когда программисты совершают ошибку в записи математического выражения. Операторный приоритет (operator precedence) является одной из основных причин многочисленных ошибок в программном коде. Рассмотрим два варианта вычисления среднего значения (листинг 2.1 и листинг 2.2):

Листинг 2.1. Пример с ошибкой
num1 = 2; num2 = 3
average = num1 + num2/2 as float

Листинг 2.2. Правильный вариант
num1 = 2; num2 = 3
average = (num1 + num2)/2 as float

  В первом варианте пользователь думает, что MAXScript будет следовать его логике и тем самым выдаст результат 2.5, но на самом деле MAXScript в первую очередь вычислит частное значения num2 от 2 и только потом к нему прибавит значение переменной num1 (результат 3.5). Решим эту проблему, обособив операцию сложения скобками, тем самым, дав ей первый приоритет выполнения (листинг 2.2). Ответ тогда будет верным 2.5. И мой Вам совет: если не помните приоритет операции, смело обособляйте её скобками, не ошибётесь.

5.2.3. Оператор If

  Иногда необходимо, что бы некоторые операции проводились только при определённых условиях. За данную “необходимость” отвечает оператор условия If, полная запись которого выглядит следующим образом:
If <условие> Then <команда> Else <выражение, выполняемое в противном случае>

  Если не требуется указывать действия, выполняемые в противном случае, можно использовать следующую запись оператора if:
If <условие> Do <команда>

  На рисунке 12 показан пример использования данного оператора и на рисунке 13 – результат. 


Рис. 12. Использование оператора If


Рис. 13. Результат кода

  В данном разделе хотелось бы заострить ваше внимание на одном важном нюансе. Не путайте оператор присваивания <=> с логическим оператором сравнения <==>. Соответственно, если в разделе <условие> оператора if вы сравниваете два значения, то используется <==>, а не <=>.

5.2.4. Оператор Case Of

  Что, если условий несколько? Использование оператора условия If допустимо, но не рационально. На этот случай предусмотрен оператор Case Of. Ниже приведена структура конструкции Case Of:

Case <переменная> Of 
(
<значение 1>: <операция 1>
<значение 2>: <операция 2>
)

5.2.5. Оператор цикла For

  Следующий немаловажный оператор – оператор цикла (loop) For. Создание циклов используется для выполнения повторяющихся действий. Его иногда называют цикл со счётчиком. Синтаксис оператора For (указания шага не обязательно, по умолчанию шаг равен единице) имеет следующий вид:

For <переменная> = <начальное значение> To <конечное значение> By <шаг> do <команда> 

  На рисунке 14 изображён листинг с кодом, результатом которого является синусоида из сфер радиусом 5 в плоскости Top (рис. 15).

Рис. 14. Использование оператора For

Рис. 15. Результат кода

  Рассмотрим другой пример. На рисунке 16 показан фрагмент кода, вычисляющего объём пространства, занимаемого только сферами по формуле 4/3 π∑_(i=1)^N▒R^3 .Перед тем как его запускать, создайте несколько сфер. При выполнении данного кода появится диалоговое окно с результатом (рис. 16). Заметьте, запись оператора несколько отличается от предыдущего варианта. Его синтаксис выглядит следующим образом:

For <переменная> In <массив/коллекция> By <шаг> do <команда> 

  Сейчас достаточно знать, что массив или коллекция – это множества объектов различных типов, подробнее эти понятия будут разобраны в следующих разделах.


Рис. 16. Код вычисления объёма пространства, занимаемого сферами.

  Объём вычисляется с учётом того, что сферы не пересекаются, иначе занимаемый ими объём не будет суммой объёмов каждой сферы (может быть такой вариант, что сферы совпадают или пересекаются). В общем, задача усложняется математически, придётся поднапрячь мозги и вспомнить стереометрию. Для нас это не важно, главное, что Вы увидели оператор For на деле и имеете какое-то представление о нём. Теперь, думаю, нетрудно понять, как устроен инструмент 3ds max Array (рис. 17).


Рис. 17. Окно инструмента Array.

  В данном примере были использованы диалоговое окно и работа со строками. О строках будет сказано далее. Что касается диалоговых окон, для их описания я не стал отдельно создавать раздел. Хочу только сказать, что любая программа, написанная программистом должна информировать или предупреждать о действиях пользователя. Для этого существуют следующие типы диалоговых окон:

Простое сообщение:
messageBox <текст сообщения> title: <название сообщения>

Сообщение с выбором да/нет:
queryBox <текст сообщения> title: <название сообщения>

Сообщение с выбором да/нет/отмена:
yesNoCancelBox <текст сообщения> title: <название сообщения>

5.3. Функции

  Функция (function) – это выражение, возвращающее некоторое значение по заданному аргументу (аргументов может быть несколько, и типы данных могут быть разными). Имейте ввиду, в MAXScript понятия функции и метода являются синонимами. В инвентарь MAXScript входит немало различных функций. Это могут быть тригонометрические функции, функции преобразований и др. Некоторые функции могут заменить операторы. Например, выражение sqrt(x) можно записать иным образом, используя при этом математический оператор, и выражение запишется x^0.5. Более того, программисту предоставляется возможность самому создавать функции. В таблице 1 приведены некоторые функции для работы с числами.

Таблица 1. Перечень функций
Запись в MAXScript Функция
sin(x), cos(x), tan(x) Вычисление синуса, косинуса, тангенса угла
asin(x), acos(x), atan(x) Вычисление арксинуса, арккосинуса, арктангенса угла 
radToDeg(x) Преобразование радианов в градусы
degToRad(x) Преобразование градусов в радианы
ceil(x) Округление сверху
floor(x) Округление снизу 
sqrt(x) Вычисление квадратного корня числа
mod x y Вычисление остатка от деления x на y
pow x y Возведение числа x в степень y


5.4. Коллекции и массивы
  Массив (array) - это группа переменных. Обращение к тому или иному элементу массива осуществляется за счёт индекса (порядкового номера). Объявление массива может выгладить, например, так:

Day = #(“Sunday”, “Monday”, “Tuesday”, “Thursday”, “Wednesday”, “Friday”, “Saturday”) 

  Тогда элемент массива Day[3], будет иметь значение “Tuesday”. Отличительная особенность MAXScript от остальных языков программирования – это возможность хранения, различных типов переменных в одном массиве. Ниже объявлен массив, в состав которого входят элементы, хранящие текстовую информацию и числовую:

A = #(“Text”, 25, 46, “String”)

  Для добавления нового элемента в массив используется ключевое слово Append. Синтаксис добавления имеет следующий вид:

Append <массив> <элемент>

  Продолжая говорить о массивах, вспомним немного математики. Массиву присуще такое свойство, как размерность. Так до сей момента речь шла об одномерных массивах, так как за индексацию отвечал всего один параметр. В общем же случае массив может быть n-мерным, т.е. возможно n независимых параметров. Двумерный массив, у которого параметры прогоняют значения от 1-го до N и M соответственно – это матрица NxM, и количество элементов равно N*M. Важно понимать эту связь, так как далее мы будем ею неоднократно оперировать.

  Понятие коллекция (collection) аналогична понятию массива, только коллекции предназначены для хранения объектов. В 3D Studio Max существует большое количество различных типов объектов (источники света (lights), камеры (cameras), помощники (helpers) и т.д.). Все эти типы, своего рода, - тоже коллекции. Их можно обозначать за переменные. При вводе данного кода, будут выбраны все возможные типы камер в сцене:

A = cameras; select A 

  Для работы с коллекциями объектов существует полезный символ <*>. Данный символ может хранить в себе отдельную часть имени. Например, чтобы создать коллекцию A из всех объектов в сцене, необходимо ввести следующую строку:

A = $*

  В вышеуказанном примере символом * заменяются все имена объектов в сцене. Теперь создайте несколько объектов sphere и box, при этом, не называя их. Напомню, их стандартные имена будут начинаться с “sphere” – для объектов sphere и “box” – для объектов box, а заканчиваться номерами (01, 02 и т.д.). Рассмотрим различные варианты создания коллекций:

1. Создать коллекцию sph только из объектов sphere:
sph = $sphere*

2. Создать коллекцию bx только их объектов box:
bx = $box*

3. Создать коллекцию только из объектов, чьи имена заканчиваются на “01”:
u = $*01

5.5. Создание функций
  Рано или поздно в процессе написания сценариев у вас появится необходимость, чтобы определенный фрагмент кода, отвечающий за конкретную задачу, использовался в нескольких местах сценария. В таких ситуациях рационально один раз написать сценарий для выполнения задачи, после чего обращаться к нему через определенную конструкцию. Что бы сделать это, MAXScript позволяет пользователю создать собственную функцию. Синтаксис создания функции выглядит следующим образом: 

function <имя функции> <обрабатываемые переменные> = <операции, выполняемые функцией>

  Для обращения к созданной функции используется следующий синтаксис:

<значение> = <имя функции> <аргументы функции> 

  В качестве примера напишем несложную функцию одного аргумента для вычисления сигнатуры, знака математического выражения (листинг 3).

Листинг 3. Функция сигнатуры.
function Sgn number =
(
local t = 0

if number > 0 do t = 1
if number < 0 do t = -1
if number == 0 do t = 0

t -- выводимое функцией значение
)

  Аргументами функции не обязательно должны быть только численная или текстовая информация, аргументами могут быть и объекты. Создадим функцию для вычисления угла, вершинами которого являются любые 3 объекта в сцене (переменные функции будут хранить имена объектов). Этапы работы функции: считываются координаты трёх тел, находятся расстояния, затем при помощи теоремы косинусов вычисляется угол. 

  В листинге 2.1 приведён сценарий функции вычисления угла ABC и на рисунке 18 приведён пример вычисления угла, вершинами которого являются три сферы. Расстояния мы будем находить функцией distance (в листинге 4.1 показана структура работы с данной функцией), данная функция значительно сокращает и упрощает программный код. Чтобы ощутить разницу, в листинге 4.2 показан сценарий, выполняющий те же самые операции, но без использования оператора distance. Согласитесь, первый вариант выглядит куда рациональней. Говорю я об этом потому, что бы вы не торопились писать функцию, прежде проверьте, имеется ли она в наличии MAXScript.

Листинг 4.1. Вычисление угла. Вариант 1
function corner A B C =
(
AC = distance A.pos C.pos
BC = distance B.pos C.pos
AB = distance A.pos B.pos 

acos((BC^2+AB^2-AC^2)/(2*AB*BC))-- угол ABC
)

Листинг 4.2. Вычисление угла. Вариант 2
function corner A B C =
local x1, y1, z1, x2, y2, z2, x3, y3, z3 
x1 = A.pos.x; y1 = A.pos.y; z1 = A.pos.z
x2 = B.pos.x; y2 = B.pos.y; z2 = B.pos.z
x3 = C.pos.x; y3 = C.pos.y; z3 = C.pos.z

AC = sqrt((x3-x1)^2+(y3-y1)^2+(z3-z1)^2)
BC = sqrt((x3-x2)^2+(y3-y2)^2+(z3-z2)^2)
AB = sqrt((x2-x1)^2+(y2-y1)^2+(z2-z1)^2)

acos((BC^2+AB^2-AC^2)/(2*AB*BC))-- угол ABC
)


Рис. 18. Результат вычисления угла

  После того, как мы создали функцию, можно к ней обращаться. Убедитесь в этом сами. Введите в розовом текстовом поле название функции corner и имена любых трёх объектов, находящихся в сцене. Нажав на <Enter>, программа выдаст результат.
Создавая собственные функции, вы имеете ряд преимуществ. Во-первых, так как написанная вами функция есть отдельный фрагмент кода, его можно проверить отдельно, при этом не изменяя текста сценария, где к данной функции есть обращение. Во-вторых, использование функций не загромождает текст сценария лишними объемами текста. В-третьих, существует вероятность, что написанная вами функция может понадобиться в других сценариях. Исходя из этих соображению, рекомендую вам для крупных задач писать функции.

5.6. Работа со строками
  Разработчики MAXScript практически ни в чем не ограничили пользователя в работе с переменными, в том числе и строковыми. Особенно часто приходится обращаться к строкам в работе с файлами (сохранение, открытие, редактирование). Для работы со строками в MAXScript существует немало различных операций, мы разберём лишь основные. У любой строки существует одно единственное свойство - count (количество символов с учетом пробелов). С помощью этого свойства можно, например, узнать количество символов в имени выбранного объекта в сцене:

s=$.name; n=s.count

  Что бы преобразовать переменную, например, с численным значением, в строковую, потребуется следующая конструкция (было использовано в п.5.2.5 рис. 14):

<имя перемееной> as string

  Не воспринимайте строку, как единое целое. Любая строка – это некоторое упорядоченное множество символов, проще говоря, строка – это массив, элементами которого являются символы, и многие операции над строками в MAXScript те же, что и у массивов.

Комментариев нет:

Отправить комментарий