体网格模型

本文介绍了体网格模型的用途、基本构成和快速入门等内容。

模型用途

简介

体网格模型可用于三维实体建模,特别是对于那些形状不规则,材质不均匀,属性各向异性的三维空间数据(如地质、洋流等),体网格模型可以描述它们复杂的内部几何结构以及多样化的属性信息。

Ganos中,使用标准的SQL语言来查询和处理体网格模型类型的数据,支持基于文本和二进制的数据格式。

Ganos Vomesh是对象关系型数据库PostgreSQL兼容版本(PolarDB PostgreSQL版(兼容Oracle))的一个时空引擎扩展,它提供了一组数据类型和函数,帮助用户高效地管理、查询和分析三维体网格模型。

功能概述

Ganos Vomesh为体网格数据处理提供了多种能力,包括空间关系判断、空间分析计算、模型简化、模型切剖、模型属性插值、模型可视化、模型查询,同时还支持使用空间索引进行查询计算加速。

主要业务场景

在实际应用中,体网格类型可以用于空间数据的建模、分析和可视化:

  • 三维数据分析计算

    在地质勘探、自然资源管理等领域,我们需要分析计算各个矿体的含煤量,各个油井的储油量,各个山脉的金属含量等,以便更好地进行工业开采。在交通运输领域,我们需要分析计算各个地层的受力情况,以便更好地进行(地铁、火车)轨道路线选址。

    体网格模型可以用于以下场景:

    • 为地质数据进行建模。

    • 利用模型切剖,获取地质体在各处的几何结构。

    • 利用模型插值,估算地质体在各处的属性信息。

    利用体网格模型,客户在以上场景可以作出更优的决策和规划。

    image

    此外,在桥梁道路、建筑等其他行业,三维数据分析计算也可以用于各种测量场景,如计算建筑物的长度、面积、体积等;判断两个空间对象的位置关系;计算交集、差集、并集等。

  • 三维数据可视化

    在诸多数字孪生场景,我们需要对三维数据进行可视化,以便更好地进行人机交互,增强用户的体验。体网格模型提供的glTF、glb,b3dm三维格式,可以将复杂的三维数据在3D建模软件或者浏览器前端进行可视化。

    image

基本构成

体网格模型概述

体网格模型(Volume Mesh,简写为Vomesh)常用于表示地质、洋流,以及各类场(气场、风向场、磁场)等三维不均匀空间,应用场景包括自然资源管理、交通运输、桥梁建筑、基础设施建设、气象预测等行业。体网格使用顶点(Vertex),面元(Face),以及体元(Cell)来对空间位置信息进行描述,并附加属性信息。

  • 顶点:每个顶点由(x,y,z)坐标组成。

  • 面元:每个面元由一组有序的顶点下标组成。每个面元都是一个简单平面多边形(凸多边形或者凹多边形)。面元是有方向的,其方向由顶点顺序确定,根据右手准则,大拇指的方向即为面元的方向,这也是面的法向量的方向。

  • 体元:每个体元由一组无序的面元下标组成。一般情况下,每个体元都是封闭的几何体。

  • 顶点属性:每个顶点可以挂载一些属性,表示它在真实世界的物理、化学、时空等性质。为了支持不同的应用场景,使得体网格模型更加通用化。属性数据的类型可以是整型(signed char,signed short,int,long)、浮点型(float,double),属性数据的维度可以是标量(scalar),一维向量(vector),二维矩阵(matrix)。

  • 面元属性:每个面元也可以挂载属性。属性数据的类型和维度同上。

  • 体元属性:每个体元同样可以挂载属性。属性数据的类型和维度也同上。

这种由若干个顶点、面元、体元以及它们的属性共同描述的实体对象模型称为体网格模型。

体网格交换格式

体网格交换格式支持文本和二进制两种格式。

  • 方便阅读的文本形式:Well-Known Text(以下简称为WKT)。详情请参见WKT

  • 可以保留数据精度且方便传输的二进制形式:Well-Known Binary(以下简称为WKB)。详情请参见WKB

空间参考系

空间参考系(Spatial Reference System,以下简称为SRS )定义了如何将Vomesh对象关联到地球表面上某个具体位置。

Ganos使用称为SRID来引用SRS定义。Vomesh对象通过其自身的SRID值与SRS关联。

更多内容请参见空间参考

索引

空间索引使Ganos处理大型空间数据集时避免对数据库进行全局顺序扫描。索引通过将数据组织到搜索树中来加速搜索,可以快速遍历该搜索树以查找特定记录。

GanosVomesh提供了一种基于GiST的三维空间索引。

可通过以下方式进行创建。

CREATE INDEX <index_name>
ON <table_name>
USING GIST(<column_name>);

空间关系判断

该工具箱可以用于判断一个Vomesh与另一个几何对象(Vomesh类型,或者Ganos Sfmesh,Meshgeom,Box3D类型)的空间位置关系:

  • 相交:两个几何对象在空间上发生部分重叠。

  • 包含:一个几何对象完全在另一个对象的内部空间。

  • 相离:两个几何对象在空间上没有任何重叠,且没有包含关系。

  • 混合:两个几何对象在空间上既不完全包含,也不完全相离,也不直接相交。

image

空间关系:(a)相离,(b)相交,(c)包含,(d)混合关系,两个蓝色立方体组成一个Sfmesh对象。

空间分析计算

该工具箱可以用于计算一个Vomesh与另一个几何对象Vomesh类型,或者Ganos Sfmesh,Meshgeom,Box3D类型)的交并差集:

  • 交集:返回两个几何对象的公共部分,该部分会继承第一个Vomesh对象的(顶点、面元、体元,以及属性)原始信息。

  • 并集:返回两个Vomesh对象的所有部分。两个参数必须都是Vomesh类型,假设依次为\(A, B\),其中\(A \setminus B\),\(A \cap B\)的部分会继承\(A\)的原始信息,\(B \setminus A\)的部分会继承\(B\)的原始信息。

  • 差集:返回第一个Vomesh与另一个几何对象的差集,该部分会继承第一个Vomesh对象的原始信息。

  • 合并:(1)将两个Vomesh“加”到一起,这里假设两个对象没有交集,只是将它们的体元堆积起来,放在一起;(2)将一个Vomesh数组“加”到一起,组成一个更大的Vomesh对象;(3)聚合函数,将表中某一列Vomesh“加”到一起。

image

空间分析计算:(a)交集,会保留第一个vomesh的几何细节;(b)差集,会保留第一个vomesh的几何细节;(c)并集,会保留两个vomesh的几何细节;(d)合并,将多个不相交的vomesh拼接成一个更大的vomesh。

模型简化

该工具箱用于减少Vomesh对象的几何与属性数据,包括合并相邻、平行、且类型相同的面元(即,减少面元的数量),合并共线的顶点(如,多个顶点共线,则可以只保留首尾两个点)。该功能在保证Vomesh拓扑结构基本不变的情况下,极大地减少了Vomesh的存储空间,在数据可视化,以及实际的应用分析中,有重大的作用。

image

模型切剖

该工具箱用于切割地质体,显示地质体的内部结构。它需要两个参数,一个是Vomesh对象,一个是若干个三角形组成的切面(这些三角形可以不共面),这些切面会把Vomesh切开,返回截面处的面片。这些截面反映了地质数据的内部结构。在地质分析,轨道交通,矿产勘测,自然资源管理等领域具有广泛的应用。

模型切剖,得到切剖后的截面如下图所示:

image

模型属性插值

该工具箱采用了(简单、普通)克里金插值函数给地质体某些特定的位置(默认是Vomesh每个体元的中心点)插值一些属性,它需要用户提供一些参考点,以及这些参考点的属性数据,基于这些信息,对地质体进行属性插值。在轨道交通选址,矿产勘测等场景具有应用前景。

模型可视化

该工具箱提供了将Vomesh转换成glTF,glb,b3dm三维数据格式的函数,使得用户可以在3D建模软件(如Blender),以及浏览器前端渲染引擎(如Cesium)中看到Vomesh数据的“真容”。

模型查询

该工具箱给用户提供了一些直接与Vomesh进行交互的查询函数:

  • 给定一个Vomesh对象,查询它所有体元或者某一个体元的中心点。

  • 给定一个Vomesh对象和一个三维的点,查询该Vomesh哪个体元包含该点。

  • 给定一个Vomesh对象,查询指定属性的最大值和最小值。

  • 给定一个Vomesh对象,查询指定属性的数据。

快速入门

简介

