【OpenMesh】使用网格的属性和特征
例子主要展示如何改变位置,法向量,颜色和纹理的数据类型。
在之前的指南中我们学习使用标准属性,通过调用适合的请求方法。不像自定义属性,用户通过传递数据类型到句柄来指定数据类型(比如,MyMesh::FPropHandleT< int>),标准属性的数据类型定义为网格特征。我们可以和特征一起定制和扩展网格数据结构。我们通过两方面做到这一点。
- 改变位置(Position),法向量(Normal),颜色(Color),和纹理坐标(Texture coordinate不知道翻译对了没)的数据类型。
- 扩展网格实体,包括顶点,面,边和Halfedge.
我们开始吧。每一个定制特性应该继承自默认特性。
struct MyTraits : OpenMesh::DefaultTraits
之前提到的,我们可以为基本数据类型改变基础数据结构 MyMesh::Point, MyMesh::Normal, MyMesh::Color, and MyMesh::TexCoord。我们可以使用提供的向量类或者我们使用其他类库提供的类。这里我们简单的替换Position和Normal的默认类型OpenMesh::Vec3f为OpenMesh::Vec3d
typedef OpenMesh::Vec3d Point;
typedef OpenMesh::Vec3d Normal;
(通常,Point和Normal向量最好用相同的标量类型,比如在这里使用double型。不然我们将要必须考虑向量类的实现。)
注意,这些设置覆盖父类的特征!正如我们通常继承DefaultTraits,让我们仔细看看。
实际上,OpenMesh::DefaultTraits仅仅是一个没有内容的类。它只是为Point,Normal,TexCoord和Color以及一个属性定义了类型,我们一直隐式地使用它们:
// HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
属性PrevHalfedge是不同的,因为它没有控制属性。然而,它对网格类型的最终结果有个很大的影响,因为它在Halfedge结构中添加了额外的信息。影响有两点:
快速地访问前一个Halfedge
添加内存消耗(居然不是一个优点……)
使用这个特点取决于我们的需要。一种情况是我们需要访问前一个Halfedge非常便利,这是网格的成员变量函数add_face().当前一个Halfedge可用的时候,成员函数的执行时间迅速下降。通常我们希望有这个信息。但是为了节约内存,我们可以轻松的移除这个特性
// HalfedgeAttributes( OpenMesh::Attributes::None );
然后我们需要少于8Byte的空间存储一条边,这就节省很多了,通过欧拉方程可以知道V-E+F=2(1-g),对于一个三角形网格,g=0,边的数目几乎是三倍的顶点数,既E=3V。
完整的代码:
#include <iostream>
#include <typeinfo>
// --------------------
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#ifndef DOXY_IGNORE_THIS
// Define my personal traits
struct MyTraits : OpenMesh::DefaultTraits
{
// Let Point and Normal be a vector of doubles
typedef OpenMesh::Vec3d Point;
typedef OpenMesh::Vec3d Normal;
// Already defined in OpenMesh::DefaultTraits
// HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge ); // Uncomment next line to disable attribute PrevHalfedge
// HalfedgeAttributes( OpenMesh::Attributes::None );
//
// or
//
// HalfedgeAttributes( 0 );
};
#endif
// Define my mesh with the new traits!
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
// ------------------------------------------------------------------ main ----
int main(int argc, char **argv)
{
MyMesh mesh;
if (argc!=2)
{
std::cerr << "Usage: " << argv[0] << " <input>\n";
return 1;
}
// 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";
return 1;
}
// Make sure that normal element type is double
if ( typeid( OpenMesh::vector_traits<MyMesh::Normal>::value_type )
!= typeid(double) )
{
std::cerr << "Ouch! ERROR! Data type is wrong!\n";
return 1;
}
// Add vertex normals as default property (ref. previous tutorial)
mesh.request_vertex_normals();
// Add face normals as default property
mesh.request_face_normals();
// load a mesh
OpenMesh::IO::Options opt;
if ( ! OpenMesh::IO::read_mesh(mesh,argv[1], opt))
{
std::cerr << "Error loading mesh from file " << argv[1] << std::endl;
return 1;
}
// If the file did not provide vertex normals, then calculate them
if ( !opt.check( OpenMesh::IO::Options::VertexNormal ) &&
mesh.has_face_normals() && mesh.has_vertex_normals() )
{
// let the mesh update the normals
mesh.update_normals();
}
// move all vertices one unit length along it's normal direction
for (MyMesh::VertexIter v_it = mesh.vertices_begin();
v_it != mesh.vertices_end(); ++v_it)
{
std::cout << "Vertex #" << v_it << ": " << mesh.point( v_it );
mesh.set_point( v_it, mesh.point(v_it)+mesh.normal(v_it) );
std::cout << " moved to " << mesh.point( v_it ) << std::endl;
}
return 0;
}
【OpenMesh】使用网格的属性和特征的更多相关文章
- OpenMesh 读写网格控制(读取写入纹理坐标,法向等)
OpenMesh读取网格默认是不自动读取obj网格中的法向,纹理坐标等信息的,写入网格同样也是.所以要读取(或写入)这些信息需要修改默认的选项. 先看一下其读写网格的函数 template<cl ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 创建属性网格
jQuery EasyUI 数据网格 - 创建属性网格 属性网格(property grid)带有一个内置的 expand(展开)/collapse(合并) 按钮,可以简单地为行分组.您可以简单地创建 ...
- CSS3 网格布局(grid-layout)基础知识 - 网格模板属性(grid-template)使用说明
CSS3引入了新的网格布局(grid layout),以适应显示和设计技术的发展(尤其是移动设备优先的响应式设计). 主要目标是建立一个稳定可预料且语义正确的网页布局模式,用来替代过往表现不稳定且繁琐 ...
- OpenMesh 删除网格顶点
OpenMesh 提供了 delete_vertex() 函数来实现从网格中删除顶点,在删除掉顶点的同时,所有与该顶点相连的边也同时被删除. OpenMesh 官方文档 中给的顶点删除函数声明如下: ...
- RadioButton 的background属性表现特征
对于radiaoButton,应该很多人都用过.下面看一个场景 上方时radiogroup,细致观察发现左1,文字开始位置和右1文字开始位置不同,这是为何呢? 查看布局: <RadioB ...
- kaggle数据挖掘竞赛初步--Titanic<派生属性&维归约>
完整代码: https://github.com/cindycindyhi/kaggle-Titanic 特征工程系列: Titanic系列之原始数据分析和数据处理 Titanic系列之数据变换 Ti ...
- Unity加载模块深度解析(网格篇)
在上一篇 加载模块深度解析(一)中,我们重点讨论了纹理资源的加载性能.这次,我们再来为你揭开其他主流资源的加载效率. 这是侑虎科技第53篇原创文章,欢迎转发分享,未经作者授权请勿转载.同时如果您有任何 ...
- Compounding绑定属性
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 特征的SID表、M表、P表、Q表、X表、Y表、T表
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
随机推荐
- JavaSE_ 反射 目录(27)
JavaSE学习总结第27天_反射 & 设计模式 & JDK5.7.8新特性27.01 反射_类的加载概述和加载时机27.02 反射_类加载器的概述和分类27.03 反射_反射概述27 ...
- JavaScript 堆
1.IE中不兼容ajax中data最后一个参数加逗号,其余chrome Firefox均支持. code: $("document ").ready(function() { $( ...
- tornado模板的自动编码问题(autoescape )
tornado新版(具体版本未知)支持自动转义,比如{{ "<div>" }}不会输出html标签,而是进行转义. {{ module.test(10) }} 也会进行 ...
- Oracle SQL篇(二)oracle自连接操作
oracle 的自连接(self join)操作 对于oracle数据库来说,目前支持两套语法,一套是oracle自己的sql语法,一套是通行标准的SQL99语法,那么对于oracle的连接操 ...
- 转:js不同类型对象的比较规则
Type(x) Type(y) Result type(x)==type(y) x===y otherwise... false null undefined true undefined null ...
- Codecs是以plugin的形式被调用的(显示中文的codec plugin文件是qcncodecs4.dll),可静态载入和动态载入
作为非英语国家人员开发的类库,QT有充分的理由优先考虑支持Unicode和各国自定义字库编码.大家也知道了QT对软件Internationalization有一套完整的开发模型,包括专门为此写的lin ...
- HDU 3015 Disharmony Trees
题解:在路边有一行树,给出它们的坐标和高度,先按X坐标排序.记录排名,记为rankx,再按它们的高度排序,记录排名,记为rankh.两颗树i,j的差异度为 fabs(rankx[i]-rankx[j] ...
- D - 金樽清酒斗十千(搜索dfs)
D - 金樽清酒斗十千 Time Limit:2000MS Memory Limit:524288KB 64bit IO Format:%I64d & %I64u Submit ...
- makefile 里面 := 和 = 的区别
此文版权属于作者所有,任何人.媒体或者网站转载.借用都必须征得作者本人同意! 参考:What is the colon equals sign ( := ) in makefiles? Makefil ...
- android下文件下载
public static void downFile(final String url){ new Thread(){ public void run(){ FileOutputStream os= ...