这篇文章的目标是
使用CMake编译简单程序SOP_TestXform。
-------------------------------------------------------------
-------------------------------------------------------------
博主个人比较讨厌使用CMake构建程序,本想坚持自己的意志不使用CMake构建HDK程序,而实际上对于HDK开发的流程来说,我只能选择屈服,原因有二:
1、当一个HDK节点的参数面板复杂性比较高时,使用PRM_TemplateList生成参数面板的工作量较大,而使用DS文件生成参数面板更加轻松。
2、PRM_TemplateList无法生成"Simple"样式的"FIle"参数面板,至少我现在还没有找到好的办法实现它。
接下来进入正题:
进入houdini,随便创建一个面板参数,将面板参数导出为文件
打开这个文件,它描述了我们导出的参数的信息,houdini称之为.ds文件,当我们的面板参数定义得越复杂就越能体现它简洁的优势。
{
name selectedparms
parm {
name "distance"
label "Distance"
type float
default { "0" }
range { 0 10 }
parmtag { "script_callback_language" "python" }
}
}
定义头文件
#pragma once
#include <SOP/SOP_Node.h>
#include <UT/UT_StringHolder.h>
class SOP_TestXform : public SOP_Node
{
public:
static PRM_Template* buildTemplates();
static OP_Node* myConstructor(OP_Network* net, const char* name, OP_Operator* op)
{
return new SOP_TestXform(net, name, op);
}
static const UT_StringHolder theSOPTypeName;
const SOP_NodeVerb* cookVerb() const override;
protected:
SOP_TestXform(OP_Network* net, const char* name, OP_Operator* op)
:SOP_Node(net, name, op)
{
mySopFlags.setManagesDataIDs(true);
}
~SOP_TestXform() override {}
OP_ERROR cookMySop(OP_Context& context) override
{
return cookMyselfAsVerb(context);
}
};
注意:我们的.h和.cpp文件只定义了SOP_TestXform以及SOP_TestXformVerb两个类,使用DS文件的流程中,Houdini自动识别DS文件的信息并生成一个头文件SOP_TestXform.proto.h,这个头文件包含了一个类SOP_TestXformParms,我们将使用这个类获取到面板参数。
#include "SOP_TestXform.h"
#include "SOP_TestXform.proto.h"
#include <PRM/PRM_TemplateBuilder.h>
#include <OP/OP_OperatorTable.h>
#include <UT/UT_DSOVersion.h>
#include <UT/UT_Vector3.h>
#include <UT/UT_StringHolder.h>
using namespace HDK_Sample;
const UT_StringHolder SOP_TestXform::theSOPTypeName("hdk_testxform"_sh);
void newSopOperator(OP_OperatorTable* table)
{
table->addOperator(new OP_Operator(
SOP_TestXform::theSOPTypeName, //真正的operator name
"HDK Test Transform", //operator label
SOP_TestXform::myConstructor, //HDK的规则
SOP_TestXform::buildTemplates(), //参数列表
1, //最小输入数量
1, //最大输入数量
0
)); //CH_LocalVariable 我暂时也没用上
}
static const char* theDsFile = R"THEDSFILE(
{
name parameters
parm {
name "distance"
label "Distance"
type float
default { "0" }
range { 0 10 }
export all
}
}
)THEDSFILE";
PRM_Template* SOP_TestXform::buildTemplates()
{
static PRM_TemplateBuilder templateBuilder("SOP_TestXform.cpp"_sh, theDsFile);
return templateBuilder.templates();
}
class SOP_TestXformVerb : public SOP_NodeVerb
{
public:
SOP_TestXformVerb() {}
virtual ~SOP_TestXformVerb() {}
virtual SOP_NodeParms* allocParms() const { return new SOP_TestXformParms(); }
virtual UT_StringHolder name() const { return SOP_TestXform::theSOPTypeName; }
virtual CookMode cookMode(const SOP_NodeParms* parms) const { return COOK_DUPLICATE; }
virtual void cook(const CookParms& cookparms) const;
static const SOP_NodeVerb::Register<SOP_TestXformVerb> theVerb;
};
const SOP_NodeVerb::Register<SOP_TestXformVerb> SOP_TestXformVerb::theVerb;
const SOP_NodeVerb*
SOP_TestXform::cookVerb() const
{
return SOP_TestXformVerb::theVerb.get();
}
void SOP_TestXformVerb::cook(const SOP_NodeVerb::CookParms& cookparms) const
{
auto&& sopparms = cookparms.parms<SOP_TestXformParms>();
float distance = sopparms.getDistance();
GU_Detail* gdp = cookparms.gdh().gdpNC();
GA_Offset ptoff;
GA_FOR_ALL_PTOFF(gdp, ptoff)
{
//得到每一个点的当前位置
UT_Vector3 pos = gdp->getPos3(ptoff);
//每个点的y轴加上参数distance的值
pos.y() += distance;
//最后通过gdp指针修改点的位置
gdp->setPos3(ptoff, pos);
}
//通过gdp指针绑定所有修改的信息,这一步必不可少
gdp->bumpAllDataIds();
}
定义好CMake文件
cmake_minimum_required( VERSION 3.6 )
project( HDK_Project )
#特别注意这一行,一定要引用到正确的路径
list( APPEND CMAKE_PREFIX_PATH "D:/Houdini19.5.303/toolkit/cmake" )
# Locate Houdini's libraries and header files.
# Registers an imported library target named 'Houdini'.
find_package( Houdini REQUIRED )
set( library_name SOP_TestXform )
# Code generation for the embedded DS file in SOP_TestXform.cpp.
houdini_generate_proto_headers( FILES SOP_TestXform.cpp )
# Add a library and its source files.
add_library( ${library_name} SHARED
SOP_TestXform.cpp
SOP_TestXform.h
)
# Link against the Houdini libraries, and add required include directories and
# compile definitions.
target_link_libraries( ${library_name} Houdini )
# Include ${CMAKE_CURRENT_BINARY_DIR} for the generated header.
target_include_directories( ${library_name} PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)
# Sets several common target properties, such as the library's output directory.
houdini_configure_target( ${library_name} )
在当前路径下应有这三个文件
接下来使用CMake编译工程
打开vs工程生成对应的HDK
之后便会在dso文件夹下生成SOP_TestXform.dll文件。