1.DAE

visual_scene

DAE中可以有几个<visual_scene>,但是只有其中一个会显示,这个显示的<visual_scene>的id在<scene>中

<library_visual_scenes>
    <visual_scene>
      <node>
          // 存放node信息
      </node>
   </visual_scene>
</library_visual_scenes>

<scene>
    <instance_visual_scene url="#my_data_scene"/>
</scene>

node

一个<visual_scene>中有很多<node>,这些<node>在3Dmax中是可以选择独立显示的模型,<node>可以相互嵌套,形成二级或三级目录

3D模型查看与格式转换教程配图
node

<node>里可能包含其他<node>,最下层的叶子<node>里包含一个<instance_geometry>,这个<instance_geometry>里包含了模型的几何数据和材质信息。

<node name="basement_surface_n33">
            <instance_geometry url="#basement_surface_geometry33">
              <bind_material>
                <technique_common>
                  <instance_material symbol="materialref" target="#basement_material"/>
                </technique_common>
              </bind_material>
            </instance_geometry>
          </node>

<instance_geometry url="#geometry"> 这个url就是存放几何数据节点的id

<instance_material symbol="materialref" target="#basement_material"/> 这个target就是材质信息的id

几何数据

<geometry name="topography_face_32">
      <mesh>
        <source>
          <float_array count="7500"> 这里省略了7500个数</float_array>
          <technique_common>
            <accessor count="2500" source="#topography_face_verts-array32-array" stride="3">
              <param type="float" name="X"/>
              <param type="float" name="Y"/>
              <param type="float" name="Z"/>
            </accessor>
          </technique_common>
        </source>
        <source>
          <float_array count="14406">这里省略了14406个数</float_array>
          <technique_common>
            <accessor count="4802" source="#topography_face_normals-array32-array" stride="3">
              <param type="float" name="X"/>
              <param type="float" name="Y"/>
              <param type="float" name="Z"/>
            </accessor>
          </technique_common>
        </source>
        <source>
          <float_array count="5000">这里省略了5000个数</float_array>
          <technique_common>
            <accessor count="2500" source="#topography_face_texcoords-array32-array" stride="2">
              <param type="float" name="S"/>
              <param type="float" name="T"/>
            </accessor>
          </technique_common>
        </source>
        <vertices>
          <input semantic="POSITION" source="#topography_face_verts-array32"/>
        </vertices>
        <triangles count="4802" material="materialref">
          <input offset="0" semantic="VERTEX" source="#topography_face_verts-array32-vertices"/>
          <input offset="1" semantic="NORMAL" source="#topography_face_normals-array32"/>
          <input offset="2" semantic="TEXCOORD" source="#topography_face_texcoords-array32"/>
          <p> 这里省略了4802*3个索引值  <p> 
        </triangles>
      </mesh>
    </geometry>

一般来说,几何数据包括顶点数据、法向数据、纹理坐标数据。这个geometry里包含了三个source,每个source里都有一个长长的数组<float_array>,分别保存了顶点数据、法向数据、纹理坐标数据。<float_array>下面的<technique_common>是对<float_array>的解释。

  • 第一个source存储的是顶点数据,由三个数字(x,y,z)表示一个点的坐标,坐标值按照x,y,z,x,y,z,x,y,z.....的顺序存放,也就是说这个<float_array>的长度一定是3的倍数,因为三个x,y,z坐标才能表示一个点。
  • 第二个source存储的是法向数据,由三个数字(x,y,z)表示一个向量。
  • 第三个source存储的是纹理坐标,由两个数字(s,t)表示一个纹理坐标。

图片是由一个个像素构成的,三维模型中的曲面则是由一个个三角形构成的。<triangles>中的<p>里存放的就是顶点数据、法向数据、纹理坐标数据的索引

<p>38 0 38 37 0 37 87 0 87 88 1 88 38 1 38 87 1 87 698 2 698 749 2 749 699 2 699 749 3 749 698 . . . . . </p>

offset(补偿)表示索引存放的顺序。第一个数38是顶点索引(offset=0),第二个数0是法向索引(offset=0),第三个数38是纹理坐标索引(offset=0)。

