我用的VS2010,CGAL4.2,Qt5,为我的世界龙息有什么用Qt4.8的例程跑不出呢?如何破解

Windows平台下CGAL配置 - Learning, thinking and coding - CSDN博客
Windows平台下CGAL配置
本文使用boost_1_54_0、CGAL-4.2,cmake-2.8.11.2-win32-x86进行配置说明。详细步骤可以参考CGAL官网对于CGAL的配置说明。
地址为:http://www.cgal.org/windows_installation.html
我在具体配置的时候并没有完全按照指示来,最终导致了挺多错误,但是幸好最终都解决了。参考文献有:
http://blog.csdn.net/lishirui/article/details/8187226
一、配置Boost,参考&http://www.boost.org/doc/libs/1_53_0/more/getting_started/windows.html
1. 从http://www.boost.org/users/download/ 上下载boost_1_54_0.tar.gz,解压到本地,使用VS2010进行编译 ,打开Tools&&&Visual
Studio 2010 Command Prompt,进行到boost目录,有一个bootstrap.bat,运行它可以得到b2.exe和bjam.exe两个文件,两个文件本质是一样的,都可以用来编译。因为我之前装的是VS2012,但是qt因为不支持,又装了VS2010,但是可能因为有点冲突,所以不能运行这个,错误信息为“计算中丢失mspdb100.dll”:
在网上找了一下,参考http://blog.csdn.net/zhenxuhit/article/details/5962830, 在环境变量中添加了d:/Program
Files/Microsoft Visual Studio 10.0/VC/bin,,即vs2010的安装目录,并D:/Program Files/Microsoft Visual Studio 10.0/VC/bin/amd64下的mspdb100.dll拷贝到vc/bin目录下,就可以运行了,但是我在用cmake编译的CGAL的时候,又出现了这情况,后来在网上找到的解决方案是将vc/bin目录下的cvtres.exe文件改名了,问题解决了,但是具体原来却不知道,忘知道的网友指教,如果还有问题,可以运行下当前目录下的vcvars32.bat进行环境重新设置。
2. 运行bjam --toolset=msvc-10.0 --prefix=D:\boost_1_53
--build-type=complete install ,大概一个小时之后,会生成D:\boost_1_53这个目录,里面包含include以及lib目录。
在环境变量中添加BOOST_ROOT=D:\boost_1_53,并把D:\boost_1_53\lib添加到path路径。
二、配置CGAL
使用cmake进行编译时,会出现找不到library的情况,可以通过以下操作配置通过:选中“Advanced”选项,并把环境变量中的“CGAL_Boost_USE_STATIC_LIBS”选中。再选择congfiure即可通过。
点击Generate之后会生成相应文件夹,点击CGAL.sln将D:\Program Files\CGAL-4.2\build\bin”加入到环境变量Path中。
相应参考文献为:
http://blog.csdn.net/zhenxuhit/article/details/5962830
http://www.boost.org/doc/libs/1_53_0/more/getting_started/windows.html
http://blog.csdn.net/lishirui/article/details/8187226
/blog/1358495
我的热门文章VS2010下安装QT5.2.1插件 - CSDN博客
VS2010下安装QT5.2.1插件
本人安装的过程是根据这篇博客来进行安装,期间遇到一些安装的问题,在这里列出来。
1.下载windows下的QT库&QT5.2.1
for vs2010:
2.下载VS2010&下的QT插件:
3.根据博客的过程安装到建立项目Qt Application时出现unable to find a qt build,此时可能路径设置不对,比如大小写错误导致找不到qmake编译器,点击VS工具栏的QT菜单选择options,指定qt
Build所在的路径(qt安装路径),然后点击ok。
这是修改过默认安装路径的
4.QT5.2.1中库函数里面包含的函数与之前版本的不同,所以在编程的时候需要谨慎,要根据新版本的函数来进行开发,不然会出现无法找到该函数或库函数的问题。
5.vs2010利用QT建立项目时,存储项目的路径和项目名称需要用英文名词来表示,如果路径中出现中文,则无法识别路径,从而导致找不到文件,无法编译运行。
d:\????\documents\visual studio 2010\Projects\QtTest\qttest.h: No such file
四个问号是一个中文的目录名,无法识别,出现错误。
本文已收录于以下专栏:
相关文章推荐
操作系统:windows 7
开发软件:vs2010+Qt5.5.0
开发语言:c++
软件下载:
vs2010:cn_visual_studio_2010_ultimate_x86_dvd_5323...
1.下载windows下的QT库
QT4.8.5 for vs2010:
http://download.qt-project.org/official_releases/qt/4.8/4.8.5/...
前言之前在网上看见一个Qt + OpenGL实现AR的帖子,便想着实现以下,所以今天打算实现下,工欲善其事必先利其器嘛,所以先配置环境下载安装软件
下载vs 2015,傻瓜式安装,但安装时间可能比较长...
最近几个项目用到QT,伙伴使用QT经验较多,现记录基础环境搭建方法如下。
QT5.5配合VS2010使用。
稍微调研了下,QT5.5支持WIN10。
安装vs2010,记得打vs2010sp1的补丁(...
1.下载windows下的QT库 QT4.8.5
for vs2010:
http://download.qt-project.org/official_releases/qt/4.8/4.8.5...
QT与JAVA有点类似,也是一种跨平台的软件(当然在windows平台和linux平台需要安装相应的QT开发环境和运行库,类似于JAVA在不同平台下的虚拟机JVM环境),因此对于某些需要同时支持win...
在vs中可以创建Qt的项目,要安装一个Qt的插件
qt-vs-addin-1.1.11-opensource.exe支持vs2010的...
因项目需要Qt开发GUI,我根据网上资料及自己的经验整理了搭建vs2010+Qt 5.4 开发环境。我的主要贡献是在Qt新版下载主页的背景下介绍离线安装Qt5.4及插件Visual St...
VS2010平台下VAssist与Qt整合配置及相关便
1、下载QT5
http://qt-project.org/downloads
3、设置环境变量
他的最新文章
讲师:何宇健
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Openmesh函数库设计及与CGAL的对比 - CSDN博客
Openmesh函数库设计及与CGAL的对比
/rocketfan/category/261367.html
在前面写了CGAL模板类设计的一些思路,这里尝试写一点openmesh库的设计思路以及和CGAL的对比.虽然OPENMESH代码量小,不过还是只看懂皮毛,很大部分算是翻译帮助文档吧,主要用作笔记,
方便以后继续分析。
相对CGAL的功能强大和庞大(包含大量计算几何算法的实现),Openmesh显得更加小巧轻量化,它更专注在三维网格数据结构的表示,
外围也提供在此基础上的网格简化算法及框架,网格细分等等应用算法。
同样是在实现上大量依赖模版类,但是Openmesh源代码的可读性更好些(很大程度上也因为它的小巧,CGAL实现文件太多了,层次结构复杂),
在提供给用户的类,
Openmesh的设计是尽可能少的让用户去知晓模版参数,也就是除非必须,
尽量减少模版参数甚至不带模板参数。
Openmesh设计的一个亮点是用户可以在程序运行时动态为网格添加属性和删除属性
这个功能很赞的。一个典型的应用,可以写一个对网格进行光顺的smooth算法
template &class Mesh& class SmootherT
typedef typename Mesh::Point
typedef OpenMesh::VPropHandleT& cog_t & Property_
// construct with a given mesh
SmootherT(Mesh& _mesh)
: mesh_(_mesh)
mesh_.add_property( cog_ );
~SmootherT()
mesh_.remove_property( cog_ );
// smooth mesh _iterations times
void smooth(unsigned int _iterations)
for (unsigned int i=0; i & _ ++i)
std::for_each(mesh_.vertices_begin(),
mesh_.vertices_end(),
ComputeCOG(mesh_, cog_));
std::for_each(mesh_.vertices_begin(),
mesh_.vertices_end(),
SetCOG(mesh_, cog_));
//--- private classes ---
class ComputeCOG
ComputeCOG(Mesh& _mesh, Property_cog& _cog)
: mesh_(_mesh), cog_(_cog)
void operator()(typename Mesh::Vertex& _v)
typename Mesh::VertexHandle
vh( mesh_.handle(_v) );
typename Mesh::VertexVertexIter
typename Mesh::Scalar
valence(0.0);
mesh_.property(cog_, vh) = typename Mesh::Point(0.0, 0.0, 0.0);
for (vv_it=mesh_.vv_iter(vh); vv_ ++vv_it)
mesh_.property(cog_, vh) += mesh_.point( vv_it );
++
mesh_.property(cog_, mesh_.handle(_v) ) /=
Property_cog& cog_;
class SetCOG
SetCOG(Mesh& _mesh, Property_cog& _cog)
: mesh_(_mesh), cog_(_cog)
void operator()(typename Mesh::Vertex& _v)
typename Mesh::VertexHandle vh(mesh_.handle(_v));
if (!mesh_.is_boundary(vh))
mesh_.set_point( vh, mesh_.property(cog_, vh) );
Property_cog& cog_;
//--- private elements ---
Property_cog cog_;
当用户希望对其所持有的mesh做光顺处理的时候,就可以交给SmooterT类来完成。
// smoothing mesh argv[1] times
SmootherT&MyMesh& smoother(mesh);
smoother.smooth(atoi(argv[1]));
这个实例也显示了openmesh和STL的结合,foreach,函数对象的使用。
最酷的还是SmootherT类会给传入的mesh对象添加顶点参数,即每一个顶点添加一个cog_,记录光顺后的位置,最后
所有顶点都计算好,原顶点位置可以改变的时候再赋值给原顶点。当完成了smooth操作后析构函数自动又把这个属性从mesh中删除,这样对于用户而言这些就是透明的,对用户而言mesh只是被光顺。
这种实现很漂亮,如果不采用动态添加属性的话,用户就需要在定义自己的mesh的时候考虑到由于光顺操作的需要,添加一个cog_属性,但是当光顺完不需要这个属性的时候,该属性也还会存在,
占用内存。
如果不想这样,那也只好在调用smooth的时候建立一个一维数组,大小和顶点数目相同,将属性值记录到该数组中,不用了删除数组占用空间。但是这样的可读性就差了。
另外一个应用,点法向的计算。(法向属性常规属性,用户也可以自由添加删除,但是调用函数和用户自定义属性有所不同)
首先可以给网格添加顶点属性即
mesh.request_vertex_normals();
因为计算顶点法向是需要面法相的(所有相邻面法向的和),所以我们需要添加面法向属性
mesh.request_face_normals();
// let the mesh update the normals
mesh.update_normals();
// dispose the face normals, as we don't need them anymore不需要面法向了就去掉它
mesh.release_face_normals();
相当的灵活。
CGAL的网格模型数据结构部分(半边数据结构)的架构。
半边结构示意图。半边结构非常适合描述网格结构,因为它可以方便的改变网格拓扑形态,如删除边,分裂边等待.
上图为CGAL中的类结构设计.
各个模块关系.
默认的顶点,边,面
这里我们只关心,最上层的Polyhedron
用户使用默认的Polyhedron
#include &CGAL/Simple_cartesian.h&
#include &CGAL/Polyhedron_3.h&
#include &iostream&
typedef CGAL::Simple_cartesian&double&
typedef Kernel::Point_3
typedef CGAL::Polyhedron_3&Kernel&
typedef Polyhedron::Vertex_iterator
int main() {
Point_3 p( 1.0, 0.0, 0.0);
Point_3 q( 0.0, 1.0, 0.0);
Point_3 r( 0.0, 0.0, 1.0);
Point_3 s( 0.0, 0.0, 0.0);
Polyhedron P;
P.make_tetrahedron( p, q, r, s);
CGAL::set_ascii_mode( std::cout);
for ( Vertex_iterator v = P.vertices_begin(); v != P.vertices_end(); ++v)
std::cout && v-&point() && std::
默认情况下用的是HalfedgeDS_defualt,是基于list的,用户可以选择使用基于vector实现的半边结构。
基于vector的半边结构适合静态的网格结构。
typedef CGAL::Polyhedron_3& Traits,
CGAL::Polyhedron_items_3,
CGAL::HalfedgeDS_default&
#include &CGAL/Cartesian.h&
#include &CGAL/HalfedgeDS_vector.h&
#include &CGAL/Polyhedron_3.h&
#include &iostream&
typedef CGAL::Cartesian&double&
K //CGAL用Traits(Kernel)表示采用的数据精度类型如这里的Cartesian&double&
typedef Kernel::Point_3
typedef CGAL::Polyhedron_3& Kernel,
CGAL::Polyhedron_items_3,
CGAL::HalfedgeDS_vector&
//使用基于vector实现的半边结构
int main() {
Point_3 p( 1.0, 0.0, 0.0);
Point_3 q( 0.0, 1.0, 0.0);
Point_3 r( 0.0, 0.0, 1.0);
Point_3 s( 0.0, 0.0, 0.0);
Polyhedron P;
// alternative constructor: Polyhedron P(4,12,4);
P.make_tetrahedron( p, q, r, s);
CGAL::set_ascii_mode( std::cout);
std::copy( P.points_begin(), P.points_end(),
std::ostream_iterator&Point_3&( std::cout, &\n&));
用户如何定义自己的特定的mesh顶点,边,面属性?
#include &CGAL/Simple_cartesian.h&
#include &CGAL/IO/Color.h&
#include &CGAL/Polyhedron_3.h&
// A face type with a color member variable.
template &class Refs&
struct My_face : public CGAL::HalfedgeDS_face_base&Refs& {
// An items type using my face.
struct My_items : public CGAL::Polyhedron_items_3 {
template &class Refs, class Traits&
struct Face_wrapper {
typedef My_face&Refs& F
typedef CGAL::Simple_cartesian&double&
typedef CGAL::Polyhedron_3&Kernel, My_items&
typedef Polyhedron::Halfedge_handle
int main() {
Polyhedron P;
Halfedge_handle h = P.make_tetrahedron();
h-&facet()-&color = CGAL::RED;
注意这种方式虽然也算方便,但是对用户而言其实他不关系Refs,Traits,最好应该能够将这些模板参数去掉,尽量少的让用户接触模板参数。Openmesh做到了这一点。
具体上面的方法怎么起到能够让程序选择使用用户自定义的结构可以看我前面关于CGAL模板类设计的文章。
openmesh,的设计
考虑能够提供动态存储管理的基于array存储的网格。
考虑提供普通的半边网格结构,和特殊的三角网格半边结构(更快,专为三角网格优化)
考虑能够兼容诸如quad tree的网格表示方法,用以实现快速的细分。也可定义其它的kernal以便实现诸如允许非流形存在的网格结构。
Openmesh中的接口:
网格提供的可选参数
&&&&&&& 什么样的Mesh普通的还是三角网格Mesh?
Kernal(WELL当前版本的OPENMESH只提供基于ARRAY(std::vector)的kernal,当然kernal还是可选)
&&&&&& 选择采用double linked list 还是 array作为底层的存储方式?container
&&&&&&& (注意这里和CGAL的Traits表示意义不同那里是表示采用什么精度类型的数据等等,一般不需要过多考虑)
&&&&&&& 这里通过这个参数,
&&&&&&&&&&&&&&&&& 用户可以定义它自己的顶点类型,面,边,加入自己需要的属性,方法。
&&&&&&& 以及修改坐标的数据类型如double , float,三维坐标还是二维坐标。
Openmesh的用户接口API等待更加友好,可以对比下
使用默认的网格结构
&&&&&&&&&& 使用默认的普通网格,array based
typedef OpenMesh::PolyMesh_ArrayKernelT&&
使用默认的三角网格,array based
用户自定义自己的traits
// Define my personal traits
struct MyTraits : OpenMesh::DefaultTraits
// Let Point and Normal be a vector of doubles
typedef OpenMesh::Vec3d P
//Point的类型被定义为3维double类型
typedef OpenMesh::Vec3d N
// Already defined in OpenMesh::DefaultTraits
// HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
// Uncomment next line to disable attribute PrevHalfedge
// HalfedgeAttributes( OpenMesh::Attributes::None );
// HalfedgeAttributes( 0 );
// Define my mesh with the new traits!
typedef OpenMesh::TriMesh_ArrayKernelT&MyTraits&
// ------------------------------------------------------------------ main ----
// Just make sure that point element type is double
if ( typeid( OpenMesh::vector_traits&MyMesh::Point&::value_type )
!= typeid(double) )
std::cerr && &Ouch! ERROR! Data type is wrong!\n&;
//另外一个例子
struct MyTraits : public OpenMesh::DefaultTraits
// store barycenter of neighbors in this member
VertexTraits
VertexT() : cog_( Point(0.0f, 0.0f, 0.0f ) ) { }
const Point& cog() const { return cog_; }
void set_cog(const Point& _p) { cog_ = _p; }
typedef OpenMesh::TriMesh_ArrayKernelT&MyTraits&
typedef OpenMesh::TriMesh_ArrayKernelT&&
注意和CGAL的不同这里用户自定义traits更加简单友好,没有任何的模板参数。
以前旧版本的openmesh里面的vertex还要写成下面的形式,有模板参数,那么现在这个是如何实现的呢?
template &class Base& class VertexT: public Base
OPENMESH同样运用了与CGAL相同的利用前置声明的技术解决类型依赖问题,见
Since the handle types depend on the containers used by the mesh
kernel (e.g. a VertexHandle may be a Vertex* or an int), the
kernel itself depends on the mesh items (in order to construct the
handle types), and the items require the handles (a vertex must store
a halfedge handle), we have to use template forward declarations
to get “safe” handle types (see [7]). Using this technique, the item
types know each other and their respective handle types, thereby
avoiding to use and cast void pointers. This also enables us to use
the handles types in the traits classes, e.g. if the face type should
contain a vertex handle。
不同的mesh将会是不同的类型,为了让mesh算法能够为所有类型的mesh服务,采用了泛型方法,将Mesh类型作为所有
算法的一个模板参数。
As we have seen, we use a custom–tailored mesh for each application.
All these meshes will be different C++ types. If we want
to design algorithms operating on all of these mesh types, we either
have to derive all meshes from a common virtual base class, or do
it the STL way and use generic programming methods. Since virtual
functions / classes lead to a certain overhead in space and time,
we have chosen the generic approach:&every algorithm gets the type
Mesh in form of a template parameter.
对比一下CGAL看一下Openmesh是如何定义顶点,边和面的。
/// Definition of mesh items for use in the ArrayKernel
struct ArrayItems
//------------------------------------------------------ internal vertex type
/// The vertex item
class Vertex
friend class ArrayK
HalfedgeHandle
halfedge_handle_;
//---------------------------------------------------- internal halfedge type
#ifndef DOXY_IGNORE_THIS
class Halfedge_without_prev
friend class ArrayK
FaceHandle
face_handle_;
VertexHandle
vertex_handle_;
HalfedgeHandle
next_halfedge_handle_;
#ifndef DOXY_IGNORE_THIS
class Halfedge_with_prev : public Halfedge_without_prev
friend class ArrayK
HalfedgeHandle
prev_halfedge_handle_;
//TODO: should be selected with config.h define
typedef Halfedge_with_prev
typedef GenProg::Bool2Type&true&
//-------------------------------------------------------- internal edge type
#ifndef DOXY_IGNORE_THIS
class Edge
friend class ArrayK
halfedges_[2];
//-------------------------------------------------------- internal face type
#ifndef DOXY_IGNORE_THIS
class Face
friend class ArrayK
HalfedgeHandle
halfedge_handle_;
//上面都用到了handle,
//那么handle是怎么定义的呢?
class BaseH
/// Handle for a vertex entity
struct VertexHandle : public BaseHandle
explicit VertexHandle(int _idx=-1) : BaseHandle(_idx) {}
/// Handle for a halfedge entity
struct HalfedgeHandle : public BaseHandle
explicit HalfedgeHandle(int _idx=-1) : BaseHandle(_idx) {}
/// Handle for a edge entity
struct EdgeHandle : public BaseHandle
explicit EdgeHandle(int _idx=-1) : BaseHandle(_idx) {}
/// Handle for a face entity
struct FaceHandle : public BaseHandle
explicit FaceHandle(int _idx=-1) : BaseHandle(_idx) {}
//一个具体的kernel如何定义的呢
class ArrayKernel : public BaseKernel, public ArrayItems
// handles
typedef OpenMesh::VertexHandle
typedef OpenMesh::HalfedgeHandle
typedef OpenMesh::EdgeHandle
typedef OpenMesh::FaceHandle
typedef Attributes::StatusInfo
typedef VPropHandleT&StatusInfo&
VertexStatusPropertyH
typedef HPropHandleT&StatusInfo&
HalfedgeStatusPropertyH
typedef EPropHandleT&StatusInfo&
EdgeStatusPropertyH
typedef FPropHandleT&StatusInfo&
FaceStatusPropertyH
HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
{ return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); }
// iterators
typedef std::vector&Vertex&
typedef std::vector&Edge&
typedef std::vector&Face&
typedef VertexContainer::iterator
KernelVertexI
typedef VertexContainer::const_iterator
KernelConstVertexI
typedef EdgeContainer::iterator
KernelEdgeI
typedef EdgeContainer::const_iterator
KernelConstEdgeI
typedef FaceContainer::iterator
KernelFaceI
typedef FaceContainer::const_iterator
KernelConstFaceI
typedef std::vector&uint&
KernelVertexIter
vertices_begin()
{ return vertices_.begin(); }
KernelConstVertexIter vertices_begin() const
{ return vertices_.begin(); }
KernelVertexIter
vertices_end()
{ return vertices_.end(); }
KernelConstVertexIter vertices_end() const
{ return vertices_.end(); }
KernelEdgeIter
edges_begin()
{ return edges_.begin(); }
KernelConstEdgeIter
edges_begin() const
{ return edges_.begin(); }
KernelEdgeIter
edges_end()
{ return edges_.end(); }
KernelConstEdgeIter
edges_end() const
{ return edges_.end(); }
KernelFaceIter
faces_begin()
{ return faces_.begin(); }
KernelConstFaceIter
faces_begin() const
{ return faces_.begin(); }
KernelFaceIter
faces_end()
{ return faces_.end(); }
KernelConstFaceIter
faces_end() const
{ return faces_.end(); }
VertexContainer
vertices_;
EdgeContainer
FaceContainer
事实上当前版本的OPENMESH的顶点,边,面的基本结构非常简单,就是相关的handle,而handle类型也是定死了的。 不存在模板循环依赖技术,与CGAL不同。
OPENMESH当前只采用基于VECTOR的构架,它把其余的顶点属性其实统统存在顶点之外,用数组保存,由于有handle即index,
所以访问的时候是用的MESH::Kernal的方法如mesh_.property(cog_, vh) += mesh_.point( vv_it ); ,mesh_根据vh找到数组中
该cog_的值。本质上是和vertex分离的,否则应该类似调用vh-&cog_了,另外包括像顶点的位置,也是如此通过mesh_.point(vh)来得到
而不是CGAL中vh-&point(),即坐标属性没有存储在vertex之中。vertex只存一个halfedge_handle。
所以用户用traits自定义属性如cog_或者动态添加cog_本质上和自己定义一个 cog[vertex_num]数组差不多,只不过openmesh封装了实现,提供统一方便的接口,
看上去似乎就像是给vertex本身加了个cog_域。mesh_.property(cog_, vh)还是反映了实际的存储情况。
但是问题是如果要提供基于list的mesh kernal呢,当前的架构似乎不能支持list吧?
不过对于自己定义traits的时候给vertex_traits加入的属性cog_,方法cog()是可以按照下面的方式访问的。(注,这个是老的版本这样支持的,
新版本去除了这一方式,其余的属性本质上就是顶点Vertex之外,由Mesh利用顶点属性数组统一管理的)
MyMesh::VertexIter
v_it-&cog()
//新版本要用mesh.data(v_it)-&cog()//看了一版本变化说明,似乎是说因为MS不支持模版的前置循环声明好像,不得已为之的。
mesh.data(v_it).set_cog(cog / valence);
下面是02年的修改声明。应该就是因为这个原因,就把顶点,边,面定死了,不过看CGAL应该是支持的啊,奇怪:)现在的MS VC8应该肯定支持的。
Removed cyclic dependency between items and kernel, because MS VC++ cannot handle the resulting template forward declaration :-(.
Therefore the&Base::Refs&class, given for the traits classes, no longer provides the types \c Vertex, \c Halfedge, \c Edge, and \c Face.
It now only provides all handle types, the point and the scalar type.
我们看下为了实现下面的应用代码,程序内部是怎么构架的。
应用代码:
struct MyTraits : public OpenMesh::DefaultTraits
// store barycenter of neighbors in this member
VertexTraits
VertexT() : cog_( Point(0.0f, 0.0f, 0.0f ) ) { }
const Point& cog() const { return cog_; }
void set_cog(const Point& _p) { cog_ = _p; }
typedef OpenMesh::TriMesh_ArrayKernelT&MyTraits&
MyM //下面就可以MyM使用这个mesh了。
//OK具体上面的代码内部是如何实现的呢。
先看DefaultTraits
//只显示部分内容
struct DefaultTraits
/// The default coordinate type is OpenMesh::Vec3f.
typedef Vec3f
/// The default normal type is OpenMesh::Vec3f.
typedef Vec3f
#ifndef DOXY_IGNORE_THIS
VertexTraits
HalfedgeTraits
EdgeTraits
FaceTraits
VertexAttributes(0);
先不管 Atrtributes,我们就看VertexTraits,
这里其实是用了宏,来对用户隐藏了模板参数。
/// Macro for defining the vertex traits. See \ref mesh_type.
#define VertexTraits \
template &class Base, class Refs& struct VertexT : public Base
//其余Tratis 如face,halfedge的一样的方式处理
所以实际代码展开之后类似下面
struct MyTraits : public OpenMesh::DefaultTraits
template &class Base, class Refs& struct VertexT : public Base
int some_additional_
这也就是为什么构造函数要写VertexT()的原因。
The template argument Base provides access to the mesh handles and to the Point and Scalar type by its member class Refs.
Adding a MyMesh::FaceHandle to the vertex class can therefore be implemented like this:
下面显示如何给顶点添加面handle属性。
struct MyTraits : public OpenMesh::DefaultTraits
VertexTraits
int some_additional_
typename Base::Refs::FaceHandle my_face_
下面再看typedef OpenMesh::TriMesh_ArrayKernelT&MyTraits& MyM意味着什么呢?
TriMesh_ArrayKernelT
它的实现利用了继承TriMesh_ArrayKernel_GeneratorT&Traits&::Mesh
template &class&Traits = DefaultTraits&
class&TriMesh_ArrayKernelT
& :&public&TriMesh_ArrayKernel_GeneratorT&Traits&::Mesh
template &class&Traits&
struct&TriMesh_ArrayKernel_GeneratorT
& typedef&FinalMeshItemsT&Traits,&true&&&&&&&&&&&&&&&&MeshI
& typedef&AttribKernelT&MeshItems, TriConnectivity&&&AttribKernel;
& typedef&TriMeshT&AttribKernel&&&&&&&&&&&&&&&&&&&&&&&Mesh;& //其实就是最终使用的mesh类型
代码所表示的正是如上图所示的继承关系。OPENMESH大量利用 template&class Base& class Derived: public Base的继承模式。
1. The BaseKernel defines the basic operations on properties like add/remove/access.
2. Next the AttribKernelT adds the standard properties all associated methods.
3. Finally the ArrayKernelT provides the methods to add/remove/access the mesh items vertices, (half-)edges, and faces. The base class is passed as a template parameter, since depending on the underlying storage type the AttribKernel might change.
1. The PolyMeshT inherits from the kernel and provide all necessary methods to work with polygonal meshes.
2. Finally we derive TriMeshT from PolyMeshT to have an specialization for triangle meshes.
1.先来看FinalMeshItemsT,为了方便去掉了一些代码如attributes的部分。
FinalMeshItemsT&Traits,&true&&&&&&&&&&&&&&&&MeshI
template &class Traits, bool IsTriMesh&
struct FinalMeshItemsT
struct Refs
typedef typename Traits::Point
//所以用户提供的MyTraits可能会改变Point的类型
typedef typename vector_traits&Point&::value_type S
typedef OpenMesh::VertexHandle
//--- export Refs types ---
typedef typename Refs::Point
class ITraits
typedef typename Traits::template VertexT&ITraits, Refs&
//这里用到了VertexT(可能由用户修改提供)
typedef typename Traits::template HalfedgeT&ITraits, Refs&
} // namespace OpenMesh
2.再看AttribKernelT
AttribKernelT&MeshItems, TriConnectivity&&&AttribKernel;通过继承Connectivity继承TriConnectivity-&PolyConnectivity-&ArrayKernel-&BaseKernel
+ ArrayItems
template &class MeshItems, class Connectivity&
class AttribKernelT : public Connectivity
// class TriConnectivity : public PolyConnectivity
//class PolyConnectivity : public ArrayKernel
//---------------------------------------------------------------- item types
typedef typename Connectivity::Vertex
typedef typename Connectivity::Halfedge
typedef typename Connectivity::Edge
typedef typename Connectivity::Face
typedef typename MeshItems::Point
typedef typename MeshItems::Normal
typedef typename MeshItems::VertexData
typedef typename MeshItems::HalfedgeData
typedef typename MeshItems::EdgeData
typedef typename MeshItems::FaceData
typedef AttribKernelT&MeshItems,Connectivity&
enum Attribs
VAttribs = MeshItems::VAttribs,
HAttribs = MeshItems::HAttribs,
EAttribs = MeshItems::EAttribs,
FAttribs = MeshItems::FAttribs
typedef VPropHandleT&VertexData&
DataVPropH
typedef HPropHandleT&HalfedgeData&
DataHPropH
typedef EPropHandleT&EdgeData&
DataEPropH
typedef FPropHandleT&FaceData&
DataFPropH
//-------------------------------------------------- constructor / destructor
AttribKernelT()
: refcount_vnormals_(0),
refcount_vcolors_(0),
add_property( points_, &v:points& );
if (VAttribs & Attributes::Normal)
request_vertex_normals();
//FIXME: data properties might actually cost storage even
//if there are no data traits??
add_property(data_vpph_);
add_property(data_fpph_);
add_property(data_hpph_);
add_property(data_epph_);
virtual ~AttribKernelT()
// should remove properties, but this will be done in
// BaseKernel's destructor anyway...
/** Assignment from another mesh of \em another type.
\note All that's copied is connectivity and vertex positions.
All other information (like e.g. attributes or additional
elements from traits classes) is not copied.
\note If you want to copy all information, including *custom* properties,
use PolyMeshT::operator=() instead.
TODO: version which copies standard properties specified by the user
template &class _AttribKernel&
void assign(const _AttribKernel& _other)
assign_connectivity(_other);
for (typename Connectivity::VertexIter v_it = Connectivity::vertices_begin();
v_it != Connectivity::vertices_end(); ++v_it)
{//assumes Point constructor supports cast from _AttribKernel::Point
set_point(v_it, (Point)_other.point(v_it));
//------------------------------------------------ request / alloc properties
void request_vertex_normals()
if (!refcount_vnormals_++)
add_property( vertex_normals_, &v:normals& );
//------------------------------------------------- release / free properties
void release_vertex_normals()
if ((refcount_vnormals_ & 0) && (! --refcount_vnormals_))
remove_property(vertex_normals_);
//---------------------------------------------- dynamic check for properties
bool has_vertex_normals()
const { return vertex_normals_.is_valid();
typedef VPropHandleT&Point&
PointsPropertyH
typedef VPropHandleT&Normal&
VertexNormalsPropertyH
//standard vertex properties
PointsPropertyHandle
points_pph() const
{ return points_; }
VertexData&
data(VertexHandle _vh)
{ return property(data_vpph_, _vh); }
//standard vertex properties
PointsPropertyHandle
VertexNormalsPropertyHandle
vertex_normals_;
//data properties handles
DataVPropHandle
data_vpph_;
DataHPropHandle
data_hpph_;
DataEPropHandle
data_epph_;
DataFPropHandle
data_fpph_;
关于add_property在class BaseKernel中。
template &class T&
void add_property( VPropHandleT&T&& _ph, const std::string& _name=&&vprop&&)
_ph = VPropHandleT&T&( vprops_.add(T(), _name) );
vprops_.resize(n_vertices());
//in BaseKernel
PropertyContainer& vprops_;
class ArrayKernel : public BaseKernel, public ArrayItems
// handles
typedef OpenMesh::VertexHandle
typedef OpenMesh::HalfedgeHandle
typedef OpenMesh::EdgeHandle
typedef OpenMesh::FaceHandle
typedef std::vector&Vertex&&&&&&&&&&&&&&&& VertexC
Vertex& vertex(VertexHandle _vh){& assert(is_valid_handle(_vh));& return vertices_[_vh.idx()];}private:
VertexContainer&&&&&&&&&&&&&&&&&&&&&&&&&& vertices_;& EdgeContainer&&&&&&&&&&&&&&&&&&&&&&&&&&&& edges_;& FaceContainer&&&&&&&&&&&&&&&&&&&&&&&&&&&& faces_;}
class BaseKernel
PropertyContainer
PropertyContainer
PropertyContainer
PropertyContainer
PropertyContainer
3.最后看TriMeshT
TriMeshT&AttribKernel&&&&&&&&&&&&&&&&&&&&&&&Mesh;
template &class Kernel&
class TriMeshT : public PolyMeshT&Kernel&
typedef TriMeshT&Kernel&
typedef PolyMeshT&Kernel&
//--- items ---
typedef typename PolyMesh::Scalar
typedef typename PolyMesh::Point
//--- handles ---
typedef typename PolyMesh::VertexHandle
typedef typename PolyMesh::HalfedgeHandle
typedef typename PolyMesh::EdgeHandle
typedef typename PolyMesh::FaceHandle
//--- iterators ---
typedef typename PolyMesh::VertexIter
//--- circulators ---
typedef typename PolyMesh::VertexVertexIter
VertexVertexI
template &class Kernel&
class PolyMeshT : public Kernel&
看一下具体执行M的时候构造函数的调用,其中PorpertyContainer是BaseKernel类的一个成员变量被初始化,其余都是代表类的默认初始化。可以看出类的层次关系。
#0& new_allocator (this=0xbfc56563) at /usr/include/c++/4.2/ext/new_allocator.h:68
#1& 0xb7f4f07b in allocator (this=0xbfc56563) at /usr/include/c++/4.2/bits/allocator.h:100
#2& 0xb7f50a81 in PropertyContainer (this=0xbfc566ac) at /home/allen/study/OpenMesh/src/OpenMesh/Core/../../OpenMesh/Core/Utils/PropertyContainer.hh:66
#3& 0xb7f56a76 in BaseKernel (this=0xbfc566a8) at /home/allen/study/OpenMesh/src/OpenMesh/Core/../../OpenMesh/Core/Mesh/BaseKernel.hh:95
#4& 0xb7f4ce46 in ArrayKernel (this=0xbfc566a8) at /home/allen/study/OpenMesh/src/OpenMesh/Core/Mesh/ArrayKernel.cc:49
#5& 0x0805854f in PolyConnectivity (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/PolyConnectivity.hh:164
#6& 0x0805856d in TriConnectivity (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/TriConnectivity.hh:55
#7& 0x in AttribKernelT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/AttribKernelT.hh:124
#8& 0x08061c21 in PolyMeshT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/PolyMeshT.hh:181
#9& 0x08061c3f in TriMeshT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/TriMeshT.hh:164
#10 0x08061c5d in TriMesh_ArrayKernelT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh:93
#11 0x080503fa in main (argc=1, argv=0xbfc56934) at smooth.cc:50
1.关于动态添加属性,究竟是如何实现的
template &class T&
typename VPropHandleT&T&::reference
property(VPropHandleT&T& _ph, VertexHandle _vh) {
&& return vprops_.property(_ph)[_vh.idx()];
vprops_是PropertyContainer类型的
mesh.property(cogs,v_it) += mesh.point( vv_it );
调用 property(cogs,v_it)&&& -&调用 vprops_.property(cogs)[v_it.idx()]
& template &class T& PropertyT&T&& property(BasePropHandleT&T& _h)
&&& assert(_h.idx() &= 0 && _h.idx() & (int)properties_.size());
&&& assert(properties_[_h.idx()] != NULL);
#ifdef OM_FORCE_STATIC_CAST
&&& return *static_cast& &PropertyT&T&*& (properties_[_h.idx()]);
&&& PropertyT&T&* p = dynamic_cast&PropertyT&T&*&(properties_[_h.idx()]);
&&& assert(p != NULL);
&&& return *p;
大概是mesh根据cogs找到它的属性数组,然后利用v_it的顶点索引,找到具体的值,
不过太复杂了,有时间再弄清细节吧。
2.用array的话,如何能够在拓扑变化的情况下,如点的删除,保证高效率的。
3.简化和细分模块是如何架构的。
本文已收录于以下专栏:
相关文章推荐
struct MyTraits : public OpenMesh::DefaultTraits
VertexTr...
struct MyTraits : public OpenMesh::DefaultTraits
VertexTr...
typedef CGAL::Simple_cartesian K //这个kernel 决定了点云的一些特性, 和精度 double。
附加说明: 1.
CGAL整体概述CGAL是一个用C++描述的,包含三个主要部分的计算几何算法库.第一部分是核心组件(Kernel),它包括基本的几何对象以及做用在这些对象上的各种操作.这...
CGAL是一个优秀的几何处理库,对于三维网格采用半边格式存储。
其实对于网格而言,无外乎定义它的边,顶点,面,数据存储。
问题是用户可能会有不同的需求,比如做模型简...
1限定三角化
(1)CGAL,Computational Geometry Algorithms Library,计算几何算法库,设计目标是,以C++库的形式,提供方便,高效,可靠的几何算法。CGAL可用于各种需要...
数学表达式解析工具 muParser
muParser 是一个快速的数学表达式的解析器,可将数学表达式转成字节码并预先计算常数表达式的部分。更多muParser信息
计算几何算法库...
http://blog.csdn.net/pipisorry/article/details/
Mayavi的安装
mayavi已经支持python3了:Done, suppo...
select函数:  系统提供select函数来实现多路复用输入/输出模型。原型:  #include   #include   select函数:  系统提供select函数来实现多路复用输入/输出...
他的最新文章
讲师:何宇健
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 我的世界命名牌怎么用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信