惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Heimdal Security Blog
SecWiki News
SecWiki News
H
Hacker News: Front Page
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
AI
AI
C
Cybersecurity and Infrastructure Security Agency CISA
Scott Helme
Scott Helme
PCI Perspectives
PCI Perspectives
S
Securelist
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Cyberwarzone
Cyberwarzone
A
Arctic Wolf
Forbes - Security
Forbes - Security
T
Tor Project blog
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
I
Intezer
Martin Fowler
Martin Fowler
Help Net Security
Help Net Security
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
博客园 - 司徒正美
W
WeLiveSecurity
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
V
Vulnerabilities – Threatpost
Jina AI
Jina AI
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
Simon Willison's Weblog
Simon Willison's Weblog
Project Zero
Project Zero
T
Threatpost
P
Privacy International News Feed
人人都是产品经理
人人都是产品经理
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research

博客园 - 平凡人

std::atomic linux学习-目录 C++设计模式--PIMPL c++的RAII C++技术之---标准容器的值语义 blender学习系列之--CLOG Blender中的DNA QT元对象系统(Meta-Object System) Blender文档翻译:ID Datablocks(ID数据块) Blender内存管理库(bf_intern_guardedalloc) IDA\Windbg调试 - 平凡人 - 博客园 IOCTL(CTL_CODE) 内核开发速查表 Blender中的事件处理器 Blender:SDNA QT信号和槽 利用QEventLoop实现同步等待信号槽返回结果 Blender文档翻译:Operators tutorial(操作教程) Blender文档翻译:Operators Blender文档翻译:RNA
Blender文档翻译-Blender库数据的通用属性
平凡人 · 2017-12-30 · via 博客园 - 平凡人

 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版代码作了修改。