HoudiniVex笔记_P9_Function函数

原视频:https://www.youtube.com/playlist?list=PLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI
Bili:Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili

Houdini版本:19.5

1、函数概述

函数可以理解为,把一个经常使用的代码块\动作提取出来(百度解释:是一个用于执行特定的任务并返回结果)。

文档速查:
点击直达VEX Functions
点击直达VEX language reference
点击直达VEX contexts
(快速打开文档:在Houdini中点击右上方的?号,复制地址到浏览器打开即可)

2、无返回值函数void function

以 append()函数为例,官方文档解释截图如下:

append()意思为,将 ‘值’ 添加到数组或字符串中

eg.创建类型为detail的attributewrangle节点(void_function),写入下面代码:

int values[] = array();     //创建一个空数组
for(int i=0; i<100; i++){
    append(values, i);      //依次将i值加入到数组
}

i[]@values = values;
//数组values[]值为0~99

3、有返回值函数return function

以len()函数统计长度函数为例 ,官方文档解释

eg.创建类型为detail的attributewrangle节点(vreturn_function),写入下面代码:

int values[] = array();     //创建一个空数组
for(int i=0; i<100; i++){
    append(values, i);      //依次将i值加入到数组
}

int size = len(values);     //len函数返回一个整数int值,值为参数的长度
i@size = size;
//结果为:size值为100

4、函数练习1—寻找最近点

eg.使用nearpoints()函数寻找最近点看,点击查看函数官方文档说明

创建3个节点:小球Sphere、Scatter(ForceTotalCount改为100)、类型为detail的attributewrangle节点(function_parameters1)。将它们依次连接。再添加一个Add节点,点击+号添加1个点,并对点进行移动(可直接拖动或直接在属性面板更改位置)

 在AttributeWrangle节点(function_parameters1)中写入以下代码:

常用使用方法一:

vector pos = point(1, 'P', 0);
int npt = nearpoint(0, pos);

i@npt = npt;

setpointattrib(0, 'Cd', npt, set(1, 0, 0));    //距离Add最近的点设置为红色

常用使用方法二:先对点进行分类或筛选,对方法一代码进行修改如下

vector pos = point(1, 'P', 0);
int npt = nearpoint(0, '@P.x>0.0', chf('dist'));
//此处的参数('@P.x>0.0')可以使用Group节点替代

i@npt = npt;

setpointattrib(0, 'Cd', npt, set(1, 0, 0));

结果为:

5、函数练习2—相交点

使用 intersect()函数 寻找相交点,点击直达官方文档说明

intersect()函数常用于太阳/灯光照射物体在地面的对象上的投影。

intersect() 函数:计算光线与几何图形的第一次交点。与图元primitive相交则返回相交点primtnum,不相交返回-1

geometry:与第几个输入点的对象相交,0为第一个输入点对象,1位第二个输入点对象…
vector orig :射线原点
vector dir :射线方向和距离(向量长度)。
&p :射线与primitive相交的点。
&u,&v,&uvw :射线与primitive相交的UV(3D物体在2D平面的展示?)。

eg.创建3个节点:圆环torus(向上稍微移动并稍微旋转)、Scatter、类型为Points的attributewrangle节点(output_parameter)。将它们依次连接。再添加一个grid1节点,连接在attributewrangle节点(output_parameter)的第二个输入点:

 在AttributeWrangle节点(function_parameters1)中写入以下代码:

vector p;
float u, v;

int inter = intersect(1, @P, set(0, -10, 0), p, u, v);
//圆环torus的所有点(参数:@P),沿-Y轴方向发射距离为10的射线,检测相对对象为第二个输入点的对象(第一个参数:1)
//P、U、V:有相交,则被重写为相交点的P、U、V

@P = p;
i@inter = inter;
//属性inter为相交的primtnum点,没相交的点值为-1

结果为:圆环被投射在网格Grid 上,下图为前后结果对比:

