
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/07_mesh_export.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_07_mesh_export.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_07_mesh_export.py:


Mesh Export
===========

Block models can be exported as triangulated surface meshes.

PLY is the canonical format for lossless storage — it preserves all vertex
and face attributes together with geometry metadata. GLB (glTF 2.0 binary)
is a derived format suited for exchange with 3D viewers and optionally
carries vertex colours derived from a scalar attribute.

.. GENERATED FROM PYTHON SOURCE LINES 13-19

.. code-block:: Python


    import tempfile
    from pathlib import Path

    from parq_blockmodel import ParquetBlockModel








.. GENERATED FROM PYTHON SOURCE LINES 20-24

Create a Block Model
--------------------
Use the toy block-model helper to create a 5 × 5 × 5 dense model with a
synthetic ellipsoidal grade distribution.

.. GENERATED FROM PYTHON SOURCE LINES 24-39

.. code-block:: Python


    temp_dir = Path(tempfile.gettempdir()) / "mesh_export_example"
    temp_dir.mkdir(parents=True, exist_ok=True)

    pbm: ParquetBlockModel = ParquetBlockModel.create_toy_blockmodel(
        filename=temp_dir / "sample.parquet",
        shape=(5, 5, 5),
        block_size=(10.0, 10.0, 10.0),
        corner=(0.0, 0.0, 0.0),
        grade_name="grade",
        grade_min=50.0,
        grade_max=100.0,
    )
    pbm





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    ParquetBlockModel(name=sample, path=/tmp/mesh_export_example/sample.pbm)



.. GENERATED FROM PYTHON SOURCE LINES 40-46

Triangulate the Mesh
--------------------
:meth:`~parq_blockmodel.ParquetBlockModel.triangulate` returns a
:class:`~parq_blockmodel.mesh.TriangleMesh` containing vertices, triangle
faces, and per-vertex/face attribute arrays.  By default only the exterior
surface is generated (``surface_only=True``).

.. GENERATED FROM PYTHON SOURCE LINES 46-53

.. code-block:: Python


    mesh = pbm.triangulate(attributes=["grade"], surface_only=True)

    print(f"Vertices : {mesh.n_vertices}")
    print(f"Faces    : {mesh.n_faces}")
    print(f"Attributes: {list(mesh.vertex_attributes.keys())}")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Vertices : 1000
    Faces    : 1500
    Attributes: ['grade']




.. GENERATED FROM PYTHON SOURCE LINES 54-60

Export to PLY
-------------
PLY is the canonical, lossless format.  The file embeds geometry metadata
as comments and writes per-vertex ``i``, ``j``, ``k`` indices alongside
``x``, ``y``, ``z`` so that every vertex can be traced back to its source
block.

.. GENERATED FROM PYTHON SOURCE LINES 60-71

.. code-block:: Python


    ply_path = temp_dir / "sample.ply"
    pbm.to_ply(ply_path, attributes=["grade"])

    # Preview the header of the written file.
    with open(ply_path) as fh:
        for line in fh:
            print(line, end="")
            if line.strip() == "end_header":
                break





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    ply
    format ascii 1.0
    comment corner=(0.0, 0.0, 0.0)
    comment block_size=(10.0, 10.0, 10.0)
    comment shape=(5, 5, 5)
    comment axis_u=(1.0, 0.0, 0.0)
    comment axis_v=(0.0, 1.0, 0.0)
    comment axis_w=(0.0, 0.0, 1.0)
    comment surface_only=True
    comment sparse=False
    element vertex 1000
    property float x
    property float y
    property float z
    property int i
    property int j
    property int k
    property float grade
    element face 1500
    property list uchar int vertex_indices
    property int i
    property int j
    property int k
    property float grade
    end_header




.. GENERATED FROM PYTHON SOURCE LINES 72-78

Export to GLB
-------------
GLB (glTF 2.0 binary) is a single-file exchange format suitable for web
viewers such as Babylon.js, Three.js and Cesium.  Passing
``texture_attribute`` maps that scalar to vertex colours using the
requested Matplotlib colormap.

.. GENERATED FROM PYTHON SOURCE LINES 78-88

.. code-block:: Python


    glb_path = temp_dir / "sample.glb"
    pbm.to_glb(glb_path, texture_attribute="grade", colormap="viridis")

    print(f"GLB file size: {glb_path.stat().st_size:,} bytes")

    # Verify the GLB magic number.
    with open(glb_path, "rb") as fh:
        print(f"GLB magic   : {fh.read(4)}")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    GLB file size: 35,164 bytes
    GLB magic   : b'glTF'




.. GENERATED FROM PYTHON SOURCE LINES 89-97

Rotated Geometry
----------------
Rotation is handled transparently.  The axis vectors stored in
:attr:`~parq_blockmodel.geometry.RegularGeometry.axis_u`,
:attr:`~parq_blockmodel.geometry.RegularGeometry.axis_v` and
:attr:`~parq_blockmodel.geometry.RegularGeometry.axis_w` are applied when
computing world-space vertex coordinates, so no special handling is
required by the caller.

.. GENERATED FROM PYTHON SOURCE LINES 97-117

.. code-block:: Python


    pbm_rot: ParquetBlockModel = ParquetBlockModel.create_toy_blockmodel(
        filename=temp_dir / "rotated.parquet",
        shape=(3, 3, 3),
        block_size=(5.0, 5.0, 5.0),
        corner=(0.0, 0.0, 0.0),
        axis_azimuth=30.0,
        axis_dip=15.0,
        axis_plunge=0.0,
    )

    print(f"axis_u: {pbm_rot.geometry.axis_u}")
    print(f"axis_v: {pbm_rot.geometry.axis_v}")
    print(f"axis_w: {pbm_rot.geometry.axis_w}")

    glb_rot_path = temp_dir / "rotated.glb"
    pbm_rot.to_glb(glb_rot_path, texture_attribute="grade")

    print(f"Rotated GLB file size: {glb_rot_path.stat().st_size:,} bytes")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    axis_u: (0.8660254037844387, 0.49999999999999994, 0.0)
    axis_v: (-0.4829629131445341, 0.8365163037378079, 0.25881904510252074)
    axis_w: (0.12940952255126034, -0.2241438680420134, 0.9659258262890683)
    Rotated GLB file size: 8,692 bytes





.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.188 seconds)


.. _sphx_glr_download_auto_examples_07_mesh_export.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: 07_mesh_export.ipynb <07_mesh_export.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: 07_mesh_export.py <07_mesh_export.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: 07_mesh_export.zip <07_mesh_export.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
