原视频:https://www.youtube.com/playlist?list=PLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI
Bili:Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili
Houdini版本:19.5
1、什么是字典
字典Dictionary与数组相似。
数组以【索引:值】方式存储数据,仅能存储单一数据类型。
字典以【key:值】方式存储数据(即键值对),能够存储多种数据类型。
2、字典声明Declare Dictionary
使用关键字dict创建字典
eg.创建一个类型为detail的AttributeWrangle节点,写入以下代码:
dict dictval = {}; //创建一个空字典
dict dictval2; 创建一个空字典变量名
dict dictval3 = set("a", 2.0, "b", 2);
dictval2 = set("key", 3.0, "nextkey", 5.0, "lastkey", "stringvalue");
d@dictval = dictval;
d@dictval2 = dictval2;
d@dictval3 = dictval3;
结果为:(应该是改版了,现在版本不显示数据类型了)
3、字典添加项/值
eg.创建一个类型为detail的AttributeWrangle(命名set_item)节点,写入以下代码:
dict dictval = {};
dictval['a'] = 2.0; //数值
dictval['b'] = 'abc'; //字符串
dictval['w'] = set(3, 2, 1); //向量
dictval['s'] = {4, 3, 3, 1}; //数组
dictval['d'] = set('aa', 2.3, 'kk', 10); //字典
d@dictval = dictval;
结果为:
4、字典删除项/值
使用 removeindex() 删除,删除成功返回整数1,否则返回0.
eg.在【2、Set Item to Dictionary字典添加值】的节点下再添加一个类型为detail的AttributeWrangle(命名remove_item),写入以下代码:
dict dictval = d@dictval; //获取上个节点的字典数据
int removed = removeindex(dictval, 'a'); //删除key为‘a'的数据
i@removed = removed; //删除成功返回1,否则返回0
d@dictval = dictval;
结果为:'a'的值已删除
5、检查字典Key值
使用 isvalidindex() 检查Key值是否存在,存在返回1,否则返回0。
eg.在【3、 Remove Item from Dictionary字典删除值】的节点下再添加一个类型为detail的AttributeWrangle(命名check_key),写入以下代码:
dict dictval = d@dictval;
int haskey1 = isvalidindex(dictval, 'w');
int haskey2 = isvalidindex(dictval, 'f');
i@haskey1 = haskey1; //key存在,值为1
i@haskey2 = haskey2; //key不存在,值为0
结果为:
6、访问字典值
主要是使用 getcomp() 访问函数,不存在是可返回自定义数值(用来检查Key值也ok)
eg.创建一个类型为detail的AttributeWrangle(命名access_dictionary)节点,写入以下代码:
dict dictval = set('a', 3.2, 'k', 'text');
//访问字典值之前,必须知道并指定值的数据类型
float cval1 = dictval['a'];
string cval2 = dictval['a'];
float cval3 = dictval['k'];
float cval4 = getcomp(dictval, 'c', -10); //访问函数,可自定义返回值
f@cval1 = cval1; //a存在,返回对应的值3.2
s@cval2 = cval2; //a键的值不是字符串,故不存在,返回Null值
f@cval3 = cval3; //k键的值不是数值,故不存在,返回0.0
f@cval4 = cval4; //c键的值不存在,返回自定义值 -10.0
结果为:
7、合并字典
使用 insert() 函数合并俩字典
eg. 创建一个类型为detail的AttributeWrangle(命名insert_dictionary)节点,写入以下代码:
dict dictval1 = set('a', 1, 'b', 2);
dict dictval2 = set('c', 3, 'd', 4);
insert(dictval1, dictval2); //字典dictval2插入到字典dictval1中
d@dictval = dictval1;
结果为:
8、字典转JSON格式
JSON是一种文本格式。使用 json_dumps(字典名, int) 函数进行转换。点击查看官方文档说明。
int值参数:范围可选0~3,代表不同的表现方式,感兴趣可以用下面的案例用font节点引用查看结果。
eg.创建一个类型为detail的AttributeWrangle(命名to_json)节点,写入以下代码:
代码主要使用了【2、Set Item to Dictionary字典添加值】的代码
dict dictval = {};
dictval['a'] = 2.0; //数值
dictval['b'] = 'abc'; //字符串
dictval['w'] = set(3, 2, 1); //向量
dictval['s'] = {4, 3, 3, 1}; //数组
dictval['d'] = set('aa', 2.3, 'kk', 10); //字典
string json = json_dumps(dictval, 0); //字典转json格式
s@json = json;
结果为:结果看上去与【2、Set Item to Dictionary字典添加值】一样,但是里面的值已被转换成字符串string并表面数据类型(截图仅部分):
添加font节点,使用【`details('../to_json', 'json')`】引用json,显示结果为:略
9、JSON 转为字典格式
使用 json_loads(json名, int) 函数进行转换。点击查看官方文档说明。
int值参数:范围可选0~2,代表不同的表现方式,感兴趣可以继续用font节点引用查看结果。
eg.在 【7、Dictionary to JSON字典转JSON格式】节点下创建连接一个类型为detail的AttributeWrangle(命名to_dict)节点,写入以下代码:
string json = s@json;
dict dictval = json_loads(json, 1);
d@dictval = dictval;
结果与【2、Set Item to Dictionary字典添加值】相同:
10、练习1——随机颜色和缩放
eg.①创建一个Sphere(polygon)节点,暂不连接;
②创建并依次连接:box1节点(polygon)、isooffset1节点(转为Volume,细分50)、scatter节点(根据小球的细分生成相同粒子数量)(ForceTotalCount:npoints('../sphere1/'))、PointWrange节点(init_dict)并写入以下代码:
vector cd = noise(@P); //随机值,后面用于颜色
float s = noise(@P); //随机值,后面用于缩放
dict dictval = set('col', cd, 's', s);
//设置字典值,每个点运行一次,即每个点存储一个字典(col、s)
d@dictval =dictval;
③创建一个pointWrangle1节点,写入以下代码:
dict dictval = point(1, 'dictval', @ptnum);
vector col = dictval['col'];
float s = dictval['s'];
v@Cd = col;
@P *= s;
节点连接截图,及最终结果(小球随着细分变大大,其形状、颜色也随着变化):
11、练习2——创建渐变点
eg.①创建一个类型为detail的AttributeWrangle(命名init_dcit1)节点,写入以下代码:
dict dictvals[] = array(); //创建数据类型为数组的字典
// 创建10*10方格的点信息,坐标值、缩放系数、颜色系数存储到字典
for(int i=0; i<10; i++){
for(int n=0; n<10; n++){
dict dictval = {};
dictval['x'] = i;
dictval['y'] = n;
dictval['s'] = (i+n) * 0.05;
dictval['c'] = set(i / 10.0, n / 10.0, 1);
append(dictvals, dictval);
}
}
d[]@dictvals = dictvals;
②继续创建并连接一个类型为detail的AttributeWrangle(命名draw_grid)节点,写入以下代码:
dict dictvals[] = d[]@dictvals;
//根据前面的字典信息,在x、z平面创建网格点
for(int i=0; i<len(dictvals); i++){
dict dictval = dictvals[i];
int x = dictval['x'];
int y = dictval['y'];
float s = dictval['s'];
vector c = dictval['c'];
int pt = addpoint(0, set(x, 0, y));
setpointattrib(0, 'pscale', pt, s);
setpointattrib(0, 'Cd', pt, c);
}
③添加copytopoints1节点(第二个输入点连draw_grid节点)、Sphere小球节点(连第一个输入点),
结果为: