//利用属性分开Primitive
Primitive Split 节点中Attribute 设置为split 。Wrangle中代码为: f@split = @ptnum>10?1:4;
比较程序化的是利用Houdini 的Paint 节点,给物体描绘上颜色,然后利用颜色属性把Primitive 分开
//曲线(在Vex中实现Carve节点的功能)
最近在做植物生长的rnd,期间生成了大量的curve,急需有能有个类似Carve节点的vex 函数,发现Vimeo上有大神用vex实现了这个功能(https://vimeo.com/104891696),后来在Odforce上看到,其实Houdini的Include文件中,有一个函数adjustPrimLength(在$HFS/houdini/vex/include/groom.h文件中定义)实现了这个功能,写的极其简洁,很美。具体代码如下:
void adjustPrimLength(const int geo, prim; const float currentlength, targetlength) { float diff = targetlength - currentlength; int points[] = primpoints(geo, prim); if(diff > 0) { vector posA = point(geo, "P", points[-2]); vector posB = point(geo, "P", points[-1]); vector posC = diff * normalize(posB-posA) + posB; int ptnum = addpoint(geo, posC); addvertex(geo, prim, ptnum); } else if(diff < 0) { vector lastpos = 0; float length = 0; int cut = 0; foreach(int idx; int pt; points) { vector pos = point(geo, "P", pt); if(idx > 0 && !cut) { float seglength = distance(pos, lastpos); if(length+seglength > targetlength) { float frac = (targetlength-length)/seglength; vector newpos = lerp(lastpos, pos, frac); int ptnum = addpoint(geo, newpos); for(int i=idx; i<len(points); i++) removepoint(geo, points[i]); addvertex(geo, prim, ptnum); break; } length += seglength; } lastpos = pos; } } }
在Houdini中的使用如下,首先每条Curve需要有一个属性 @perimeter,记录曲线的长度,这个属性可以由Measure节点实现(Type设成Perimeter,Attribute设成perimeter)。然后下面接一个primitive wrangle 节点(Run Over设成Primitives),里面代码如下:
#include <groom.h> adjustPrimLength(0, @primnum, @perimeter, @perimeter*chf("dist"));
前后对比如下:
实际应用中,应该把dist也设置成属性,来更方便的控制:adjustPrimLength(0, @primnum, @perimeter, @perimeter*@dist);
//Pack 物体 ,传递Name属性
利用pack 节点pack 物体后,把name从原来的primitive传递到point
s@name = primintrinsic(0, "fragmentname", @primnum);
//VEX 隐藏属性: primive的P属性
新建一个Grid, 下面接一个point wrangle ,代码如下:
@P = prim(0,"P",@primnum);
再接一个 delete , 删掉primitive,保留点,把之前的Grid template 显示,可以看到点移到primitive 的中心去了,不过如果两个面共享一个点时,这时这个点会跑到一个面的中心,但是对于Pack物体来说,就无所谓了,一个Primitive就对应一个点
// Cone Twist Contraint 的配置
Primitive Wrangle
s@constraint_name = "cone"; s@constraint_type = "all"; v@constrained_twist_axis = @N; v@constrained_up_axis = set(0,1,0); v@goal_twist_axis = @N; v@goal_up_axis = set(0,1,0);
// 两点组成的曲线
primitive wrangle
int pointindex(int prim; int vtx) { return vertexpoint(geoself(), vertexindex(geoself(), prim, vtx)); } int pt0 = pointindex(@primnum, 0); int pt1 = pointindex(@primnum, 1); f@restlength = distance(pt0,pt1);
// 临界边
比较有意思,实现起来其实不难,想法比较好。先把Surface碎开,如下图左。然后用Divide节点,勾选 Remove Shared Edges,图中。
然后,Wrangle如下,把边上的点删掉,只留顶点,最后用Convertline转成线,就得到一个简单的邻边。
if(len(nearpoints(0,@P,0.0001))<3) { removepoint(geoself(),@ptnum); }