Книга: Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода

RNA-свойства против ID-свойств

RNA-свойства против ID-свойств

В Блендере есть два различных типа свойств: ID-свойства и RNA-свойства. RNA-свойства расширяют определение структуры данных. Они должны быть объявлены до того, как будут использоваться.

Я потратил некоторое время на выяснение того, как же расшифровывается и что означает аббревиатура RNA для программирования на Питоне в Блендере. Может быть, я был недостаточно настойчив в поисках, но всё, что я нашел — это РНК, Рибонуклеиновая кислота. Разработчики применили химико-биологическую метафору для обозначения реальных структур данных на языке С (DNA, в переводе ДНК) и соответствующих им структур на Питоне (RNA, в переводе РНК). С понятием ID, думаю все и так знакомы, это сокращение слова Идентификатор. - прим. пер.

bpy.types.Object.myRnaInt = bpy.props.IntProperty(
    name = "RNA int",
    min = -100,
    max = 100,
    default = 33)

Как только RNA-свойства были объявлены, они будут доступны через точечный синтаксис:

cube.myRnaInt = -99

После декларации RNA-свойства myRnaInt расширяет определение структуры данных Object, каждый объект будет иметь это свойство.

ID-cвойство добавляется к единственному блоку данных, не влияя на другие данные того же самого типа. Ему не нужна какая-либо предварительная декларация, но оно автоматически определяется при присвоении, напр.

cube.data["MyIdInt"] = 4711

ID-свойства могут только быть целыми, вещественными, и строками; другие типы автоматически будут преобразованы. Следовательно, строка

cube.data["MyIdBool"] = True

определяет целое ID-свойство, а не логическое.

Не знаю, как в предыдущих версиях, а в 2.57 вполне можно определять списки — прим. пер.

Свойства сохраняются в blend-файле, но декларации свойств — нет.

Вот скрипт, который создает три меша, назначает различные свойства и печатает их величины в консоли.

#----------------------------------------------------------
# File properties.py
#----------------------------------------------------------
import bpy
from bpy.props import *
# Очистка сцены и создание нескольких объектов
bpy.ops.object.select_by_type(type='MESH')
bpy.ops.object.delete()
bpy.ops.mesh.primitive_cube_add(location=(-3,0,0))
cube = bpy.context.object
bpy.ops.mesh.primitive_cylinder_add(location=(0,0,0))
cyl = bpy.context.object
bpy.ops.mesh.primitive_uv_sphere_add(location=(3,0,0))
sphere = bpy.context.object
# Определение RNA-свойства для каждого объекта
bpy.types.Object.myRnaInt = IntProperty(
    name = "RNA int",
    min = -100, max = 100,
    default = 33) 
bpy.types.Object.myRnaFloat = FloatProperty(
    name = "RNA float",
    default = 12.345,
    min = 1, max = 20)  
bpy.types.Object.myRnaString = StringProperty(
    name = "RNA string",
    default = "Ribonucleic acid")  
bpy.types.Object.myRnaBool = BoolProperty(
    name = "RNA bool") 
bpy.types.Object.myRnaEnum = EnumProperty(
    items = [('one', 'eins', 'un'),
             ('two', 'zwei', 'deux'),
             ('three', 'drei', 'trois')],
    name = "RNA enum")
# Присвоение RNA-свойств кубу
cube.myRnaInt = -99
cube.myRnaFloat = -1
cube.myRnaString = "I am an RNA prop"
cube.myRnaBool = True
cube.myRnaEnum = 'three'
# Создание ID-свойств для меша куба присвоением значений.
cube.data["MyIdInt"] = 4711
cube.data["MyIdFloat"] = 666.777
cube.data["MyIdString"] = "I am an ID prop"
cube.data["MyIdBool"] = True
# Печать всех свойств
def printProp(rna, path):
    try:
        print('  %s%s =' % (rna.name, path), eval("rna"+path))
    except:
        print('  %s%s does not exist' % (rna.name, path))
for ob in [cube, cyl, sphere]:
    print("%s RNA properties" % ob)
    printProp(ob, ".myRnaInt")
    printProp(ob, ".myRnaFloat")
    printProp(ob, ".myRnaString")
    printProp(ob, ".myRnaBool")
    printProp(ob, ".myRnaEnum")
    print("%s ID properties" % ob.data)
    printProp(ob.data, '["MyIdInt"]')
    printProp(ob.data, '["MyIdFloat"]')
    printProp(ob.data, '["MyIdString"]')
    printProp(ob.data, '["MyIdBool"]')

Скрипт напечатает следующий результат на консоль:

<bpy_struct, Object("Cube")> RNA properties Cube.myRnaInt = -99
    Cube.myRnaFloat = 1.0
    Cube.myRnaString = I am an RNA prop
    Cube.myRnaBool = True
    Cube.myRnaEnum = three
<bpy_struct, Mesh("Cube.001")> ID properties
    Cube.001["MyIdInt"] = 4711
    Cube.001["MyIdFloat"] = 666.777
    Cube.001["MyIdString"] = I am an ID prop
    Cube.001["MyIdBool"] = 1
