{ "cells": [ { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "# Mesh I/O and manipulation" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "nbsphinx": "hidden", "tags": [] }, "outputs": [], "source": [ "import drjit as dr\n", "import mitsuba as mi\n", "\n", "mi.set_variant(\"llvm_ad_rgb\")" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Reading a mesh from disk\n", "\n", "Mitsuba provides an abstract `Shape` class to handle all geometric shapes. For triangle meshes, it has a concrete class `Mesh` that is further extended by 3 plugins which can load meshes directly from a file:\n", "\n", "- [OBJ][1]: handles meshes containing triangles and quadrilaterals from Wavefront OBJ files\n", "- [PLY][2]: handles Stanford PLY format meshes (both the ASCII and binary format)\n", "- [Serialized][3]: Mitsuba 0.6 serialized mesh format.\n", "\n", "As any other Mitsuba object, we can use the `load_dict` function to instantiate one of these three plugins. They each have their own specific input parameters which you'll find in their respective documentation, but here are the input parameters they all share:\n", "\n", "- **filename**: filename of the mesh file that should be loaded\n", "- **face_normals**: when set to true, any existing or computed vertex normals are discarded and face normals will instead be used during rendering. This gives the rendered object a faceted appearance.\n", "- **to_world**: specifies an linear object-to-world transformation. \n", "\n", "Let's now load a mesh and start playing with it.\n", "\n", "[1]: https://mitsuba.readthedocs.io/en/latest/src/generated/plugins_shapes.html#wavefront-obj-mesh-loader-obj\n", "[2]: https://mitsuba.readthedocs.io/en/latest/src/generated/plugins_shapes.html#ply-stanford-triangle-format-mesh-loader-ply\n", "[3]: https://mitsuba.readthedocs.io/en/latest/src/generated/plugins_shapes.html#serialized-mesh-loader-serialized" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PLYMesh[\n", " name = \"bunny.ply\",\n", " bbox = BoundingBox3f[\n", " min = [-0.0785918, -0.0623055, -0.0730216],\n", " max = [0.0868213, 0.0980685, 0.0476517]\n", " ],\n", " vertex_count = 208349,\n", " vertices = [4.77 MiB of vertex data],\n", " face_count = 69451,\n", " faces = [814 KiB of face data],\n", " face_normals = 0\n", "]\n" ] } ], "source": [ "bunny = mi.load_dict({\n", " \"type\": \"ply\",\n", " \"filename\": \"../scenes/meshes/bunny.ply\",\n", " \"face_normals\": False,\n", " \"to_world\": mi.ScalarTransform4f.rotate([0, 0, 1], angle=10),\n", "})\n", "\n", "print(bunny)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The string representation of a `Mesh` object gives an overview of its size. If you wish to access some of these values, they are available through the following methods `Shape.bbox()`, `Mesh.vertex_count()`, `Mesh.face_count()`." ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Procedural mesh \n", "\n", "By directly using the `Mesh` class, it is also possible to procedurally create a mesh. To illustrate this, we will build a spanning triangle disk and give it a wavy fringe. The exact details of how the vertex positions and face indices are generated are not important for the purposes of this guide. However, we do leave them as comments in the code." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Wavy disk construction\n", "#\n", "# Let N define the total number of vertices, the first N-1 vertices will compose\n", "# the fringe of the disk, while the last vertex should be placed at the center.\n", "# The first N-1 vertices must have their height modified such that they oscillate\n", "# with some given frequency and amplitude. To compute the face indices, we define\n", "# the first vertex of every face to be the vertex at the center (idx=N-1) and the\n", "# other two can be assigned sequentially (modulo N-2).\n", "\n", "# Disk with a wavy fringe parameters\n", "N = 100\n", "frequency = 12.0\n", "amplitude = 0.4\n", "\n", "# Generate the vertex positions\n", "theta = dr.linspace(mi.Float, 0.0, dr.two_pi, N)\n", "x, y = dr.sincos(theta)\n", "z = amplitude * dr.sin(theta * frequency)\n", "vertex_pos = mi.Point3f(x, y, z)\n", "\n", "# Move the last vertex to the center\n", "vertex_pos[dr.eq(dr.arange(mi.UInt32, N), N - 1)] = 0.0\n", "\n", "# Generate the face indices\n", "idx = dr.arange(mi.UInt32, N - 1)\n", "face_indices = mi.Vector3u(N - 1, (idx + 1) % (N - 2), idx % (N - 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `Mesh` constructor allocates all the necessary buffers to hold its data. Specifically, the constructor takes as arguments the number of vertices and faces which will then be fixed. It is not possible to edit a mesh in a way that would require the buffers to be resized (more/less faces for examples), a new `Mesh` would need to be created for such use cases.\n", "The constructor can also takes two boolean arguments `has_vertex_normals` and `has_vertex_texcoords` that must also be know at the construction of the object, in order to allocate the appropriate buffers." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Create an empty mesh (allocates buffers of the correct size)\n", "mesh = mi.Mesh(\n", " \"wavydisk\",\n", " vertex_count=N,\n", " face_count=N - 1,\n", " has_vertex_normals=False,\n", " has_vertex_texcoords=False,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In order to assign our existing vertex positions and face indices to the newly created `Mesh` object we will use the `traverse()` mechanism. All of the allocated buffers of a `Mesh` object are exposed, and can therefore be modified with this mechanism. This approach has the advantage of simplifying some of the assignment operations. In addition, if any vertex position is modified, a call to `SceneParameters.update()` will trigger recomputation of both the bounding box and vertex normals.\n", "\n", "One caveat here is that meshes in Mitsuba store their data in **flat linear buffers**. Hence it is necessary to change the layout of the array of vertex positions and face indices computed above. Luckily, Dr.Jit provides `dr.ravel()` which does exactly that. The complement of this function is `dr.unravel()` which will convert a flat linear array to a structure-of-array of the specific type (e.g., `Point3f`)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(Mesh[\n", " name = \"wavydisk\",\n", " bbox = BoundingBox3f[\n", " min = [-0.999874, -0.999497, -0.399547],\n", " max = [0.999874, 1, 0.399547]\n", " ],\n", " vertex_count = 100,\n", " vertices = [1.17 KiB of vertex data],\n", " face_count = 99,\n", " faces = [1.16 KiB of face data],\n", " face_normals = 0\n", "], {'faces', 'vertex_positions'})]\n" ] } ], "source": [ "mesh_params = mi.traverse(mesh)\n", "mesh_params[\"vertex_positions\"] = dr.ravel(vertex_pos)\n", "mesh_params[\"faces\"] = dr.ravel(face_indices)\n", "print(mesh_params.update())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now let's take a look at our new mesh!" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "scene = mi.load_dict({\n", " \"type\": \"scene\",\n", " \"integrator\": {\"type\": \"path\"},\n", " \"light\": {\"type\": \"constant\"},\n", " \"sensor\": {\n", " \"type\": \"perspective\",\n", " \"to_world\": mi.ScalarTransform4f.look_at(\n", " origin=[0, -5, 5], target=[0, 0, 0], up=[0, 0, 1]\n", " ),\n", " },\n", " \"wavydisk\": mesh,\n", "})\n", "\n", "img = mi.render(scene)\n", "\n", "from matplotlib import pyplot as plt\n", "\n", "plt.axis(\"off\")\n", "plt.imshow(mi.util.convert_to_bitmap(img));" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Writing a mesh to disk\n", "\n", "No matter how a `Mesh` object was loaded or built, it can always be exported to a [PLY file format](https://en.wikipedia.org/wiki/PLY_(file_format)) using the `Mesh.write_ply()` method. No other file formats are currently supported.\n", "\n", "
\n", "\n", "🗒 **Note**\n", "\n", "Any mesh attribute (see below) that is attached to the object at the time when `Mesh.write_ply()` is called will be written to output file as a property. Mitsuba therefore allows you to create complex procedural properties for your meshes and export them to be used in some other context entirely.\n", "
" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "mesh.write_ply(\"wavydisk.ply\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adding and editing attributes\n", "\n", "Meshes in Mitsuba can have additional attributes per face or per vertex. Each attribute is either one or several floating point numbers, no other types are supported.\n", "\n", "The `Mesh.add_attribute()` methods lets you define new attributes by giving them a name, a number of feilds, and their initial values. The attribute name must be prefixed with either `vertex_` or `face_`, as this defines whether the attribute is defined for each face or for each vertex. For this example, we will be adding a RGB color to each vertex. \n", "\n", "Moreover, Mitsuba 3 has a [mesh attribute][1] texture plugin that conviently allows you to visualize attributes.\n", "\n", "[1]: https://mitsuba.readthedocs.io/en/latest/src/generated/plugins_textures.html#mesh-attribute-texture-mesh-attribute" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "mesh = mi.load_dict({\n", " \"type\": \"ply\",\n", " \"filename\": \"wavydisk.ply\",\n", " \"bsdf\": {\n", " \"type\": \"diffuse\",\n", " \"reflectance\": {\n", " \"type\": \"mesh_attribute\",\n", " \"name\": \"vertex_color\", # This will be used to visualize our attribute\n", " },\n", " },\n", "})\n", "\n", "# Needs to start with vertex_ or face_\n", "attribute_size = mesh.vertex_count() * 3\n", "mesh.add_attribute(\n", " \"vertex_color\", 3, [0] * attribute_size\n", ") # Add 3 floats per vertex (initialized at 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once an attribute is created it can still be modified using the `traverse()` mechanism. As shown below, the attribute's buffer will be exposed with a key corresponding to the attribute's name." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SceneParameters[\n", " ----------------------------------------------------------------------------------------\n", " Name Flags Type Parent\n", " ----------------------------------------------------------------------------------------\n", " bsdf.reflectance.scale float MeshAttribute\n", " vertex_count int PLYMesh\n", " face_count int PLYMesh\n", " faces UInt PLYMesh\n", " vertex_positions ∂, D Float PLYMesh\n", " vertex_normals ∂, D Float PLYMesh\n", " vertex_texcoords ∂ Float PLYMesh\n", " vertex_color ∂ Float PLYMesh\n", "]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mesh_params = mi.traverse(mesh)\n", "mesh_params" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now easily change the values of the attribute using some simple Dr.Jit arithmetic." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(PLYMesh[\n", " name = \"wavydisk.ply\",\n", " bbox = BoundingBox3f[\n", " min = [-0.999874, -0.999497, -0.399547],\n", " max = [0.999874, 1, 0.399547]\n", " ],\n", " vertex_count = 100,\n", " vertices = [3.52 KiB of vertex data],\n", " face_count = 99,\n", " faces = [1.16 KiB of face data],\n", " face_normals = 0,\n", " mesh attributes = [\n", " vertex_color: 3 floats\n", " ]\n", " ],\n", " {'vertex_color'})]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N = mesh.vertex_count()\n", "\n", "vertex_colors = dr.zeros(mi.Float, 3 * N)\n", "fringe_vertex_indices = dr.arange(mi.UInt, N - 1)\n", "dr.scatter(vertex_colors, 1, fringe_vertex_indices * 3) # Fringe is red\n", "dr.scatter(vertex_colors, 1, [(N - 1) * 3 + 2]) # Center is blue\n", "\n", "mesh_params[\"vertex_color\"] = vertex_colors\n", "mesh_params.update()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And visualize the result!" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "scene = mi.load_dict(\n", " {\n", " \"type\": \"scene\",\n", " \"integrator\": {\"type\": \"path\"},\n", " \"light\": {\"type\": \"constant\"},\n", " \"sensor\": {\n", " \"type\": \"perspective\",\n", " \"to_world\": mi.ScalarTransform4f.look_at(\n", " origin=[0, -5, 5], target=[0, 0, 0], up=[0, 0, 1]\n", " ),\n", " },\n", " \"wavydisk\": mesh,\n", " }\n", ")\n", "\n", "img = mi.render(scene)\n", "\n", "plt.axis(\"off\")\n", "plt.imshow(mi.util.convert_to_bitmap(img));" ] } ], "metadata": { "file_extension": ".py", "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.13" }, "metadata": { "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" } }, "mimetype": "text/x-python", "name": "python", "npconvert_exporter": "python", "pygments_lexer": "ipython3", "version": 3 }, "nbformat": 4, "nbformat_minor": 4 }