OpenVDB Cookbook 笔记

目录

  • Hello World
  • Creating and writing a grid
  • Populating a grid with values
  • Reading and modifying a grid
  • Stream I/O
  • Handling metadata
    • Adding metadata
    • Retrieving metadata
    • Removing metadata
  • Iteration
    • Node Iterator
    • Leaf Node Iterator
    • Value Iterator
    • Iterator Range
  • Interpolation of grid values
    • Index-space samplers
    • Grid Sampler
    • Dual Grid Sampler
  • Transforming grids
    • Geometric transformation
    • Value transformation
  • Combining grids
    • Level set CSG operations
    • Compositing operations
    • Generic combination
  • Generic programming
    • Calling Grid methods
  • “Hello, World” for OpenVDB Points
  • Converting Point Attributes
  • Random Point Generation
  • Point Iteration, Groups and Filtering
    • Point Iteration
    • Creating and Assigning Point Groups
    • Point Filtering using Groups
    • Point Filtering using Custom Filters
  • Strided Point Attributes
    • Constant Stride Attributes
  • Moving Points in Space
    • Advecting Points
    • Moving Points with a Custom Deformer

代码示例:

https://www.openvdb.org/documentation/doxygen/codeExamples.html#sHelloWorld

Hello World

初始化

创建网格

从网格获取访问器

创建坐标

修改坐标

访问器访问指定坐标

遍历网格

Creating and writing a grid

创建 openvdb::io::File 类型的对象,使用它来读写 vdb 文件

Populating a grid with values

第一步只创建表面周围的 SDF 值,也就是创建一个窄带

窄带的 SDF 值的区间取为 [-background_SDF, background_SDF]background_SDF 是正数,是背景的 SDF 值

按照一定的间隔,跳跃着遍历立方体 grid

遍历到的元素的 SDF 值如果在这个区间内,也就是在窄带内,那么就赋值,否则跳过

具体怎么计算遍历到的元素的 SDF 值,是 (x,y,z) - center 的长度减去球的半径

Reading and modifying a grid

遍历一个 openvdb::io::File 对象中的所有网络,根据网格名字查找到某一个网络

用网格基类存储查找到的网格。如果已知网格子类的类型,就可以直接 cast。

遍历 active 的 grid 元素,这些元素对应窄带 narrow band 元素

遍历 inactive 的 grid 元素,这些元素对应内部 interior 的元素

Stream I/O

写入(读取) string 流或者文件流

Handling metadata

元数据

Adding metadata

添加元数据

重复添加相同的名字相同类型的值,那么就是覆盖

如果是重复添加相同的名字不同类型的值,那么就报错

Retrieving metadata

已知元数据的数据类型,根据名字可以获取值

遍历元数据 map

可以获得元数据的 string 形式的类型名称,进而得知某个元数据的数据类型,进而进行类型转换

Removing metadata

删除不存在的元数据,不会报错,但是也没有效果

Iteration

Node Iterator

遍历树

Leaf Node Iterator

遍历叶子节点

遍历常量叶子节点

转换成引用或者指针

Value Iterator

遍历 active 的 grid 元素,这些元素对应窄带 narrow band 元素

遍历 inactive 的 grid 元素,这些元素对应内部 interior 的元素

Iterator Range

怎么使用 tbb 的 parallel_for 并行执行任务

首先要输入 openvdb 提供的迭代器

然后要自己创建一个重载了括号运算符的结构体

输入这个结构体作为任务

这个结构体的括号运算符的重载就是任务主体。它接受一个迭代器
,这个迭代器的范围是由 tbb 划分的,原始迭代范围的子区间

Interpolation of grid values

需要在分数坐标的值的时候,就需要在整数坐标的值之间插值

GridSampler 用于插值

GridTransformer 用于对所有值进行变换

Index-space samplers

在索引空间中插值

零阶插值 最近邻

一阶插值 线性

二阶插值 二次函数

通过树 grid.tree() 来访问是线程安全的,但是因为没有缓存,所以是次优的

最佳的是通过访问器,例如 grid.getConstAccessor()

因为访问器采用了缓存

也因此,访问器必须是一个线程一个访问器

Grid Sampler

