有时顶点或面的一些属性并不是总是需要的. VCG 提供了一种方式来指定可选组件. 例如, 属性并不是静态存储在内存中, 而是在你需要的时候可以动态开辟的. 静态开辟的组件的使用是完全易懂的.
为了定义可选组件, 你需要做两件事情:
- 在曲面定义中使用指定类型的容器(继承
std::vector
) - 在 simplex 定义中指定正确的组件类型
当一个可选组件是 enable 的时候它才可以被使用, 例如, 当它的内存已经开辟. 通过调用 Enable
函数可以启用可选组件. VCG 提供了两种机制来管理可选组件: 第一种叫做 Ocf
(for Optional Component Fast), 对每一个 simplex 它使用一个指针, 这样访问可选属性的速度几乎和其他属性一样快. 第二种叫做 Occ
(for Optional Component Compact) , 对每个曲面它仅需要少量内存, 但是访问速度较慢. 下面仅讨论它们的使用.
Optional Component Fast
下面 MyMesh
的定义中指定了顶点和面的一些 Optional Component.
class MyVertexOcf;
class MyFaceOcf;
struct MyUsedTypesOcf: public vcg::UsedTypes<
vcg::Use<MyVertexOcf>::AsVertexType,
vcg::Use<MyFaceOcf>::AsFaceType>{};
class MyVertexOcf : public vcg::Vertex< MyUsedTypesOcf,
vcg::vertex::InfoOcf, // <--- Note the use of the 'special' InfoOcf component
vcg::vertex::Coord3f, vcg::vertex::QualityfOcf,
vcg::vertex::Color4b, vcg::vertex::BitFlags,
vcg::vertex::Normal3f, vcg::vertex::VFAdjOcf >{};
class MyFaceOcf : public vcg::Face< MyUsedTypesOcf,
vcg::face::InfoOcf, // <--- Note the use of the 'special' InfoOcf component
vcg::face::FFAdjOcf, vcg::face::VFAdjOcf,
vcg::face::Color4bOcf, vcg::face::VertexRef,
vcg::face::BitFlags, vcg::face::Normal3fOcf > {};
// the mesh class must make use of the 'vector_ocf' containers instead of the classical std::vector
class MyMeshOcf : public vcg::tri::TriMesh< vcg::vertex::vector_ocf<MyVertexOcf>, vcg::face::vector_ocf<MyFaceOcf> > {};
在访问可选属性的数据容器之前, 必须调用 EnableXXX()
函数, 这样属性对应的内存空间才会开辟.
MyMeshOcf cmof;
assert(tri::HasFFAdjacency(cmof) == false);
cmof.face.EnableFFAdjacency();
assert(tri::HasFFAdjacency(cmof) == true);
不调用EnableXXX()
函数而直接使用属性将会导致错误:
cmof.face.EnableNormal(); // remove this line and you will throw an exception for a missing 'normal' component
tri::UpdateNormal<MyMeshOcf>::PerVertexPerFace(cmof);
更多例子参考 trimesh_optional.cpp