zoukankan      html  css  js  c++  java
  • Interpolation particles In Katana

    I write the sphere radius interpolation for katana plugin that can transfer attributes,render attributes ,render velocity motion blur directly.

     

    --GLY_MATH header source:

    //
    // Created by gearslogy on 4/13/16.
    //
    
    #ifndef GLY_POINTSINTERPOLATION_GLY_COMMON_MATH_H
    #define GLY_POINTSINTERPOLATION_GLY_COMMON_MATH_H
    
    
    #include <stdlib.h>
    #include <string>
    #include <vector>
    #include <sstream>
    #define gly_rand_01 double(rand()) / double(RAND_MAX)
    
    namespace GLY_MATH
    {
        template <typename T>
        T min(T a,T b)
        {
            if(a>b)
            {
                return b;
            }
            else
            {
                return a;
            }
        }
        template <typename T>
        T max(T a,T b)
        {
            if(a>b)
            {
                return a;
            }
            else
            {
                return b;
            }
        }
    
        template <typename T>
        int zero_compare(T a, double tol=0.00001)
        {
            return a >= -tol && a <= tol;
        }
    
        // DO NOT USE THIS FIT TO FIT VECTOR VALUE
        template <typename T>
        T fit(T var, T omin, T omax,T nmin, T nmax)
        {
            T d = omax-omin;
            if(zero_compare(d))
            {
                return (nmin+nmax)*0.5;
            }
            if(omin<omax)
            {
                if (var < omin) return nmin;
                if (var > omax) return nmax;
            }
            else
            {
                if (var < omax) return nmax;
                if (var > omin) return nmin;
            }
            return nmin + (nmax-nmin)*(var-omin)/d;
        }
    
        //return -1 to 1
        template <typename  T>
        T fit_negate(T var,T omin,T omax)
        {
            return fit(var,omin,omax,-1.0,1.0);
        }
        // fast random 01 var
        double random_01_value(int seed)
        {
            srand(seed);
            return gly_rand_01;
        }
    
        //string split
        std::vector <std::string> split_string(std::string &inputString, char &split_char)
        {
            std::stringstream ss(inputString);
            std::string sub_str;
            std::vector <std::string> sp_strPath;
            sp_strPath.clear();
            while(getline(ss,sub_str,split_char))
            {
                sp_strPath.push_back(sub_str);
            }
            return sp_strPath;
        }
    
        //value to string
        template <typename T>
        // T must be a value int/float/double
        std::string value_to_str(T &value)
        {
            std::ostringstream os;
            os<< value;
            return os.str();
        }
    
    }
    
    #endif //GLY_POINTSINTERPOLATION_GLY_COMMON_MATH_H
    View Code

    --Arnold Source Code:

    #include <ai.h>
    #include <stdio.h>
    #include <cstring>
    #include "GLY_common_math.h"
    #include <vector>
    #include <string>
    #include <omp.h>
    #include <assert.h>
    using namespace std;
    #define RAND_NORMALIZE float(rand()) / float(RAND_MAX)
    
    // global variables for read data
    
    //@pt_radius = point radius
    float pt_radius;
    //@pt_list_num = point interpolation num
    AtUInt32 pt_list_num;
    
    //
    float replicate_radius;
    AtArray *offset_vec;
    AtArray *frequency_vec;
    
    //motion blur param
    //@pt_use_vel_mb choose should use motion blur
    
    int pt_use_vel_mb;
    float shuffer_open_val;
    float shuffer_close_val;
    
    //exist attribute
    AtArray *id_array_list; //Katana particles id ->define named "ins_id" from houdini abc
    AtArray *pos_array_list; // Katana particles P ->define named "P" from houdini abc
    AtArray *vel_array_list;
    
    // other attribute
    string attribute_list;
    struct katana_attribute_map
    {
        string name;
        AtArray *map_array;
        //@map_array type = AI_TYPE_BYTE  ->0
        //@map_array type = AI_TYPE_INT   ->1
        //@map_array type = AI_TYPE_FLOAT ->4
        //@map_array type = AI_TYPE_POINT ->8
    
    };
    
    vector <katana_attribute_map> att_maps;
    
    
    
    //get shuffer open pos
    AtVector get_shuffer_open_pos(AtVector &curl_v,AtVector &curl_p,
                                  float shuffer_open_val)
    {
        return curl_p+curl_v*shuffer_open_val;
    }
    // get shuffer close pos
    AtVector get_shuffer_close_pos(AtVector &curl_v,AtVector &curl_p,
                                   float shuffer_close_val)
    {
        return curl_p+curl_v*shuffer_close_val;
    }
    
    
    
    // this is set the constant radius
    static void setConstantRadius(AtArray *radius_array , float &rad)
    {
        #pragma omp parallel for
        for(int i=0;i<radius_array->nelements;i++)
        {
            AiArraySetFlt(radius_array,i,rad);
        }
    }
    
    //@shuffer_value may be open or close value
    //@cur_pos_array is the new pos from the interpolation array
    //@orig_velocity_array is from katana
    
    static AtArray* createMotionBlurOpenPoints(AtArray *orig_velocity_array,
                                           AtArray *cur_pos_array,float shuffer_value,AtUInt32 &iter_num)
    {
    
        AtInt32 num_pt = orig_velocity_array->nelements/3;
        printf("motion open ->get the num_pt is %d 
    ",num_pt);
        AtArray *_motion_points = AiArrayAllocate(cur_pos_array->nelements,1,AI_TYPE_POINT);
    
        vector <AtVector> large_vel_list;
    
        // THIS IS NOT SIMD PROGRAM
        /*
        for(AtUInt32 i=0;i<num_pt;i++)
        {
    
            AtVector __vel;
            __vel.x = AiArrayGetFlt(orig_velocity_array,i*3 + 0);
            __vel.y = AiArrayGetFlt(orig_velocity_array,i*3 + 1);
            __vel.z = AiArrayGetFlt(orig_velocity_array,i*3 + 2);
    
            for(int j=0;j<iter_num;j++)
            {
                large_vel_list.push_back(__vel);
            }
    
        }
        printf("motion open ->get the large vel array size is %d
    ",large_vel_list.size());
        printf("motion open ->get the pos array size is %d
    ",cur_pos_array->nelements);
       */
        large_vel_list.resize(iter_num * num_pt); // TELL THE GCC SIZE ,INDEX THE THREAD
        #pragma omp parallel for
        for(AtUInt32 i=0;i<num_pt;i++)
        {
    
            AtVector __vel;
            __vel.x = AiArrayGetFlt(orig_velocity_array,i*3 + 0);
            __vel.y = AiArrayGetFlt(orig_velocity_array,i*3 + 1);
            __vel.z = AiArrayGetFlt(orig_velocity_array,i*3 + 2);
    
            for(int j=0;j<iter_num;j++)
            {
                large_vel_list[i * iter_num + j ] = __vel;
            }
    
        }
    
        #pragma omp parallel for
        for(int i=0; i<large_vel_list.size();i++)
        {
            AtVector __vel = large_vel_list[i];
            AtVector __pos = AiArrayGetPnt(cur_pos_array,i);
            AtVector __open_pos = get_shuffer_open_pos(__vel,__pos,shuffer_value);
            AiArraySetPnt(_motion_points,i,__open_pos);
        }
        return _motion_points;
        printf("motion open -> end
     ");
    }
    
    static AtArray* createMotionBlurClosePoints(AtArray *orig_velocity_array,
                                               AtArray *cur_pos_array,float shuffer_value,AtUInt32 &iter_num)
    {
    
        AtInt32 num_pt = orig_velocity_array->nelements/3;
        printf("motion open ->get the num_pt is %d 
    ",num_pt);
        AtArray *_motion_points = AiArrayAllocate(cur_pos_array->nelements,1,AI_TYPE_POINT);
    
    
        vector <AtVector> large_vel_list;
        /*
        for(AtUInt32 i=0;i<num_pt;i++)
        {
    
            AtVector __vel;
            __vel.x = AiArrayGetFlt(orig_velocity_array,i*3 + 0);
            __vel.y = AiArrayGetFlt(orig_velocity_array,i*3 + 1);
            __vel.z = AiArrayGetFlt(orig_velocity_array,i*3 + 2);
    
            for(int j=0;j<iter_num;j++)
            {
                large_vel_list.push_back(__vel);
            }
    
        }*/
    
        //SIMD METHOD
        large_vel_list.resize(iter_num*num_pt);
        #pragma omp parallel for
        for(AtUInt32 i=0;i<num_pt;i++)
        {
    
            AtVector __vel;
            __vel.x = AiArrayGetFlt(orig_velocity_array,i*3 + 0);
            __vel.y = AiArrayGetFlt(orig_velocity_array,i*3 + 1);
            __vel.z = AiArrayGetFlt(orig_velocity_array,i*3 + 2);
    
            for(int j=0;j<iter_num;j++)
            {
                large_vel_list[i * iter_num + j] = __vel;
            }
    
        }
    
        #pragma omp parallel for
        for(int i=0; i<large_vel_list.size();i++)
        {
            AtVector __vel = large_vel_list[i];
            AtVector __pos = AiArrayGetPnt(cur_pos_array,i);
            AtVector __close_pos = get_shuffer_close_pos(__vel,__pos,shuffer_value);
            AiArraySetPnt(_motion_points,i,__close_pos);
        }
        return _motion_points;
        printf("motion close -> end
     ");
    }
    
    
    
    
    //transfer the vector attribute to the replicate points
    static void fork_vector_attribute(AtArray *src_vector_array,AtArray *des_vector_array,AtUInt32 &iter_num)
    {
        float *src_vec_data = static_cast<float *> (src_vector_array->data);
        AtUInt32 src_num_pt = src_vector_array->nelements/3;// divide 3 because from Katana is a float array..
    
        vector <AtRGBA> src_vec_list;
        src_vec_list.resize(src_num_pt * iter_num);
        #pragma omp parallel for
        for(AtUInt32 i=0; i<src_num_pt; i++)
        {
            AtRGBA __vec;
            __vec.r = src_vec_data[i*3 + 0];
            __vec.g = src_vec_data[i*3 + 1];
            __vec.b = src_vec_data[i*3 + 2];
            __vec.a = 1.0f;
            for(int j=0;j<iter_num;j++)
            {
                //src_vec_list.push_back(__vec);
                src_vec_list[i*iter_num + j] = __vec;
            }
        }
        assert(src_vec_list.size() == des_vector_array->nelements);
        #pragma omp parallel for
        for(AtUInt32 i=0;i<src_vec_list.size();i++)
        {
            AiArraySetRGBA(des_vector_array,i,src_vec_list[i]);
        }
    }
    
    
    
    //transfer the float attribute to the replicate points
    
    static void fork_float_attribute(AtArray *src_float_array,AtArray *des_vector_array,AtUInt32 &iter_num)
    {
        float *src_flt_data = static_cast<float *>(src_float_array->data);
        AtUInt32 src_num_pt = src_float_array->nelements;
    
        vector <AtRGBA> src_vec_list;
        src_vec_list.resize(src_num_pt * iter_num);
    
        #pragma omp parallel for
        for(AtUInt32 i=0;i<src_num_pt; i++)
        {
            // convert float to the RGBA,"use_data_rgb/user_data_rgba" node get attribute in katana
            AtRGBA __vec;
            __vec.r = src_flt_data[i];
            __vec.g = src_flt_data[i];
            __vec.b = src_flt_data[i];
            __vec.a = 1.0f;
            for(int j=0;j<iter_num;j++)
            {
                src_vec_list[i*iter_num + j] = __vec;
            }
    
        }
        assert(src_vec_list.size() == des_vector_array->nelements);
        #pragma omp parallel for
        for(int j=0;j<src_vec_list.size();j++)
        {
            AiArraySetRGBA(des_vector_array,j,src_vec_list[j]);
        }
    
    }
    
    
    //create point replicate
    static AtArray * makeSpherePoints(AtInt32 iter_num,AtInt32 orig_num_pt,AtArray *orig_pos_array,AtArray *orig_id_array)
    {
    
    
        AtVector _offset;
        _offset.x = AiArrayGetFlt(offset_vec,0);
        _offset.y = AiArrayGetFlt(offset_vec,1);
        _offset.z = AiArrayGetFlt(offset_vec,2);
    
        AtVector _frequency;
        _frequency.x = AiArrayGetFlt(frequency_vec,0);
        _frequency.y = AiArrayGetFlt(frequency_vec,1);
        _frequency.z = AiArrayGetFlt(frequency_vec,2);
    
    
        AtInt32 num_pt = iter_num * orig_num_pt;
        AtArray *_sphere_pos_array = AiArrayAllocate(num_pt,1,AI_TYPE_POINT);
    
        assert(orig_pos_array->type==4); // 4 is the AI_TYPE_FLOAT,because from katana P data is Array Float....
        assert(orig_id_array->type==1); // 1 is the AI_TYPE_INT
    
        vector <AtVector> child_pt_pos_list;
    
        for(AtUInt32 i=0;i<orig_id_array->nelements;i++)
        {
            int _id = AiArrayGetInt(orig_id_array,i);
            AtVector orig_pos;
            orig_pos.x = AiArrayGetFlt(orig_pos_array,i*3 + 0);
            orig_pos.y = AiArrayGetFlt(orig_pos_array,i*3 + 1);
            orig_pos.z = AiArrayGetFlt(orig_pos_array,i*3 + 2);
    
            //printf("orig_pos_x -> : %f 
    ",orig_pos.x);
            //printf("orig_pos_y -> : %f 
    ",orig_pos.y);
            //printf("orig_pos_z -> : %f 
    ",orig_pos.z);
            for(int k=0;k<iter_num;k++)
            {
                AtVector pt;
                srand(_id * 5000 + k*1000+100);
                pt.x=GLY_MATH::fit(RAND_NORMALIZE,0.0f,1.0f,-1.0f,1.0f);
                srand(_id * 111000 + k*10000+10000);
                pt.y=GLY_MATH::fit(RAND_NORMALIZE,0.0f,1.0f,-1.0f,1.0f);
                srand(_id * 50000 + k*100000+100000);
                pt.z=GLY_MATH::fit(RAND_NORMALIZE,0.0f,1.0f,-1.0f,1.0f);
    
    
                //get offst
    
                //get frequency
    
    
                AtVector new_pt = AiVNoise3(pt*_frequency +_offset,4,0.0f,1.90f)*replicate_radius;
    
                //printf("the father %d,the child %d,noise_pos_x -> : %f 
    ",i,k,pt.x);
                //printf("the father %d,the child %d,noise_pos_y -> : %f 
    ",i,k,pt.y);
                //printf("the father %d,the child %d,noise_pos_z -> : %f 
    ",i,k,pt.z);
    
    
                child_pt_pos_list.push_back(new_pt + orig_pos);
    
            }
    
        }
        assert(child_pt_pos_list.size()==num_pt);
        #pragma omp parallel for
        for(AtUInt32 child=0;child<num_pt;child++)
        {
            AiArraySetPnt(_sphere_pos_array,child,child_pt_pos_list[child]);
        }
        return _sphere_pos_array;
    
    }
    
    
    
    
    static int pt_init(AtNode *node,void **user_ptr)
    {
        *user_ptr = node;// make a copy of the parent procudural
        //AtArray *pt_data_array = AiNodeGetArray(node,"point_data");
    
        pt_list_num = AiNodeGetInt(node,"interpolationNum");
        pt_radius = AiNodeGetFlt(node,"pointRadius");
        pt_use_vel_mb = AiNodeGetInt(node,"use_vel_motion_blur");
        shuffer_open_val = AiNodeGetFlt(node,"shuffer_open");
        shuffer_close_val = AiNodeGetFlt(node,"shuffer_close");
        // shape control
        replicate_radius = AiNodeGetFlt(node,"replicate_radius");
    
        // Get id/pos list ...
        id_array_list = AiNodeGetArray(node,"ins_id");
        pos_array_list = AiNodeGetArray(node,"P");
        vel_array_list = AiNodeGetArray(node,"v");
        offset_vec = AiNodeGetArray(node,"offset");
        frequency_vec = AiNodeGetArray(node,"frequency");
        attribute_list = AiNodeGetStr(node,"attributeTransferList");
        /*
        for(int i=0;i<offset_vec->nelements;i++)
        {
            printf("get the offset val %f 
    ",AiArrayGetFlt(offset_vec,i));
        }
         */
        //printf("pt_init get the attribtue list is %s 
    ",attribute_list.c_str());
        /*
        printf("get the type is %d 
    ",vel_array_list->type);
        for(int i=0;i<vel_array_list->nelements;i++) {
            printf("get the array is %f
    ", AiArrayGetFlt(vel_array_list, i));
        }
    
    
    */
        char split_char = ',';
        vector <string > _attrib_list = GLY_MATH::split_string(attribute_list,split_char);
        att_maps.resize( _attrib_list.size() );
        // SIMD SET ARRAY...
        #pragma omp parallel for
        for(int i=0; i<_attrib_list.size();i++)
        {
            string _curl_attrib_name = _attrib_list[i];
            katana_attribute_map _map;
            _map.name = _curl_attrib_name;
            _map.map_array = AiNodeGetArray(node,_curl_attrib_name.c_str());
            att_maps[i] = _map;
        }
    
        printf("pt_init get iter num particles is %d 
    ",pt_list_num);
        printf("pt_init get particles radius is %f 
    ",pt_radius);
        printf("pt_init get shuffer_open is %f 
    ", shuffer_open_val);
        printf("pt_init get shuffer close is %f 
    ", shuffer_close_val);
        printf("pt_init get the use_motion_blur is %d 
    ",pt_use_vel_mb);
        return true;
    }
    static int pt_cleanup(void *user_ptr)
    {
        return true;
    }
    static int pt_numnodes(void *user_ptr)
    {
        return 1;
    }
    static AtNode *MyGetNode(void *user_ptr,int i)
    {
    
        printf("create node
    ");
        AtNode *node = AiNode("points");
    
        AtInt32 orig_num_pt = id_array_list->nelements;  // from Houdini have num_pt
        AtInt32 iter_num_pt = orig_num_pt * pt_list_num; // every point have-> orig num pt * iterNum
    
    
        AtArray *pointArray = AiArrayAllocate(iter_num_pt,1,AI_TYPE_POINT);
        if(pt_use_vel_mb)
        {
            pointArray = AiArrayAllocate(iter_num_pt,2,AI_TYPE_POINT);
        }
        else
        {
            pointArray = AiArrayAllocate(iter_num_pt,1,AI_TYPE_POINT);
        }
    
    
    
    
        printf("start create pt
    ");
        AtArray *curl_pos_array = AiArrayAllocate(iter_num_pt,1,AI_TYPE_POINT);
        curl_pos_array=makeSpherePoints(pt_list_num,orig_num_pt,pos_array_list,id_array_list);
    
    
        if(pt_use_vel_mb)
        {
            printf("start create motion blur points
    ");
            AtArray *__open_pos_array = createMotionBlurOpenPoints(vel_array_list,curl_pos_array,shuffer_open_val,pt_list_num);
            AtArray *__close_pos_array = createMotionBlurClosePoints(vel_array_list,curl_pos_array,shuffer_close_val,pt_list_num);
    
            float *__open_pos_array_data = static_cast<float *> (__open_pos_array->data);
            float *__close_pos_array_data = static_cast<float *> (__close_pos_array->data);
    
            printf("setting motion blur points
    ");
            AiArraySetKey(pointArray,0,__open_pos_array_data);
            AiArraySetKey(pointArray,1,__close_pos_array_data);
            printf("setting motion blur points compelte
    ");
        }
        else
        {
            pointArray = curl_pos_array;
        }
    
        //Radius setttings
        //printf("starting create radius array
    ");
        AtArray *radiusArray = AiArrayAllocate(iter_num_pt,1,AI_TYPE_FLOAT);
        setConstantRadius(radiusArray,pt_radius);
    
        // transfer v attribute that can use "use_data_rgb/use_data_rgba" to render channel.
        AtArray *channel_v = AiArrayAllocate(iter_num_pt,1,AI_TYPE_RGBA);
        fork_vector_attribute(vel_array_list,channel_v,pt_list_num);
        AiNodeDeclare(node, "v", "uniform RGBA");
        AiNodeSetArray(node,"v",channel_v);
    
    
        // transfer other transfer attribute
        for(int i=0; i<att_maps.size() ;i++)
        {
            katana_attribute_map map_attrib = att_maps[i];
            string att_name = map_attrib.name;
            AtArray *array = map_attrib.map_array;
    
            AtArray *_channel = AiArrayAllocate(iter_num_pt,1,AI_TYPE_RGBA);
            AiNodeDeclare(node,att_name.c_str(),"uniform RGBA");
    
            if(array->nelements == orig_num_pt) // not vector attrib
            {
                printf("fork other float/int attribute name is %s 
    ",att_name.c_str());
                fork_float_attribute(array,_channel,pt_list_num);
                AiNodeSetArray(node,att_name.c_str(),_channel);
    
            }
            if(array->nelements == orig_num_pt *3 ) // vector attrib
            {
                printf("fork other vector attribute name is %s 
    ",att_name.c_str());
                fork_vector_attribute(array,_channel,pt_list_num);
                AiNodeSetArray(node,att_name.c_str(),_channel);
            }
    
        }
    
    
        AiNodeSetArray(node,"points",pointArray);
        AiNodeSetArray(node,"radius",radiusArray);
        AiNodeSetStr(node, "mode", "sphere");
        printf("complete the procedural points
    ");
        return node;
    }
    proc_loader
    {
        vtable->Init = pt_init;
        vtable->Cleanup = pt_cleanup;
        vtable->NumNodes = pt_numnodes;
        vtable->GetNode = MyGetNode;
        strcpy(vtable->version,AI_VERSION);
        return true;
    }
    View Code


    --KATANA Source code:

    ---header

    //
    // Created by GearsLogy on 4/11/16.
    // this file connect the procedural points create ...
    //
    
    #ifndef GLY_INTERPOLATIONPARTICLES_GLY_INTERPOLATIONOP_H
    #define GLY_INTERPOLATIONPARTICLES_GLY_INTERPOLATIONOP_H
    
    #include <FnRenderOutputUtils/FnRenderOutputUtils.h>
    #include <FnGeolib/op/FnGeolibOp.h>
    #include <FnPluginSystem/FnPlugin.h>
    #include <FnAttribute/FnAttribute.h>
    #include <FnAttribute/FnGroupBuilder.h>
    #include <FnGeolib/util/Path.h>
    #include <FnGeolibServices/FnGeolibCookInterfaceUtilsService.h>
    
    class GLY_InterpolationOP : public Foundry::Katana::GeolibOp
    {
    public:
        static void setup(Foundry::Katana::GeolibSetupInterface &interface)
        {
            interface.setThreading(Foundry::Katana::GeolibSetupInterface::ThreadModeConcurrent);
        }
        static void cook(Foundry::Katana::GeolibCookInterface &interface);
    
    
    
    };
    
    
    #endif //GLY_INTERPOLATIONPARTICLES_GLY_INTERPOLATIONOP_H
    View Code

    ---source

    /
    // Created by gearslogy on 4/11/16.
    //
    
    #include "GLY_InterpolationOP.h"
    #include <stdio.h>
    #include <string>
    #include <vector>
    #include <sstream>
    using namespace std;
    void GLY_InterpolationOP::cook(Foundry::Katana::GeolibCookInterface &interface)
    {
        FnAttribute::StringAttribute get_par_loc = interface.getOpArg("particle_path");
        FnAttribute::StringAttribute get_procedural_loc = interface.getOpArg("procedural_path");
    
        if(!get_procedural_loc.isValid() || get_procedural_loc.getValue("",false).empty()) return;
        // next create a location just for the rendering...
        string procedural_loc_str = get_procedural_loc.getValue("",false);
        Foundry::Katana::CreateLocationInfo createLocationInfo;
        Foundry::Katana::CreateLocation(createLocationInfo,interface,procedural_loc_str);
    
    
    
        if(!get_par_loc.isValid()) {
            printf("%s not found the attribute",get_par_loc.getValue("", false));
            return;
        }
        /*
        int ex = interface.doesLocationExist(get_par_loc.getValue("",false));
        if(!ex) {
            printf("%s do not exist in the location
    ",get_par_loc.getValue("", false));
            return;
        }*/
        string par_loc_str = get_par_loc.getValue("",false);
        FnAttribute::FloatAttribute get_par_radius_att = interface.getOpArg("pointRadius");
        FnAttribute::IntAttribute get_par_num_att = interface.getOpArg("interpolationNum");
        FnAttribute::IntAttribute get_use_motion_blur = interface.getOpArg("use_vel_motion_blur");
        FnAttribute::FloatAttribute get_shuffer_open = interface.getOpArg("shuffer_open");
        FnAttribute::FloatAttribute get_shuffer_close = interface.getOpArg("shuffer_close");
        FnAttribute::FloatAttribute get_replicate_radius = interface.getOpArg("replicate_radius");
        FnAttribute::FloatAttribute get_noise_fre = interface.getOpArg("frequency");
        FnAttribute::FloatAttribute get_noise_offset = interface.getOpArg("offset");
        FnAttribute::StringAttribute get_attribute_list = interface.getOpArg("attributeTransferList");
    
        //printf("oparg check
    ");
        if(!get_par_radius_att.isValid()) return;
        if(!get_par_num_att.isValid()) return;
        if(!get_shuffer_open.isValid()) return;
        if(!get_use_motion_blur.isValid()) return;
        if(!get_shuffer_close.isValid()) return;
        if(!get_replicate_radius.isValid()) return;
        if(!get_attribute_list.isValid()) return;
        if(!get_noise_fre.isValid()) {printf("not found frequency arg
    ");return;}
        if(!get_noise_offset.isValid()) {printf("not found offset arg
    ");return;}
        //float pt_radius = get_par_radius_att.getValue(0.0f,false);
        //int pt_num = get_par_num_att.getValue(0,false);
        //printf("transfer data
    ");
        //get id and p attribute
        FnAttribute::IntAttribute id_attribute = interface.getAttr("geometry.arbitrary.ins_id.value",par_loc_str);
        FnAttribute::FloatAttribute pos_attribute = interface.getAttr("geometry.point.P",par_loc_str);
        FnAttribute::FloatAttribute vel_attribute = interface.getAttr("geometry.point.v",par_loc_str);
    
        if(!id_attribute.isValid()){
            Foundry::Katana::ReportError(interface,"No ins_id attribute in particles location
    ");
            return;
        }
        if(!pos_attribute.isValid()){
            Foundry::Katana::ReportError(interface,"No P attribute in particles");
            return;
        }
        if(!vel_attribute.isValid()){
            Foundry::Katana::ReportError(interface,"No v attribute in particles");
            return;
        }
    
        string fullName = interface.getOutputLocationPath();
        FnGeolibUtil::Path::FnMatchInfo fnMatchInfo;
        FnGeolibUtil::Path::FnMatch(fnMatchInfo, fullName,procedural_loc_str);
        if (!fnMatchInfo.match) return;
    
    
    
    
    
    
    
    
    
        //attribute transfer list checking
        string attr_list = get_attribute_list.getValue("", false);
        //printf("current attribute list is %s 
    ",attr_list.c_str());
        stringstream ss(attr_list);
        string sub_str;
        vector <string> sp_strPath;
        sp_strPath.clear();
        while(getline(ss,sub_str,','))
        {
            sp_strPath.push_back(sub_str);
        }
    
        if(sp_strPath.size()!=0 && attr_list!="")
        {
    
            interface.setAttr("rendererProcedural.args.attributeTransferList",get_attribute_list);
            for(int i=0;i<sp_strPath.size();i++)
            {
                string __attri_base_name = sp_strPath[i];
                string __prefix = "geometry.arbitrary.";
                string __endfix = ".value";
                string __attri_des_name = __prefix + __attri_base_name + __endfix;
                //printf("checking the %s attribute
    ",__attri_des_name.c_str());
                FnAttribute::Attribute __att__handle = interface.getAttr(__attri_des_name,par_loc_str);
                int __att__type = __att__handle.getType();
               // printf("the type is %d
    ",__att__type);
                if(__att__handle.isValid())
                {
                    //printf("found attribute in particles %s
    ",__attri_des_name.c_str());
                    if (__att__type == 1) // int
                    {
                        //printf("set to the int
    ");
                        FnAttribute::IntAttribute __int_handle = FnAttribute::IntAttribute(__att__handle);
                        interface.setAttr(string("rendererProcedural.args.")+ __attri_base_name , __int_handle);
                    }
                    if(__att__type == 2) // float
                    {
                        //printf("set to the float
    ");
                        FnAttribute::FloatAttribute __float_handle = FnAttribute::FloatAttribute(__att__handle);
                        interface.setAttr(string("rendererProcedural.args.")+ __attri_base_name , __float_handle);
                    }
                }
                else
                {
                    string error_msg = "please check the error attribute  :" + __attri_base_name + " do not exist
    ";
                    Foundry::Katana::ReportError(interface,error_msg);
                    return;
                }
    
            }
        }
    
        // set our procedural attribute
        interface.setAttr("type",FnAttribute::StringAttribute("renderer procedural"));
        interface.setAttr("rendererProcedural.procedural",FnAttribute::StringAttribute("libArnoldGLY_PointInterpolation"));
        interface.setAttr("rendererProcedural.args.__outputStyle",FnAttribute::StringAttribute("typedArguments"));
        interface.setAttr("rendererProcedural.args.interpolationNum",get_par_num_att);
        interface.setAttr("rendererProcedural.args.pointRadius",get_par_radius_att);
        interface.setAttr("rendererProcedural.args.replicate_radius",get_replicate_radius);
        interface.setAttr("rendererProcedural.args.frequency",get_noise_fre);
        interface.setAttr("rendererProcedural.args.offset",get_noise_offset);
        //
        interface.setAttr("rendererProcedural.args.use_vel_motion_blur",get_use_motion_blur);
        interface.setAttr("rendererProcedural.args.shuffer_open",get_shuffer_open);
        interface.setAttr("rendererProcedural.args.shuffer_close",get_shuffer_close);
    
        interface.setAttr("rendererProcedural.args.ins_id",id_attribute);
        interface.setAttr("rendererProcedural.args.P",pos_attribute);
        interface.setAttr("rendererProcedural.args.v",vel_attribute);
    
    
    
    
        printf("katana Interpolation Particles -> setting complete
    ");
    }
    View Code
  • 相关阅读:
    vuex最简单、最详细的入门文档
    详解vue生命周期
    Js基础算法题
    Git常用命令
    webpack构建React开发环境
    React快速构建脚手架
    打开页面开始倒计时
    Yahoo前端35条性能优化
    特殊引用类型(string)
    What is in your backpack?
  • 原文地址:https://www.cnblogs.com/gearslogy/p/5421039.html
Copyright © 2011-2022 走看看