Houdini HDK 入门学习 创建一个圆锥形状

头文件 sop_mycone.h

///*这个例子创建一个简单的圆锥形状*/
#ifndef __sop_mycone_h__
#define __sop_mycone_h__
#include

class SOP_MyCone : public SOP_Node
{
public:
	static OP_Node *myConstructor(OP_Network *, const char *, OP_Operator *);//创建sop节点
	static PRM_Template myTemplateList[];//节点参数面板需要的参数
protected:
	SOP_MyCone(OP_Network *net, const char *name, OP_Operator *op);//构造
	virtual ~SOP_MyCone();//虚析构
	virtual OP_ERROR cookMySop(OP_Context &context);//sop核心计算
private:
	//参数面板的参数属于该节点私有
	fpreal CENTERX(fpreal t) { return evalFloat("t", 0, t); }
	fpreal CENTERY(fpreal t) { return evalFloat("t", 1, t); }
	fpreal CENTERZ(fpreal t) { return evalFloat("t", 2, t); }
	fpreal HEIGHT(fpreal t) { return evalFloat("height", 0, t); }
	fpreal RADIUS(fpreal t) { return evalFloat("rad", 0, t); }
	fpreal SCALE(fpreal t) { return evalFloat("s", 0, t); }
	int DIVSION(fpreal t) { return evalInt("divs", 0, t); }
};

#endif

源文件 sop_mycone.cpp

#include"sop_mycone.h"
#include
#include
#include//PRM相关的头文件貌似都包含在这里了
#include//有这个houdini里面才能找到你编译好的东西
#include
#include//这里主要是是取了个圆周率M_PI
#include//创建poly多边形
#include//对象指针gdp在这里

//newSopOperator是Houdini从这个DLL抓取并调用注册SOP的钩子。在这种情况下,我们将自己添加到指定的OperatorTable中
void newSopOperator(OP_OperatorTable *table)
{
	table->addOperator(new OP_Operator("mycone", "Cone",
		SOP_MyCone::myConstructor,//创建新的对象
		SOP_MyCone::myTemplateList,//参数模板列表
		0, 0,//最小最大输入端口数
		nullptr,//本地变量
		OP_FLAG_GENERATOR//标识为常规
	));
}
//创建锥形对象
OP_Node *SOP_MyCone::myConstructor(OP_Network *net, const char *name, OP_Operator *op)
{
	return new SOP_MyCone(net, name, op);
}
//参数模板
PRM_Template SOP_MyCone::myTemplateList[] = {
	PRM_Template(PRM_XYZ, PRM_Template::PRM_EXPORT_TBX, 3, &PRMcenterName),
	PRM_Template(PRM_FLT, 1, &PRMheightName, PRMoneDefaults),
	PRM_Template(PRM_FLT, 1, &PRMradiusName, PRMoneDefaults),
	PRM_Template(PRM_FLT, 1, &PRMscaleName, PRMoneDefaults),
	PRM_Template(PRM_INT, 1, &PRMdivName, PRMthreeDefaults, 0, &PRMdivision2Range),
	PRM_Template()
};
//构造
SOP_MyCone::SOP_MyCone(OP_Network *net, const char *name, OP_Operator *op) :SOP_Node(net, name, op)
{
	mySopFlags.setManagesDataIDs(true);
}
//析构,啥都不干
SOP_MyCone::~SOP_MyCone() {};

//如何创建一个3边形polygon
void addPolygon(GU_Detail* gdp, exint v1, exint v2, exint v3)
{
	//追加一个新的多边形primitive,原始类型在GEO_PrimType.h中定义
	GEO_PrimPoly *prim_poly_ptr = (GEO_PrimPoly *)gdp->appendPrimitive(GA_PRIMPOLY);
	//追加形成这个primitive的vertices,点偏移
	prim_poly_ptr->appendVertex(v1);
	prim_poly_ptr->appendVertex(v2);
	prim_poly_ptr->appendVertex(v3);
	prim_poly_ptr->close();//最后封闭primitive使其成为多边形而不是多段线。
}
//锥形的底部需要封闭起来,函数重载(跟上面的创建3变形函数名相同,但是参数不同)
void addPolygon(GU_Detail* gdp, exint vstart, exint nv)
{
	GEO_PrimPoly *prim_poly_ptr = (GEO_PrimPoly *)gdp->appendPrimitive(GA_PRIMPOLY);
	//追加形成这个primitive的vertices,我们利用索引图的单调性保证来避免保留单独的添加点偏移数组
	for (vstart; vstart <= nv; ++vstart)
	{
		prim_poly_ptr->appendVertex(vstart);
	}
	prim_poly_ptr->close();//封闭primitive使其成为多边形而不是多段线。
}

//sop 锥形形状核心计算
OP_ERROR SOP_MyCone::cookMySop(OP_Context &context)
{
	fpreal now = context.getTime();
	UT_Vector3 center(CENTERX(now), CENTERY(now), CENTERZ(now));
	fpreal height = HEIGHT(now);
	fpreal rad = RADIUS(now);
	fpreal scale = SCALE(now);
	int divsion = DIVSION(now);
	//这里例子是生产一个锥形的节点,没有任何输入端,所以需要销毁所有可能的数据
	gdp->clearAndDestroy();

	//形成锥形的点位置
	for (exint i = 0; i < divsion + 1; i++)
	{
		GA_Offset ptoff = gdp->appendPoint();
		UT_Vector3 pos;
		if (i == 0)//锥形的顶部点,我把它作为起始点
		{
			pos(0) = 0; pos(1) = height * scale; pos(2) = 0;
		}
		else {
			pos(0) = SYScos((float)(i - 1) * 2 * M_PI / (float)divsion) * rad * scale;
			pos(1) = 0;
			pos(2) = SYSsin((float)(i - 1) * 2 * M_PI / (float)divsion) * rad * scale;
		}
		pos += center;
		gdp->setPos3(ptoff, pos);
	}
	//形成一个多边形至少需要3个点,所以i初始为2
	for (exint i = 2; i < divsion + 1; i++)
	{
		addPolygon(gdp, 0, i, i-1);
		if(i>2)
			addPolygon(gdp, 0, 1, divsion);
		if(i>2 && i==divsion)
			addPolygon(gdp, 1, divsion);
	}
	return error();
}

这个HDK太TM难学了,就做这么一个简单的锥形废了老多精力,还要继续更加努力...掌握更好的学习方法

你可能感兴趣的:(Houdini,HDK学习)