GridSampler 可以在索引空间或者世界空间中插值

使用网格来构造 GridSamplerGridSampler 会自动获得索引空间到世界空间的变换

但是使用树或者访问器来构造 GridSampler,需要提供变换

用访问器构造 GridSampler 更快

Dual Grid Sampler

有些时候存在两个网格,一个源网格,一个目标网格

给定目标网格中的索引,需要从源网格得到相同索引位置的插值结果

所以提供了工具类 DualGridSampler

这个类还会检查两个网格的变换是不是一样的,如果不一样的话,这个任务就没有意义了

Transforming grids

Geometric transformation

有点不知道为什么,网格从一个变换转到另外一个变换是 源 transform 乘 目标 transform 的逆

Value transformation

openvdb::tools::foreach 可以遍历所有的值

openvdb::tools::transformValues 遍历源网格的值,同时把结果输出到一个目标网格

Combining grids

假设某个索引坐标,在两个网格中都对应同一个世界坐标,才能谈网格的组合

如果不是对应同一个世界坐标,那就是两个网格的变换不同,一般的方法是先将一个网格重新采样到另一个网格的索引空间

Level set CSG operations

Constructive solid geometry, CSG,构造立体几何

并集 交集 差集

Compositing operations

组合操作,取最大值,取最小值,加法,乘法

Generic combination

自定义操作符

使用 Tree::combine 来对两个树进行自定义操作符的操作

Tree::combineExtended 可以设置两个树的迭代元素的值和 active 状态

Tree::combine 将结果写到 A,B 留空;Tree::combine2 将结果写到第三个树

Generic programming

Calling Grid methods

这节演示了怎么泛型编程

processTypedGrid 这个函数用了一个叫作 dependent names 的特性,这个之前我还没见过,很酷

https://en.cppreference.com/w/cpp/language/dependent_name

The template disambiguator for dependent names
Similarly, in a template definition, a dependent name that is not a member of the current instantiation is not considered to be a template name unless the disambiguation keyword template is used or unless it was already established as a template name:

template<typename T>
struct S
{template<typename U>void foo() {}
};template<typename T>
void bar()
{S<T> s;s.foo<T>();          // error: < parsed as less than operators.template foo<T>(); // OK
}

之后的 PruneOp 类中也用到了这个特性

“Hello, World” for OpenVDB Points

对点集进行划分的工具类

对点集划分之后,可以计算体素大小

根据体素大小可以获得网格的变换

然后就可以创建点网格

根据字符串获得属性的这个,有点奇妙啊

const openvdb::points::AttributeArray& array =leafIter->constAttributeArray("P");

他用 “P” 来获得 position,这种缩写的规则,看上去就很容易搞混啊

从点网格获得属性的过程是,先获取叶子节点,然后得到 AttributeArray,然后得到 AttributeHandle

Converting Point Attributes

要对属性进行操作的时候,需要共通的 openvdb::tools::PointIndexGrid

创建 openvdb::points::PointDataGrid 的时候,还有把新的数组添加的网格的新字段的时候,都需要 openvdb::tools::PointIndexGrid

创建 openvdb::points::PointDataGrid 的时候,看上去是默认创建了一个名字为 “P” 的字段

然后之后如果要对点添加新字段的话,先注册类型

openvdb::points::TypedAttributeArray<float, Codec>::registerType();

然后再 openvdb::points::appendAttribute 添加字段到网格

现在网格有了字段,还是没有对应的数据

还要用 openvdb::points::populateAttribute 添加数据到对应字段

Random Point Generation

创建一个 openvdb::points::PointDataTree,可以拷贝别的网格的树结构来创建

要想使用 openvdb::points::PointDataTree 来创建 openvdb::points::PointDataGrid,还需要创建 openvdb::points::AttributeSet::Descriptor,然后 initializeAttributes 初始化 PointDataTree 的每一个叶节点

Point Iteration, Groups and Filtering

Point Iteration

迭代点网格的方法

两层循环,外层迭代树结构的所有叶子节点,内层对于每一个叶子节点,根据属性的名字构建 openvdb::points::AttributeArray,进而创建 openvdb::points::AttributeHandle。内层循环是对于叶子节点的每个索引,根据索引从 AttributeHandle 中 get 或 set 值