<bpy_struct, Object("Cylinder")> RNA properties
    Cylinder.myRnaInt = 33
    Cylinder.myRnaFloat = 12.345000267028809
    Cylinder.myRnaString = Ribonucleic acid
    Cylinder.myRnaBool = False
    Cylinder.myRnaEnum = one
<bpy_struct, Mesh("Cylinder")> ID properties
    Cylinder["MyIdInt"] does not exist
    Cylinder["MyIdFloat"] does not exist
    Cylinder["MyIdString"] does not exist
    Cylinder["MyIdBool"] does not exist
<bpy_struct, Object("Sphere")> RNA properties
    Sphere.myRnaInt = 33 Sphere.myRnaFloat = 12.345000267028809
    Sphere.myRnaString = Ribonucleic acid
    Sphere.myRnaBool = False
    Sphere.myRnaEnum = one
<bpy_struct, Mesh("Sphere")> ID properties
    Sphere["MyIdInt"] does not exist
    Sphere["MyIdFloat"] does not exist
    Sphere["MyIdString"] does not exist
    Sphere["MyIdBool"] does not exist


Все три объекта имеют RNA-свойства, поскольку они являются расширением типа данных Object. RNA-свойствам Куба программой присвоены значения, кроме значения myRnaFloat, которое не может быть меньше чем 1. Цилиндру и сфере никаких свойств присвоено не было, но они все равно имеют RNA-свойства со значением по умолчанию.

Мешу куба программой были заданы ID-свойства. Заметьте, что свойство MyIdBool является целочисленной 1, а не логической True.

Свойства Объекта отображаются в панели пользовательского интерфейса под Properties, и также в контексте объекта. Свойства меша можно найти в контексте меша.


Как мы видели в распечатке, мы можем иметь доступ к RNA-свойствам объекта сферы. Тем не менее, они не появляются в интерфейсе пользователя. Очевидно, только присвоенные значения свойств сохраняются в блоке данных Объекта. Мы можем использовать RNA-свойство, которое не присвоено в скрипте; при этом берется значение по умолчанию. В противовес этому, если мы попытаемся получить доступ к незаданному ID-свойству, будет возбуждена ошибка.


Свойства совместимы со связями файлов. Сохраните blend-файл и привяжите (link) куб в новый файл. Как RNA-, так и ID-свойства появляются в новом файле, но они серые, поскольку они не могут быть доступны в связанном файле.


Если мы проксим (proxify) связанный куб, свойства объекта принадлежат блоку данных прокси-объекта, и могут быть модифицированы в связанном файле. В противовес этому, свойства меша принадлежат блоку данных меша и не могут изменяться.


Как упомянуто выше, свойства сохранены в blend-файлах, но декларации свойств — нет. Закройте и перезапустите Блендер и откройте файл, который мы сохранили выше. Свойства myRnaBool и myRnaEnum окажутся преобразованными в целые. Фактически, они и были сохранены как целые всё время, но отображались как логические и перечисления из-за продекларированных свойств, сохранённых в типе данных Object.

Чтобы подтвердить, что RNA-свойства превратились в ID-свойства, выполните следующий скрипт.

#----------------------------------------------------------
# File print_props.py
#----------------------------------------------------------
import bpy 
def printProp(rna, path):
    try:
        print('  %s%s =' % (rna.name, path), eval("rna"+path))
    except:
        print('  %s%s does not exist' % (rna.name, path))  
ob = bpy.context.object print("%s RNA properties" % ob)
printProp(ob, ".myRnaInt")
printProp(ob, ".myRnaFloat")
printProp(ob, ".myRnaString")
printProp(ob, ".myRnaBool")
printProp(ob, ".myRnaEnum")
print("%s ID properties" % ob)
printProp(ob, '["myRnaInt"]')
printProp(ob, '["myRnaFloat"]')
printProp(ob, '["myRnaString"]')
printProp(ob, '["myRnaBool"]')
printProp(ob, '["myRnaEnum"]')
print("%s ID properties" % ob.data)
printProp(ob.data, '["MyIdInt"]')
printProp(ob.data, '["MyIdFloat"]')
printProp(ob.data, '["MyIdString"]')
printProp(ob.data, '["MyIdBool"]')

Этот скрипт выведет следующий текст на терминале.

RNA properties
    Cube.myRnaInt does not exist
    Cube.myRnaFloat does not exist
    Cube.myRnaString does not exist
    Cube.myRnaBool does not exist
    Cube.myRnaEnum does not exist
<bpy_struct, Object("Cube")> ID properties
    Cube["myRnaInt"] = -99
    Cube["myRnaFloat"] = 1.0
    Cube["myRnaString"] = I am an RNA prop
    Cube["myRnaBool"] = 1
    Cube["myRnaEnum"] = 2
<bpy_struct, Mesh("Cube.001")> ID properties
    Cube.001["MyIdInt"] = 4711
    Cube.001["MyIdFloat"] = 666.777
    Cube.001["MyIdString"] = I am an ID prop
    Cube.001["MyIdBool"] = 1

Если мы восстановим декларации свойств, ID-свойства преобразуются обратно в RNA-свойства.

Оглавление книги


Генерация: 1.195. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз