几个经典的数学库之一学习---VCGlib(2)

更新时间:2023-06-13 05:15:07 阅读: 评论:0

⼏个经典的数学库之⼀学习---VCGlib(2)
⼏个经典的数学库之⼀学习---VCGlib(2)
1. Optional Component(可选的组件)
  有许多Vertex和Face的属性并不是⼀直都是必要的,如Face-Face的邻接关系。VCG库提供了⼀种可以指定可选组件的⽅法。如属性信息并不是静态保存在simplex(简素)中的,⽽是当被需要他们的时候,静态分配这些属性信息的。
  定义使⽤这些组件,需要做以下两种事情:  (1)使⽤在mesh的定义中使⽤经典的容器,从std::vector中继承  (2)在simplex的定义中使⽤指定的组分类型定义
  当component被激活时,其能够被使⽤,即通过调⽤Enableing函数。VCG处理Optional Componnet采⽤两个机制:
(1)Ocf(Optional component Fast),即使⽤指针对于每种“简素Simliex”,但是可以和non-optional 对象数据⼀样快。
(2)Occ(Optional Component Compact),对于每个mesh,需要的内存空间⾮常⼩,但是这样的弊端是获取访问数据⾮常慢。
  下⾯讨论两种⽅法。
Optional Component Fast
  下⾯定义MyMesh,指定了定点和⾯的⼀些component。指定的属性vcg::vertex::InfoOcf 与 vcg::face::InfoOcf 是定点和⾯的第⼀个属性,并且我们使⽤vcg::vertex::vertex_Ocf 与 vcg::face::vectorOcf作为容器;
  (/icmzn提供)
class MyVertexOcf;
class MyFaceOcf;
struct MyUdTypesOcf: public vcg::UdTypes<
vcg::U<MyVertexOcf>::AsVertexType,
vcg::U<MyFaceOcf>::AsFaceType>{};
class MyVertexOcf  : public vcg::Vertex< MyUdTypesOcf,
vcg::vertex::InfoOcf,//  <--- Note the u 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< MyUdTypesOcf,
vcg::face::InfoOcf,//  <--- Note the u 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 u 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> > {};
  在获取Optional Component中的数据是,需要⾸先调⽤EnalbeXX()来激活相应的可选属性。然后相应的属性可以被分配空间,并且获取。直到调⽤disAble()为⽌。
MyMeshOcf cmof;
asrt(tri::HasFFAdjacency(cmof) == fal);
cmof.face.EnableFFAdjacency();
asrt(tri::HasFFAdjacency(cmof) == true);
  在激活之前,获取的Componnent的数据,或者在关闭之后,相应的组件会抛出异常。
cmof.face.EnableNormal();  // remove this line and you will throw an exception for a missing 'normal' component
tri::UpdateNormal<MyMeshOcf>::PerVertexPerFace(cmof);
2. Bit Flags
  对于mesh的每⼀种simplex(简素),都有⼀种BitFlags的组件,保存固定的32bit的⽮量标识,⽤来
分类判别的需要。可以使⽤下⾯相关的类:
  IsD():删除标识
  可以判定该简素对象是否被删除。因为mesh中的元素可以被Allocating和Deleting⽹格。
  IsB(),ClearB(),SetB():边界标识
  可以判定顶点或者⾯是否再边界上。这些bit不是默认计算获取,他们是连同拓扑⼀起或者不是⼀起计算后的结果。如果FF拓扑计算这些标识效率⾼。
  这些标识的关联是,有许多的算法需要边界特征来计算是⾼效率的。⽽没有必要对整个FF拓扑结构进⾏全部运算。
  IsS(), ClearS(), SetS():选择标识
  IsV(), ClearV(), SetV():访问标识
  访问标识,对于⼀些算法是很有⽤的。你不应该依赖这些标识的状态,或者⼈⼯设置当前的状态,因为任何的⼀种算法都可以清理这些标识以及更新这些标识。
  使⽤tri::UpdateFlags<YourMeshClass>::VertexClearV(yourMesh),来清理所有的bits
  ⽤户⾃定义标识
草莓如何清洗  如果⽤户定义私有的标识,通过NewBigFlag()函数⽅式,可以返回⼀个Mash(掩码)⽤来设置,清理,测试针对特定big。下⾯例⼦分配三个bit,对每⼀个face然后清理他们。
  int e0bit = MyFace::NewBitFlag();
  int e1bit = MyFace::NewBitFlag(); 
  int e2bit = MyFace::NewBitFlag();
  int ebit[3] = {e0bit,e1bit,e2bit};
  for(MyMesh::FaceIterator fi=m.face.begin();fi!=d();++fi)
    for(int i=0;i<3;++i)
      (*fi).ClearUrBit(ebit[i]);
  通过使⽤tri::UpdateFlags<YourMeshClass>::FaceClear(yourMesh,e0bit|e1bit|e2bit);来清理所有mesh的定点或者⾯的指定bit
3. Allocating and Deleting mesh elements
Creating elements 
 通过AddVertices and AddFaces functions 来给指定的mesh增加三⾓⽹格,或者增加元素。新添加的元素在mesh的最后,且函数返回第⼀个添加元素的指针。如果新添加元素引起vector重新内存分配,则指向该类的vector的指针将⽆效。这些函数管理安全的重新分配以及指针更新所有的保存在mesh内部的指针,即如果添加⼀些vectors,且引起了vertex vector的重新内存分配,则在face结构中的指针指向vector,这些指针将会⾃动进⾏更新通过Allocator Functions。所以,⽤户不能直接进⾏reallocate 或者resize  vectors or face vectors.
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
int main()
{
MyMesh m;
MyMesh::VertexIterator vi = vcg::tri::Allocator<MyMesh>::AddVertices(m,3);
MyMesh::FaceIterator fi = vcg::tri::Allocator<MyMesh>::AddFaces(m,1);
MyMesh::VertexPointer ivp[4];
ivp[0]=&*vi; vi->P()=MyMesh::CoordType ( 0.0, 0.0, 0.0); ++vi;
ivp[1]=&*vi; vi->P()=MyMesh::CoordType ( 1.0, 0.0, 0.0); ++vi;
ivp[2]=&*vi; vi->P()=MyMesh::CoordType ( 0.0, 1.0, 0.0); ++vi;
fi->V(0)=ivp[0];
fi->V(1)=ivp[1];
fi->V(2)=ivp[2];
在platonic.h⽂件中有很多增加元素的例⼦。
  如果⽤户内部的⼀些指针指向mesh元素,但是增加的元素可能⽆效这些指针,可以通过传⼊vcg::tri::Allocator函数,来更新这些内部的私有指针。
// a potentially dangerous pointer to a mesh element
MyMesh::FacePointer fp = &m.face[0];
vcg::tri::Allocator<MyMesh>::PointerUpdater<MyMesh::FacePointer> pu;
// now the fp pointer could be no more valid due to eventual re-allocation of the m.face vector.
vcg::tri::Allocator<MyMesh>::AddVertices(m,3);
就日英文日期格式正确写法
vcg::tri::Allocator<MyMesh>::AddFaces(m,1,pu);
// check if an update of the pointer is needed and do it.二手房定金合同
if(pu.NeedUpdate()) pu.Update(fp);
Destroying Elements
  vcglib采⽤ lazy Deletion Strategy(惰性删除策略),即在vector中的元素通过flagged处理,进⾏“预删除”,即它们仍然在这⾥。
  标记deleted的mark元素,对⽣于的结构没有影响。因此如果标记顶点但是没有合适所有的face,且⾯依附这个已经removed的vertex,则⽤户创建了⼀个⾮⼀致的状态。
  ⽤户永远不要试图⾃⾏删除vertex,即⾃⾏进⾏删除标记,⽤户需要调⽤Allocator Utility Function。
// Now fill the mesh with an Icosahedron(⼆⼗⾯体) and then delete some faces
vcg::tri::Icosahedron(m);
vcg::tri::Allocator<MyMesh>::DeleteFace(m,m.face[1]);
vcg::tri::Allocator<MyMesh>::DeleteFace(m,m.face[3]);
  如上⾯的例⼦,在⼀个⼆⼗⾯体重删除⼀些vertex。通过上述操作,faces的vertor仍然包含20个元素(⼆⼗⾯体重包含⾯的数量),但是m.FN()返回的是18⾯,因此如果算法中含有删除处理,则可能会发⽣容器中的数量不等于mesh中有效的元素数量。
m.vert.size() != m.VN()
m.face.size() != m.FN()
  因此,当⽤户扫描vertects和face的容器时,可能会遇到被deleted marked的元素,所以⽤户需要格外⼩⼼。通过调⽤IsD()进⾏检测判定处理。
// If you loop in a mesh with deleted elements you have to skip them!
MyMesh::CoordType b(0,0,0);
for(fi = m.face.begin(); fi!=d(); ++fi )
{
if(!fi->IsD()) // <---- Check added
{
b += vcg::Barycenter(*fi);
}
}
  在⼀些情形中,当⽤户遍历⼤量的mesh的元素时,通过上述isD()检测效率低,可以通过简便实⽤的两个garbage collection
function函数,通过显⽰调⽤:
肆意青春(m);
(m);
  通过掉应上述两个函数,就不需要对mesh的元素进⾏isD()检测,直接进⾏操作,效率更⾼。
无锡东林书院
m.vert.size() == m.VN()
m.face.size() == m.FN()
注意:
  1. 如果在mesh中没有deleted标识的元素, compactor函数将直接返回(其内部通过判定,容器vector的size函数是否与元素数量匹配判定),所以在左右的⾼强度操作前调⽤compactor函数⾮常安全。
行列式是什么
  2. 如果不清楚deleted元素位置,则不能通过m.FN ()或者m_VN()函数来作为for函数的终⽌条件,因为m.FN() != m.face.size(),因为m.FN()是有效的face的数量,⽽m.face.size()是face的容器的元素数量,因为容器中可能包含deleted标记的元素,这deleted标记的元素不是有效的元素。下⾯的例⼦是WRONG
// WRONG WAY of iterating: FN() != m.face.size() if there are deleted elements
for(int i=0;i<m.FN();++i)
{
if(!fi->IsD())
{
b += vcg::Barycenter(*fi);
}
}
How to copy a mesh
  考虑到intricate nature (复杂的本质) of mesh, vcglib库禁⽌拷贝mesh作为⼀个简单的对象。
  如果需要拷贝mesh,则必须使⽤附加的⼯具类: The Append Utility Class。
MyMesh m2;
(m2,m);
  vcg\complex\append.h⽂件中包含了⼯具类:Append的详细实现。还有可以实现可选的mesh,或者添加后⼀个mesh到前⼀个mesh中的⼯具。
4. Adding ur defined attributes to mesh elements
Ur-Defined Attributes
  vcglib提供简单的机制来关联ur-defined 属性到“简素”simplicies以及mehs。
  attributes以及components都是与simplex关联的数据,即components是静态定义的成员数据,attributes则是运⾏时run-time定义的,处理的数据。
  ⼆者的区别:1,conceptually(概念上) component是指来定义simplex(简素)的基本的信息,如position,normal,以及相关的信息。但是ur-defined attribute是针对指定的算法⽽添加的可获取的数据信息,如⼀个定点可见的平均⽅向。2.
pratically(事实上), 对于每⼀个optional Conponents,都有其本⾝non-optional 部分,⽽且可以通过simplex(简素)的成员函数可以获取,如Vi->N()。对于属性attribute则只能通过创建attribute然后返回。
// add a per-vertex attribute with type float named "Irradiance"
MyMesh::PerVertexAttributeHandle<float> named_hv = vcg::tri::Allocator<MyMesh>:: GetPerVertexAttribute<float> (m,std::string("Irradiance"));
  可以通过handle或者name来删除属性。注意,handle的作⽤于并不⼲扰属性的内存的分配。如果没有显⽰地(explicitly)删除属性,该属性将会⼀直保留分配的内存,指导mesh被摧毁,及时没有任何handle可以处理。
// delete an attribute by name
(m, "Radiosity");
// delete an attribute by handle
(m, anon_hv);
  上述两个⽅法可以同样适应于edges,faces以及mesh。仅仅通过替换PerVertex,PerFace,PerEdge,PerMesh等。如果增加属性但是没有指定名字且丢失handle,则将不会把handle重新返回。
  对于Per-Mesh的指定的属性,可以通过稍微不同的⽅式获取:
// you can also have PerMesh attributes
MyMesh::PerMeshAttributeHandle<int> hm = vcg::tri::Allocator<MyMesh>:: GetPerMeshAttribute<int> (m,std::string("ADummyIntegerAttribute"));
// PerMesh attributes are accesd directly using the handle itlf
hm() = 10;
 C++ type of a mesh and reflection 
  VCGlib 提供⼀系列的函数来实现reflection(反射),如在运⾏时获取mesh的类型。这些函数遵循以下格式: Has[attribute] (mesh),然后返回⼀个boolean值,表⽰指定的属性是否存在。
  因为VCGlib的反射机制考虑了可选组件optional components,因此HasPerVertexNormal(m)返回ture,如果vertex的类型包含属性vcg::vertex::Normal3f 或者如果包含属性作为opetional,vcg::vertex::Normal3fOCF 且 enabled。
5. Loading and saving meshes
  VCGlib提供以下的⽂件格式进⾏导⼊导出:
纪忆
import: PLY, STL, OFF, OBJ, 3DS, COLLADA, PTX, V3D, PTS, APTS, XYZ, GTS, TRI, ASC, X3D, X3DV, VRML, ALN  export: PLY, STL, OFF, OBJ, 3DS, COLLADA, VRML, DXF, GTS, U3D, IDTF, X3D

本文发布于:2023-06-13 05:15:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1036106.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:元素   属性   函数   标识   指定
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图