{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Getting Started with Meshes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Before you start!\n",
    "\n",
    "- This [notebook](getting-started-with-meshes.ipynb) assumes that shapeworks conda environment has been activated using `conda activate shapeworks` on the terminal.\n",
    "- See [Setting Up ShapeWorks Environment](setting-up-shapeworks-environment.ipynb) to learn how to set up your environment to start using shapeworks library. Please note, the prerequisite steps will use the same code to setup the environment for this notebook and import `shapeworks` library.\n",
    "- Note example output was generated on Linux/Mac environment and may look different on Windows.\n",
    "\n",
    "\n",
    "## In this notebook, you will learn:\n",
    "\n",
    "1. How to define your dataset location and explore what is available in it\n",
    "2. How to load a single mesh \n",
    "3. How to convert `shapeworks` mesh to `vtk` mesh for visualization\n",
    "4. How to visualize a surface mesh using `pyvista`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Importing `shapeworks` library"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import shapeworks as sw"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Defining and exploring your dataset\n",
    "\n",
    "### Defining dataset location\n",
    "\n",
    "You can download exemplar datasets from [ShapeWorks data portal](https://girder.shapeworks-cloud.org) after you login. For new users, you can [register](https://girder.shapeworks-cloud.org/#?dialog=register) an account for free. Please do not use an important password.\n",
    "\n",
    "After you login, click `Collections` on the left panel and then `use-case-data-v2`. Select the dataset you would like to download by clicking on the checkbox on the left of the dataset name. See the video below.\n",
    "\n",
    "**This notebook assumes that you have downloaded `ellipsoid_1mode` and you have placed the unzipped folder`ellipsoid_1mode`in `Examples/Python/Data`.** Feel free to use your own dataset. \n",
    "\n",
    "\n",
    "<p><video src=\"https://sci.utah.edu/~shapeworks/doc-resources/mp4s/portal_data_download.mp4\" autoplay muted loop controls style=\"width:100%\"></p>\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os # for paths and mkdir\n",
    "\n",
    "# dataset name is the folder name for your dataset\n",
    "datasetName  = 'ellipsoid_1mode'\n",
    "\n",
    "# path to the dataset where we can find shape data \n",
    "# here we assume shape data are given as surface meshes\n",
    "shapeDir      = '../../Data/' + datasetName + '/meshes/'\n",
    "    \n",
    "print('Dataset Name:     ' + datasetName)\n",
    "print('Shape Directory:  ' + shapeDir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### What is available in the dataset?\n",
    "\n",
    "First let's see how many shapes we have in the dataset.\n",
    "\n",
    "**File formats:** For surface meshes, all vtk-supported mesh formats can be used (e.g., vtk, ply, and stl)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import glob # for paths and file-directory search\n",
    "from pathlib import Path # for generating robust paths irrespective of the platform:Win/Linux/Mac\n",
    "# file extension for the shape data\n",
    "shapeExtention = '.vtk'\n",
    "\n",
    "# let's get a list of files for available meshes in this dataset\n",
    "# * here is a wild character used to retrieve all filenames \n",
    "# in the shape directory with the file extensnion\n",
    "shapeFilenames = sorted(glob.glob(shapeDir + '*' + shapeExtention)) \n",
    "\n",
    "print ('Number of shapes: ' + str(len(shapeFilenames)))\n",
    "print('Shape files found:')\n",
    "for shapeFilename in shapeFilenames:\n",
    "    shapeFilename = Path(shapeFilename)\n",
    "    print(shapeFilename)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Loading a single mesh\n",
    "\n",
    "We will select one mesh to explore for now. We will then use `shapeworks` Mesh class to load this surface mesh and print out its header information that includes ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# select a shape by setting the shape index (in the filenames list)\n",
    "shapeIdx       = 0\n",
    "\n",
    "# the filename for the selected shape\n",
    "shapeFilename  = shapeFilenames[shapeIdx]\n",
    "\n",
    "# use shapeworks Mesh class to load it\n",
    "print('Loading: ' + shapeFilename)\n",
    "shapeMesh = sw.Mesh(shapeFilename)\n",
    "\n",
    "# let's print out header information of this mesh - TODO: #828 \n",
    "print('Header information: ')\n",
    "print(shapeMesh)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Convert to a VTK mesh\n",
    "\n",
    "To visualize a `shapeworks` mesh with `pyvista`, we need first to convert it to a `vtk` mesh. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# convert shapeworks mesh to a vtk mesh\n",
    "shapeMesh_vtk = sw.sw2vtkMesh(shapeMesh)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Visualizing surface mesh using `pyvista`\n",
    "\n",
    "[`pyvista`](https://docs.pyvista.org/index.html) is a python library for 3D visualization and analysis. It is built on top of `vtk` and brings a paraview-like visualizations to notebooks. It also supports multiple rendering windows that can be linked. This feature is very useful when visualizing multiple samples from your dataset side-by-side and making them share the same camera view."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# to have an interactive visualization, \n",
    "# click r to reset the view after zooming\n",
    "# click w to show wireframe and s to return back to sur\n",
    "notebook = False # True sets the figure inline in the notebook.\n",
    "shapeMesh_vtk.plot(notebook = notebook) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p><img src=\"https://sci.utah.edu/~shapeworks/doc-resources/pngs/mesh.png\"></p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Visualizing multiple meshes\n",
    "\n",
    "When exploring datasets and results of different grooming (data preprocessing) steps, it is important to simultaneously visualize multiple shape samples. Here, we visualize two meshes side-by-side and link their views using `pyvista`. This linking is useful to make all rendering windows share the same camera view.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading the second mesh and convert it to `vtk` mesh\n",
    "\n",
    "First, let's select another mesh and load it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# select a shape by setting the shape index (in the filenames list)\n",
    "shapeIdx2       = 1\n",
    "\n",
    "# the filename for the selected shape\n",
    "shapeFilename2  = shapeFilenames[shapeIdx2]\n",
    "\n",
    "# use shapeworks Mesh class to load it\n",
    "print('Loading: ' + shapeFilename2)\n",
    "shapeMesh2 = sw.Mesh(shapeFilename2)\n",
    "\n",
    "# let's print out header information of this mesh \n",
    "print('Header information: ')\n",
    "print(shapeMesh2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can view the two meshes side by side using the ShapeWorks plot_meshes() function. \n",
    "To view the meshes in a side-by-side view, we set the use_same_window parameter to False.\n",
    "To view the meshes in the same window, we set the use_same_window parameter to True. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "meshList = [shapeMesh, shapeMesh2]\n",
    "# View meshes side-by-side\n",
    "sw.plot_meshes(meshList, use_same_window=False, notebook=notebook)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p><img src=\"https://sci.utah.edu/~shapeworks/doc-resources/pngs/two_window_meshes.png\"></p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# View meshes in the same window\n",
    "sw.plot_meshes(meshList, use_same_window=True, notebook=notebook)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p><img src=\"https://sci.utah.edu/~shapeworks/doc-resources/pngs/one_window_meshes.png\"></p>"
   ]
  }
 ],
 "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.7.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
