zoukankan      html  css  js  c++  java
  • Houdini18 HDK Offline Test

    cmake_minimum_required(VERSION 3.5)
    
    project(Triangle)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    # OPENGL
    find_package(OpenGL REQUIRED)
    include_directories(${OpenGL_INCLUDE_DIRS})
    link_directories(${OpenGL_LIBRARY_DIRS})
    add_definitions(${OpenGL_DEFINITIONS})
    
    if(NOT OPENGL_FOUND)
        message(ERROR " OPENGL not found!")
    endif(NOT OPENGL_FOUND)
    
    # GLEW
    set(GLEW_HOME D:/plugin_dev/libs/glew-2.1.0)
    include_directories(${GLEW_HOME}/include)
    link_directories(${GLEW_HOME}/lib/Release/x64)
    
    # GLFW
    set(GLFW_HOME D:/plugin_dev/libs/glfw-3.3.1.bin.WIN64)
    include_directories(${GLFW_HOME}/include/)
    link_directories(${GLFW_HOME}/lib-vc2019)
    
    # STB
    include_directories(D:/plugin_dev/libs/stb)
    
    # GLM
    include_directories(D:/plugin_dev/libs/GLM_include)
    
    
    
    
    # ---------------- HOUDINI
    if (MSVC)
        # Prevent Boost auto-linking.
        add_definitions(-DBOOST_ALL_NO_LIB )
        add_definitions(-D_SCL_SECURE_NO_WARNINGS
                -D_CRT_SECURE_NO_WARNINGS
                -D_WIN32
                -D_WINSOCK_DEPRECATED_NO_WARNINGS
                -D__x86_64__)
    
        # HOUDINI :
        add_definitions(-TP
                -Zc:forScope
                -DVERSION="18.0.348"
                -DI386
                -DWIN32
                -DSWAP_BITFIELDS
    
                -DWINVER=0x0501
                -DNOMINMAX
                -DSTRICT
                -DWIN32_LEAN_AND_MEAN
                -D_USE_MATH_DEFINES
                -D_CRT_SECURE_NO_DEPRECATE
                -D_CRT_NONSTDC_NO_DEPRECATE
                -D_SCL_SECURE_NO_WARNINGS
                -DSESI_LITTLE_ENDIAN
                -DHBOOST_ALL_NO_LIB
                -DEIGEN_MALLOC_ALREADY_ALIGNED=0
                -DFBX_ENABLED=1
                -DOPENCL_ENABLED=1
                -DOPENVDB_ENABLED=1
                -MD
                -EHsc
                -GR
                -DNEED_SPECIALIZATION_STORAGE
                -DAMD64
                -DSIZEOF_VOID_P=8)
    
    endif()
    
    
    set(HOUDINI_HOME "D:/Program Files/Side Effects Software/Houdini 18.0.348")
    include_directories("${HOUDINI_HOME}/toolkit/include")
    link_directories("${HOUDINI_HOME}/custom/houdini/dsolib")
    
    
    
    
    
    # output excutable dir
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
    
    
    # SRC FILE
    FILE(
        GLOB
        SRC
        *.cpp *.h
        )
    
    add_executable(Triangle ${SRC})
    
    
    
    target_link_libraries(Triangle
        PRIVATE
        libGA.lib
        libGU.lib
        libUT.lib
        libCE.lib
        libLM.lib
        libFS.lib
        libSYS.lib
        libGEO.lib
    
        )
    CMakeLists

    HDK Geometry Struct:

    Houdini Geometry responsed to this figure:

    1, get GLDraw info from this code:

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <iostream>
    
    
    using namespace std;
    
    
    int main(){
        GU_Detail gdp;
        gdp.load("geos/box.bgeo");
    
        cout << "Numpoints:"<<gdp.getNumPoints() <<endl;
        cout << "NumVerticles" << gdp.getNumVertices() << endl;
        cout << "NumFace:" << gdp.getNumPrimitives() << endl;
    
        // LOOP All face, cout this vertex count
        GEO_Primitive *geoPrim;
        GA_FOR_ALL_PRIMITIVES(&gdp,geoPrim){
             int faceCount = geoPrim->getVertexCount() ;// per face have 3 point
    
    
        }
    
        cout << "------------------ Iterator Face ID & Per face point ID, this can used  GL_DRAW_ELMENTS()----------------
    ";
        GA_Iterator primIter(gdp.getPrimitiveRange());
        fpreal start_primtive_num = *primIter;
        cout << "START primtive num:" << start_primtive_num << endl;
    
    
        // loop the face(prim)
        for (;!primIter.atEnd();++primIter) {
            GA_Primitive *prim = gdp.getPrimitive(*primIter);
    
    
            // iterator face points
            cout <<"this face id :" << *primIter <<"->have vertex count:" <<prim->getVertexCount() << endl;
            GA_Iterator pointIter(prim->getPointRange());
            for(;!pointIter.atEnd();++pointIter){
                cout <<"share point id:" <<*pointIter << endl;
            }
    
        }
    
    
        cout << "------------------  access points Iterator directly not opengl draw indcices----------------
    ";
        // Loop the point, direct access the point , not prim vertex shared point
        GA_Iterator pointIter(gdp.getPointRange());
        while(!pointIter.atEnd()){
    
            int pointNum = *pointIter ;
            GA_Index pointIndex = gdp.pointIndex(*pointIter);
            GA_Offset pointOffset = gdp.pointOffset(pointIndex);
    
            cout <<"Lookup -> Point id:" <<*pointIter << " Point Index:" << pointIndex
                << " Point offset:" << pointOffset
                << endl;
    
            GA_OffsetArray orry;
            gdp.getVerticesReferencingPoint(orry,pointOffset);
            cout <<"And this point have "<< orry.size() << " verticles, and the vertex number:" ;
            for(auto &of: orry){
                cout << of << " ";
            }
            cout << endl;
            ++pointIter;
        }
    
    
    
    
    
    
    
        cin.get();
        return 0;
    
    }
    main.cpp

    The GA_Primitive class is a base class, GEO manipulate 3d  Geometry further .

     一些名词:Attribute Type Implementation (ATI), Each ATI class maintains arrays of data for each element in the geometry.The ATI provides interfaces (AIFs) for accessing the data. 

    Some ATIs include GA_ATINumericGA_ATIStringGA_ATIIndexPair. Some AIFs include GA_AIFTupleGA_AIFSharedStringTuple, GA_AIFInterp. Numeric and string attributes can be accessed more easily and directly using the classes in GA_Handle.h (e.g. GA_ROHandleV3, GA_RWHandleS), and GA_PageHandle.h (e.g. GA_RWPageHandleV3).

    属性的载体拥有者:

    属性的GA_StorageClass

    属性的长度:

    GA_Attribute *att;
    att->getTupleSize();

    1为浮点(GA_StorageClass)的类型属性,

    2为长度为2浮点(GA_StorageClass)类型,

    3为长度为3的向量(GA_StorageClass)

    .....

    2,访问属性

    GA_Attribute必须要作为参数输入到GA_RWHandle 开始的类对象,然后可以检查属性的可访问性。RW意思代表可以直接改属性到gdp

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <iostream>
    
    
    using namespace std;
    
    
    int main(){
        GU_Detail gdp;
        gdp.load("geos/box.bgeo");
    
        cout << "Numpoints:"<<gdp.getNumPoints() <<endl;
        cout << "NumVerticles" << gdp.getNumVertices() << endl;
        cout << "NumFace:" << gdp.getNumPrimitives() << endl;
    
        // LOOP All face, cout this vertex count
        GEO_Primitive *geoPrim;
        GA_FOR_ALL_PRIMITIVES(&gdp,geoPrim){
             int faceCount = geoPrim->getVertexCount() ;// per face have 3 point
    
    
        }
    
        cout << "------------------ Iterator Face ID & Per face point ID, this can used  GL_DRAW_ELMENTS()----------------
    ";
        GA_Iterator primIter(gdp.getPrimitiveRange());
        fpreal start_primtive_num = *primIter;
        cout << "START primtive num:" << start_primtive_num << endl;
    
    
        // loop the face(prim)
        for (;!primIter.atEnd();++primIter) {
            GA_Primitive *prim = gdp.getPrimitive(*primIter);
    
    
            // iterator face points
            cout <<"this face id :" << *primIter <<"->have vertex count:" <<prim->getVertexCount() << endl;
            GA_Iterator pointIter(prim->getPointRange());
            for(;!pointIter.atEnd();++pointIter){
                cout <<"share point id:" <<*pointIter << endl;
            }
    
        }
    
    
        cout << "------------------  access points Iterator directly not opengl draw indcices----------------
    ";
        cout << "method 1:
    ";
        GA_Attribute *att =gdp.findPointAttribute("P");
        cout <<"attribute size:" <<att->getTupleSize() <<endl;
        GA_RWHandleV3 PAttribHandle(att);
    
        // Loop the point, direct access the point , not prim vertex shared point
        GA_Iterator pointIter(gdp.getPointRange());
        while(!pointIter.atEnd()){
    
            int pointNum = *pointIter ;     // This is point offset
            GA_Index pointIndex = gdp.pointIndex(*pointIter); // This is point index
            GA_Offset pointOffset = gdp.pointOffset(pointIndex); // This is point offset
    
            // ------ access the Position attribute ----------
            if(PAttribHandle.isValid()){
                UT_Vector3 P = PAttribHandle.get(pointOffset);
                cout <<"position: "<< P.x() << " " << P.y() << " " << P.z() <<endl;
            }
            else{
                cout << "can not access the Position 
    ";
            }
            ++pointIter;
        }
    
        cout << "method 2:
    ";
        GA_RWHandleV3 Phandle(&gdp, GA_ATTRIB_POINT, "P");
        if (Phandle.isValid())
        {
            for (GA_Iterator it(gdp.getPointRange()); !it.atEnd(); ++it)
            {
                GA_Offset offset = *it;
                UT_Vector3 P = Phandle.get(offset);
                cout <<"position: "<< P.x() << " " << P.y() << " " << P.z() <<endl;
                P.y()+= 2.0;
                Phandle.set(offset, P);
            }
        }
        
        // save to disk 
        GA_SaveOptions saveOptions;
        gdp.save("change.bgeo",&saveOptions);
        
        
        
        
        cout << "method 3
    ";
        GA_Attribute *attrib = gdp.findFloatTuple(GA_ATTRIB_POINT, "N", 3);
        const GA_AIFTuple *tuple = attrib->getAIFTuple();
        if (tuple)
        {
            UT_Vector3 P;
            for (GA_Iterator it(gdp.getPointRange()); !it.atEnd(); it.advance())
            {
                GA_Offset offset = it.getOffset();
                tuple->get(attrib, offset, P.data(), 3);
                
                // change P
                // .....
                tuple->set(attrib, offset, P.data(), 3);
            }
        }
        
    
    
        cin.get();
        return 0;
    
    }
    View Code

    String Attribute:

    假设面属性:

     修改后:

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <iostream>
    
    
    using namespace std;
    
    
    int main(){
        GU_Detail gdp;
        gdp.load("geos/box.bgeo");
    
        cout << "Numpoints:"<<gdp.getNumPoints() <<endl;
        cout << "NumVerticles" << gdp.getNumVertices() << endl;
        cout << "NumFace:" << gdp.getNumPrimitives() << endl;
    
    
    
        GA_RWHandleS strAttrib(&gdp,GA_ATTRIB_PRIMITIVE, "mystr");
        if(!strAttrib.isValid()){
            cout << "Can not find primtive attribute
    ";
            return 1;
        }
        for(GA_Iterator iter(gdp.getPrimitiveRange()); !iter.atEnd(); ++iter){
            GA_Offset offset = *iter;
            UT_String value(strAttrib.get(offset) );
            value.append("_CPP");
            UT_StringHolder holder(value.c_str());
            strAttrib.set(offset, holder);
            cout << value <<endl;
        }
    
    
    
        // save to disk
        GA_SaveOptions saveOptions;
        gdp.save("change.bgeo",&saveOptions);
    
    
    
    
    
        cin.get();
        return 0;
    
    }
    View Code

    遍历器所有属性,但是始终需要GA_Offset来引导获得真正的属性值:祭出我以前把H17.5的GU_Detail发送给Katana3.2,这样katana可以读取houdini的bgeo

    // Copyright (c) 2016 The Foundry Visionmongers, Ltd.
    #include <FnGeolib/op/FnGeolibOp.h>
    #include <FnAttribute/FnAttribute.h>
    #include <GU/GU_Detail.h>
    #include <iostream>
    #include <FnGeolibServices/FnGeolibCookInterfaceUtilsService.h>
    using namespace std;
    namespace
    {
    // "Hello World"-style op that sets a string attribute at the root location.
        class HelloWorldOp : public Foundry::Katana::GeolibOp
        {
        public:
            // Boilerplate that indicates the Op's cook() function is safe to be called
            // concurrently.
            static void setup(Foundry::Katana::GeolibSetupInterface& interface)
            {
                interface.setThreading(
                        Foundry::Katana::GeolibSetupInterface::ThreadModeConcurrent);
            }
    
            static void cook(Foundry::Katana::GeolibCookInterface& interface)
            {
                FnAttribute::StringAttribute celAttr = interface.getOpArg("CEL");
                if (!celAttr.isValid())
                {
                    interface.stopChildTraversal();
                    return;
                }
                FnGeolibServices::FnGeolibCookInterfaceUtils::MatchesCELInfo info;
                FnGeolibServices::FnGeolibCookInterfaceUtils::matchesCEL(info,
                    interface,
                    celAttr);
    
                if (!info.canMatchChildren)
                {
                    interface.stopChildTraversal();
                }
    
                // If the CEL doesn't match the current location, stop cooking
                if (!info.matches)
                {
                    return;
                }
                FnAttribute::StringAttribute bgeoFileAttr =
                    interface.getOpArg("bgeoFile");
                if (!bgeoFileAttr.isValid()) {
                    cout << "Can not find bgeoFile attribute in param
    ";
                    return;
                }
                string bgeoStr = bgeoFileAttr.getValue();
    
                interface.setAttr("type", FnAttribute::StringAttribute("pointcloud"));
                GU_Detail gdp;
                gdp.load(bgeoStr.c_str());
                uint64 numpt = gdp.getNumPoints();
                GA_Iterator iter(gdp.getPointRange());
                fpreal start_point_num = *iter;
    
                for (GA_AttributeDict::iterator it = gdp.getAttributeDict(GA_ATTRIB_POINT).begin(GA_SCOPE_PUBLIC); !it.atEnd(); ++it)
                {
                    GA_Attribute *attrib = it.attrib();
                    UT_String attribName (attrib->getName());
                    int attSize = attrib->getTupleSize();
                    GA_StorageClass storage = attrib->getStorageClass();
                    cout << "loop attribute " << attribName << endl;
                    if (attSize == 1) {
                        
                        if (storage == GA_STORECLASS_FLOAT) {
                            // FLOAT Attribute
                            float * floatValues = new float[numpt];
                            GA_RWHandleF handle(attrib);
                            for (uint64 i = start_point_num; i < numpt + start_point_num; i++) {    
                                uint64 KTNStride = i - start_point_num;
                                // set Houdini attribute for mem
                                floatValues[KTNStride] = handle.get(i);
                            }
                            // Attribute for arbitrary value
                            string katanaAttributeName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".value");
                            string scopeAttribName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".scope");
    
    
                            // Set the scope attribute
                            interface.setAttr(scopeAttribName.c_str(), FnAttribute::StringAttribute("point"), false);
    
                            // create KATANA attribute for interface
                            FnAttribute::FloatAttribute KTNAttribute(floatValues, numpt, 1);
    
                            // create KATANA attribute for interface values
                            interface.setAttr(katanaAttributeName.c_str(), KTNAttribute, false);
    
                            // Release mem
                            delete []floatValues;
                        }
    
                        if (storage == GA_STORECLASS_INT) {
                            // INT Attribute
                            int * intValues = new int[numpt];
                            GA_RWHandleI handle(attrib);
                            for (uint64 i = start_point_num; i < numpt + start_point_num; i++) {
                                uint64 KTNStride = i - start_point_num;
                                // set Houdini attribute for mem
                                intValues[KTNStride] = handle.get(i);
                            }
                            // Attribute for arbitrary value
                            string katanaAttributeName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".value");
                            string scopeAttribName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".scope");
    
                            // Set the scope attribute
                            interface.setAttr(scopeAttribName.c_str(), FnAttribute::StringAttribute("point"), false);
    
                            // create KATANA attribute for interface values
                            FnAttribute::IntAttribute KTNAttribute(intValues, numpt, 1);
                            interface.setAttr(katanaAttributeName.c_str(), KTNAttribute, false);
                            // Release mem
                            delete[]intValues;
                        }
                        
    
                    }
                    else if (attSize == 3) {
                        cout << "Vector attribute:" << attribName << endl;
    
                        float * newPoints = new float[numpt * 3];
                        GA_RWHandleV3 handle(attrib); 
                        for (uint64 i = start_point_num; i < numpt + start_point_num; i++) {
    
                            float x = float(handle.get(i).x());
                            float y = float(handle.get(i).y());
                            float z = float(handle.get(i).z());
                            // KTN index
                            uint64 KTNStride = i - start_point_num;
                            uint64 xIndex = KTNStride * 3;
                            uint64 yIndex = KTNStride * 3 + 1;
                            uint64 zIndex = KTNStride * 3 + 2;
    
                            // set Houdini attribute for mem
                            newPoints[xIndex] = x;
                            newPoints[yIndex] = y;
                            newPoints[zIndex] = z;
    
                        }
                        string katanaAttributeName;
                        
                        if (attribName == "P" || attribName == "v") {
                            katanaAttributeName = string("geometry.point.") + string(attribName.c_str());
                            // create KATANA attribute for interface
                        }
                        else {
                            katanaAttributeName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".value");
                            // SCOPE NAME FOR arnold AI_UserData_RGB
                            string scopeAttribName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".scope");
                            string inputTypeAttribName = string("geometry.arbitrary.") + string(attribName.c_str()) + string(".inputType");
                            interface.setAttr(scopeAttribName.c_str(), FnAttribute::StringAttribute("point"), false);
                            interface.setAttr(inputTypeAttribName.c_str(), FnAttribute::StringAttribute("vector3"), false);
                        }
    
    
                        FnAttribute::FloatAttribute vectorAttribute(newPoints, numpt * 3, 3);
                        interface.setAttr(katanaAttributeName.c_str(), vectorAttribute, false);
    
                        // Release mem
                        delete[]newPoints;
    
    
    
    
                    }
                    else if (attSize == 4) {
                        
                    }
                    else {
                        cout << " do not support this the attribute:" << attribName << endl;;
                    }
    
                }
    
            }
        };
        DEFINE_GEOLIBOP_PLUGIN(HelloWorldOp)
    }  // namespace
    
    void registerPlugins()
    {
        REGISTER_PLUGIN(HelloWorldOp, "HelloWorld", 0, 1);
    }
    View Code

    官网也说的清:

    //Each GA_AttributeOwner has its own dictionary of attributes that can be searched or traversed independently. Aside from the public attributes, a dictionary can contain private and group attributes, so be careful about scope during traversal.
    
    //For example, to traverse all the public primitive attributes in an undefined order:
    
    for (GA_AttributeDict::iterator it = gdp->getAttributeDict(GA_ATTRIB_PRIMITIVE).begin(GA_SCOPE_PUBLIC); !it.atEnd(); it.advance())
    {
        GA_Attribute *attrib = it.attrib();
        ...
    }
    //To traverse all the public primitive attributes in a well-defined (alpabetic) order:
    
    for (GA_AttributeDict::ordered_iterator it = gdp->getAttributeDict(GA_ATTRIB_PRIMITIVE).obegin(GA_SCOPE_PUBLIC); !it.atEnd(); it.advance())
    {
        GA_Attribute *attrib = it.attrib();
        ...
    }

    当然也可以使用 GA/GA_GBMacros.h 提供的宏函数:

    GA_Attribute *Patt = gdp.findPointAttribute("P");
    GA_RWHandleV3 Phandle(Patt);
    GA_Offset ptoff;
    GA_FOR_ALL_PTOFF(&gdp,ptoff){
        UT_Vector3 P = Phandle.get(ptoff);
        P.y()+=1.0f;
        Phandle.set(ptoff,P );
    }

    当然:Handle的构造也可以直接从gdp构造,不用GA_Attribute,假设你不想知道 属性的信息。

    // Read only, from named attribute
    GA_ROHandleV3       vel_h(const_gdp, GEO_POINT_DICT, "v");
    // Read write, from a named attribute, but must be at least 2 floats
    GA_RWHandleF        life_h(gdp, GEO_POINT_DICT, "life", 2);
    // From an existing const GA_Attribute *
    GA_ROHandleI        id_h(const_attribute);
    // From a GA_AttributeRef, (common when interfacing with legacy code)
    GA_RWAttributeRef   scale_gah(gdp->findFloatTuple(GEO_POINT_DICT, "pscale"));
    GA_RWHandleF        scale_h(scale_gah.getAttribute());

    3,并行访问设置属性

    cmake_minimum_required(VERSION 3.5)
    
    project(Triangle)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    # OPENGL
    find_package(OpenGL REQUIRED)
    include_directories(${OpenGL_INCLUDE_DIRS})
    link_directories(${OpenGL_LIBRARY_DIRS})
    add_definitions(${OpenGL_DEFINITIONS})
    
    if(NOT OPENGL_FOUND)
        message(ERROR " OPENGL not found!")
    endif(NOT OPENGL_FOUND)
    
    # GLEW
    set(GLEW_HOME D:/plugin_dev/libs/glew-2.1.0)
    include_directories(${GLEW_HOME}/include)
    link_directories(${GLEW_HOME}/lib/Release/x64)
    
    # GLFW
    set(GLFW_HOME D:/plugin_dev/libs/glfw-3.3.1.bin.WIN64)
    include_directories(${GLFW_HOME}/include/)
    link_directories(${GLFW_HOME}/lib-vc2019)
    
    # STB
    include_directories(D:/plugin_dev/libs/stb)
    
    # GLM
    include_directories(D:/plugin_dev/libs/GLM_include)
    
    
    # openmp
    find_package(OpenMP)
    if (OPENMP_FOUND)
        set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
        set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
        set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
    endif()
    
    
    
    # ---------------- HOUDINI
    if (MSVC)
        # Prevent Boost auto-linking.
        add_definitions(-DBOOST_ALL_NO_LIB )
        add_definitions(-D_SCL_SECURE_NO_WARNINGS
                -D_CRT_SECURE_NO_WARNINGS
                -D_WIN32
                -D_WINSOCK_DEPRECATED_NO_WARNINGS
                -D__x86_64__)
    
        # HOUDINI :
        add_definitions(-TP
                -Zc:forScope
                -DVERSION="18.0.348"
                -DI386
                -DWIN32
                -DSWAP_BITFIELDS
    
                -DWINVER=0x0501
                -DNOMINMAX
                -DSTRICT
                -DWIN32_LEAN_AND_MEAN
                -D_USE_MATH_DEFINES
                -D_CRT_SECURE_NO_DEPRECATE
                -D_CRT_NONSTDC_NO_DEPRECATE
                -D_SCL_SECURE_NO_WARNINGS
                -DSESI_LITTLE_ENDIAN
                -DHBOOST_ALL_NO_LIB
                -DEIGEN_MALLOC_ALREADY_ALIGNED=0
                -DFBX_ENABLED=1
                -DOPENCL_ENABLED=1
                -DOPENVDB_ENABLED=1
                -MD
                -EHsc
                -GR
                -DNEED_SPECIALIZATION_STORAGE
                -DAMD64
                -DSIZEOF_VOID_P=8)
    
    endif()
    
    
    set(HOUDINI_HOME "D:/Program Files/Side Effects Software/Houdini 18.0.348")
    include_directories("${HOUDINI_HOME}/toolkit/include")
    link_directories("${HOUDINI_HOME}/custom/houdini/dsolib")
    
    
    
    
    
    # output excutable dir
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
    
    
    # SRC FILE
    FILE(
        GLOB
        SRC
        *.cpp *.h
        )
    
    add_executable(Triangle ${SRC})
    
    
    
    target_link_libraries(Triangle
        PRIVATE
        libGA.lib
        libGU.lib
        libUT.lib
        libCE.lib
        libLM.lib
        libFS.lib
        libSYS.lib
        libGEO.lib
    
        )
    CMakeLists With OMP

    Add life attribute, then set value parallel:

    1 >> 没有用GA_RWHandleF,因为我测试后是线程不安全。如果用GA_RWPageHandleF 将是线程安全。

     // or iterate using a GA_PageIterator - this gives contiguous blocks
        GA_Attribute *LifeAtt = gdp.addFloatTuple(GA_ATTRIB_POINT,GA_SCOPE_PUBLIC,"life",1);
        GA_RWPageHandleF Life_pageHandle(LifeAtt);
        GA_Offset block_start, block_end;
        for (GA_Iterator pageI(gdp.getPointRange()); pageI.blockAdvance(block_start, block_end); )
        {
            Life_pageHandle.setPage(block_start);
            
            #pragma omp parallel for
            for (int ptoff = block_start; ptoff < block_end; ++ptoff){
                Life_pageHandle.value(ptoff) = ptoff; // direct data access
            }
        }

    上面的指示把每一个page里的点并行了,不是并行的page,page相当于TBB的block.我觉得这个方式可能会出问题。相当于block是串行,block里面的东西并行。

    所以属性可以直接作为Page的默认参数,也可以直接从gdp获取:

    GA_ROPageHandleV3   v_ph(gdp, GEO_POINT_DICT, "v");
    GA_RWPageHandleV3   p_ph(gdp->getP());

    2 >> 使用UTparallelFor()来制作并行处理,实际上是TBB那套。TBB这套必须分Block,每个block有多大。有多少个Block(每个block都是相互独立并行),在houdini我觉得对应Page id(每个Page都是相互独立并行)

    图示:

    做了个20* 20 * 20的立方体共:2168个点,每个block/page 的大小为1024,总共能分三块:

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <GA/GA_PageHandle.h>
    #include <GA/GA_GBMacros.h>
    #include <GA/GA_AttributeRefMap.h>
    #include <UT/UT_ThreadedAlgorithm.h>
    #include <UT/UT_ParallelUtil.h>
    #include <GA/GA_PageIterator.h>
    #include <GA/GA_Range.h>
    
    #include <iostream>
    #include <omp.h>
    
    using namespace std;
    
    struct MoveY{
    
        MoveY(const GA_RWAttributeRef &attRef):rwAttrRef(attRef){
    
        }
    
        void operator()(const GA_SplittableRange &r) const
        {
            GA_RWPageHandleV3 pageHandle(rwAttrRef.getAttribute()); // Use Page Handle to point attribute
    
    
            // Iterate over pages in the range
            for (GA_PageIterator pit = r.beginPages(); !pit.atEnd(); ++pit)
            {
                GA_Offset       start, end;
                // iterate over the elements in the page.
                for (GA_Iterator it(pit.begin()); it.blockAdvance(start, end); )
                {
                    // Perform any per-page setup required, then
                    pageHandle.setPage(start);
                    cerr <<" --------------PAGE:" <<start <<"----------------------"<<endl;
                    for (GA_Offset i = start; i < end; ++i)
                    {
                        UT_Vector3  P = pageHandle.get(i);
                        P.y()+=5;
                        pageHandle.set(i, P);
                    }
                }
            } // page iter
        }
    
        GA_RWAttributeRef rwAttrRef;
    
    };
    
    void
    DoMove(const GA_Range &range, const GA_RWAttributeRef &attRef)
    {
        // Create a GA_SplittableRange from the original range
        UTparallelFor(GA_SplittableRange(range), MoveY(attRef));
    }
    
    
    
    
    int main(){
        GU_Detail gdp;
        gdp.load("geos/box.bgeo");
    
    
        GA_RWAttributeRef attRef(gdp.findPointAttribute("P"));
        GA_Range range = gdp.getPointRange();
    
    
        if(!attRef.isValid())
            cout << "can not change P
    ";
        else{
            DoMove(range,attRef);
        }
    
        // save to disk
        GA_SaveOptions saveOptions;
        gdp.save("geos/change.bgeo.sc",&saveOptions);
    
    
    
        cout << "ret end
    ";
        cin.get();
        return 0;
    
    }
    View Code

    从返回结果看是没问题的。每个块独立。

    3>>还有一种方案,只不过对GA_Offset稍微麻烦点,如果单纯的bgeo直接操作属性,不用管这个事情

    这里还有一个问题是page.setPage()不知道性能消耗大不,我将每个offset 对到 page上:

    class MoveY2 {
    public:
        MoveY2(GA_Attribute  *att) : attrib(att) {}
    
        void operator()(const UT_BlockedRange<int64> &range) const
        {
            GA_RWPageHandleV3  myPageHandle(attrib);
            for (int64 i = range.begin(); i != range.end(); ++i)
            {
                myPageHandle.setPage(i);
                UT_Vector3 &value = myPageHandle.value(i);
                value.y()+= 5.0f;
            }
        }
        GA_Attribute *attrib;
    
    };
    
    void
    DoMove2(GA_Attribute *attrib, int64 length)
    {
        UTparallelFor(UT_BlockedRange<int64>(0, length), MoveY2(attrib));
    }
    View Code

    C++11 Thread构建块我也做过,根据线程数目分块

    4, add attribute

    1,GA_Attribute&GA_RWHandleF,GA_RWHandleV3,  Basis add point number to the age attribute and for normal <0,1,0>

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <iostream>
    
    
    using namespace std;
    
    
    int main(){
        GU_Detail gdp;
        gdp.load("geos/box.bgeo");
    
        // add float attribute
        GA_Attribute *ageAttribute = gdp.addFloatTuple(GA_ATTRIB_POINT,GA_SCOPE_PUBLIC,"age",1);
        GA_RWHandleF ageHandle(ageAttribute);
        for(GA_Iterator it(gdp.getPointRange()) ; !it.atEnd(); it.advance()) {
            GA_Offset offset = *it;
            ageHandle.set(offset,*it);
        }
    
    
        // add vector N attribute
        GA_Attribute *normalAttribute = gdp.addFloatTuple(GA_ATTRIB_POINT, GA_SCOPE_PUBLIC, "N", 3);
        GA_RWHandleV3 NHandle(normalAttribute);
        if (!NHandle.isValid() ) {
            cout << "can not change N attribute
    ";
            return 0;
        }
        for(GA_Iterator it(gdp.getPointRange()) ; !it.atEnd(); it.advance()) {
            GA_Offset offset = *it;
            NHandle.set(offset,UT_Vector3(0.f,1.0f,0.0f));
        }
    
    
        // save to disk
        GA_SaveOptions saveOptions;
        gdp.save("geos/change.bgeo",&saveOptions);
    
    
    
    
        cout << "ret end
    ";
        cin.get();
        return 0;
    
    }
    View Code

    GU_Detail的添加属性方法重载比较多,最常用的添加public属性:

    GA_Attribute *att = gdp.addFloatTuple(GA_ATTRIB_POINT,"attname",3);                  // float vector attribute
    GA_Attribute *att = gdp.addFloatTuple(GA_ATTRIB_POINT,GA_SCOPE_PUBLIC, "attname",3); // float vector attribute

    5,选择一部分属性,执行线性插值:

    GA_AttributeRefMap

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <GA/GA_PageHandle.h>
    #include <GA/GA_GBMacros.h>
    #include <GA/GA_AttributeRefMap.h>
    #include <iostream>
    #include <omp.h>
    
    using namespace std;
    
    
    int main(){
        GU_Detail gdp;
        gdp.load("geos/line.bgeo");
    
        GA_Iterator iter(gdp.getPointRange()) ;
        GA_Offset pt0 = *iter;
        GA_Offset pt1 = pt0 + 1;
    
        GA_Offset new_pt = gdp.appendPoint();
        GA_AttributeRefMap  hmap(gdp);
        // Append all point & vertex attributes (including "P")
        hmap.append(GA_AttributeFilter::selectNumeric(), GA_ATTRIB_POINT);
    
        // Perform linear interpolation, writing to new_vtx
        hmap.lerpValue(GA_ATTRIB_POINT, new_pt, GA_ATTRIB_POINT, pt0, pt1 , .5);
    
        // save to disk
        GA_SaveOptions saveOptions;
        gdp.save("geos/change.bgeo.sc",&saveOptions);
    
        cout << "ret end
    ";
        cin.get();
        return 0;
    
    }
    View Code

    中间生成的点,把所有的点属性都插值,包括P,Cd。这里按照0.5的bias

    6, Read the binary .Bgeo. from python

    try:
        # Try for ASCII/binary support
        import hjson
        json = hjson
    except:
        # Fall back to only ASCII support
        import simplejson
        json = simplejson
    
    fileName = "D:/line.bgeo"
    geo = json.load(open(fileName, 'rb'))
    print json.dumps(geo, binary=False, indent=4)

    剩下的可以按照geo[]来取值。hjson文档说是python的高性能使用方法

    7,Eliminating GEO_Point,Do Not USE GEO_Point:

    The GA library doesn't store point (GEO_Point) or vertex (GEO_Vertex) objects,然而你依然可以获取GB方式的GEO_Point:

    GEO_Point   *ppt = gdp->getGBPoint();

    Rather than using GEO_Point objects, try to use the GA_Offset of the point. 访问GEO_Point属于间接方式,不是直接方式。GA Keep memory usage lower (no persistent objects)

    8,Create Geometry

    colsed polygon

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <GA/GA_PageHandle.h>
    #include <GA/GA_GBMacros.h>
    #include <GA/GA_AttributeRefMap.h>
    #include <UT/UT_ThreadedAlgorithm.h>
    #include <UT/UT_ParallelUtil.h>
    #include <GA/GA_PageIterator.h>
    #include <GA/GA_Range.h>
    
    #include <iostream>
    #include <omp.h>
    
    using namespace std;
    
    
    
    
    
    const int npoints = 3;
    
    
    int main(){
        GU_Detail gdp;
        //gdp.load("geos/box.bgeo");
    
        gdp.clearAndDestroy();
        GA_Offset start_vtxoff;
        GA_Offset start_ptoff ;
    
        // @arg1 = GA_PRIMPOLY
        // @arg2 = nprimitives
        // @arg3 = nvertices_each
        // @arg4 = vertex_block_start
        // @arg5 = close polygon
        gdp.appendPrimitivesAndVertices(GA_PRIMPOLY, 1, npoints, start_vtxoff, true);
    
        // Create the right number of points, as a contiguous block
        start_ptoff = gdp.appendPointBlock(npoints);
        // Wire the vertices to the points.
        for (exint i = 0; i < npoints; ++i)
        {
            gdp.getTopology().wireVertexPoint(start_vtxoff+i,start_ptoff+i);
        }
    
    
        // We added points, vertices, and primitives,
        // so this will bump all topology attribute data IDs,
        // P's data ID, and the primitive list data ID.
        gdp.bumpDataIdsForAddOrRemove(true, true, true);
    
    
        UT_Vector3 Ps[3] = {
            UT_Vector3(-1,0,0),
            UT_Vector3(1,0,0),
            UT_Vector3(0,1,0) };
    
    
        for(int i =0; i< npoints;i++){
            GA_Offset offset = i+ start_ptoff;
            gdp.setPos3(offset, Ps[i]);
        }
    
    
        // save to disk
        GA_SaveOptions saveOptions;
        gdp.save("geos/change.bgeo.sc",&saveOptions);
    
    
    
        cout << "ret end
    ";
        cin.get();
        return 0;
    
    }
    View Code

    9:TBN Matrix

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <GA/GA_PageHandle.h>
    #include <GA/GA_GBMacros.h>
    #include <GA/GA_AttributeRefMap.h>
    #include <UT/UT_ThreadedAlgorithm.h>
    #include <UT/UT_ParallelUtil.h>
    #include <GA/GA_PageIterator.h>
    #include <GA/GA_Range.h>
    #include <GU/GU_DetailHandle.h>
    #include <GU/GU_PackedGeometry.h>
    #include <GU/GU_PrimPacked.h>
    #include <GU/GU_PolyFrame.h>
    
    
    #include <iostream>
    #include <omp.h>
    
    using namespace std;
    
    
    
    int main(){
    
        UT_Options option;
        GU_Detail *gdp = new GU_Detail;
    
        GU_Detail::IOStatus stat = gdp->load("geos/grid.bgeo");
        if(! stat.success() ){
            cout << "load file error
    ";
        }
    
        cout << gdp->getNumPoints() << endl;
    
        GU_PolyFrame polyframe(gdp);
        GU_PolyFrameParms polyframeParms;
        polyframeParms.style = GU_POLYFRAME_TEXTURE;
        polyframeParms.left_handed = false;
        polyframeParms.orthogonal = true;
        polyframeParms.which = GU_POLYFRAME_NORMAL | GU_POLYFRAME_BITANGENT | GU_POLYFRAME_TANGENT ;
        polyframeParms.uv_name = "uv";
        polyframeParms.names[0] = "T";
        polyframeParms.names[1] = "B";
        polyframeParms.names[2] = "N";
        polyframe.computeFrames(polyframeParms);
        
        GA_SaveOptions save_option;
        gdp->save("geos/grid_pf.bgeo",&save_option);
    
    
        delete gdp;
        cin.get();
        return 0;
    
    }
    View Code

    10:GU_PrimPacked Packed GEOMETRY:

    操作pack首选GU_PrimPacked,从类关系看应该是最全的。

    REF:tookit->samples->SOP_CopyPacked.C

     

    #include <GU/GU_Detail.h>
    #include <GEO/GEO_Primitive.h>
    #include <GEO/GEO_PrimPoly.h>
    #include <GA/GA_Primitive.h>
    #include <GA/GA_Iterator.h>
    #include <GA/GA_SaveOptions.h>
    #include <GEO/GEO_AttributeHandle.h>
    #include <GA/GA_PageHandle.h>
    #include <GA/GA_GBMacros.h>
    #include <GA/GA_AttributeRefMap.h>
    #include <UT/UT_ThreadedAlgorithm.h>
    #include <UT/UT_ParallelUtil.h>
    #include <GA/GA_PageIterator.h>
    #include <GA/GA_Range.h>
    #include <GU/GU_DetailHandle.h>
    #include <GU/GU_PackedGeometry.h>
    #include <GU/GU_PrimPacked.h>
    #include <GU/GU_PolyFrame.h>
    #include <GA/GA_LoadOptions.h>
    
    #include <iostream>
    #include <omp.h>
    
    using namespace std;
    
    
    
    int main(){
    
        GA_LoadOptions load_option;
        GU_Detail *gdp = new GU_Detail;
        gdp->loadIODSOs(); // make sure can load packed geo
    
    
        GU_Detail::IOStatus stat = gdp->load("geos/packed.bgeo",&load_option);
        if(! stat.success() ){
            cout << "load file error
    ";
        }
    
        cout << "static method->Has packed prim:"<<GU_PrimPacked::hasPackedPrimitives(*gdp) << endl;
        cout << "static method->Has packed num of prim:" << GU_PrimPacked::countPackedPrimitives(*gdp) << endl;
        cout << "Num points:"<<gdp->getNumPoints() << endl;
        cout << "Num Prims:"<<gdp->getNumPrimitives() << endl;
    
    
        GA_RWHandleS pathAttribHandle(gdp,GA_ATTRIB_PRIMITIVE,"path");
        for(GA_Iterator it(gdp->getPrimitiveRange()); !it.atEnd(); it.advance()){
            GA_Primitive *prim = gdp->getPrimitive(*it);
            GU_PrimPacked *pack_prim = static_cast<GU_PrimPacked*>(prim);
    
            cout << pathAttribHandle.get(*it) << endl;
    
        }
    
    
    
        //GA_SaveOptions save_option;
        //gdp->save("geos/grid_pf.bgeo",&save_option);
    
    
        delete gdp;
        cin.get();
        return 0;
    
    }
    View Code

     11, NOT TESTED

     https://www.sidefx.com/docs/hdk/class_g_a___attribute_ref_map.html

    // Compute the average value of the P attribute and store in a
    // global attribute "averageP".
    GA_WeightedSum              sum;
    GA_AttributeRefMap          map(gdp);
    GA_AttributeRefMap::Handle  gah(map);
    int                         npts;
    map.append( detail.findGlobalAttribute("averageP"),
                detail.findPointAttribute("P") );
    gah.setGlobal();    // Write to global attributes
    gah.startSum(sum);
    for (GA_Iterator it = gdp.getPointRange(); !it.atEnd(); ++it)
        gah.sumPoint(sum, it.getOffset(), 1);
    npts = gdp.getNumPoints();
    gah.finishSum(sum, npts ? 1./npts : 0);

    REF:https://www.sidefx.com/docs/hdk/index.html

    GA User Guide:https://www.sidefx.com/docs/hdk/_h_d_k__g_a__using.html#HDK_GA_Using_GEO_Point 讲解的非常详细GA/GB的各种操作

    GA Porting Guide:https://www.sidefx.com/docs/hdk/_h_d_k__g_a__porting.html#HDK_GA_PortingCookbook_Simple_Name_Translation 各种GA的案例,必须删除点,删除未使用面....

  • 相关阅读:
    01开卡主流程
    eclipse开发工程右键菜单例子
    eclipse插件开发需要什么
    installshield安装程序自注册dll
    eclipse开发视图
    vbscript和cmd命令 如何获取当前文件的路径
    eclipse开发视图
    vbscript和cmd命令 如何获取当前文件的路径
    vbscript设置环境变量
    eclipse开发工程右键菜单例子
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12808723.html
Copyright © 2011-2022 走看看