要使用 TBB 的并行,TBB 需要迭代器和回调函数,迭代器由 openvdb::tree::LeafManager 提供,回调函数就是自己创建结构体重载括号运算符

为了单线程调试 TBB,可以把输入的范围做成没有拆分的,对于 openvdb::tree::LeafManager 就是把 leafRange 的参数 grainsize 设置得很大,大于所有叶子节点的总数

Creating and Assigning Point Groups

树底下是节点,遍历叶子节点

叶子节点里面可以遍历 index

index 可以添加到 Group

添加到 Group 的 handle 需要从叶子节点这里获取

很神奇噢,属性句柄 AttributeHandle 和顶点组写入句柄 openvdb::points::GroupWriteHandle 都是从叶子节点这里得来的

Point Filtering using Groups

顶点组可以方便过滤迭代

如果已经创建好了一个顶点组

那么使用这个顶点组的名称就可以创建 openvdb::points::GroupFilter

在迭代某个叶子节点的 index 的时候,使用这个 filter,就可以自动遍历属于这个组的 index

for (auto indexIter = leafIter->beginIndexOn(filter); indexIter; ++indexIter) {

Point Filtering using Custom Filters

不用点组的话,可以自己创建一个结构体,提供 valid 函数,作为过滤器

Strided Point Attributes

步长表示每一个属性能有多少个值

Constant Stride Attributes

openvdb::points::appendAttribute 添加属性的时候,就把步长参数传进去了

Moving Points in Space

Advecting Points

使用一个均匀的场来平流点

Moving Points with a Custom Deformer

自定义平流方法

也是自定义一个结构体,提供特定函数的方法,形参是 vec3 和 index

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

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

相关文章

Vegeta压测工具学习与使用

Vegeta压测工具学习与使用 目标&#xff1a; 能够在命令行下使用Vegeta对指定API进行测试了解如何导出结果&#xff0c;以及能获得什么样的结果(P99,P99.9,QPS)探索能否导出其他结果&#xff0c;是否能够执行复杂命令或简易脚本等 时间比较紧迫&#xff0c;预计两到三个小时内完…

详解tomcat中的jmx监控

目录 1.概述 2.如何开启tomcat的JMX 3.tomcat如何实现JMX的源码分析 1.概述 本文是博主JAVA监控技术系列文章的第二篇&#xff0c;前面一篇文章中我们介绍了JAVA监控技术的基石——jmx&#xff1a; 【JMX】JAVA监控的基石-CSDN博客 本文我们将从使用和源码实现两个方面聊…

BLDC驱动刹车电路、能量泄放电路

不同STM32的性能; APM2.8飞控整合资料&#xff1a; APM2.8飞控说明书 GitBook BLDC的制动首先要考虑MOS的泄放电阻的选择&#xff0c;参考前面博客。 刹车电阻制动&#xff1a; 如图所示就是一种通过功率电阻耗散电机制动过程中产生电能的电路。因为功率电阻在这个电路中起…

【AI视野·今日Robot 机器人论文速览 第七十八期】Wed, 17 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Wed, 17 Jan 2024 Totally 49 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Safe Mission-Level Path Planning for Exploration of Lunar Shadowed Regions by a Solar-Powered Rover Authors Olivier L…

【并发编程】ThreadPoolExecutor类

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程⛺️稳重求进&#xff0c;晒太阳 ThreadPoolExecutor 1) 线程池状态 ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态&#xff0c;低 29 位表示线程数量 状态名 高三位 …

rtt设备io框架面向对象学习-uart设备

目录 1.uart设备基类2.uart设备基类的子类3.初始化/构造流程3.1设备驱动层3.2 设备驱动框架层3.3 设备io管理层 4.总结5.使用 1.uart设备基类 此层处于设备驱动框架层。也是抽象类。 在/ components / drivers / include / drivers 下的serial.h定义了如下uart设备基类 struc…

Transformer实战-系列教程18:DETR 源码解读5(BackboneBase类/Backbone类)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 DETR 算法解读 DETR 源码解读1&#xff08;项目配置/CocoDetection类&#xff09; …

我的NPI项目之嵌入式总线系列(一) -- SPI 接口

如我的NPI项目之Android 安全系列 -- 外挂SE集成&#xff08;SPI&#xff09;接口-CSDN博客 提到SPI的接口&#xff0c;基本的电气特性已经给出。这边文章就针对协议部分进行详细解析。从协议网找到了原文&#xff1a;SPI protocol 还有wilipedia SPI 主要涉及一下几个方面&a…

bat 定时收缩sqlserver2017

如果你希望使用批处理&#xff08;.bat&#xff09;文件来定时收缩SQL Server的数据库&#xff0c;你可以编写一个脚本来执行这个任务。但首先&#xff0c;需要注意的是&#xff0c;定期收缩数据库通常不是一个好的做法&#xff0c;因为它可能会对性能产生负面影响&#xff0c;…

全闭环直播推流桌面分享远控系统

直播推流涉及多协议&#xff0c;多端技术栈和知识点&#xff0c;&#xff0c;想要做好并不容易&#xff0c;经过几年时间的迭代&#xff0c;终于小有成就&#xff0c;聚集了媒体服务器&#xff0c;实时会议sfu&#xff0c;远控kvm等功能。可以做一个音视频应用的瑞士小军刀。主…

详解Vue文件结构+实现一个简单案例

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

测试开发-2-概念篇

文章目录 衡量软件测试结果的依据—需求1.需求的概念2.从软件测试人员角度看需求3.为什么需求对软件测试人员如此重要4.如何才可以深入理解被测试软件的需求5.测试用例的概念6.软件错误&#xff08;BUG&#xff09;的概念7.开发模型和测试模型8.软件的生命周期9.瀑布模型&#…

MATLAB知识点:randperm函数(★★★★★)将一个数字序列进行随机打乱

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第…

Codeforces Round 923 - A.B.C.D

文章目录 A. Make it WhiteB. Following the StringC.Choose the Different Ones!D. Find the Different Ones! A. Make it White #include<bits/stdc.h>using namespace std;void solve() {int n;cin >> n;string s; cin >> s;int flag 0;int x 0, y -1…

django中admin页面汉化

在Django中&#xff0c;将admin界面汉化为中文需要进行一些配置和翻译文件的添加。下面是一个基本的步骤指南&#xff0c;帮助你实现Django admin的汉化&#xff1a; 一&#xff1a;安装并配置Django: 如果你还没有安装Django&#xff0c;首先通过pip安装它&#xff1a; pip…

【开源训练数据集1】神经语言程式(NLP)项目的15 个开源训练数据集

一个聊天机器人需要大量的训练数据,以便在无需人工干预的情况下快速解决用户的询问。然而,聊天机器人开发的主要瓶颈是获取现实的、面向任务的对话数据来训练这些基于机器学习的系统。 我们整理了训练聊天机器人所需的对话数据集,包括问答数据、客户支持数据、对话数据和多…

ESP32学习(1)——环境搭建

使用的ESP32板子如下图所示 它可以用Arduino 软件&#xff0c;基于C语言开发。但是&#xff0c;在这里&#xff0c;我是用Thonny软件&#xff0c;基于micro_python对其进行开发。 1.安装Thonny Thonny的软件安装包&#xff0c;可以去它官网上下载。Thonny, Python IDE for begi…

【MySQL】学习外键约束处理员工数据

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-g4glZPIY0IKhiTfe {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

【原理解密】多角度、多尺度、多目标的边缘模板匹配

学习《OpenCV应用开发&#xff1a;入门、进阶与工程化实践》一书 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; 边缘模板匹配的基本原理 OpenCV中自带的模板匹配算法&#xff0c;完全是像素基本的模板匹配&#xff0c;特别容易受到光照影…

【剪映】如何使用曲线变速?

如何使用曲线变速 进入视频编辑界面后&#xff0c;选中视频&#xff0c;点击下方工具栏的-【变速】-【曲线变速】&#xff0c;进入后可以看到七个预设变速&#xff0c;其中后六个为系统自带预设变速&#xff0c;每个预设变速效果不同&#xff0c;直接点击这六个预设&#xff0c…