6、自定义无返回值函数(点击查看官方文档说明

创建类型为detail的attributewrangle节点(user_defined_void_function),写入下面代码:

//无返回值函数基本用法: void 函数名(变量类型;变量类型;……)
void sprialPos(float ang, rad; vector pos){
    vector newpos = pos + set(cos(ang), 0, sin(ang)) * rad;
    int pt = addpoint(0, newpos);
}

vector pos = (0, 0, 0);//point(1, 'p', 0);
for(int i=0; i<100; i++){
    //调用函数,函数名字、变量类型一一对应
    sprialPos($PI * chf('ang')*i, i*chf('rad'), pos);   //循环内,角度ang、半径rad递增
}

 结果随角度ang、半径变化。
下图为半径不变,滑动角度ang(值0~1)的结果:(如果把点相连,结果就更直观了,可以去看第十四节笔记的【5、练习2——Sprial Rotation螺旋旋转】的结果)

7、自定义有返回值函数

与【6、自定义无返回值函数】类似,对其代码进行修改

//Function 返回的数据类型 函数名(变量类型;变量类型;……)
function vector sprialPos(float ang, rad; vector pos){
    vector newpos = pos + set(cos(ang), 0, sin(ang)) * rad;
    return newpos;   
    //返回一个向量
}

vector pos = (0, 0, 0);
for(int i=0; i<100; i++){
    //调用函数,函数名字、变量类型一一对应
    vector npos = sprialPos($PI * chf('ang')*i, i*chf('rad'), pos);   
    int pt = addpoint(0, npos);
}

函数需要与return配合使用

代码运行结果与【6、自定义无返回值函数】相同。

eg扩展.对上面的函数代码加入if-lese条件判断,使它在0~180°、180°~360°之间执行不同动作

//Function 返回的数据类型 函数名(变量类型;变量类型;……)
function vector sprialPos(float ang, rad; vector pos){
    float val = ang % ($PI *2.0);   //余数运算 $PI *2.0 = 360°
    if(val < $PI){
        vector newpos = pos + set(cos(ang), 0, sin(ang)) * rad;
        return newpos;   
    }else{
        vector newpos = pos - set(cos(-ang), 0, sin(-ang)) * rad;
        return newpos; 
    }
    //返回一个向量
}

vector pos = (0, 0, 0);//point(1, 'p', 0);
for(int i=0; i<100; i++){
    //调用函数,函数名字、变量类型一一对应
    vector npos = sprialPos($PI * chf('ang')*i, i*chf('rad'), pos);   
    int pt = addpoint(0, npos);
    //循环内,角度ang、半径rad递增
}

结果:生成的点相似镜像,感兴趣可自行尝试。

8、自定义输出参数函数

在函数变量内使用  export关键字+数据类型+变量名字(与【7、自定义有返回值函数】类似)

eg、对【6、自定义无返回值函数】的代码进行修改

//与【7、自定义有返回值函数】相似 多了个export关键字来定义变量
//void 函数名(变量类型;变量类型;……; export 数据类型 参数名字)
void sprialPos(float ang, rad; vector pos; export vector spos){
    vector newpos = pos + set(cos(ang), 0, sin(ang)) * rad;
    spos = newpos;
}

vector pos = (0, 0, 0);
for(int i=0; i<100; i++){
    vector spos;
    //调用函数,函数名字、变量类型一一对应
    sprialPos($PI * chf('ang')*i, i*chf('rad'), pos, spos); 
    //可直接使用函数的变量spos,相当于返回值(需自定义)
    int pt = addpoint(0, spos);
}

代码运行结果与【6、自定义无返回值函数】相同。

9、导入外部函数—houdini外部函数

可以理解为导入脚本,使用【#include "脚本名字"】导入。houdini的外部函数在【安装目录\vex\include】内,格式为【.h】结尾。

eg.以函数groom.h为例,使用其中的【调整prim曲线长度】功能,其函数声明为:

 如下图创建节点并进行设置:对字体设置为描边并进行重新采样(均匀分布并增加点,使用measure节点对字体描边进行测量)

创类型为Pirmitives的attributewrangle节点(include_external_function1),写入下面代码:

#include "groom.h"
//使用函数前,需使用#include关键字导入脚本

//根据具体用法调用函数
adjustPrimLength(0, @primnum, @perimeter, min(@perimeter, chf('length')));
//@perimeter为measure节点测量字体描边长度值
//min(a,b)函数取括号内最小值

 结果为:字体随数值length变大逐渐显现

10、导入外部函数—自定义函数

使用【#include "全路径/脚本名字"】导入脚本。

eg.把【7、自定义有返回值函数】的函数代码

void sprialPos(float ang, rad; vector pos; export vector spos){
    vector newpos = pos + set(cos(ang), 0, sin(ang)) * rad;
    spos = newpos;
}

使用记事本保存命名为【 sprialPos】,并将格式改为【.h】,
创建类型为detail的attributewrangle节点(include_external_function2),写入下面代码:

#include "D:\HoudiniProject\Strongest VEX\sprialPos.h"
//脚本路径在当前项目下,路径可写为  "$HIP\sprialPos.h"

vector pos = (0, 0, 0);
for(int i=0; i<100; i++){
    vector npos = sprialPos($PI * chf('ang')*i, i*chf('rad'), pos); 
    int pt = addpoint(0, npos);
}

代码运行结果与【6、自定义无返回值函数】相同。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值