跳转到内容

arrays

本页内容* 概述 * 声明数组类型 * 访问和设置数组值 * 数组切片 * 数组与向量/矩阵间的复制 * 遍历数组 * 数组操作 * VCC编译指令 * 限制

概述

概述

VEX包含数组数据类型,在以下场景中非常有用:

  • 支持渐变参数
  • 使用import()函数从表面节点读取捕捉数据
  • 常规编程中需要数组的场景

注意 当前VEX不支持多维数组。

注意 在Snippet、Wrangle或其他函数内部定义的返回数组的函数需要使用function关键字。

以下示例展示了数组的一些高级用法:

surface
crazy(
string maps[] = { "Mandril.rat", "default.pic" };
export float alength = 0;
)
{
vector texclr, av[];
texclr = texture(maps[s+t > 1], s, t);
av = array( {1,0,0}, vector(nrandom()), t, texclr, {.5,0,0});
if (fit(noise(s*8), 0, 1, .3, .7) > t)
av = array(1, {0,1,0}, 0);
Cf = spline("linear", s, av);
alength = len(av);
}

声明数组类型

声明数组类型

声明数组变量的通用格式为成员类型 变量名[]

// my_array是浮点数数组
float my_array[];
// v是单个向量,vector_array是向量数组
vector v, vector_array[];
// str_array是字符串数组
string str_array[];

可以在方括号内指定大小,但VEX编译器目前会忽略该值。

声明返回数组的函数:

// 返回向量数组的函数
// 在WRANGLE/SNIPPET中无效:需使用function关键字
vector[] rgb_array()
{
...
};

嵌套函数存在类型歧义。注意Wrangles和Snippets总是隐式嵌套。声明嵌套的返回数组函数:

// 返回向量数组的函数
cvex
foo()
{
// 使用可选的'function'关键字避免类型歧义
function vector[] rgb_array()
{
...
};
}

指定字面量数组时,使用花括号并用逗号分隔数组成员:

vector an_array[] = { {1, 2, 3}, {2, 3, 4}, {4, 5, 6} };
vector[] rgb_array()
{
return { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };
}

注意 字面量数组在编译时构造,因此不能包含变量。

例如,以下代码会报错:

int arr[] = { my_var, other_var + 2 }; // 错误

要避免此错误,可使用运行时构造数组的array()函数:

int arr[] = array( my_var, other_var + 2 );

当向量预期位置指定标量时,编译器会将标量值赋给向量的所有分量:

vector an_array[] = { 1, 2, 3};
// an_array[] == { {1, 1, 1}, {2, 2, 2}, {3, 3, 3} }

array()函数从其参数创建数组:

int my_array[] = array(1, 2, 3, 4, 5);

可以使用array()生成任何类型的数组。 强制生成向量数组(例如):

vector (array (value1, value2, ...) );

访问和设置数组值

访问和设置数组值

使用数组名[索引]通过位置查找数组中的值。

vector bw[] = { 0, 1 };
// bw[] == { {0, 0, 0}, {1, 1, 1} }
Cf = bw[index];

数组边界在运行时检查。越界读取将返回0""。未来可能生成警告或可选的运行时错误。 向数组末尾之后写入会调整数组大小以包含写入索引,新条目将设为0""

使用Python风格索引,负索引表示从数组末尾开始的位置。

int nums[] = { 0, 1, 2, 3, 4, 5 };
int n = nums[10]; // 返回0
int b = nums[-2]; // 返回4
string strs[] = { };
string s = strs[20]; // 返回""

也可以使用方括号表示法赋值:

float nums[] = { };
nums[0] = 3.14;

getcompsetcomp函数等同于使用方括号表示法。)

注意 方括号运算符也适用于向量。可以用于矩阵:float a = m3[0][1];

数组切片

数组切片

方括号可以使用Python切片表示法提取子数组。

