OpenSubdiv是一种用于细分曲面的开源C ++库。 Bfr.Parameterization是其中一种函数,用于对曲面进行参数化以便于细分。
template<class T> void Bfr::Parameterization(T const & mesh,
T::PrimVar const & uvs,
T * ptex,
int nchannels,
int facevarying,
bool requireUV,
float * fvarData=nullptr)
参数 | 说明 |
---|---|
mesh | 要参数化的网格 |
uvs | 该网格已存在的纹理坐标 |
ptex | 一个可选的参数化坐标;调用函数后,这个参数将包含从纹理坐标转换的参数化坐标 |
nchannels | 网格中的通道数 |
facevarying | 是否进行面间参数化 |
requireUV | 是否需要使用纹理坐标 |
fvarData | 一个可选的数据块,它包含网格上的fvar数据,如果存在的话 |
// 定义一个类派生自Osd::MeshInterface
class FooMesh : public OpenSubdiv::Osd::MeshInterface {
public:
// 实现几个虚函数,以支持它在Bfr.Parameterization中使用
// 实现GetNumVertices方法
int GetNumVertices() const override {
return numvertices_;
}
// 实现GetNumFaces方法
int GetNumFaces() const override {
return numfaces_;
}
// 实现GetNumVertsPerFace方法
int GetNumVertsPerFace(int faceid) const override {
return numvertsperface_[faceid];
}
// 实现GetVertVertexIndices
void GetVertVertexIndices(int vertid, int * outbuffer) const override {
outbuffer[0] = vertexindices_[vertid];
}
// 实现GetFaceVertexIndices
void GetFaceVertexIndices(int faceid, int * outbuffer) const override {
memcpy(outbuffer, &vertexfaceindices_[facevtxoffsets_[faceid]],
sizeof(int) * numvertsperface_[faceid]);
}
// 实现GetVertexAttribData
void GetVertexAttribData(int index, int * numcompspervertex,
int * attribsize, void const ** attribdata) const override {
switch (index) {
case 0: // 第一个属性
*numcompspervertex = 2;
*attribsize = sizeof(float) * 2;
*attribdata = uvcoords_;
break;
default:
// 其他属性默认为空
*numcompspervertex = 0;
*attribsize = 0;
*attribdata = nullptr;
}
}
// 设置顶点,拓扑和纹理坐标等
void SetupMesh(int numvertices, int numfaces, int const * numvertsperface,
int const * vertsperface, int const * vertexindices,
float const * uvcoords) {
numvertices_= numvertices;
numfaces_= numfaces;
numvertsperface_ = numvertsperface;
vertexfaceindices_.resize(numfaces * 4);
facevtxoffsets_.resize(numfaces + 1, 0);
vertexindices_ = vertexindices;
uvcoords_ = uvcoords;
for (int i = 0; i < numfaces; ++i) {
int const num = numvertsperface[i];
facevtxoffsets_[i + 1] = facevtxoffsets_[i] + num;
memcpy(&vertexfaceindices_[facevtxoffsets_[i]],
&vertsperface[facevtxoffsets_[i]],
num * sizeof(int));
}
}
private:
int numvertices_ = 0;
int numfaces_ = 0;
std::vector<int> numvertsperface_;
std::vector<int> vertexfaceindices_;
std::vector<int> facevtxoffsets_;
int const * vertexindices_ = nullptr;
float const * uvcoords_ = nullptr;
};
// 创建FooMesh实例,设置其顶点,拓扑和纹理坐标等
FooMesh foo;
int const verts[4] = {0, 1, 2, 3}; // 一个四边形
float const uvcoords[8] = {0, 0, 0, 1, 1, 1, 1, 0}; // 对应的纹理坐标
int const numvertsperface[1] = {4}; // 一个四边形
foo.SetupMesh(4, 1, numvertsperface, verts, verts, uvcoords);
// 使用Bfr::Parameterization方法进行参数化
// 参数uvcoords是FooMesh实例foo的纹理坐标
// 参数ptex是一个可选的参数化坐标,调用函数后,它将包含从纹理坐标转换的参数化坐标
Bfr::Parameterization(foo, 1, &ptex, 2, 0, true, nullptr);