{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Constructing a CartesianMesh\n\nThis example demonstrates how to build a\n:class:`~pyvisual.core.mesh3d.CartesianMesh` from NumPy arrays and how to\nconvert a :class:`~pyvisual.core.mesh3d.SphericalMesh` to Cartesian\ncoordinates for direct PyVista rendering.\n\n:class:`~pyvisual.core.mesh3d.CartesianMesh` wraps\n:class:`pyvista.StructuredGrid` with a Cartesian-frame tag.  Because the\nunderlying grid type is a structured grid (not a rectilinear grid), the three\ncoordinate arrays must be 3-D meshgrids of identical shape, not independent\n1-D axis vectors.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nfrom pyvisual import Plot3d\nfrom pyvisual.core.mesh3d import CartesianMesh, SphericalMesh"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Building from 3-D Meshgrid Arrays\n\nCreate a :class:`~pyvisual.core.mesh3d.CartesianMesh` from a regular\nCartesian grid.  Each coordinate array must have the same 3-D shape.\nHere we build a sphere of radial-distance data, which is everywhere equal\nto $\\sqrt{x^2 + y^2 + z^2}$.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "x = np.linspace(-5, 5, 15)\ny = np.linspace(-5, 5, 15)\nz = np.linspace(-5, 5, 15)\nX, Y, Z = np.meshgrid(x, y, z, indexing='ij')\ndist = np.sqrt(X ** 2 + Y ** 2 + Z ** 2)\n\nmesh = CartesianMesh(X, Y, Z, data=dist, dataid='r')\nprint(f\"dimensions : {mesh.dimensions}\")\nprint(f\"data range : [{mesh.data.min():.2f}, {mesh.data.max():.2f}]\")\n\nplotter = Plot3d()\nplotter.show_axes()\nplotter.add_sun()\nplotter.add_mesh(mesh, cmap='plasma', opacity=0.3, show_scalar_bar=False)\nplotter.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Converting a SphericalMesh to Cartesian\n\n:meth:`~pyvisual.core.mesh3d.SphericalMeshFilters.spherical_to_cartesian`\ncasts a :class:`~pyvisual.core.mesh3d.SphericalMesh` to a\n:class:`pyvista.StructuredGrid` with Cartesian point coordinates.  The\nresulting dataset can be wrapped in a :class:`~pyvisual.core.mesh3d.CartesianMesh`\nfor continued processing with the filter API, or added directly to the\nplotter.\n\nThis conversion is useful when you want to apply Cartesian-space filters\n(such as PyVista's ``clip``, ``threshold``, or ``extract_surface``) to data\nthat was originally defined on a spherical grid.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "r = np.linspace(1, 5, 10)\nt = np.linspace(0, np.pi, 20)\np = np.linspace(0, 2 * np.pi, 40)\nR, T, P = np.meshgrid(r, t, p, indexing='ij')\nBr = np.cos(T) / R ** 2\n\nsph_mesh = SphericalMesh(r, t, p, data=Br, dataid='Br')\ncart_struct = sph_mesh.spherical_to_cartesian()\ncart_mesh = CartesianMesh(cart_struct)\n\nprint(f\"SphericalMesh frame : {sph_mesh.user_dict['MESH_FRAME']}\")\nprint(f\"CartesianMesh frame : {cart_mesh.user_dict['MESH_FRAME']}\")\n\nplotter = Plot3d()\nplotter.show_axes()\nplotter.add_sun()\nplotter.add_mesh(cart_mesh, cmap='seismic', opacity=0.4, show_scalar_bar=False)\nplotter.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.13.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}