MarchineCubes实现思路总结

news2024/9/23 5:29:09

MarchineCubes定义

是一种基于体素构建三维模型的方式,有些类似《我的世界》中的堆方块,但实际上,建模是以方块之间的交点为中心点,每个cube表示八个象限的相交模型

实现思路

在三维空间中划分网格,每个网格是一个cube,其8个顶点各有两个状态{in、out},分别表示该顶点是否位于三维模型的内部
根据这8个顶点的状态,可确定当前cube自身的模型,这个排列组合正好是一个8位二进制
这里需要对这8个顶点进行约定,为后续代码提供方便
在这里插入图片描述这样约定的好处是,某些临边、对角位置可用二进制位运算方便获取,临边是相应位异或、对角是按位取反

Cube建模

总共有255种组合,其中有些是重复形状的翻转、和旋转,且0x00、0xff实际上是空模型,那么一个cube就需要254个模型,我没有采用Polygonising中的三角形列表,而是用python在maya中建模

import maya.cmds as cmd
for i in range(1,255):
    names=[]
    for j in range(0,8):
        if 1<<j&i:
            names.append("aaa%d_%d"%(i,j))
            # 若相邻顶点{in、out}状态不同就w、h、d=0.9是故意在模型中间留条缝
            cmd.polyCube(w=1<<(1<<2^j)&i and 1 or 0.9,h=1<<(1<<1^j)&i and 1 or 0.9,d=1<<(1<<0^j)&i and 1 or 0.9,n=names[-1])
            cmd.move((1<<2&j and 0.5 or -0.5),1<<1&j and 0.5 or -0.5,1<<0&j and 0.5 or -0.5)
    if len(names)>1:
        cmd.polyCBoolOp(names,n="aaa%d"%(i))
    elif len(names)>0:
        cmd.rename(names[-1],"aaa%d"%(i))
    if len(names)>0:
        cmd.makeIdentity("aaa%d"%(i),a=1,t=1)

这样就建立好1~254所有模型,并重叠摆在原点中心。然后清空历史,选中所有模型,手动将模型上、下、左、右、前、后0.5米之外的部分切割掉

切割前切割后
在这里插入图片描述在这里插入图片描述

切割之后,就是一个1x1单位中心对齐的模型,再通过脚本将其一字排开

for i in range(1,255):
    cmd.move(i*1.5,0,0,"aaa%d"%(i))

在这里插入图片描述在Outliner中可以看到每个mesh被命名为aaa1 ~ aaa254,方便后续引擎中按索引直接取出对应模型

数据结构及伪代码

这里采用自研引擎+lua环境实现
由于lua数组实际是hash结构,所以可以将网格中的三维坐标转为一个整形数值用来做hash key,也就没必要存储为三维数组了

-- id表示为三维空间坐标,由于double有效数为9007199254740992,所以用1024^3足够,哈希值:x*1024^2+y*1024+z
function coordToId(x,y,z)
    return x*1024^2+y*1024+z
end

-- 那么当某个hash反推:x=math.floor(v/1024/1024)、y=math.floor(v/1024%1024)、z=v%1024
function idToCoord(id)
    return math.floor(id/1024/1024),math.floor(id/1024%1024),id%1024
end

定义grids、cubes数据

function EditorBehavior:__init(name)
    ...
    self.grids={}
    self.cubes={}
end

grids表示网格的交点坐标
cubes表示围绕交点周围的模型,也就是说cubes在每一维度都比grids多一个单位
当修改某个grids的状态,in:1、out:nil

function EditorBehavior:AddGrid(x,y,z)
    self.grids[coordToId(x,y,z)]=1
    self:UpdateTileRoundTheGrid(x,y,z,true)
end

function EditorBehavior:RemoveGrid(x,y,z)
    self.grids[coordToId(x,y,z)]=nil
    self:UpdateTileRoundTheGrid(x,y,z,false)
end

然后根据这个grids内容更新周围八个象限cubes的状态值,若某个cube更新后数值为0,则清除这个cube

