zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    Ubuntu 16 安装redis客户端
    crontab 参数详解
    PHP模拟登录发送闪存
    Nginx配置端口访问的网站
    Linux 增加对外开放的端口
    Linux 实用指令之查看端口开启情况
    无敌的极路由
    不同的域名可以指向同一个项目
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error
    Redis 创建多个端口
  • 原文地址:https://www.cnblogs.com/peng-vfx/p/12495492.html
Copyright © 2011-2022 走看看