顶点数据是三个数表示一个点,顶点索引38指向的点的xyz坐标,就是顶点数据中下标为[38*3,38*3+1,38*3+2]这三个数。法向数据同理

纹理坐标数据是两个数表示一个纹理坐标,纹理坐标索引38指向的点的ST坐标,就是顶点数据中下标为[38*2,38*2+1]这两个数。

索引开头的[38 0 38]共同表示了第一个三角形的第一个点的顶点数据索引、法向数据索引、纹理坐标数据索引。而一个三角形有三个点,所以表示一个三角形需要9个索引, 例如[38 0 38 37 0 37 87 0 87]这9个数字表示了一个三角形。

<geometry>文件中不一定是包含顶点数据、法向数据、纹理坐标数据,可以包括只有顶点数据(只有顶点在某些软件上可能会显示不正常),或者没有纹理数据(仅显示纯色),也可包含更多的其他数据。

材质信息

material里会包含一个effect,这个effect可以是纯色,可以有贴图。

<color>中存放的就是颜色,格式是RGBA,A表示透明度,color中的数值范围是0~1。

有图片的effect是这样的

<effect name="topography_effect">
      <profile_COMMON>
        <newparam sid="topography_Sampler2D">
          <sampler2D>
            <source>topography_surface</source>
          </sampler2D>
        </newparam>
        <newparam sid="topography_surface">
          <surface type="2D">
            <init_from>topographyimage</init_from>
            <format>A8R8G8B8</format>
          </surface>
        </newparam>
        <technique sid="common">
          <phong>
            <diffuse>
              <texture texture="topography_Sampler2D" texcoord="topography_map"/>
            </diffuse>
            </reflectivity>
            <transparent>
              <color>0.0 0.0 0.0 1.0</color>
            </transparent>
            <transparency>
              <float>1.0</float>
            </transparency>
          </phong>
        </technique>
        <extra>
          <technique profile="GOOGLEEARTH">
            <double_sided>0</double_sided>
          </technique>
        </extra>
      </profile_COMMON>
    </effect>

这里的嵌套关系很复杂,<surface>中的topographyimage是image的id

<library_images>
    <image name="topographyimage">
      <init_from>tex/C015.jpg</init_from>
    </image>
  </library_images>

通过id找到image节点,里面的tex/C015.jpg就是文件的图片路径


2.VTR

VTP文件也是属于vtk的,可以用paraview打开

顶点

<Points>
        <DataArray type="Float32" Name="Points" NumberOfComponents="3" format="ascii" RangeMin="708.5835234925046" RangeMax="2902.0823939476886">
          10 10 708.4423828125 10 30 708.6803588867188
          30 10 708.4388427734375 30 30 708.68115234375
          10 50 708.9192504882812 30 50 708.9244995117188

这里存储的是顶点数据,存放格式与DAE的顶点数据一摸一样。


顶点索引

<Polys>
        <DataArray type="Int64" Name="connectivity" format="ascii" RangeMin="0" RangeMax="13819">
          2 1 0 3 1 2
          3 4 1 5 4 3
          5 6 4 7 6 5
          7 8 6 9 8 7
          9 10 8 11 10 9
          11 12 10 13 12 11

这里存放的就是三角形顶点的索引。三个点就能连成一个三角形,例如开头数组 (2,1,0),表示第一个三角形的三个点分别是Points 中的第3个,第2个,第1个点。(数组下标从0开始数)。顶点索引数组的长度不仅一定3的倍数,并且一定是整数,因为数组下标肯定是整数。

3.VTP

VTP文件也是属于vtk的,可以用paraview打开,显示体数据,也就是实心的三维模型。

VTP原始文件在paraview中的显示

3D模型查看与格式转换教程配图

clip过滤器裁剪过后的VTP文件

3D模型查看与格式转换教程配图

文件前几行

<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
  <RectilinearGrid WholeExtent="0 100 0 100 0 100">
  <Piece Extent="0 100 0 100 0 100">
    <PointData>
    </PointData>
    <CellData Scalars="Lithology">
      <DataArray type="Float64" Name="Lithology" format="ascii" RangeMin="-100" RangeMax="9">
        9 9 9 9 9 9
        9 9 9 9 9 9
        9 9 9 9 9 9
        9 9 9 9 9 9

