【CAD开发】glTF和b3dm文件格式读取三(Python, JS)

大数据 创建于:2023-05-28

1、简介

glTF格式使用scene对象来描述场景。对glTF数据的JSON文件进行解析时,对场景结构的遍历也是从scene对象开始。每个scene对象引用了一个nodes数组,nodes数组通过索引引用了场景的根结点。

示例中的代码只包含了一个scene对象,这一scene对象引用了一个索引为0的node对象,这个node对象引用了索引为0的mesh对象:

{
  "scenes" : [
    {
      "nodes" : [ 0 ]
    }
  ],
  
  "nodes" : [
    {
      "mesh" : 0
    }
  ],
  
  "meshes" : [
    {
      "primitives" : [ {
        "attributes" : {
          "POSITION" : 1
        },
        "indices" : 0
      } ]
    }
  ],

  "buffers" : [
    {
      "uri" : "data:application/octet-stream;base64,AAAA为了排版而省略,可以使用英文原文中的代码",
      "byteLength" : 44
    }
  ],
  "bufferViews" : [
    {
      "buffer" : 0,
      "byteOffset" : 0,
      "byteLength" : 6,
      "target" : 34963
    },
    {
      "buffer" : 0,
      "byteOffset" : 8,
      "byteLength" : 36,
      "target" : 34962
    }
  ],
  "accessors" : [
    {
      "bufferView" : 0,
      "byteOffset" : 0,
      "componentType" : 5123,
      "count" : 3,
      "type" : "SCALAR",
      "max" : [ 2 ],
      "min" : [ 0 ]
    },
    {
      "bufferView" : 1,
      "byteOffset" : 0,
      "componentType" : 5126,
      "count" : 3,
      "type" : "VEC3",
      "max" : [ 1.0, 1.0, 0.0 ],
      "min" : [ 0.0, 0.0, 0.0 ]
    }
  ],
  
  "asset" : {
    "version" : "2.0"
  }
}

2、gltflib (v2.0, python)

https://pypi.org/project/gltflib/

Library for parsing, creating, and converting glTF 2.0 files in Python 3.6+.

This library is intended for working with glTF 2.0 at a fairly low level, meaning you are responsible for managing the actual geometry data yourself. This library facilitates saving this data into a properly formatted glTF/GLB file. It also helps with converting resources inside a glTF/GLB file between external files or web URLs, data URLs, and embedded GLB resources.

pip install gltflib

在这里插入图片描述

2.1 Parsing a glTF 2.0 Model

from gltflib import GLTF

gltf = GLTF.load('D:/glTF-Sample-Models/2.0/BoxTextured/gltf/BoxTextured.gltf')
# print(gltf.model)

print(gltf.model.buffers[0].uri)
print(gltf.resources)
resource = gltf.resources[0]
print(resource)

在这里插入图片描述

2.2 Exporting a glTF 2.0 Model

import struct
import operator
from gltflib import (
    GLTF, GLTFModel, Asset, Scene, Node, Mesh, Primitive, Attributes, Buffer, BufferView, Accessor, AccessorType,
    BufferTarget, ComponentType, GLBResource, FileResource)

vertices = [
    (-4774424.719997984, 4163079.2597148907, 671001.6353722484),
    (-4748098.650098154, 4163079.259714891, 837217.8990777463),
    (-4689289.5292739635, 4246272.966707474, 742710.4976137652)
]

vertex_bytearray = bytearray()
for vertex in vertices:
    for value in vertex:
        vertex_bytearray.extend(struct.pack('f', value))
