на каком языке написан 3ds max
Настоящее программирование для гуманитариев с нуля в… 3DS Max
статья расcчитана прежде всего на «гуманитариев».
Исполняемая среда и
Почему 3DS Max?
Предлагаю немного необычный, но действенный, на мой взгляд способ знакомства с практическим программированием для “гуманитариев».
Статья будет очень простой и доступной но для основательности попробуем начать с “истории анатомии» :
Что есть программирование?
Инструкций кому?
— В конечном итоге процессору компьютера или смартфона, т.е. физическому, реальному устройству.
Теоретически все верно, но процессор понимает только машинный код, фактически поток цифр или, если уж совсем анатомично, — электрических сигналов “высокого” (например 3 вольта) и “низкого” (1 вольта) напряжения, которое “понимается» схемотехникой процессора как нули и единицы, бинарные сигналы.
В физику полупроводников лезть не станем, но кому интересно — гуглите “полупроводники и логические элементы» )
Ничто не мешает реализовать и “десятинарные” сигналы и десятичную математику но это громоздко и не экономично. Хотя в телекоммуникациях очень много именно “троичных» элементов и математики.
Итак самая настоящая программа это включение и выключение сигналов в электрической цепи процессора, полвека назад только так и было и инженеры буквально паяли свои “программы» из элементарных логических элементов на плате и припаивали к “мэйнфрейму», запускали выполнение и потом отпаивали уступая место следующему “программисту».
Мы и сейчас “припаиваем» оперативную память, видеокарту или жесткий диск, да даже флэшку к своим компьютерам, но благодаря “дядьке Фон Нейману” делаем это без паяльника.
Ища более продуктивные пути взаимодействия с компьютером люди придумали сперва перфокарты а потом и просто доску с ключами-тумблерами “keyboard” для ввода данных в компьютер.
Но главная проблема — непонятность машинных кодов для человека!
Коды решили заменить буквенными аббревиатурами add, mov и т.д. Так появился первый язык программирования — Ассемблер. Этот язык умел только «мычать односложными звуками» с точки зрения человека, но это уже было понятнее чем “язык жестов цифр”.
Такая “замена» реального явления — чем-то другим, называется “абстрагирование». Абстрагирование, использование “абстракций”. Когда древний египтянин подсчитывал урожай своего региона то брал глиняную табличку и обходя поля отмечал каждые десять мешков зерна — одной черточкой в табличке.
Абстрагирование приносит “облегчение» вам не надо держать в голове колонки шестнадцатеричных чисел машинных кодов, думая “вот это вот, это число или код команды?”
И навык абстрагирования, не какого-то “абстрактного мышления», а умения выявить характерные, применимые с точки зрения задачи, черты и представить (кодировать) их в некоем более понятном виде — куда более важный и полезный навык чем, например, “математический склад ума”.
Например именно абстрактный анализ позволяет ясно увидеть ключевой недостаток ООП — практик: подталкивание к бесконтрольному порождению все новых сущностей.
Но вернемся к теме статьи.
Итак все это время программы писались “для процессора» то-есть без знания схемотехники процессора для которого вы пишите программу вы не могли быть программистом, с тех пор пошла легенда о том что программист это физик-математик-марсианин.
Задачи далеких от айти сфер, которые должны были решать программы очень мало походили на схемотехнику процессора и поэтому на ассемблере стали писать новые языки программирования. Все более “предметные”, близкие человеческим категориям мышления, программирование на этих языках уже не требовало знания устройства процессора и за это их называли “высокоуровневыми».
Под “уровнем» подразумевают степень абстрагированности от процессора.
Так в Ассемблер вы буквально оперируете регистрами процессора, в языке Си это вовсе не обязательно но вы сами “управляете памятью” компьютера решая в какой ячейке памяти какая переменная храниться, а в Джава прямого доступа к памяти у вас вообще нет.
Одни и те-же нули и единицы, благодаря абстрагированию становятся для музыкантов — нотами, а для художников — оттенками цвета.
Но если, благодаря абстрагированию, мы больше не пишем прграмм «для процессора», то для кого мы их пишем?
Виртуальные абстракции процессора так и называют “виртуальные машины”, например “виртуальная машина джава”.
Это программа которая с одной стороны “знает» все о процессоре и памяти компьютера на котором работает, а с другой позволяет общаться с собой человеку на куда более человечном языке, тот же джава.
Забегая вперед, скажу, что наиболее совершенной и всеобъемлющей средой сегодня конечно же является WEB. Только в среде WEB вы сможете написать и сайт и игру и десктопное приложение и практически все, что можно представить, за исключением разве что драйверов устройств.
При этом WEB остается максимально доступным и демократичным и развивается наиболее интенсивно и полноценно.
Итак мы твердо поняли, что программирование это в первую очередь не язык а исполняемая среда (которая к слову, может понимать несколько языков).
Исполняемая среда 3DS Max
Если вы до сих пор, при всем желании, не программист, то скорее всего у вас, как и у меня — не очень хорошо с абстрактным мышлением, типичные примеры для вас не достаточно наглядны а алгоритм “решение квадратного уравнения” вгоняет в сон.
3DS Max это наглядная среда, вы буквально видите со всех сторон и во времени что создаете и это исключительно эффективно для людей с “не техническим восприятием».
Что из себя представляет “исполняемая среда”? — Это программа, в которую встроен свой язык программирования и которая позволяет с его помощью делать то для чего она предназначена.
Почти все крупные программные пакеты сегодня представляют из себя “исполняемую среду» от ворда до фотошопа. То-есть сегодня и музыкант и художник могут и должны программировать в своей основной деятельности получая выгоду от программного подхода к своей работе!
Итак 3DS Max это программная среда для создания трехмерных компьютерных сцен, объектов, миров. Какой же язык она поддерживает?
На самом деле не один а сразу два языка: MaxScript и Python.
Я немного знаю Python но опыта в 3DS Max на нем у меня практически нет, так что я буду говорить о MaxScript.
Этот язык хорош тем что практически младший брат основного языка WEB — Javascript!
О том какой язык лучше человечество спорит все время их существования, я лишь скажу что для новичка правильнее начинать с языков с динамической типизацией, что бы это ни значило )
MaxScript как раз такой язык. В двух словах — переменные в динамических языках “не имеют типа», то-есть вы можете хранить в любой переменной любой тип данных (число, текст, трехмерный объект и т.п.)
Услышав ООП, “объектно ориентированное программирование», “классы”, “наследование», “паттерны» и т.п. — воспринимайте это как программисты ООП воспринимают “регистры процессора» — “некая тайная данность, в которую нинада лезть” )
Теоретическое понимание ООП и классов это прекрасно и необходимо, но не более!
MaxScript
Чтобы программировать в некоей исполняемой среде — нужна эта самая среда!
3DS Max — очень дорогая программа, но вы можете получить ученическую лицензию на три года совершенно бесплатно просто указав при регистрации на сайте автодеск что вы ученик. Я не буду вдаваться в юридические нюансы, скажу только что никакой проверки степени вашего ученичества автодеск не делает и вы можете каждые три года получать новую лицензию на очередную версию 3DS Max (и десятков других ее продуктов)
Такая лицензия не годится для коммерческого использования но мы тут учимся.
Итак вы зарегистрировались, скачали и установили 3DS Max.
Запустите его и в меню Scripting выберите Script Editor
Script Editor это простенький редактор в котором можно писать и выполнять программы на MaxScript для 3DS Max.
Программа записывается построчно, элементом программы является одна законченная команда исполняемой среде 3DS Max а значит мы можем просто “поговорить” с 3DS Max «короткими фразами» в одну команду.
Это одно из важных преимуществ этого метода обучения! Возможность “просто початиться» без необходимости сразу писать «целые письма» программ.
Чтобы открыть такое окно общения с 3DS Max нажмите F11
В этом окне есть две половинки верхняя — розовая и нижняя — белая я привык писать в белой, нижней.
Кликните там мышкой и напишите… Что!?
Как и с человеком, общение с исполняемой средой (ИС) нужно вести на понятном ей языке о понятных ей вещах. Каждая ИС создана для работы с какими-то конкретными категориями которые называют “типы данных». ИС для музыки будет понимать категории нот и интервалов а 3DS Max создана для трехмерной графики и понимает все, что касается трехмерного пространства, векторов, матриц, кватернионов, текстур и полигонов, а также десятков объектов уже реализованных в ней.
К слову говоря есть типы данных понятные всем средам, как улыбка понятна всем людям на планете )
Такие типы данных называют базовыми: текст, строка, число и т.п.
«Строка и в Африке строка»
Традиционно первой программой новичка становится “Привет мир!”
Хотя я бы предложил в контексте “общения со средой» поздороваться с ней самой, для чего введите :
Print “привет тридэмакс!” и обязательно нажмите в конце клавишу “enter”
Первый момент: если вы “пишете текст» то вы используете “строковый тип данных». Такой тип всегда заключают в кавычки, это справедливо практически для всех языков программирования и для всех исполняемых сред!
Print это известная исполняемой среде макса команда, отправляющая следующую за ней строку в “консоль». Консолью называют то самое окошко в которое вы вводите команды ИС.
После нажатия “ввод» последует ответ от исполняемой среды (3DS Max в данном случае). Ответ может быть синим или красным, синий означает “я тебя понял и выполнение твоей команды прошло успешно», красный — “не понял тебя» или “при выполнении что-то пошло не так”
В жизни мы испытываем настороженность к ошибкам как явлению, но на самом деле ошибки это неизбежные спутники на пути к опыту. Постарайтесь как можно быстрее избавиться от психологического неприятия факта ошибки и воспринимать его как разновидность задач.
просто введите:
Print хи-хи, играем с ошибками!
Окно макс-скрипт-листнер выдаст красный ответ об обнаружении ошибки:
Как вы думаете в чем заключается обнаруженная ошибка?
Писать вывод в консоль текстовых сообщений это основной базовый навык программиста!
Помните мы не учим тридэмакс и даже не “программирование в тридэмакс” мы изучаем программирование вообще и нам важно отмечать общие черты характерные для всех исполняемых сред.
Создавая программу или исследуя чужую вы будете то и дело вставлять такие текстовые выводы значений переменных и результатов действий, чтобы во время исполнения программы видеть как и с каким результатом выполняются ее шаги.
Но все это остается “программированием для программирования». Важно помнить, что программируете вы для решения конкретной задачи которая лежит вне области самого программирования: “написать музыку», “построить дом”, “создать игру”.
Программирование само по себе очень увлекательно и завораживающе, оно может легко поглотить всё ваше время и внимание которое вы будете тратить на бесконечные знакомства со все новыми инструментами и технологиями, приемами и т.п.
Легко поддаться искушению пренебречь конечной целью в угоду “красоты/чистоты кода», “совершенства инструмента» и т.п. Забывая о собственно творчестве и проводя дни в жарких спорах о том чье мнение правильнее и какая технология лучше.
Давайте попробуем заставить тридэмакс выполнить что-то по его прямому назначению, “привет мир!” в трехмерной графике — это создать кубик, введите в окне листнера:
Закройте окно MAXScript Listener (вы всегда можете его открыть нажав F11) и полюбуйтесь на ваш результат :
Теперь вызовите окно MAXScript Listener (F11) и введите:
Тридэмакс умеет создавать не только кубики но и чайники!
Беда только что чайник “съел» наш кубик который прекрасно сошел бы за стол.
То-есть нам нужно поднять чайник по вертикальной оси (в тридэмакс это ось Z) на высоту кубика.
И тут мы сталкиваемся с одной из самых базовых задач в современном программировании (программировании исполняемых сред): обращение к объекту!
“Програмными объектами” называют составляющие программу предметные сущности, объекты представляют из себя “экземпляры» типов данных, помните?
“Текст”, “Строка», “Число» и т.д.
Типы данных иначе называют “классами» хоть нам это пока совершенно не важно. Важно то, что создать в любой программе можно только экземпляр известного исполняемой среде типа данных.
Тридэмакс имеет тип данных “чайники», “кубики” и дает вам возможность пораждать экземпляры этих типов, каждый экземпляр чайника отличается от самого типа “чайник” (Teapot) тем, что имеет имя и может быть отображен в трехмерном пространстве сцены. Имя указывается в выводе при создании объекта, обратите внимание:
Символ доллара и следующее за ним слово обозначают тип данных: “Box”, “Teapot” и т.д.
А слово следующее после двоеточия — это собственное имя созданного экземпляра этого типа данных: Box001, Teapot001
Чтобы “обратиться к объекту” нужно ввести знак доллара и сразу после него собственное имя этого объекта:
При этом тридэмакс радостно выведет вам указанный объект в консоль.
Свойства это предметные атрибуты объекта. Собственно говоря программирование это во многом и есть создание объектов, обращение к ним и изменение их свойств.
Запомните эту мысль она так же справедлива и при создании сайтов и игр и любом другом прикладном программировании сегодня!
Тридэмакс позволяет просмотреть все свойства объекта с помощью команды show
Но узнать о свойствах всегда можно из документации исполняемой среды изучение документации это 80% вашего обучения реальному прграммированию. Знание языка программирования как такового ровным счетом ничего не дает вам в части знания исполняемой среды. Как знание английского языка не означает знания английской литературы или микробиологии.
Это тоже важный момент в понимании современного ремесла программирования!
Вы можете прекрасно владеть JavaScript но совершенно не знать библиотеку jQuery или React или не знать структуру веб-документа, его объекты и их свойства а для создания сайта или приложения нужно именно знание «предметной области» той среды в которой вы работаете.
Итак давайте введем
Мы видим множество имеющихся у объекта Box001 параметров — свойств.
Одни из них “только для чтения” другие можно изменять.
Обратимся теперь к свойству height объекта Box001:
Как видите высота кубика была равна 25
За положение объектов по оси Z отвечает под-свойство “Z» свойства “position” (которое имеет краткий синоним “pos”) чтобы изменить свойство а не просто посмотреть его значение, надо “присвоить» ему какое-то значение с помощью знака равно:
не забывайте нажимать “enter” на клавиатуре!
Вуаля, наш чайник теперь на “столе» )
Осталось изменить его размер так чтобы гостям было где поставить чашки.
Уверен теперь вы сами справитесь с этой задачей.
Говоря непосредственно о тридэмакс, отмечу прекрасное свойство “записывать» ваши действия в окне трехмерного вида как программный код!
Попробуйте выделить инструмент масштабирования и изменить масштаб чайника, и в розовой верхней части окна max script listener вы увидите как ваше действие выглядит в программном виде :
Знаком \$ обозначается выделенный в данный момент времени объект.
Остлеживая розовое окно max script listener и поглядывая в документацию вы постепенно овладеете всей структурой исполняемой среды макса (или любой другой сходным образом) и сможете програмно выполнять в ней то для чего предназначена сама среда.
Следующий шаг — методический, разобраться какие задачи стоят того чтобы решать их в коде а какие нет.
Действительно, передвинуть чайничек проще «руками» для этого не надо учить программирование и писать код.
А вот многократно (тысячекратно) повторяемые задачи очень здорово воплощать в виде программ и даже программных инструментов.
Так я, например, занимаясь анимацией мимики персонажей пишу скрипт который позволяет выделять области носа, глаз, щек и т.п. «в один клик» это экономит уйму времени и сил.
Максскрипт даже позволяет создавать графический интерфейс для ваших скриптов, хоть и убогий по современным меркам )
Итак мы познакомились с практическим программированием в реальной исполняемой среде и почти не упоминали при этом даже переменные.
Для реальной пользы такого программирования обязательно знакомство и с переменными и с циклами, а также массивами. Что мы и сделаем в следующей части статьи.
Создание плагина 3ds Max
Введение
В уроке рассматривается технологическая цепочка создания плагина 3ds Max в среде Microsoft Visual Studio с употреблением 3ds Max SDK и языка программирования C++. Также реализуется MAXScript-версия плагина. Предоставляемый материал – это лишь начальная точка на пути освоения техники разработки 3ds Max SDK-плагинов.
Урок подготовлен по заявкам пользователей Render.ru.
Плагин – это программный модуль, подключаемый к основной программе и либо реализующий часть функционала основной программы, либо расширяющий ее возможности.
Так, в 3ds Max к первой группе плагинов относятся стандартные плагины, хранящиеся в папке stdplugs и загружаемые при запуске приложения. Их список отображается в приведенном на рис. 1 диалоге Plug-in Manager (меню Customize – Plug-in Manager).
Рис. 1. Plug-in Manager
Эти плагины, их около 350, реализуют значительную часть функционала 3ds Max. Например, плагин prim.dlo обеспечивает создание стандартных примитивов, сплайнов и стандартных источников света.
Прочие, нестандартные плагины предпочтительнее размещать в других папках и загружать по мере необходимости.
3ds Max SDK (Solution Development Kit, инструментарий разработчика) имеется в профессиональной версии 3ds Max и содержит заголовочные и библиотечные файлы, обеспечивающие доступ к классам и другим данным 3ds Max. Кроме того, в поставке имеется помощник и большое число примеров.
Плагин 3ds Max может быть написан на языке MAXScript и на языке C++ с употреблением 3ds Max SDK.
В первом случае плагин создается в среде 3ds Max, а во втором – в среде Microsoft Visual Studio.
Во многих случаях MAXScript может обеспечить такой же функционал, как и SDK. Однако скорость SDK-плагинов выше.
SDK-плагин – это откомпилированный и собранный dll-файл C++ (DLL, Dynamic Linked Library, динамически подключаемая библиотека). Рекомендованное расширение файла зависит от назначения плагина. В стандартной поставке 3ds Max плагины, оперирующие материалами и их картами, имеют расширение DLT, а плагинам, создающим объекты, дается расширение DLO, плагины-модификаторы выделяются расширением DLM и так далее.
Поставка 3ds Max SDK включает помощник создания плагинов Plug-in Wizard. Он поддерживает (или планирует поддерживать) создание около 40 следующих видов плагинов (в скобках указывается стандартное расширение):
После уяснения задачи написание SDK-плагина, как правило, предполагает создание надлежащего интерфейса пользователя и реализацию намеченных процедур. Например, плагин gSphere.dlo обеспечивает приведенный на рис. 2 интерфейс и программно поддерживает соответствующую реакцию приложения на предусмотренные интерфейсом действия.
Рис. 2. Пользовательский интерфейс плагина gSphere.dlo
При разработке SDK-плагинов каждая версия 3ds Max предполагает использование соответствующей версии Microsoft Visual Studio, что отражено в следующей таблице:
Версия 3ds Max | Операционная система (32 и 64 бит) | Совместимые версии 3ds Max SDK | Microsoft Visual C++ версия компилятора |
---|---|---|---|
2011 | Windows 7 Windows Vista Windows XP Pro SP2 | 2011, 2010 | Visual C++ 9.0 (Visual Studio 2008) Service Pack 1 с установленным от 28 июля 2009 security patch |
2010 | Windows Vista Windows XP Pro SP2 | 2010 | Visual C++ 9.0 (Visual Studio 2008) Service Pack 1 |
2009 | Windows Vista Windows XP Pro SP2 | 2009 | Visual C++ 8.0 (Visual Studio 2005) Service Pack 1 |
Постановка задачи
Порядок разработки плагина рассмотрим на следующем примере: создать плагин, формирующий примитив куб (Cube).
Такой простой объект отвечает цели урока, заключающейся в демонстрации технологической цепочки разработки SDK-плагинов.
Примитив имеет один параметр Size, для управления которым используется редактируемое поле со счетчиком (рис. 3).
Рис. 3. Интерфейс плагина Cube
Как и другие примитивы, куб вводится в сцену мышкой с прижатой левой кнопкой.
MAXScript реализация плагина
Одну и ту же задачу можно решить средствами 3ds Max SDK и MAXScript. Для иллюстрации этого положения реализуем прежде плагин создания куба на MAXScript, дав плагину имя CubeMS.
Рис. 4. Генератор идентификатора класса плагина
Параметризованный куб создается обработчиком buildMesh в результате применения метода SetMesh, получающего массив arrVrts с координатами вершин примитива и массив его граней arrFcs. Размер куба определяется значением параметра Size. Сглаживающие группы и нормали куба заданы по аналогии с примитивом Box.
После копирования и запуска кода в MAXScript Editor, плагин будет доступен на вкладке Create – Geometry – Scripted Primitives (рис. 5).
Рис. 5. Вызов плагина CubeMS
Категория (Scripted Primitives) и положение элемента в командном окне определяются параметрами выражения Plugin. Так, класс SimpleObject указывает на принадлежность примитива к геометрическим объектам, понятно и назначение свойства Category.
После загрузки плагина кубом можно оперировать средствами языка MAXScript, например:
Заметим, что созданный объект не имеет текстурных координат, поэтому при употреблении материала следует позаботиться о создании таких координат, например при помощи модификатора UVWmap:
Настройка помощника Plug-in Wizard
Необходимые для использования помощника файлы расположены в папке MAXSDK\Howto\3DSMaxPluginWizard.
Откроем в текстовом редакторе имеющийся в этой папке файл 3dsmaxPluginWizard.vsz и определим в нем следующее значение параметра:
Param=»ABSOLUTE_PATH = C:\Program Files\Autodesk\3ds Max 2009 SDK\maxsdk\howto\3dsmaxPluginWizard»
То есть укажем полный путь к папке с файлами помощника. Сохраним изменения и закроем файл.
Оставаясь в этой папке, скопируем три следующие файла:
и вставим их в VC/vcprojects директорию установки Microsoft Visual Studio (это может быть C:\Program Files\Microsoft Visual Studio 5\VC\vcprojects).
Этого достаточно, чтобы 3ds Max Plug-in Wizard оказался доступным как шаблон в Microsoft Visual Studio.
Проверим это, запустив Visual Studio и выбрав File > New:Projects > Visual C++ > 3ds Max Plug-in Wizard (рис. 6).
Рис. 6. Создание проекта Visual C++ с помощью 3ds Max Plug-in Wizard
Порядок создания 3ds Max SDK-плагина
После разработки проекта плагина и оформления проекта, например, в виде технического задания запускается Microsoft Visual Studio, где и выполняются все последующие действия.
В проекте SDK-плагина полезно указать следующие характеристики:
Характеристика плагина | Пример значения |
---|---|
Имя файла | cube.dlo |
Идентификатор класса утилиты | Class_ID(0xd667c5aa, 0xb65e9ddb) |
Описание IDS_LIBDESCRIPTION | «Cube» |
Категория IDS_CATEGORY | «SDK simple object» |
Имя класса IDS_CLASS_NAME | «Cube» |
Интерфейс пользователя, предоставляемый плагином, сформируем в соответствии с рис. 7, добавив возможность ручного ввода (Keyboard Entry) примитива Cube.
Рис. 7. Уточненный пользовательский интерфейс плагина
При вводе посредством нажатия на кнопку Create центр куба будет размещен в начале мировой системы координат.
Создадим теперь в Microsoft Visual Studio проект C++ Win32, компиляция и сборка которого (Compile and Link) обеспечат создание запрошенного плагина.
Проект создается как многониточная библиотека (Multy-threaded DLL). Используется гибридная (Hybrid) конфигурация, пригодная и для отладки (Debugging), и для построения готового решения (Solution).
Создание нового проекта
Запустим Visual Studio и используем для создания проекта помощник 3ds Max Plug-in Wizard (см. рис. 6). В поле Name введем имя Cube, а в поле Location укажем, например, имя папки C:\sdk. Снимем флажок Create directory for solution. Нажмем на ОК и в открывшемся диалоге выберем Procedural Objects (процедурные объекты, рис. 8).
Рис. 8. Выбор вида плагина
Нажмем на Next и введем в появившемся диалоге указанные на рис. 9 значения.
Рис. 9. Детализация описания плагина Cube. В качестве базового выбран класс SimpleObject2
Нажмем на Next и в появившемся диалоге проверим наличие указанных на рис. 10 значений.
Рис. 10. Некоторые детали проекта
В поле MAXSDK path указан путь
C:\Program Files\Autodesk\3ds Max 9 SDK\maxsdk
а в поле 3dsmax.exe path указан путь
C:\Program Files\Autodesk\3ds Max 2009
Ваши значения могут быть иными.
Нажмем на кнопку Finish.
Свойства (Properties) проекта Cube
Практически все свойства проекта Cube будут установлены помощником. Наша задача просмотреть эти свойства и внести незначительные коррективы.
На вкладке Solution Explorer расположится дерево решения (рис. 11).
Рис. 11. Дерево решения Cube
Первый заголовочный файл 3dsmaxsdk_preinclude.h удален, а файл cube.h приведен к следующему виду:
#include «Max.h»
#include «resource.h»
#include «istdplug.h»
#include «iparamb2.h»
#include «iparamm2.h»
#include «Simpobj.h»
extern TCHAR *GetString(int id);
extern HINSTANCE hInstance;
Удаление файла 3dsmaxsdk_preinclude.h потребует изъятия всех #pragma message из файла cube.cpp. Такие куски кода появятся в файле, если в качестве базового класса выбрать GeomObject.
Добавим теперь в проект конфигурацию Hybrid.
Выберем в дереве проекта вершину cube (см. рис. 11), нажмем на правую кнопку мыши и в появившемся меню выберем Properties.
В открывшемся окне нажмем на кнопку Configuration Manager и в списке Active Solution Configuration добавим новый вид конфигурации Hybrid; этот же вид выберем и в нижерасположенной таблице диалога (рис. 12).
Рис. 12. Добавление конфигурации Hybrid
Далее все настройки будут выполнены для этой конфигурации.
Ветвь Configuration Properties – General после внесенных изменений будет содержать следующие сведения (рис. 13):
Рис. 13. Ветвь Configuration Properties – General
Переместимся в ветвь C++ – General. В поле Additional Include Directories проверим путь к include-директории 3ds Max SDK:
«C:\Program Files\Autodesk\3ds Max 2009 SDK\maxsdk\include»
В вашем случае путь может быть иным. Если путь содержит пробелы, то его нужно заключить в кавычки.
Прочие поля диалога оставим без изменений. Нажмем на кнопку Применить.
В ветви C++ – Command Line поле Additional options (дополнительные опции) вставим следующие значения:
/GR /we4706 /we4390 /we4557 /we4546 /we4545 /we4295 /we4310 /we4130 /we4611 /we4213 /we4121 /w34701 /wd4244 /wd4018
Они взяты из файла AdditionalCompilerOptions.txt, имеющегося в поставке 3ds Max SDK. Применить.
Имя выходного файла (создаваемого плагина) найдем в ветви Linker – General – Output File. В рассматриваемом примере помощник указал имя C:\sdk\cube.dlo.
Проверим путь к SDK библиотекам (Additional Library Directories):
«C:\Program Files\Autodesk\3ds Max 2009 SDK\maxsdk\lib»
Если путь имеет пробелы, то его следует заключить в кавычки. Применить.
Прочие значения свойств проекта оставим без изменений.
Файл ресурсов cube.rc
В этом файле создадим указанные на вышеприведенном рис. 7 диалоги Keyboard Entry и Parameters. Также отредактируем таблицу символов (String Table) с идентификаторами ресурса.
Перейдем в Visual Studio на вкладку Resource View. Откроем созданную помощником заготовку диалога IDD_PANEL, выберем форму диалога, в окне свойств изменим его идентификатор (свойство ID) на IDD_KBRD, а саму форму диалога приведем к следующему виду (рис. 14):
Рис. 14. Форма диалога IDD_KBRD
Этот диалог будет употреблен для ручного ввода примитива. Его размер 108*63 единицы (пикселя).
Свойства (ID и Caption) существующих в заготовке элементов (текст, поле ввода и счетчик) установим в соответствии с рис 15.
Рис. 15. Свойства элементов диалога IDD_KBRD
Ниже этих полей добавим кнопку класса CustButton (пользовательский класс). Это можно сделать, употребив инструмент Custom Control и приведя свойства (Caption, Class, ID и Style) добавленного элемента в соответствие с рис. 16.
Рис. 16. Добавление и настройка кнопки Create
Выделим теперь в дереве файла cube.rc ветвь IDD_KBRD, выполним ее копирование и вставку. Изменим идентификатор добавленного диалога на IDD_PARAMS (рис. 17), а его форму и свойства его элементов установим в соответствии с рис. 18.
Рис. 17. Добавлен диалог IDD_PARAMS
Рис. 18. Свойства элементов диалога IDD_PARAMS
Диалог IDD_PARAMS отражает текущее значение параметра Size и может быть, в частности, употреблен для изменения размера куба на вкладке Modify.
Откроем теперь таблицу символов ресурса и приведем ее в соответствие с рис. 19.
Рис. 19. Таблица символов ресурса cube.rc
Таблица символов содержит используемые плагином свойства ресурса (детали см. ниже).
В диалогах ресурса использованы следующие пользовательские элементы управления:
Файл resource.h
Сохраним все изменения и убедимся, что этот файл содержит, кроме прочих, следующие данные (значения идентификаторов могут быть иными):
#define IDS_LIBDESCRIPTION | 1 |
#define IDS_CATEGORY | 2 |
#define IDS_CLASS_NAME | 3 |
#define IDS_KBRD | 4 |
#define IDS_PARAMS | 5 |
#define IDS_CB_SIZE | 6 |
#define IDD_PARAMS | 101 |
#define IDD_KBRD | 102 |
#define IDC_KBSZ | 1001 |
#define IDC_KBSZSPIN | 1002 |
#define IDC_KBSTATIC | 1003 |
#define IDC_CREATE | 1004 |
#define IDC_SZSTATIC | 1005 |
#define IDC_SZ | 1490 |
#define IDC_SZSPIN | 1496 |
Иными словами, файл должен содержать идентификаторы таблицы символов и диалогов ресурса. Прочие определения из файла могут быть удалены.
Код файла cube.rc
Перейдем на вкладку Solution Explorer и просмотрим код файла cube.rc (выбрать имя cube.rc – правая кнопка мыши – View Code). Код должен, помимо прочих, содержать следующие определения:
// Dialog
//
IDD_KBRD DIALOGEX 0, 0, 108, 63
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
FONT 8, «MS Sans Serif», 0, 0, 0x0
BEGIN
CONTROL | «»,IDC_KBSZ,»CustEdit»,WS_TABSTOP,43,17,35,10 |
CONTROL | «»,IDC_KBSZSPIN,»SpinnerControl»,0x0,79,17,7,10 |
LTEXT | «Size»,IDC_KBSTATIC,21,18,14,8 |
CONTROL | «Create»,IDC_CREATE,»CustButton»,WS_TABSTOP,31,36,44,12 |
END
IDD_PARAMS DIALOGEX 0, 0, 108, 48
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
FONT 8, «MS Sans Serif», 0, 0, 0x0
BEGIN
CONTROL | «»,IDC_SZ,»CustEdit»,WS_TABSTOP,43,17,35,10 |
CONTROL | «»,IDC_SZSPIN,»SpinnerControl»,0x0,79,17,7,10 |
LTEXT | «Size»,IDC_SZSTATIC,21,18,14,8 |
END
…
// String Table
//
STRINGTABLE
BEGIN
IDS_LIBDESCRIPTION | «Cube» |
IDS_CATEGORY | «SDK simple object» |
IDS_CLASS_NAME | «Cube» |
IDS_KBRD | «Keyboard Entry» |
IDS_PARAMS | «Parameters» |
IDS_CB_SIZE | «Size» |
END
После просмотра окно с кодом следует закрыть, чтобы не создавать препятствий для работы с ресурсом на вкладке Resource View.
Файл cube.def
Файл cube.def генерируется помощником. Он содержит имя dll-файла и используемые плагином виды определений (описание библиотеки, число классов, описание классов, версия библиотеки, инициализация и закрытие библиотеки):
LIBRARY cube.dlo
EXPORTS
LibDescription | @1 PRIVATE |
LibNumberClasses | @2 PRIVATE |
LibClassDesc | @3 PRIVATE |
LibVersion | @4 PRIVATE |
LibInitialize | @6 PRIVATE |
LibShutdown | @7 PRIVATE |
SECTIONS
.data READ WRITE
При изменении в свойствах проекта имени библиотеки соответствующую правку нужно выполнить и в def-файле.
Основные характеристики примитива
Создаваемый куб имеет следующие особенности:
Код плагина cube.dlo
С позиции пользователя код, в частности, должен решать две следующие задачи:
Сгенерированное помощником решение включает два cpp-файла с исходным кодом – это DllEntry.cpp и cube.cpp. Первый файл содержит код, обслуживающий dll-библиотеку. Это файл в нашем случае практически не требует изменений:
Главная функция формирует DllMain hInstance – дескриптор экземпляра плагина, передаваемый файлу cube.cpp посредством заголовочного файла cube.h.
Имена declspec-функций файла отвечают имеющимся в def-файле определениям.
Функция GetString получает значение (Value) идентификатора ресурса и возвращает значение поля Caption таблицы символов (String Table) ресурса cube.rc проекта.
Код, обеспечивающий функционал плагина, размещен в файле cube.cpp.
Код перимущественно сформирован помощником и включает набор классов и функций (методов), необходимых для создания и управления процедурными объектами. При необходимости разработчик может добавить свои классы и методы, а также внести отвечающие цели проекта изменения в предоставленный помощником код.
Поскольку удален заголовочный файл 3dsmaxsdk_preinclude.h, то в файле cube.cpp не должны присутствовать #pragma message.
Код содержит определения следующих четырех классов:
На рис. 20 и 21 показаны иерархии классов, лежащих в основе классов cube и cubeClassDesc.
Рис. 20. Класс cube: иерархия родительских классов
Рис. 21. Класс cubeClassDesc: иерархия родительских классов
Класс cube обеспечивает создание и управление примитивом.
Класс cubeClassDesc обеспечивает регистрацию объекта в 3ds Max.
Класс cubeKBDlgProc отвечает за связь плагина с диалогом ручного создания куба: его функция DlgProc регистрирует нажатие на кнопку Create (IDC_CREATE) диалога и обеспечивает создание куба заданного размера с центром в начале мировой системы координат.
Класс cubeCreateCallBack отвечает за ввод в сцену примитива посредством мыши: его функция proc получает информацию о мышиных событиях – это сообщения 3ds Max с именами MOUSE_POINT, MOUSE_MOVE и MOUSE_ABORT и соответствующим образом реагирует на эти события. Метод SetObj класса ассоциирует созданную меш с кубом.
Обе функции (DlgProc и proc) употребляют метод BuildMesh класса cube, используя соответственно методы NonMouseCreate (класс IObjParam) и InvalidateUI (класс ParamBlockDesc2).
Прочие пояснения см. в комментариях к приводимому ниже коду. При этом прежде следует комментарий, а затем комментируемый код.
Загрузка и вызов плагина
Созданный плагин, файл cube.dlo следует загружать в начале сеанса работы с 3ds Max, открыв меню Customize – Plug-in Manager – табличная часть диалога – правая кнопка мыши – Load New Plug-in – найти загружаемый файл.
Загруженный плагин доступен в командном окне: вкладка Create – Geometry – SDK simple object (рис. 22).
Рис. 22. Вызов плагина Cube
Если загружать плагин не вначале сеанса, а позже, то может возникнуть указанная на рис. 23 ошибка.
Рис. 23. Ошибка инициализации плагина
Заключение
Создание дополнительного инструмента 3ds Max – это достаточно трудоемкая работа. Поэтому должна быть серьезная мотивация для ее выполнения. Например, наличие идеи расширения функционала 3ds Max, интересной широкому кругу пользователей приложения. Удачное расширение может бы