int nums[] = { 0, 1, 2, 3, 4, 5 };
int start[] = nums[0:2]; // { 0, 1 }
int end[] = nums[-2:]; // { 4, 5 }
int rev[] = nums[::-1]; // { 5, 4, 3, 2, 1, 0 }
int odd[] = nums[1::2]; // { 1, 3, 5 }

slice函数等同于使用基于切片的方括号表示法。

数组与向量/矩阵间的复制

数组与向量矩阵间的复制

赋值运算符支持在向量类型和浮点数数组之间赋值:

float x[];
// Cf和P是向量
x = set(P); // 将P的分量赋给数组x的对应成员
Cf = set(x); // 将x的前3个成员作为向量Cf的分量

如果数组长度不足以填充向量/矩阵,最后一个成员会重复填充。

float x[] = {1, 2} // 长度不足以填充向量
Cf = set(x); // Cf == {1, 2, 2}

也可以在矩阵类型和vector2/vector/vector4数组之间赋值:

vector2 v2[];
vector v[];
vector4 v4[];
matrix2 m2 = 1;
matrix3 m3 = 1;
matrix m4 = 1;
v = set(m3); // 将3x3矩阵的每行放入一个向量
m3 = set(v); // 将向量复制到矩阵的行向量中
v4 = set(m4); // 将矩阵的行提取到vector4数组
m4 = set(v4); // 使用数组中的vector4作为行向量创建矩阵

总结:

左侧 =右侧说明
vector2float[]例如 vector2 v = {1,2}
vectorfloat[]例如 vector v = {1,2,3}
vector4float[]例如 vector4 v = {1,2,3,4};
matrix2float[]例如 matrix2 m = {1,2,3,4};
matrix2vector2[]例如 matrix2 m = { {1,2}, {4,5} };
matrix3float[]例如 matrix3 m = {1,2,3,4,5,6,7,8,9};
matrix3vector[]例如 matrix3 m = { {1,2,3}, {4,5,6}, {7,8,9}};
matrixfloat[]例如 matrix m = {1,2,3,4,5,6,7,8,9.., 16};
matrixvector4[]例如 matrix m = { {1,2,3,4}, {5,6,7,8}, ... {13,14,15,16}};
float[]vector2从分量创建2个浮点数的数组
float[]vector从分量创建3个浮点数的数组
float[]vector4从分量创建4个浮点数的数组
float[]matrix2从matrix2创建4个浮点数的数组
vector2[]matrix2从matrix2创建2个vector2的数组
float[]matrix3从matrix3创建9个浮点数的数组
vector[]matrix3从matrix3创建3个向量的数组
float[]matrix4创建16个浮点数的数组
vector4[]matrix4创建4个vector4的数组

遍历数组

遍历数组

参见foreach

数组操作

数组操作

以下函数用于查询和操作数组:

resize

设置数组长度。如果数组扩大,中间值将为0""

len

返回数组长度。

pop

移除数组最后一项(数组大小减1)并返回。

removevalue

移除数组中第一个匹配的值。如果移除了项返回1,否则返回0

removeindex

移除给定索引处的项并返回。

push

向数组末尾添加项(数组大小加1)。

getcomp

获取数组组件的值,等同于数组[编号]

setcomp

设置数组组件的值,等同于数组[编号] = 值

array

高效地从参数创建数组。

serialize

将向量或矩阵数组展平为浮点数数组。

unserialize

反转serialize的效果:将浮点数平面数组组装为向量或矩阵数组。

neighbours

替代neighbourcount/neighbour组合的基于数组的方案。返回给定点的邻居点编号数组。

此外,以下函数也适用于数组:

VCC编译指令

vcc编译指令

ramp编译指令可为一组参数指定渐变用户界面。

#pragma ramp <渐变参数> <基础参数> <键参数> <值参数>

详见VCC编译指令

限制

限制

  • 当前VEX不支持多维数组
  • 数组不能在着色器之间传递(通过simport等)
  • 数组不能写入图像平面