一、实验目标/要求:
The goal of this assignment is to try your hand at various mesh processing tasks. A half-edge mesh adjacency data structure is provided, along with a very simple .obj mesh parser. As you modify the triangle mesh, it is critical that the manifold properties of the input surface are maintained, and that the adjacency data structure remains consistent. Throughout this assignment you are asked to consider the efficiency of various mesh operations: is it quadratic, linear, logarithmic, constant, etc? It’s ok if you don’t always implement the most efficient strategy (which may require additional data structures).
(上面的的意思大概就是利用Loop Subdivision算法对简单模型进行细分。)

二、实现效果:
第一组

第二组

第三组

三、实现方法/思路:

  1. 先更新原来的旧顶点,根据旧顶点信息计算出新顶点位置信息并将计算的新位置信息和原来的点组成pair并储存在一个新的vector中(即下面算法中的update)。(另:此处要注意内部顶点和边界点的更新方式,公式不要出错)
  2. 分别根据内部边和和边界边不同的处理方式算出插入的新点的位置信息,然后直接向原来的点vector(即vertices)中插入(用addVertex函数)新顶点。
  3. 利用步骤1)中的vector(即update)来更新旧顶点的位置信息(用一个for循环和setPos函数即可)。
  4. 新建一个临时三角形面片的哈希表来存储旧三角形面片信息(即下面算法中的tempTriangles),然后清除旧三角形面片信息(triangles.clear())和边信息(edges.clear()),然后再利用临时的三角形面片哈希表重构新的三角形面片信息和新的边信息(边信息是随着三角形面片信息的更新而更新的,不用管)。
  5. 修复一下这边信息,即为原来crease值不为零的边及其“衍生”的边重新附上crease值。
  6. 清空vertex_parents(这个玩意儿是通过一条边的两个端点去找边上所产生的新点的,在插入新店的步骤(即步骤2)中进行准备,用在重构三角形面片信息的步骤(即步骤4中),为下一次细分做准备。

算法代码如下:
(只包含算法部分的代码,不包含其余部分的代码,太多了,懒得整,嘿嘿)


void Mesh::LoopSubdivision()
{printf("Subdivide the mesh!\n");//store new position of old vertex in update.//(Traversal of all vertices)std::vector<std::pair<Vertex*, Vec3f>> update;for (edgeshashtype::iterator eIterator1 = edges.begin();eIterator1 != edges.end(); eIterator1++){Edge* e = eIterator1->second;Edge* temp = e->getNext();Vec3f newPosition(0, 0, 0);std::vector<Vertex*> neighborVertices;while (temp->getOpposite() != NULL && temp->getOpposite() != e){neighborVertices.push_back(temp->getEndVertex());temp = temp->getOpposite()->getNext();}if (temp->getOpposite() == NULL){neighborVertices.clear();Vertex* v1 = temp->getEndVertex();assert(temp->getStartVertex() == e->getEndVertex());temp = e;while (temp->getOpposite() != NULL){temp = temp->getOpposite()->getNext()->getNext();}Vertex* v2 = temp->getStartVertex();assert(temp->getEndVertex() == e->getEndVertex());newPosition = newPosition = 3.0 / 4.0 * e->getEndVertex()->getPos() + 1.0 / 8.0 * (v1->getPos() + v2->getPos());}else{//degree of current vertexint degree = neighborVertices.size();//beta is a constant used to get new inner vertex positionfloat beta = (5.0 / 8.0 - std::pow(3.0 / 8.0 + 1.0 / 4.0 * std::cos(2 * std::acos(-1) / degree), 2)) / degree;for (int k = 0; k < degree; k++)newPosition += beta * neighborVertices[k]->getPos();newPosition += (1.0 - degree * beta) * e->getEndVertex()->getPos();}update.push_back(std::make_pair(e->getEndVertex(), newPosition));}//add new verticesfor (edgeshashtype::iterator eIterator2 = edges.begin();eIterator2 != edges.end(); eIterator2++){Edge* e = eIterator2->second;Vec3f newVertexPos(0, 0, 0);if (e->getOpposite() != NULL){if (getChildVertex(e->getStartVertex(), e->getEndVertex()) != NULL) continue;//每条内部边只加一个点newVertexPos = 3.0 / 8.0 * (e->getEndVertex()->getPos() + e->getStartVertex()->getPos())+ 1.0 / 8.0 * (e->getNext()->getEndVertex()->getPos() + e->getOpposite()->getNext()->getEndVertex()->getPos());}elsenewVertexPos = 1.0 / 2.0 * (e->getStartVertex()->getPos() + e->getEndVertex()->getPos());Vertex* newVertex = addVertex(newVertexPos);if (newVertex != NULL) setParentsChild(e->getStartVertex(), e->getEndVertex(), newVertex);}//refresh old vertex positionfor (int i = 0; i < update.size(); i++) update[i].first->setPos(update[i].second);//add triangle meshtriangleshashtype tempTriangles = triangles;triangles.clear();//clear old triangle meshesedges.clear();//clear information of old edgestriangleshashtype::iterator tIterator = tempTriangles.begin();for (; tIterator != tempTriangles.end(); tIterator++){Triangle* t = tIterator->second;Vertex* v1, * v2, * v3, * c12, * c23, * c13;v1 = (*t)[0]; v2 = (*t)[1]; v3 = (*t)[2];c12 = getChildVertex(v1, v2);c23 = getChildVertex(v2, v3);c13 = getChildVertex(v1, v3);if (c12 == NULL || c23 == NULL || c13 == NULL) break;addTriangle(c12, c23, c13);addTriangle(v1, c12, c13);addTriangle(v2, c23, c12);addTriangle(v3, c13, c23);}//set creasefor (edgeshashtype::iterator eIterator3 = edges.begin();eIterator3 != edges.end(); eIterator3++){Edge* e = eIterator3->second;std::pair<Vertex*, Vertex*> ePair = eIterator3->first;if (vertex_parents.find(ePair) == vertex_parents.end()) continue;if (e->getCrease()){Vertex* childVertex = vertex_parents.find(ePair)->second;assert(edges.find(std::make_pair(e->getStartVertex(), childVertex)) != edges.end());edges.find(std::make_pair(e->getStartVertex(), childVertex))->second->setCrease(e->getCrease());assert(edges.find(std::make_pair(childVertex, e->getEndVertex())) != edges.end());edges.find(std::make_pair(childVertex, e->getEndVertex()))->second->setCrease(e->getCrease());}}vertex_parents.clear();
}

四、实验感受与体会:
原来的模型干干巴巴的,麻麻赖赖的,一点儿都不圆润,盘它!

山东大学计算机图形学实验(Opengl实现):Loop Subdivision算法对模型进行细分相关推荐

  1. 计算机图形学实验报告 裁剪,计算机图形学-实验报告三-图形裁剪算法

    <计算机图形学-实验报告三-图形裁剪算法>由会员分享,可在线阅读,更多相关<计算机图形学-实验报告三-图形裁剪算法(9页珍藏版)>请在人人文库网上搜索. 1.图形裁剪算法1. ...

  2. c语言图形学扫描线填充算法,《计算机图形学》OpenGL实现扫描线填充算法

    顾名思义啊,就是在OpenGL中用扫描填充算法画一个稍微复杂的图形: #include #include #include #include #define COLOR_NEW 1.0,0.0,0.0 ...

  3. OpenGL南邮计算机图形学实验报告二——两个纹理的渐变变换和移动

    OpenGL南邮计算机图形学实验报告二--两个纹理的渐变变换和移动 计算机图形学的新题目要求 OpenGL配置参考: 南邮老前辈wonz哥的OpenGL配置(Shader.h始终不用改).SOIL2 ...

  4. OpenGL南邮计算机图形学实验报告四——用键盘控制物体

    OpenGL南邮计算机图形学实验报告四--用键盘控制物体 计算机图形学的新题目要求 OpenGL配置参考: 南邮老前辈wonz哥的OpenGL配置(Shader.h始终不用改).SOIL2 环境配置. ...

  5. OpenGL南邮计算机图形学实验报告三——实现类似地月系统的两物体环绕移动

    OpenGL南邮计算机图形学实验报告三--实现类似地月系统的两物体环绕移动 计算机图形学的新题目要求 OpenGL配置参考: 南邮老前辈wonz哥的OpenGL配置(Shader.h始终不用改).SO ...

  6. 计算机图形Opengl的实验报告,opengl计算机图形学实验报告之3D漫游世界.doc

    opengl计算机图形学实验报告之3D漫游世界.doc 北师大珠海分校信息技术学院计算机图形学实验报告实验报告文件命名方式学号姓名_实验序号_实验名称.doc姓名学号1001010092专业计算机任课 ...

  7. 华北电力大学计算机图形学实验报告,华北电力大学计算机图形学实验报告分析.doc...

    华北电力大学计算机图形学实验报告分析 科 技 学 院 课程设计(综合实验)报告 ( 2013 -- 2014 年度第 2 学期) 实验名称 OpenGL基本图元绘制实验 课程名称 计算机图形学 | | ...

  8. 计算机图形学真实感显示代码,计算机图形学实验 - 真实感图形场景的生成

    <计算机图形学实验 - 真实感图形场景的生成>由会员分享,可在线阅读,更多相关<计算机图形学实验 - 真实感图形场景的生成(4页珍藏版)>请在人人文库网上搜索. 1.计算机图形 ...

  9. 计算机图形学E1——OpenGL 方中有圆,圆中有方,无穷尽焉

    其他计算机图形学实验见 链接 使用OpenGL绘制如图所示图形 有穷的: #include <GL/glut.h> #include <math.h> #include< ...

  10. 计算机图形学实验——二维卡通人物交互

    计算机图形学实验1.2卡通人物交互 OpenGL卡通人物交互 基础"图元"绘制 OpenGL拾取物体 反走样 略提反走样问题 OpenGL实现二维反走样 放缩.旋转和拖动 小结 O ...

最新文章

  1. JAVA从数据库中拿到数据
  2. 恐怖的shell命令
  3. 联想笔记本Win10 F1-F12失效的解决方法
  4. cocos2d-x游戏循环与调度
  5. 需求用例分析之二:级别设置
  6. python获得本机硬件信息
  7. php输出分组,ThinkPHP 项目分组中的模板输出
  8. 如何充分利用各大银行免费资源最大限度减少理财成本
  9. Zabbix实战-简易教程--订阅类
  10. ActionScript 3.0
  11. python中split函数源代码_Pandas.split()函数用法及源码
  12. C# string转DateTime DateTime转string
  13. Kali安装网易云音乐
  14. 多线程-生产者消费者模式-CopyOnWriteArrayList索引越界问题
  15. chrome等浏览器滚动全屏截图方法
  16. python 正则表达式 前瞻_【正则表达式】前瞻,后顾,负前瞻,负后顾
  17. 从头实现YOLOv3:第4部分
  18. SDUT 2084 DOTA-人王之战(博弈论)
  19. Python中os.listdir的排序问题
  20. 【委托】—是什么怎么用什么用

热门文章

  1. python selenium 刷课_基于Python和selenium的内蒙古继续教育网---刷课
  2. 群晖服务器怎么做文件转移,群晖(黑) 篇五:群晖系统迁移:旧群晖数据和系统转移到新机器...
  3. SQL Server根据地图坐标经纬度计算距离
  4. html工资计算页面模板,工资计算表Excel模板
  5. Windows 文本编辑器 EditPlus 的简单使用
  6. 人口预测模型及matlab代码
  7. php 快递100接口
  8. 手把手教你学DSP:基于TMS320C55x
  9. 从零开始系类——模拟电子技术
  10. CAM350 12.1(附补丁)