function EditorBehavior:UpdateTileRoundTheGrid(x,y,z,inside)
    for i=0,1 do for j=0,1 do for k=0,1 do
        local pos=i*4+j*2+k
        local ipos=bit.band(bit.bnot(pos),0x7)
        local mask=bit.lshift(0x1,ipos)
        local cube=self.cubes[coordToId(x+i,y+j,z+k)]
        if cube then
            if inside then
                self.cubes[coordToId(x+i,y+j,z+k)]=bit.bor(cube,mask)
            else
                cube=bit.band(cube,bit.bnot(mask))
                if 0==cube then
                    self.cubes[coordToId(x+i,y+j,z+k)]=nil
                else
                    self.cubes[coordToId(x+i,y+j,z+k)]=cube
                end
            end
        else
            if inside then
                self.cubes[coordToId(x+i,y+j,z+k)]=mask
            end
        end
    end end end
end

在渲染时,将所有cube的状态值,以及模型渲染出来
这里cube的状态值,正好对应之前maya中模型的aaa1 ~ aaa254
在这里插入图片描述

参考

https://www.cs.carleton.edu/cs_comps/0405/shape/marching_cubes.html
http://paulbourke.net/geometry/polygonise/
https://www.researchgate.net/publication/202232897_Marching_Cubes_A_High_Resolution_3D_Surface_Construction_Algorithm
https://www.bilibili.com/video/BV1yJ411r73v

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/69125.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]JAVA毕业设计体育竞赛成绩管理系统(系统+LW)

[附源码]JAVA毕业设计体育竞赛成绩管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目…

Java基础之《netty(9)—netty和线程模型概述》

一、netty概述 1、NIO的类库和API繁杂&#xff0c;使用麻烦&#xff1b;需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。 2、需要具备其他的额外技能&#xff0c;要熟悉Java多线程编程&#xff0c;因为NIO编程涉及到Reactor模式&#xff0c;你必须…

Java --- Spring6之Set方法注入

目录 一、注入外部Bean与内部Bean 二、简单类型注入 三、级联属性赋值 四、注入数组 五、List与Set注入 六、Map和Properties注入 一、注入外部Bean与内部Bean public class OrderDao {private static final Logger logger LoggerFactory.getLogger(UserDao.class);public…

led台灯哪个牌子效果最好?2022最新国产led灯品牌排行

目前台灯的发展非常迅速&#xff0c;已经到了全面led灯的时代&#xff0c;传统的卤素灯已经近乎完全淘汰&#xff0c;这不仅仅是跟技术的发展有关&#xff0c;也跟led灯本身的优势有关&#xff0c;各方面很适合做成护眼灯。 护眼灯为什么都是led灯&#xff1f; 护眼台灯使用le…

外卖配送系统搭建,骑手实时更新,路线规划更科学

在如今快节奏的现代生活&#xff0c;人们基本离不开外卖&#xff0c;这也催生了不少外卖配送系统的诞生&#xff0c;那你知道外卖配送系统搭建吗&#xff1f;如果想要一款外卖系统&#xff0c;如何着手呢&#xff1f; 要想开发一款成功的外卖配送系统&#xff0c;要先进行市场…

论文笔记|DeepWalk

简介 DeepWalk是由Bryan Perozzi&#xff0c;Rami Al-Rfou和Steven Skiena在2014年提出的&#xff0c;它是一种基于图的无监督特征学习方法&#xff0c;它有趣的点是将文本处理任务中词向量的处理思想迁移到了图特征学习上&#xff0c;就像处理句子得到word embedding一样&…

深入linux内核架构--进程线程

简介 进程和线程这两个词&#xff0c;每个程序员都十分熟悉&#xff0c;但是想要很清晰的描述出来却有一种不知道从何说起的感觉。所以今天结合一个具体的例子来描述一下进程与线程的相关概念&#xff1a;在terminal上敲出a.out这个自己编译出来可执行程序路径后&#xff0c;这…

【预测模型】基于随机蛙跳算法 SFLA优化神经网络实现数据回归预测附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

Kafka 3.3.1 Kraft 多端口协议搭建

Kafka 3.3.1 Kraft 多端口协议搭建 序 Kafka 3.3.1 已经出来挺久了&#xff0c;很多公司还停留在 1.X/2.X 甚至 0.8 版本的 kafka&#xff0c;不是说不能用&#xff0c;但是用起来真的糟糕&#xff0c;况且现在 Kraft 已经正式推出了&#xff0c;早就该更新了。 本篇文章从实…

276 t230 二叉搜索树第k小的元素

题解 思路:定义一个全局变量,初值赋予k.中序遍历,每次访问一个,变量–,当该变量为0时,就把val值赋予另一个全局变量返回. class Solution {int resKthSmallest0;int countKthSmallest;// 276 t230 二叉搜索树第k小的元素public int kthSmallest(TreeNode root, int k) {count…

大数据人工智能实验室-大数据培训方案

随着计算机和信息技术的迅猛发展和普及应用&#xff0c;行业应用系统的规模迅速扩大&#xff0c;行业应用所产生的数据呈爆炸性增长。企业需要将隐藏在大批杂乱无章的数据中进行信息的集中、萃取和提炼&#xff0c;找出所研究对象的内在规律&#xff0c;从而对决策提供帮助&…

预训练模型-代码补全(二):Copilot(GitHub)

​ GitHub Copilot是一个为开发者提供的突破性的AI编程辅助工具&#xff0c;但这才是开始。 昨天&#xff0c;Copilot团队推出了一个名为GitHub Copilot Labs的VS Code配套扩展。它独立于&#xff08;并依赖于&#xff09;GitHub Copilot扩展。它可以用来解释代码和翻译代码。…

【元胞自动机】格子波尔兹曼模型研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【JNA】java springboot 动态读取动态库

【JNA】java springboot 动态读取动态库创建名为dynamic-lib-load.xml的文件资源目录结构如下工具类LibraryLoadDynamicParseUtil工具类调用我们在使用第三方动态库 时长出现动态库无法读取jar包内的动态库文件&#xff0c;以下代码希望对大家有帮助 废话不多说&#xff0c;上代…

【王道计算机网络笔记】数据链路层-局域网广域网

文章目录局域网局域网拓扑结构局域网传输介质局域网介质访问控制方法局域网的分类以太网以太网提供无连接、不可靠的服务以太网传输介质与拓扑结构的发展10BASE-T以太网适配器与MAC地址以太网的MAC帧高速以太网IEEE802标准MAC子层和LLC子层IEEE802.11有固定基础设施无线局域网无…

嵌入式:ARM体系结构详解

文章目录指令集与指令集架构主要计算机指令集架构PC及服务器领域嵌入式领域新生代ARM体系结构的演变ARM发展的历程指令集与指令集架构 指令&#xff1a;就是指挥计算机工作的命令&#xff0c;程序就是一系列按一定顺序排列的指令&#xff0c;计算机就是通过执行程序中的指令来…

11. softmax回归的简洁实现

通过深度学习框架的高级API也能更方便地实现softmax回归模型。 继续使用Fashion-MNIST数据集&#xff0c;并保持批量大小为256。 import torch from torch import nn from d2l import torch as d2lbatch_size 256 train_iter, test_iter d2l.load_data_fashion_mnist(batch…

在IDEA中配置Maven

文章目录Maven 简介Maven 下载与安装修改Maven配置文件Maven文件目录的含义配置IDEA的MavenMaven 简介 Maven 项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以程序构建能力为特色之外&#x…

数据库审核工具SQLE接口调用

点击上方蓝字关注我接上文数据库审核接口SQLE的探索使用&#xff0c;本次自定义接口进行调用&#xff0c;实现需求。1、创建自定义审核接口因直接调用SQLE的审核接口&#xff0c;会出现token过期&#xff0c;且审核及结果查询接口是分开的&#xff0c;因此&#xff0c;出于以上…

Mock模拟数据动态字节码编译插件优化

模块介绍 dmc-plugin-java 动态编译字节码 关于动态编译字节码技术参考&#xff1a; https://blog.csdn.net/huxiang19851114/article/details/127881616 优化如下&#xff1a; 动态文本类改为界面配置及数据库保存 数据库表结构&#xff1a; DROP TABLE IF EXISTS compi…