Skip to content

GeoplexGIS/py3dtiles

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

https://secure.travis-ci.org/Oslandia/py3dtiles.png

py3dtiles

Python module to manage 3DTiles format.

For now, only the Point Cloud and the Batched 3D Model specifications are supported.

py3dtiles is distributed under LGPL2 or later.

Install

From sources

To use py3dtiles from sources:

$ git clone https://github.com/Oslandia/py3dtiles
$ cd py3dtiles
$ virtualenv -p /usr/bin/python3 venv
$ . venv/bin/activate
(venv)$ pip install -e .
(venv)$ python setup.py install

If you wan to run unit tests:

(venv)$ pip install nose
(venv)$ nosetests
...

Specifications

Generic Tile

The py3dtiles module provides some classes to fit into the specification:

  • Tile with a header TileHeader and a body TileBody
  • TileHeader represents the metadata of the tile (magic value, version, ...)
  • TileBody contains varying semantic and geometric data depending on the the tile's type

Moreover, a utility class TileReader is available to read a tile file as well as a simple command line tool to retrieve basic information about a tile: py3dtiles_info.

How to use py3dtiles_info

Here is an example on how to retrieve basic information about a tile, in this case pointCloudRGB.pnts:

$ py3dtiles_info tests/pointCloudRGB.pnts
Tile Header
-----------
Magic Value:  pnts
Version:  1
Tile byte length:  15176
Feature table json byte length:  148
Feature table bin byte length:  15000

Feature Table Header
--------------------
{'POSITION': {'byteOffset': 0}, 'RGB': {'byteOffset': 12000}, 'POINTS_LENGTH': 1000, 'RTC_CENTER': [1215012.8828876738, -4736313.051199594, 4081605.22126042]}

First point
-----------
{'Z': -0.17107764, 'Red': 44, 'X': 2.19396, 'Y': 4.4896851, 'Green': 243, 'Blue': 209}

Point Cloud

Points Tile Format: https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/PointCloud

In the current implementation, the Pnts class only contains a FeatureTable (FeatureTableHeader and a FeatureTableBody, which contains features of type Feature).

How to read a .pnts file

>>> from py3dtiles import TileReader
>>> from py3dtiles import Pnts
>>>
>>> filename = 'tests/pointCloudRGB.pnts'
>>>
>>> # read the file
>>> tile = TileReader().read_file(filename)
>>>
>>> # tile is an instance of the Tile class
>>> tile
<py3dtiles.tile.Tile>
>>>
>>> # extract information about the tile header
>>> th = tile.header
>>> th
<py3dtiles.tile.TileHeader>
>>> th.magic_value
'pnts'
>>> th.tile_byte_length
15176
>>>
>>> # extract the feature table
>>> ft = tile.body.feature_table
>>> ft
<py3dtiles.feature_table.FeatureTable
>>>
>>> # display feature table header
>>> ft.header.to_json()
{'RTC_CENTER': [1215012.8828876738, -4736313.051199594, 4081605.22126042],
'RGB': {'byteOffset': 12000}, 'POINTS_LENGTH': 1000, 'POSITION': {'byteOffset': 0}}
>>>
>>> # extract positions and colors of the first point
>>> f = ft.feature(0)
>>> f
<py3dtiles.feature_table.Feature>
>>> f.positions
{'Y': 4.4896851, 'X': 2.19396, 'Z': -0.17107764}
>>> f.colors
{'Green': 243, 'Red': 44, 'Blue': 209}

How to write a .pnts file

To write a Point Cloud file, you have to build a numpy array with the corresponding data type.

>>> from py3dtiles import Feature
>>> import numpy as np
>>>
>>> # create the numpy dtype for positions with 32-bit floating point numbers
>>> dt = np.dtype([('X', '<f4'), ('Y', '<f4'), ('Z', '<f4')])
>>>
>>> # create a position array
>>> position = np.array([(4.489, 2.19, -0.17)], dtype=dt)
>>>
>>> # create a new feature from a uint8 numpy array
>>> f = Feature.from_array(dt, position.view('uint8'))
>>> f
<py3dtiles.feature_table.Feature>
>>> f.positions
{'Y': 2.19, 'X': 4.489, 'Z': -0.17}
>>>
>>> # create a tile directly from our feature. None is for "no colors".
>>> t  = Pnts.from_features(dt, None, [f])
>>>
>>> # the tile is complete
>>> t.body.feature_table.header.to_json()
{'POINTS_LENGTH': 1, 'POSITION': {'byteOffset': 0}}
>>>
>>> # to save our tile as a .pnts file
>>> t.save_as("mypoints.pnts")

Batched 3D Model

Batched 3D Model Tile Format: https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/Batched3DModel

How to read a .b3dm file

>>> from py3dtiles import TileReader
>>> from py3dtiles import B3dm
>>>
>>> filename = 'tests/dragon_low.b3dm'
>>>
>>> # read the file
>>> tile = TileReader().read_file(filename)
>>>
>>> # tile is an instance of the Tile class
>>> tile
<py3dtiles.tile.Tile>
>>>
>>> # extract information about the tile header
>>> th = tile.header
>>> th
<py3dtiles.b3dm.B3dmHeader>
>>> th.magic_value
'b3dm'
>>> th.tile_byte_length
47246
>>>
>>> # extract the glTF
>>> gltf = tile.body.glTF
>>> gltf
<py3dtiles.gltf.GlTF>
>>>
>>> # display gltf header's asset field
>>> gltf.header['asset']
{'premultipliedAlpha': True, 'profile': {'version': '1.0', 'api': 'WebGL'}, 'version': '1.0', 'generator': 'OBJ2GLTF'}

How to write a .b3dm file

To write a Batched 3D Model file, you have to import the geometry from a wkb file containing polyhedralsurfaces or multipolygons.

>>> import numpy as np
>>> from py3dtiles import GlTF
>>>
>>> # load a wkb file
>>> wkb = open('tests/building.wkb', 'rb').read()
>>>
>>> # define the geometry's bouding box
>>> box = [[-8.75, -7.36, -2.05], [8.80, 7.30, 2.05]]
>>>
>>> # define the geometry's world transformation
>>> transform = np.array([
...             [1, 0, 0, 1842015.125],
...             [0, 1, 0, 5177109.25],
...             [0, 0, 1, 247.87364196777344],
...             [0, 0, 0, 1]], dtype=float)
>>> transform.flatten('F')
>>>
>>> # generate the glTF part from the wkb file.
>>> # notice that from_wkb accepts array of wkbs and boxes for batching purposes.
>>> gltf = GlTF.from_wkb([wkb], [box], transform)
>>>
>>> # create a b3dm tile directly from the glTF.
>>> t = B3dm.from_glTF(glTF)
>>>
>>> # to save our tile as a .b3dm file
>>> t.save_as("mymodel.b3dm")

Third party assets

Dragon model from Analytical Graphics Inc.'s 3d-tiles samples

About

Python module to manage 3DTiles format

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 100.0%