• Blender文档翻译-Blender库数据的通用属性


     Blender库数据的通用属性

    引言

    Blender现在支持在所有库数据中存储自定义数据(如对象、材料、纹理、几何体,如网格、曲线,元球,场景和更多)。现在渲染导出、游戏导出和需要它的任何脚本类型都可以将数据存储到.blend附加到库数据中。

    称之为ID属性系统,因为所有的属性存储在所有库数据都有的唯一ID结构中。

    它是如何工作的

    属性由以下基本类型组成:

    • Array:简单一维float或int型数组 a simple one-dimensional array of either floats or ints
    • String: 字符串
    • Group: 一组属性
    • Float: 浮点数
    • Int: 整数

    另外,属性都有(明显地)一个名字。

    标准

    有一个专用的ID属性标准页在BlenderDev/PropertyStandards这里。请与其他作者一起工作形成自己脚本标准,这个想法是为了避免每个脚本都有一套独特的属性。

     Python教程

    从python的角度看使用ID属性是很容易的。下面示例代码展示了它的简单性:

     1 import Blender
     2 from Blender import Material
     3 mat = Material.Get("Material")
     4  
     5 # get a property
     6 try:
     7     TranslucencyFactor = mat.properties['SomeRenderer']['TransFac']
     8 except:
     9     TranslucencyFactor = 0.0
    10     mat.properties['SomeRenderer']={}
    11     mat.properties['SomeRenderer']['TransFac'] = 0.0
    12  
    13 # some more code to demonstrate how to make groups, arrays, etc.
    14 mat.properties['a float array'] = [0.0, 1.0, 2.0]
    15 mat.properties['a group'] = {"IntArray": [1, 2, 3], "AnotherGroup": {"int": 1}}
    16 mat.properties['a string'] = "Sdfdsfsd"
    17 mat.properties['a float'] = 0.0
    18 mat.properties['an int'] = 0
    19  
    20 # to get a properties type, use type()
    21 if type(mat.properties['a float array']) is Blender.Types.IDArrayType:
    22     print "It's an array!"
    23 if type(mat.properties['an int']) is int:
    24     print "It's an int!"
    25  
    26 # iterate over a group
    27 for property in mat.properties['a group']:
    28     print property
    29     print type(property)
    30  
    31 theint = mat.properties['an int']
    32 thestring = mat.properties['a string']

    正如您所看到的,属性可以通过简单的python类型创建,比如int、float、dict和List。从属性中获取数据就像访问它的.data成员一样简单。

    C API

    ID属性的C API是在头文件原文source/Blender/makesdna/DNA_ID.h中原型化的。与使用pythonAPI相比,使用C API有很大不同;它的级别很低。最终会建立一种类似于XML的ID验证系统。现在,还只是低级别的函数。

    下面是IDProperty结构和ID结构(译者:以下代码摘自Blender2.8)

     1 typedef struct IDPropertyData {
     2     void *pointer;
     3     ListBase group;
     4     int val, val2;  /* note, we actually fit a double into these two ints */
     5 } IDPropertyData;
     6 
     7 typedef struct IDProperty {
     8     struct IDProperty *next, *prev;
     9     char type, subtype;
    10     short flag;
    11     char name[64];  /* MAX_IDPROP_NAME */
    12 
    13     /* saved is used to indicate if this struct has been saved yet.
    14      * seemed like a good idea as a pad var was needed anyway :) */
    15     int saved;
    16     IDPropertyData data;  /* note, alignment for 64 bits */
    17 
    18     /* array length, also (this is important!) string length + 1.
    19      * the idea is to be able to reuse array realloc functions on strings.*/
    20     int len;
    21 
    22     /* Strings and arrays are both buffered, though the buffer isn't saved. */
    23     /* totallen is total length of allocated array/string, including a buffer.
    24      * Note that the buffering is mild; the code comes from python's list implementation. */
    25     int totallen;
    26 } IDProperty;
    27 
    28 typedef struct ID {
    29     void *next, *prev;
    30     struct ID *newid;
    31     struct Library *lib;
    32     char name[66]; /* MAX_ID_NAME */
    33     /**
    34      * LIB_... flags report on status of the datablock this ID belongs to (persistent, saved to and read from .blend).
    35      */
    36     short flag;
    37     /**
    38      * LIB_TAG_... tags (runtime only, cleared at read time).
    39      */
    40     int tag;
    41     int us;
    42     int icon_id;
    43     int recalc;
    44     int pad;
    45     IDProperty *properties;
    46 
    47     IDOverrideStatic *override_static;  /* Reference linked ID which this one overrides. */
    48     void *pad1;
    49 
    50     void *py_instance;
    51 } ID;

    由ID获取ID属性

    由ID获取ID属性(具体说,是一个连接于ID的Group类型属性)用下面的函数:

     struct IDProperty *IDP_GetProperties(struct ID *id, int create_if_needed); 

     如果传入值为1的create_if_needed,将会自动创建并连接Group类型的IDProperty到ID,否则若ID中没有Group类型属性结构时将返回NULL。

    创建一个ID属性

    创建ID属性很容易;首先创建IDPropertyTemplate并设置适当的值。IDPropertyTemplate是一个联合体,这非常容易。若要设置float属性的数据,只需设置.f为浮点数;.i为整数;.str为字符串;数组的.array.len和.array.type(IDP_Float或IDP_int);对于新建group属性什么都不需要。

    一旦你创建了模板联合体,就可以将它与ID属性类型及其名称一起提供给IDP_New函数。下面是一个例子:

     1 IDPropertyTemplate val;
     2 IDProperty *group, *idgroup, *color;
     3 group = IDP_New(IDP_GROUP, val, "group1"); //groups don't need a template.
     4  
     5 val.array.len = 4
     6 val.array.type = IDP_FLOAT;
     7 color = IDP_New(IDP_ARRAY, val, "color1");
     8  
     9 idgroup = IDP_GetProperties(some_id, 1);
    10 IDP_AddToGroup(group, color);
    11 IDP_AddToGroup(idgroup, group);

    在组中查找ID属性

    查找ID属性使用下面的函数:

     IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, char *name); 

    下面这部分内容在Blender2.8版中已不存在了

    迭代组中的ID属性

    若要迭代组属性中的id属性,请分配一个void*指针,并使用此函数将其设置为迭代器:

     void *IDP_GetGroupIterator(struct IDProperty *prop); 

    然后你可用下面函数迭代:

     void *IDP_GroupIterNext(void *vself); 

    注意迭代器在迭代结束时自动释放,但如果停止迭代初期就可以释放它:

     void IDP_FreeIterBeforeEnd(void *vself); 

    使用它的一个例子:

    1 IDProperty *prop;
    2 void *iter = IDP_GetGroupIterator(some_group);
    3 for (prop=GroupIterNext(iter);prop;prop=GroupIterNext(iter)) {
    4    . . .
    5 }

    原文(Blender官方文档):https://wiki.blender.org/index.php/Dev:Source/Data_System/ID_Property,由于原文是基于Blender2.5的,译者结合2.8版代码作了修改。

  • 相关阅读:
    词法分析器实验报告(JAVA)
    词法编辑器(Java)
    编译原理的那些事
    Discuz7.2 faq.php页面注入漏洞分析
    Discuz7.2 XML漏洞
    Python 爬取广州商学院新闻----测试版
    进程调度
    DOS下的网络管理命令
    DOS批处理实验
    熟悉使用DOS操作命令
  • 原文地址:https://www.cnblogs.com/jiaping/p/8150627.html
Copyright © 2020-2023  润新知