下图描述了细分的基本思想,每次细分都是在每条边上插入一个新的顶点,可以看到随着细分次数的增加,折线逐渐变成一条光滑的曲线。曲面细分需要有几何规则和拓扑规则,几何规则用于计算新顶点的位置,拓扑规则用于确定新顶点的连接关系。下面介绍两种网格细分方法:Catmull-Clark细分和Loop细分。

Catmull-Clark subdivision

  Catmull-Clark细分是一种四边形网格的细分法则,每个面计算生成一个新的顶点,每条边计算生成一个新的顶点,同时每个原始顶点更新位置。下图为Catmull-Clark细分格式的细分掩膜,对于新增加的顶点位置以及原始顶点位置更新规则如下:

1.网格内部F-顶点位置:

  设四边形的四个顶点为v0、v1、v2、v3,则新增加的顶点位置为v = 1/4*(v0 + v1 + v2 + v3)。

2.网格内部V-顶点位置:

  设内部顶点v0的相邻点为v1、v2,…,v2n,则该顶点更新后位置为,其中α、β、γ分别为α = 1 - β - γ。

3.网格边界V-顶点位置:

  设边界顶点v0的两个相邻点为v1、v2,则该顶点更新后位置为v = 3/4*v0 + 1/8*(v1 + v2)。

4.网格内部E-顶点位置:

  设内部边的两个端点为v0、v1,与该边相邻的两个四边形顶点分别为v0、v1、v2、v3和v0、v1、v4、v5,则新增加的顶点位置为v = 1/4*(v0 + v1 + vf1 + vf2) = 3/8*(v0 + v1) + 1/16*(v2 + v3 + v4 + v5)。

5.网格边界E-顶点位置:

  设边界边的两个端点为v0、v1,则新增加的顶点位置为v = 1/2*(v0 + v1)。

效果:

function [VV, FF, S] = CC_subdivision(V, F, iter)
% Catmull_Clark subdivision
if ~exist('iter','var')
iter = ;
end
VV = V;
FF = F; for i = :iter
nv = size(VV,);
nf = size(FF,); O = outline(FF); original = :nv;
boundary = O(:,)';
interior = original(~ismember(original, boundary)); no = length(original);
nb = length(boundary);
ni = length(interior); %% Sv
Etmp = sort([FF(:,) FF(:,);FF(:,) FF(:,);FF(:,) FF(:,);FF(:,) FF(:,)],);
[E, ~, idx] = unique(Etmp, 'rows'); Aeven = sparse([E(:,) E(:,)], [E(:,) E(:,)], , no, no);
Aodd = sparse([FF(:,) FF(:,)], [FF(:,) FF(:,)], , no, no);
Aodd = Aodd + Aodd'; val_even = sum(Aeven,);
beta = ./(*val_even); val_odd = sum(Aodd,);
gamma = ./(*val_odd); alpha = - beta - gamma; Sv = sparse(no,no);
Sv(interior,:) = ...
sparse(:ni, interior, alpha(interior), ni, no) + ...
bsxfun(@times, Aeven(interior,:), beta(interior)./val_even(interior)) + ...
bsxfun(@times, Aodd(interior,:), gamma(interior)./val_odd(interior));
Sboundary = ...
sparse([O(:,);O(:,)],[O(:,);O(:,)],/,no,no) + ...
sparse([O(:,);O(:,)],[O(:,);O(:,)],/,no,no);
Sv(boundary,:) = Sboundary(boundary,:); %% Sf
Sf = / .* sparse(repmat((:nf)',1 ,4), FF, 1);
i0 = no + (:nf)'; %% Se
flaps = sparse([idx;idx], ...
[FF(:,) FF(:,);FF(:,) FF(:,);FF(:,) FF(:,);FF(:,) FF(:,)], ...
);
onboundary = (sum(flaps,) == );
flaps(onboundary,:) = ; ne = size(E,);
Se = sparse( ...
[:ne :ne]', ...
[E(:,); E(:,)], ...
[onboundary;onboundary].*/ + ~[onboundary;onboundary].*/, ...
ne, ...
no) + ...
flaps*/; %% new faces & new vertices
i1 = no + nf + (:nf)';
i2 = no + *nf + (:nf)';
i3 = no + *nf + (:nf)';
i4 = no + *nf + (:nf)'; FFtmp = [i0 i4 FF(:,) i1; ...
i0 i1 FF(:,) i2; ...
i0 i2 FF(:,) i3; ...
i0 i3 FF(:,) i4]; reidx = [(:no)'; no+(1:nf)'; no+nf+idx];
FF = reidx(FFtmp); S = [Sv; Sf; Se];
VV = S*VV;
end
end

Loop subdivision

  Loop细分是一种三角形网格的细分法则,它按照1-4三角形分裂,每条边计算生成一个新的顶点,同时每个原始顶点更新位置。下图为Loop细分格式的细分掩膜,对于新增加的顶点位置以及原始顶点位置更新规则如下:

1.网格内部V-顶点位置:

  设内部顶点v0的相邻点为v1、v2,…,vn,则该顶点更新后位置为,其中

2.网格边界V-顶点位置:

  设边界顶点v0的两个相邻点为v1、v2,则该顶点更新后位置为v = 3/4*v0 + 1/8*(v1 + v2)。

3.网格内部E-顶点位置:

  设内部边的两个端点为v0、v1,相对的两个顶点为v2、v3,则新增加的顶点位置为v = 3/8*(v0 + v1) + 1/8*(v2 + v3)。

4.网格边界E-顶点位置:

  设边界边的两个端点为v0、v1,则新增加的顶点位置为v = 1/2*(v0 + v1)。

效果:

本文为原创,转载请注明出处:http://www.cnblogs.com/shushen

三维网格细分算法(Catmull-Clark subdivision & Loop subdivision)附源码的更多相关文章

  1. 三维网格精简算法(Quadric Error Metrics)附源码

    在计算机图形应用中,为了尽可能真实呈现虚拟物体,往往需要高精度的三维模型.然而,模型的复杂性直接关系到它的计算成本,因此高精度的模型在几何运算时并不是必须的,取而代之的是一个相对简化的三维模型,那么如 ...

  2. 三维网格精简算法(Quadric Error Metrics)附源码(转载)

    转载:  https://www.cnblogs.com/shushen/p/5311828.html 在计算机图形应用中,为了尽可能真实呈现虚拟物体,往往需要高精度的三维模型.然而,模型的复杂性直接 ...

  3. 网格测地线算法(Geodesics in Heat)附源码

    测地线又称为大地线,可以定义为空间曲面上两点的局部最短路径.测地线具有广泛的应用,例如在工业上测地线最短的性质就意味着最优最省,在航海和航空中,轮船和飞机的运行路线就是测地线.[Crane et al ...

  4. 卡通图像变形算法(Moving Least Squares)附源码

    本文介绍一种利用移动最小二乘法来实现图像变形的方法,该方法由用户指定图像中的控制点,并通过拖拽控制点来驱动图像变形.假设p为原图像中控制点的位置,q为拖拽后控制点的位置,我们利用移动最小二乘法来为原图 ...

  5. 基于Zlib算法的流压缩、字符串压缩源码

    原文:基于Zlib算法的流压缩.字符串压缩源码 Zlib.net官方源码demo中提供了压缩文件的源码算法.处于项目研发的需要,我需要对内存流进行压缩,由于zlib.net并无相关文字帮助只能自己看源 ...

  6. 三维网格细分算法(Catmull-Clark subdivision & Loop subdivision)附源码(转载)

    转载:  https://www.cnblogs.com/shushen/p/5251070.html 下图描述了细分的基本思想,每次细分都是在每条边上插入一个新的顶点,可以看到随着细分次数的增加,折 ...

  7. SM4密码算法(附源码)

    SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳→_→:http://www.cnnic.NET.cn/jscx/mixbz/sm4/ 具体的密码标准和算法官方有非常 ...

  8. arcgis api 3.x for js 共享干货系列之一自写算法实现地图量算工具(附源码下载)

    0.内容概览 Geometry 地图服务方式实现地图距离以及面积的量算,简单描述 arcgis api 提供的接口类 geometryEngine 实现地图距离以及面积的量算,简单描述 自定义距离以及 ...

  9. sm4算法(附源码、测试代码)

    from:http://blog.csdn.net/mao0514/article/details/52930944 SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳 ...

随机推荐

  1. go git 安装配置与使用 (windows 7 64bit)

    go语言安装使用第三方库方式一般采用 go get github.com/.../...  命令.例如: go get github.com/astaxie/beego 1.错误情况一: packag ...

  2. React Native 常见问题集合

    在使用React Native时候,我记录下比较常遇到的问题,分为以下几类: 1. 调试问题 2. 写法问题 3. 疑难问题 4. 奇怪问题 调试问题 1. 在react-native run-and ...

  3. js一些代码方法

    概要 1.替换json对象中属性值(包括子对象) 2.兼容多个$库写法(zepto与jquery) 3.闭包保持变量的做法 详情 1.替换json对象中属性值(包括子对象) //替换json对象属性值 ...

  4. 转:ibatis常用16条SQL语句

    1.输入参数为单个值 <delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" par ...

  5. 在Powershell ISE中添加sharepoint的智能提示,Enable SharePoint PowerShell Commandlets in the PowerShell ISE

    Powershell ISE在默认状态下有一个不好的地方就是不会显示关于SharePoint的一些智能提示,例如你写一个"get-"后面提示的选项里没有sp开头的一些对象.于是找了 ...

  6. 使用powershell部署WSP包

    代码如下,先卸载,然后删除,然后添加,然后安装. 卸载之后会重启IIS,所以等待几秒钟,直到卸载完成. 添加snapin $snapin = Get-PSSnapin | Where-Object { ...

  7. ios 怎么解决Could not find Developer Disk Image

  8. objective-c系列-单例

    // 地球只有一个,所以声明一个地球对象就可以了,千万不能声明两个啊!同理,有时候一个类也有只能有一个对象的情况,例如服务器,只想存到一个里 // 面,这样子,下次才可以取出上次存的数据. //用全局 ...

  9. iOS沙盒目录结构解析

    iOS沙盒目录结构解析 原文地址:http://blog.csdn.net/wzzvictory/article/details/18269713     出于安全考虑,iOS系统的沙盒机制规定每个应 ...

  10. iOS开发之Runtime使用

    runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C语言,函数的调用在编译的时候会决定调用哪个函数. 对于OC的函数,属于动态 ...