快速入门文档帮助用户快速理解Ganos Vomesh引擎的基本用法,包括扩展创建、建表、插入数据、查询结果、创建索引、空间查询等内容。

语法说明

  • 创建扩展

    CREATE EXTENSION ganos_vomesh CASCADE;
    说明

    建议将扩展安装在public模式下,避免权限问题。

    Create extension ganos_vomesh with schema public CASCADE;
  • 创建具有VOMesh字段的表

    CREATE TABLE t_mesh(id integer,
                        mesh vomesh
                      );
  • 插入数据

    --向表中插入数据
    INSERT INTO
        t_mesh(id, mesh)
    VALUES
    (1, 'SRID=4326;LOD=2;VOMESH(VERTEX(COORDS(1 0 0,0 1 0,-1 0 0,0 -1 0,0 0 1)),FACE(INDEX((0,1,2,3),(0,1,4),(1,2,4),(2,3,4),(0,3,4))),CELL(INDEX((0,1,2,3,4)),DIRECTION((0,1,1,1,0))))'::vomesh),
    
    (2, 'LOD=2;VOMESH(VERTEX(COORDS(0 0 0,0 1 0,1 1 0,1 0 0,1 0 1,1 1 1,0 1 1,0 0 1),ATTRS(ATTR(NAME(height),TYPE(double),SCALAR(1.0,1.0,1.0,1.0,2.0,2.0,2.0,2.0)),ATTR(NAME(mass),TYPE(double),SCALAR(2.1,0.9,3.4,3.8,5.6,10.1,9.2,8.3)),ATTR(NAME(center),TYPE(int4),VECTOR((0,1),(2,3),(4,5),(6,7),(8,9),(10,11),(12,13),(14,15))))),FACE(INDEX((0,1,2,3),(0,1,6,7),(0,3,4,7),(2,3,4,5),(1,2,5,6),(4,5,6,7)),ATTRS(ATTR(NAME(color),TYPE(int8),SCALAR(222,198,157,210,100,99)))),CELL(INDEX((0,1,2,3,4,5)),DIRECTION((1,0,1,0,0,1)),ATTRS(ATTR(NAME(solid),TYPE(double),SCALAR(21.9)))))'::vomesh);
  • 查询数据结果

    SELECT id, ST_AsText(mesh)
    FROM t_mesh;
    
    -------------------------
    1 | LOD=2;VOMESH(VERTEX(COORDS(1 0 0,0 1 0,-1 0 0,0 -1 0,0 0 1)),FACE(INDEX((0,1,2,3),(0,1,4),(1,2,4),(2,3,4),(0,3,4))),CELL(INDEX((0,1,2,3,4)),DIRECTION((0,1,1,1,0))))
    2 | LOD=2;VOMESH(VERTEX(COORDS(0 0 0,0 1 0,1 1 0,1 0 0,1 0 1,1 1 1,0 1 1,0 0 1),ATTRS(ATTR(NAME(height),TYPE(double),SCALAR(1,1,1,1,2,2,2,2)),ATTR(NAME(mass),TYPE(double),SCALAR(2.1,0.9,3.4,3.8,5.6
    ,10.1,9.2,8.3)),ATTR(NAME(center),TYPE(int4),VECTOR((0,1),(2,3),(4,5),(6,7),(8,9),(10,11),(12,13),(14,15))))),FACE(INDEX((0,1,2,3),(0,1,6,7),(0,3,4,7),(2,3,4,5),(1,2,5,6),(4,5,6,7)),ATTRS(ATTR(NAME(c
    olor),TYPE(int8),SCALAR(222,198,157,210,100,99)))),CELL(INDEX((0,1,2,3,4,5)),DIRECTION((1,0,1,0,0,1)),ATTRS(ATTR(NAME(solid),TYPE(double),SCALAR(21.9)))))
  • 创建索引

    -- 创建GiST索引
    CREATE INDEX idx_t_mesh
    ON t_mesh
    USING GIST(mesh);
  • 空间查询

    -- 与某个三维空间对象相交
    SELECT id
    FROM t_mesh
    WHERE ST_3DIntersects(mesh, 'BOX3D(-1 -1 0, -0.1 -0.1 1)'::box3d);
  • 删除扩展(可选)

    DROP EXTENSION ganos_vomesh CASCADE;