//利用屬性分開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); }

