Houdini Volume Deform 奇 思


最近在做Houdini Volume的一些結算,工作的過程中突然閃現一個想法,可不可以把Houdini 中 Point Deform 節點的原理和算法運用到Volume上 ? 經過測試, 發現是可以的。

Point Deform 是根據 模型的變形(Geometry Deform) 來改變點的位置。利用模型的變形的好處是:模型本身的點相對少,內存占用少些,效率更高。Volume Deform 運用Point Deform相同的原理,利用模型變形的信息的話,會繼承它的這些優點。

在這之前想說的是,還有很多Volume Deform的方法,這里只是提供另一個思路~

測試的Demo如下:

 

這題的框架如下圖:

 

其中compute_xforms_sequential是Point Deform節點中對應的相應節點,注意的是我測試用的Houdini版本是16。目前houdini 18的話,Point Deform會:如果模型中(第二個端口)存在id屬性,會優先使用id,而不是ptnum(點號)。

上圖中VolumeDeform的參數和代碼整合如下:

 // vex

 

// ************************************************
// Capture and CaptWeights
// ************************************************
float radius = ch("radius");
int maxpt = chi("maxpt");
int minpt = chi("minpt");

int pCaptPts[];
float pCaptWeights[];

pCaptPts = pcfind(1, 'P', @P, radius, maxpt);
if (len(pCaptPts) < minpt)
{
    pCaptPts = pcfind(1, 'P', @P, 1e15, minpt);
    radius = 1.1 * distance(@P, point(1, 'P', pCaptPts[-1]));
}

foreach (int pt; pCaptPts)
{
    float r2 = distance2( vector(point(1, 'P', pt)), @P );
    r2 /= radius*radius;
    float weight = 1-r2;
    weight *= weight;
    //weight = 1-weight;
    
    push(pCaptWeights, weight);
}

// ************************************************
// Compute Offset
//*************************************************
float totalweight = 0;
vector delta = 0;
matrix3 totalxform = 0;
vector offset;
foreach (int idx; int pt; pCaptPts)
{
    vector oldcenter = point(1, 'P', pt);
    vector diff = point(2, 'P', pt) - oldcenter;
    matrix3 xform = point(1, 'xform', pt);
    float weight = pCaptWeights[idx]; 
    
    // Compute our new location according this xform.
    vector newp = @P;
    newp -= oldcenter;
    newp *= xform;
    newp += oldcenter;
    newp += diff;
    diff = newp - @P;
    delta += diff * weight;
    totalweight += weight;
    totalxform += xform * weight;
}

delta /= totalweight;
//@P += delta;
offset = delta;

if (totalweight > 0)
{
    totalxform /= totalweight;
    if (chi("rigidprojection"))
        totalxform = polardecomp(totalxform);
   
}

// ************************************************
//Deform
// ************************************************
 f@density = volumesample(3,0,@P + offset);
View Code

 

另外的思路

//利用 Tetrahedral Mesh 來Deform Volume,在Applied Houdini - Volumes VI 中學的新思路

 主要是利用了tetrahedral mesh的一個特性,tetrahedral mesh是由一個個四面體組成的,而且是實體的四面體,基本結構如下圖:

tetrahedral mesh 很重要的一個特性 ,是用xyzdist 函數時, 比如

int prim;
vector uvw;
xyzdist(1,@P,prim,uvw);
v@pos = primuv(1,"P",prim,uvw);

使用xyzdist采樣第二個接口的tetrahedral mesh時, 如果這個點在tetrahedral mesh的體積內,最終的pos其實就是當前點的位置 即 @pos等於@P;如果在tetrahedral mesh的體積外,位置就有誤差了。這也側面解釋了,如果對tetrahedral mesh變形用力過大,比如組成它的某個四面體,如下變形(翻轉了,1點本來在2、3點的左邊,后來跑右面了)

這種變形過大的情況會造成Volume Deform的誤差。

利用這個特性,完全可以先變形tetrahedral mesh,然后利用primuv得到點在變形后的tet mesh的prim和uvw,再根據prim,uvw得到點在原始的tet mesh中的位置信息,最后用得到的位置信息采樣原始的Volume,結構如下圖

pointwrangle2中的代碼如下:

int prim;
vector uvw;

float dist = xyzdist(1,@P,prim,uvw);
vector origP = primuv(2,"P",prim,uvw);

@density = volumesample(3,"density",origP);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM