Інтроспекція в maxscript
MaxScript має розвинені засоби інтроспекції, тобто можливість визначити тип і структуру об'єкту під час виконання програми або при роботі в консолі (Listener).
У довідці по MaxScript функції і метди, відповідальні за интроспекцию, розкидані по різних розділах, що не дуже зручно.
Надалі, при перерахуванні методів будуть згадуватися тільки методи, що мають відношення до інтроспекції. Це не означає, що у класу немає інших методів.
Під час написання даної статті не ставили за мету дати повний опис кожної згадуваної функції. Повну і детальну інформацію можна знайти в системі допомоги по MaxScript.
Деякі фрагменти статті є перекладами на українську мову матеріалів з системи допомоги по MaxScript.
apropos
Функція здійснює пошук і висновок на консоль інформації про глобальних змінних на підставі зазначеного шаблону імені змінних і класу їх значень. Синонімом для apropos () є help ().
Слід зазначити, що в MaxScript все імена вбудованих функцій, класів та інших постійних сутностей є глобальними змінними.
Треба відзначити, що хоча у цій функції є багатообіцяючий псевдонім «help», якийсь розгорнутої інформації з цікавого об'єкту (тобто глобальної змінної), функція не видає. Однак з її допомогою можна виявити об'єкти, про існування яких ви навіть не підозрювали.
showClass
Функція виводить у вікно консолі інформацію про клас (або класах) MaxScript. Як перший аргумент вона приймає шаблон для пошуку (рядок з символами підстановки) імен класів, імен суперкласів і / або імен властивостей. Шаблон має вигляд:
"
де
Одним з найбільш корисних застосувань функції є отримання списку властивостей для даного класу. Тобто коли є об'єкт відомого класу (отримати клас об'єкта завжди можна за допомогою функції classOf ()) і потрібно змінити одне з властивостей, але ім'я властивості не відомо, то за допомогою функції showClass () можна дізнатися ім'я властивості і його тип.
Наприклад, можна подивитися всі властивості класу Box:
getPropertyController
setPropertyController
Отримати доступ до контролера, який призначений властивості об'єкта, можна за допомогою функцій getPropertyController () і setPropertyController (). Якщо властивості не призначено контролер, функція getPropertyController () поверне значення undefined.
hasProperty
Функція hasProperty () дозволяє перевірити чи є вказане властивість у об'єкта. Як аргумент функція приймає рядок-шаблон з символами підстановки.
Функція всередині себе використовує виклик функції showProperties () і, отже, має ті ж особливості роботи.
isProperty
Функція isProperty () дозволяє перевірити чи має об'єкт вказане властивість. Як аргумент функція приймає ім'я або рядок без символів узагальнення.
hasProperty () і isProperty () схожі, але в деяких випадках дають різні результати:
hasProperty b "name"
isProperty b "name"
Справа в тому, що hasProperty () використовує результат виклику функції showProperties () в якому шукає відповідність шаблону імені властивості. Функція isProperty () намагається звернутися до зазначеного властивості об'єкта. Для об'єкта класу Box функція showProperties () повертає тільки список властивостей класу Box. але не батьківських класів. Властивість name належить класу Node. тому функція hasProperty () його не бачить, а isProperty () - бачить.
isPropertyAnimatable
Функція повертає true. якщо вказане властивість існує і воно може бути анимировано.
-- роздруковуємо список всіх властивостей сфери
-- із зазначенням можливості анімації
for i in getPropNames s do format "% Property:% - Animatable:% \ n" s.name i (isPropertyAnimatable s i)
Sphere01 Property: #smooth - Animatable: true
Sphere01 Property: #radius - Animatable: true
Sphere01 Property: #mapCoords - Animatable: false
Sphere01 Property: #segs - Animatable: true
Sphere01 Property: #slice - Animatable: false
Sphere01 Property: #hemisphere - Animatable: true
Sphere01 Property: #sliceFrom - Animatable: true
Sphere01 Property: #sliceTo - Animatable: true
Sphere01 Property: #chop - Animatable: false
Sphere01 Property: #recenter - Animatable: false
Якщо ми створимо об'єкт класу Box і подивимося список властивостей через showClass () і showProperties (). то виявимо, що набір властивостей відрізняється:
У властивостях об'єкта (екземпляра класу) з'явилася властивість realWorldMapSize. Воно було додано інтерфейсом realWorldMapSizeInterface. Механізм інтерфейсів в MaxScript, по суті, реалізує ідею множинного спадкоємства. Наприклад, згаданий інтерфейс мають всі стандартні геометричні примітиви і нектороие модифікатори.
Ця область дуже погано документована в системі допомоги по MaxScript. Якщо не вдаватися в подробиці архітектури 3ds Max, то інтерфейси, з точки зору MaxScript, є класами, в які виділена певна функціональність. Таким чином, кожен клас може мати не тільки свої властивості і методи, але і інтерфейси з їх властивостями і методами, а також успадковані від батьківських класів властивості, методи і інтерфейси.
Клас Box має інтерфейс realWorldMapSizeInterface. Клас Box є нащадком класів (по ієрархії успадкування) GeometryClass. node. MAXWrapper. Value. З цих батьківських класів тільки у класу node є декількох інтерфейсів. Таким чином, при створенні екземпляра класу Box. об'єкт успадковує як властивості, так і інтерфейси класу Box. і всіх його батьківських класів.
Треба відзначити, що функція showProperties () працює тільки з останнім рівнем успадкування. Наприклад, екземпляр класу Box має інтерфейс INodeLayerProperties. успадкований від класу node. Цей інтерфейс, серед інших, має властивість displayByLayer. Наступний код спрацьовує без помилок:
Цей приклад також показує, що можна звернутися до будь-якого властивості будь-якого інтерфейсу (який має об'єкт), використовуючи в ієрархічній dot-нотації ім'я інтерфейсу. Та сама дія в більшості випадків може бути виконано простіше:
Такий метод спрацює, якщо ім'я властивості інтерфейсу не повторюється серед імен властивостей об'єкта та / або серед імен властивостей інших інтерфейсів.
Перелік інтерфейсів об'єкта можна отримати за допомогою функції showInterfaces ():
Повертає суперклас для аргументу. Тобто клас, від якого успадкований клас аргументу. Вираз superClassOf arg фактично еквівалентно висловом classOf (classOf arg).
isKindOf
Функція повертає true. якщо об'єкт, що перевіряється є екземпляром зазначеного класу або екземпляром класу, успадкованого від зазначеного.
За допомогою цієї функції зручно перевіряти приналежність об'єкта до певного класу. Наприклад, необхідно зробити якусь операцію з усіма виділеними камерами в сцені. У найпростішому випадку задача вирішується тривіально. Але якщо допустити, що можуть бути виділені не тільки камери, і в сцені є камери різних типів, то рішення стає більш складним. Це завдання можна вирішувати і за допомогою функції classOf (). але в цьому випадку буде перевірятися відповідність тільки конкретного класу і треба робити кілька перевірок. Простіше використовувати функцію isKindOf ():
for obj in selection do (
if isKindOf obj camera do (
-- робимо операцію з об'єктом камера
-- наприклад роздруковуємо ім'я об'єкта
Тут в умови перевіряється належність об'єкта до класу camera. або до класу, успадкованого від класу camera. Всі типи камер в 3ds Max повинні бути успадковані від класу camera. Це стосується як вбудованих типів (Free camera і Target camera), так і типів камер, що додаються плагінами третіх виробників (наприклад VRayPhysicalCamera). Таким чином, операція буде проводитися з камерами і тільки з камерами.
Повертає true. якщо аргумент - визначення структури.
Повертає true. якщо аргумент - екземпляр структури.
Повертає true. якщо аргумент - контролер.
Повертає true. якщо аргумент - плагін, написаний на MAXScript.
Повертає true. якщо аргумент - клас плагіна, написаного на MAXScript.
Повертає true. якщо аргумент - призначений для користувача атрибут MaxScript (MAXScript Custom Attribute).
Зауваження. Оскільки атрибути є спеціальним випадком плагіна, написаного на MaxScript, функція isMSPlugin () також буде повертати true.
Повертає true, якщо аргумент - клас для користувача атрибуту MaxScript.
Інтроспекціонние властивості і методи класу MAXWrapper
Клас MAXWrapper є базовим класом для всіх класів, які представляють об'єкти 3ds Max, такі як геометричні об'єкти, модифікатори, матеріали і т.п. Примірники класів, успадкованих від MAXWrapper. містять посилання на пов'язані об'єкти 3ds Max, що дозволяє їм стежити за об'єктом. Це дозволяє MaxScript знати, коли об'єкт піддався трансформації, видалено користувачем або були змінені його властивості.
Як можна було помітити, багато інтроспекціонние функції приймають в якості аргументу об'єкти типу MAXWrapper.
Клас MAXWrapper має кілька властивостей, що відносяться до інтроспекції, але вони досить специфічні і рідко використовуються при практичній роботі з MaxScript.
Повертає масив значень MAXClass (тобто класів), які належать даному суперкласу.
Властивість містить внутрішній ідентифікатор (ID) класу 3ds Max для класів і об'єктів, успадкованих від класу MAXWrapper. Являє собою масив з двох цілих чисел, однозначно ідентифікують клас.
Властивість містить внутрішній ідентифікатор (ID) суперкласу 3ds Max для класів і об'єктів.
Повний перелік властивостей класу MAXWrapper - см. Систему допомоги по MaxScript.
Повертає ім'я класу аргументу у вигляді рядка.
В 3ds Max багато об'єктів залежать від інших об'єктів. Матеріал залежить від своїх карт, геометричний об'єкт залежить від базового об'єкта і т.п. Внутрішній механізм 3ds Max визначає відносини залежностей між об'єктами.
У MaxScript є структура refs. яка визначає чотири функції для роботи з залежностями:
refs.dependents
Повертає масив інших об'єктів (точніше, посилань на ці об'єкти) 3ds Max, які залежать від зазначеного об'єкта (всі об'єкти є нащадками класу MAXWrapper). Якщо необов'язковий аргумент immediateOnly дорівнює true, то будуть повернуті тільки об'єкти, що залежать безпосередньо.
Наприклад, такий вираз показує, що дифузна карта матеріалу, призначеного об'єкту foo. використовується в матеріалах Material_ # 1, Material_ # 2, Material_ # 3 і в текстурной мапі Map_ # 2: Noise.
# (Material_ # 3, Material_ # 2, Map_ # 2: Noise, Material_ # 1)
Функції в MaxScriptтакже є об'єктами. Визначення функції є виразом, результатом виконання якого буде об'єкт типу MAXScriptFunction. За замовчуванням ім'ям цього об'єкта буде ім'я визначається функції. Однак вираз визначення функції повертає значення, яке може бути присвоєно іншій змінній:
fp1 = fn func1 a b = (a - b)
У цьому випадку змінні func1 і fp1 посилаються на один об'єкт, але самі змінні є різними і незалежними один від одного.
Якщо розглядати класичну схему в стилі C, то в вищенаведеному прикладі func1 є ім'ям функції, а fp1 - покажчиком на функцію. І, мається на увазі, що func1 - це константа, а fp1 - змінна. Однак в MaxScript ці обидва ідентифікатора називають посилання на об'єкт і є ідентифікаторами змінних. Таким чином, змінну func1 можна в будь-який момент перевизначити, призначивши їй будь-який інший об'єкт (функцію, число, etc.), а до функції звертатися через змінну fp1. Якщо змінна fp1 буде також перевизначена, тобто на об'єкт-функції не буде посилатися жодна змінна, то об'єкт функції буде утилізовано складальником сміття.
висновок
У цій статті я постарався зібрати разом відомості про найбільш важливих і вживаних (з моєї точки зору) функціях, властивості і методи, що мають відношення до інтроспекції в MaxScript. Можливо, що за рамками цієї статті залишилися якісь важливі і цікаві моменти. Можливо, що якихось речей я не приділив достатньо уваги. MaxScript Reference вам на допомогу - там є майже все.