bytelen = len(vertex_bytearray)
mins = [min([operator.itemgetter(i)(vertex) for vertex in vertices]) for i in range(3)]
maxs = [max([operator.itemgetter(i)(vertex) for vertex in vertices]) for i in range(3)]
model = GLTFModel(
    asset=Asset(version='2.0'),
    scenes=[Scene(nodes=[0])],
    nodes=[Node(mesh=0)],
    meshes=[Mesh(primitives=[Primitive(attributes=Attributes(POSITION=0))])],
    buffers=[Buffer(byteLength=bytelen, uri='vertices.bin')],
    bufferViews=[BufferView(buffer=0, byteOffset=0, byteLength=bytelen, target=BufferTarget.ARRAY_BUFFER.value)],
    accessors=[Accessor(bufferView=0, byteOffset=0, componentType=ComponentType.FLOAT.value, count=len(vertices),
                        type=AccessorType.VEC3.value, min=mins, max=maxs)]
)

resource = FileResource('vertices.bin', data=vertex_bytearray)
gltf = GLTF(model=model, resources=[resource])
gltf.export('triangle.gltf')
# gltf.export('triangle.glb')

2.3 Converting Between glTF and GLB

from gltflib import GLTF

gltf = GLTF.load('D:/glTF-Sample-Models/2.0/BoxTextured/gltf/BoxTextured.gltf')
gltf.export('D:/BoxTextured.glb')
from gltflib import GLTF

gltf = GLTF.load('D:/glTF-Sample-Models/2.0/BoxTextured/glTF-Binary/BoxTextured.glb')
glb_resource = gltf.get_glb_resource()
gltf.convert_to_file_resource(glb_resource, 'BoxTextured.bin')
gltf.export('D:/BoxTextured.gltf')

<font color=blue size=5>相关测试代码见网址链接: https://download.csdn.net/download/hhy321/85182743

3、three.js(v2.0, javascript)

3.1 下载和编译

https://github.com/mrdoob/three.js

下载GitHub代码:

git clone --depth=1 https://github.com/mrdoob/three.js.git

使用npm编译代码:

npm install
npm start
or 
npm run dev

在这里插入图片描述

3.2 官网代码示意

  • 代码1:
import * as THREE from 'three';

// init

const camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;

const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
const material = new THREE.MeshNormalMaterial();

const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animation );
document.body.appendChild( renderer.domElement );

// animation

function animation( time ) {

	mesh.rotation.x = time / 2000;
	mesh.rotation.y = time / 1000;

	renderer.render( scene, camera );

}
  • 代码2:
<script type="module">
	import * as THREE from 'three';
	import Stats from './jsm/libs/stats.module.js';
	import { GUI } from './jsm/libs/lil-gui.module.min.js';
	import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
	import { GPUComputationRenderer } from './jsm/misc/GPUComputationRenderer.js';

	/* TEXTURE WIDTH FOR SIMULATION */
	const WIDTH = 64;
	const BIRDS = WIDTH * WIDTH;

	/* BAKE ANIMATION INTO TEXTURE and CREATE GEOMETRY FROM BASE MODEL */
	const BirdGeometry = new THREE.BufferGeometry();
	let textureAnimation, durationAnimation, birdMesh, materialShader, indicesPerBird;

	function nextPowerOf2( n ) {
		return Math.pow( 2, Math.ceil( Math.log( n ) / Math.log( 2 ) ) );
	}

	Math.lerp = function ( value1, value2, amount ) {
		amount = Math.max( Math.min( amount, 1 ), 0 );
		return value1 + ( value2 - value1 ) * amount;
	};

	const gltfs = [ 'models/gltf/Parrot.glb', 'models/gltf/Flamingo.glb' ];
	const colors = [ 0xccFFFF, 0xffdeff ];
	const sizes = [ 0.2, 0.1 ];
	const selectModel = Math.floor( Math.random() * gltfs.length );
	new GLTFLoader().load( gltfs[ selectModel ], function ( gltf ) {
		//.........
		//.........
		//.........
	}
	
//.........	
//.........	
//.........
</script>

在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭ 如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O??? 感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

原文地址:https://blog.51cto.com/u_15800063/5764768

免责声明:本文来源于互联网,版权归合法拥有者所有,如有侵权请公众号联系管理员

* 本站提供的一些文章、资料是供学习研究之用,如用于商业用途,请购买正版。

爱看书的小沐