Extent="0 100 0 100 0 100" 表示:x方向上有0到100个值,y方向上有0到100个值,z方向上有0到100个值。

一个单元格(cell)可以想象成一个小方块(或者一个像素),这个小方块可大可小。

下面的9就是数值,总共会有100*100*100个值,不同的值在paraview中会映射成不同的颜色。

我们把DataArray比作一个数组,DataArray[0]是数组的第一个值(为了便于讲解,我们让数组下标从0开始), DataArray[i]是数组的第i+1个值,这些值中最大值(RangeMax)是9,最小值(RangeMin)是-100。Cell[x][y][z]表示单元格的坐标,这个坐标不表示实际的空间距离,仅表示该单元格在x,y,z方向上排第几个,例如(0,1,2)表示在x方向第1个,在y方向第2个,在z方向第3个的单元格。DataArray值的排布顺序是先排满x方向,再排满y方向,最后是z方向。即

Cell [x] [y] [z] = DataArray[ z*100*100 + y*100 + x ]

因为x方向上有100个值,y方向上有100个值,所以上式要乘与100。如果x方向和y方向的值的数量是其他数字,则要改变上式。

文件后几行

<Coordinates>
      <DataArray type="Float64" Name="Array 000001308A49BF60" format="ascii" RangeMin="0" RangeMax="2000">
        0 20 40 60 80 100
        120 140 160 180 200 220
        240 260 280 300 320 340
        360 380 400 420 440 460
        480 500 520 540 560 580
        600 620 640 660 680 700
        720 740 760 780 800 820
        840 860 880 900 920 940
        960 980 1000 1020 1040 1060
        1080 1100 1120 1140 1160 1180
        1200 1220 1240 1260 1280 1300
        1320 1340 1360 1380 1400 1420
        1440 1460 1480 1500 1520 1540
        1560 1580 1600 1620 1640 1660
        1680 1700 1720 1740 1760 1780
        1800 1820 1840 1860 1880 1900
        1920 1940 1960 1980 2000
      </DataArray>
      <DataArray type="Float64" Name="Array 000001308A49A130" format="ascii" RangeMin="0" RangeMax="2000">
        0 20 40 60 80 100
        120 140 160 180 200 220
        240 260 280 300 320 340
        360 380 400 420 440 460
        480 500 520 540 560 580
        600 620 640 660 680 700
        720 740 760 780 800 820
        840 860 880 900 920 940
        960 980 1000 1020 1040 1060
        1080 1100 1120 1140 1160 1180
        1200 1220 1240 1260 1280 1300
        1320 1340 1360 1380 1400 1420
        1440 1460 1480 1500 1520 1540
        1560 1580 1600 1620 1640 1660
        1680 1700 1720 1740 1760 1780
        1800 1820 1840 1860 1880 1900
        1920 1940 1960 1980 2000
      </DataArray>
      <DataArray type="Float64" Name="Array 000001308A49ED50" format="ascii" RangeMin="0" RangeMax="1600">
        0 16 32 48 64 80
        96 112 128 144 160 176
        192 208 224 240 256 272
        288 304 320 336 352 368
        384 400 416 432 448 464
        480 496 512 528 544 560
        576 592 608 624 640 656
        672 688 704 720 736 752
        768 784 800 816 832 848
        864 880 896 912 928 944
        960 976 992 1008 1024 1040
        1056 1072 1088 1104 1120 1136
        1152 1168 1184 1200 1216 1232
        1248 1264 1280 1296 1312 1328
        1344 1360 1376 1392 1408 1424
        1440 1456 1472 1488 1504 1520
        1536 1552 1568 1584 1600
      </DataArray>
    </Coordinates>

可以看到每个DataArray里都是等差数列,并且数组长度都是101。

这三个数组分别表示x,y,z单元格的尺寸,可以看到第一和第二数组的公差为20,则一个单元格在x和y方向上的长度(或者说距离)都为20,第三个数组的公差为16,则一个单元格在z方向上的长度为16。