【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,并以超链接形式标明文章原始出处,否则将 ...
随机推荐
- Visual format language
所谓的VFL语言其实就是Visual format language 的缩写,是一种使用代码添加约束的方式,类似于Masonry SDAutolayout的效果,但是操作起来可能要相对简单.一行代码 ...
- MysqlHelp
using System.Configuration;using MySql.Data: public class MySqlHelp { //链接字符串 private static string ...
- 关于LZO和LZOP
LZO 是一个适合实时解压.压缩的压缩库 LZOP 基于LZO库的压缩解压工具 PS:有了压缩解压库LZO,还不能直接操作文件压缩解压,需要LZOP 下载的话直接google吧~~~
- app 转caf 音频 代码
afconvert /Users/xiaoye/Downloads/cat.caf /Users/xiaoye/Downloads/cat1.caf -d ima4 -f caff -v;
- Git Command Summary (Updated)
取得Git仓库 初始化一个版本仓库 git init Clone远程版本库 git clone git@xbc.me:wordpress.git 添加远程版本库origin,语法为 git remot ...
- ListBox控件例子
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ListBox.aspx.c ...
- AES 加密
package com.sprucetec.tms.utils; import java.security.Key; import javax.crypto.Cipher;import javax.c ...
- HDU 2719 The Seven Percent Solution
#include <cstdio> #include <cstring> int main() { ]; ]!='#') { ; while (i<strlen(s)) ...
- HDU 2852 KiKi's K-Number
权值线段树 #include <cstdio> #include <cstring> const int N=200000,M=220000; int k,q,x,y,sum[ ...
- Java集合框架的知识总结
说明:面试准备,写的挺不错的. 转载地址: http://www.cnblogs.com/zhxxcq/archive/2012/03/11/2389611.html 1.综述 所有集合类都位于jav ...