MATLAB实现Catmull-Clark细分(CC细分)

2023-12-25 22:30

本文主要是介绍MATLAB实现Catmull-Clark细分(CC细分),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

终于调试好了Catmull-Clark细分(CC细分)的全部程序,将之前只适用于封闭四边形网格的程序进行了完善

主要一段代码来自于三维网格细分算法(Catmull-Clark subdivision & Loop subdivision)附源码,这个博主的很多篇博文都写的非常好,但是经常丢三落四的,像在这篇博文中他就用到了函数outline.m用来计算网格的边界,但是博主却没有给出outline函数,我自己重新编写了这个函数,并且能够成功执行^^,现在我贴出完整代码

function [VV, FF, S] = CCSubdivision(V, F, iter)  % Catmull_Clark subdivision  if ~exist('iter','var')  iter = 1;  end  VV = V;  FF = F;  for i = 1:iter   nv = size(VV,1);  nf = size(FF,1);   O = outline(FF);  original = 1:nv;  boundary = O(:,1)';  interior = original(~ismember(original, boundary));  no = length(original);  nb = length(boundary);  ni = length(interior);  %% Sv  Etmp = sort([FF(:,1) FF(:,2);FF(:,2) FF(:,3);FF(:,3) FF(:,4);FF(:,4) FF(:,1)],2);  [E, ~, idx] = unique(Etmp, 'rows');  Aeven = sparse([E(:,1) E(:,2)], [E(:,2) E(:,1)], 1, no, no);  Aodd = sparse([FF(:,1) FF(:,2)], [FF(:,3) FF(:,4)], 1, no, no);  Aodd = Aodd + Aodd';  val_even = sum(Aeven,2);  beta = 3./(2*val_even);  val_odd = sum(Aodd,2);  gamma = 1./(4*val_odd);  alpha = 1 - beta - gamma;  Sv = sparse(no,no);  Sv(interior,:) = ...  sparse(1: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(:,1);O(:,2)],[O(:,2);O(:,1)],1/8,no,no) + ...  sparse([O(:,1);O(:,2)],[O(:,1);O(:,2)],3/8,no,no);  Sv(boundary,:) = Sboundary(boundary,:);  %% Sf  Sf = 1/4 .* sparse(repmat((1:nf)',1 ,4), FF, 1);  i0 = no + (1:nf)';  %% Se  flaps = sparse([idx;idx], ...  [FF(:,3) FF(:,4);FF(:,4) FF(:,1);FF(:,1) FF(:,2);FF(:,2) FF(:,3)], ...  1);  onboundary = (sum(flaps,2) == 2);  flaps(onboundary,:) = 0;  ne = size(E,1);  Se = sparse( ...  [1:ne 1:ne]', ...  [E(:,1); E(:,2)], ...  [onboundary;onboundary].*1/2 + ~[onboundary;onboundary].*3/8, ...  ne, ...  no) + ...  flaps*1/16;  %% new faces & new vertices  i1 = no +   nf + (1:nf)';  i2 = no + 2*nf + (1:nf)';  i3 = no + 3*nf + (1:nf)';  i4 = no + 4*nf + (1:nf)';  FFtmp = [i0 i4 FF(:,1) i1; ...  i0 i1 FF(:,2) i2; ...  i0 i2 FF(:,3) i3; ...  i0 i3 FF(:,4) i4];  reidx = [(1:no)'; no+(1:nf)'; no+nf+idx];  FF = reidx(FFtmp);  S = [Sv; Sf; Se];  VV = S*VV;  end  end  
其中outline函数如下

function out = outline( FF )
%OUTLINE Summary of this function goes here
%   Detailed explanation goes here
Etmp = sort([FF(:,1) FF(:,2);FF(:,2) FF(:,3);FF(:,3) FF(:,4);FF(:,4) FF(:,1)],2);
[~, ~, idx] = unique(Etmp, 'rows');oriEtmp = [FF(:,1) FF(:,2);FF(:,2) FF(:,3);FF(:,3) FF(:,4);FF(:,4) FF(:,1)];
hh=sortrows([oriEtmp,idx],3);x2=diff(sortrows(idx));
vector = all(x2==0, 2);index1=find(vector);
index2=index1+1;
index=[index1;index2];hh(index,:)=[];
out=hh(:, 1:2);end
对于任意四边形网格是适用的,下面是我们的测试代码

[V,F]=obj__read('six.obj');
V=V';F=F';
iter=4;
[VV, FF] = CCSubdivision(V, F, iter);
%[VV, FF] = CCsub(V, F, iter);
obj_write('six1.obj',VV',FF');[V,F]=obj__read('torus.obj');
V=V';F=F';
iter=4;
[VV, FF] = CCSubdivision(V, F, iter);
%[VV, FF] = CCsub(V, F, iter);
obj_write('torus1.obj',VV',FF');
最后贴上细分效果

开放四边形网格
 六面开口盒子四次细分
封闭四边形网格
 四边形框四次细分
搞定哈哈^^

这篇关于MATLAB实现Catmull-Clark细分(CC细分)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/537188

相关文章

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

在React聊天应用中实现图片上传功能

《在React聊天应用中实现图片上传功能》在现代聊天应用中,除了文字和表情,图片分享也是一个重要的功能,本文将详细介绍如何在基于React的聊天应用中实现图片上传和预览功能,感兴趣的小伙伴跟着小编一起... 目录技术栈实现步骤1. 消息组件改造2. 图片预览组件3. 聊天输入组件改造功能特点使用说明注意事项

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

debian12安装docker的实现步骤

《debian12安装docker的实现步骤》本文主要介绍了debian12安装docker的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录步骤 1:更新你的系统步骤 2:安装依赖项步骤 3:添加 docker 的官方 GPG 密钥步骤

基于Redis实现附近商铺查询功能

《基于Redis实现附近商铺查询功能》:本文主要介绍基于Redis实现-附近商铺查询功能,这个功能将使用到Redis中的GEO这种数据结构来实现,需要的朋友可以参考下... 目录基于Redis实现-附近查询1.GEO相关命令2.使用GEO来实现以下功能3.使用Java实现简China编程单的附近商铺查询4.Red

使用Python实现实时金价监控并自动提醒功能

《使用Python实现实时金价监控并自动提醒功能》在日常投资中,很多朋友喜欢在一些平台买点黄金,低买高卖赚点小差价,但黄金价格实时波动频繁,总是盯着手机太累了,于是我用Python写了一个实时金价监控... 目录工具能干啥?手把手教你用1、先装好这些"食材"2、代码实现讲解1. 用户输入参数2. 设置无头浏

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Python实现剪贴板历史管理器

《Python实现剪贴板历史管理器》在日常工作和编程中,剪贴板是我们使用最频繁的功能之一,本文将介绍如何使用Python和PyQt5开发一个功能强大的剪贴板历史管理器,感兴趣的可以了解下... 目录一、概述:为什么需要剪贴板历史管理二、功能特性全解析2.1 核心功能2.2 增强功能三、效果展示3.1 主界面

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

springboot实现配置文件关键信息加解密

《springboot实现配置文件关键信息加解密》在项目配置文件中常常会配置如数据库连接信息,redis连接信息等,连接密码明文配置在配置文件中会很不安全,所以本文就来聊聊如何使用springboot... 目录前言方案实践1、第一种方案2、第二种方案前言在项目配置文件中常常会配置如数据库连接信息、Red