TikZ (.tikz)
TikZ/PGF output — a 2-D drawing of the mesh cells as a LaTeX figure, written and read back, not a mesh format: the reader parses only the structure meshio++'s own writer emits. Flat 2D meshes draw directly; genuinely 3D meshes are rendered: the boundary skin of any volume cells is extracted (see extract_skin) and projected through an orthographic camera, drawn back-to-front. By default it emits a standalone, directly pdflatex-compilable document; it can also emit a bare tikzpicture snippet for \input into a larger LaTeX document. It is the LaTeX counterpart to the SVG writer (the project logo — the Stanford bunny — is produced through this machinery, see doc/logo/gen_logo_tikz.py).
| Format name | tikz |
| Extensions | .tikz |
| Read / Write | ✓ (a 2-D drawing, planar) / ✓ |
| Extra dependencies | — |
Reading & writing
meshioplusplus.tikz.read(path, strict=True) reads a figure back (see Reading). Full write signature:
import meshioplusplus
meshioplusplus.tikz.write(
"out.tikz", mesh,
float_fmt=".6f",
standalone=True,
line_width=None,
fill="gray!30",
draw="black",
scale=None,
azimuth=45.0,
elevation=35.264389682754654,
roll=0.0,
color_by=None,
component=None,
cmap="viridis",
vmin=None,
vmax=None,
nan_color="gray",
colorbar=False,
)float_fmt— coordinate number format.standalone— ifTrue(default), wrap thetikzpicturein a full\documentclass{standalone}+\usepackage{tikz}document that compiles directly withpdflatex. IfFalse, emit only the\begin{tikzpicture}…\end{tikzpicture}environment for\inputinto an existing document.line_width— TikZ line width for edges, e.g."0.4pt"; ifNone(default), TikZ's own default width is used. When set it is applied both on thetikzpictureoptions and on each\draw.fill— xcolor fill spec for the filled faces (triangles/quads), e.g."gray!30","blue!20".draw— xcolor spec for the edge stroke.scale— optional\begin{tikzpicture}[scale=…]factor; ifNone(default), coordinates are emitted verbatim and noscalekey is added.azimuth/elevation/roll— orthographic camera angles in degrees, used only for genuinely 3D input; same semantics and defaults (the classic CAD isometric view) as the SVG writer.color_by…colorbar— data-driven colouring, see below. Withcolor_byunset (the default) the output is byte-identical to previous releases.
Data-driven colouring
color_by names a point_data or cell_data array; each filled face then carries its own fill= colour instead of the flat fill spec. The rules are exactly the SVG writer's — the two share one resolution layer — so only the differences are repeated here.
meshioplusplus.tikz.write(
"quality.tikz",
meshioplusplus.attach_quality(mesh),
color_by="quality:scaled_jacobian",
cmap="viridis",
colorbar=True,
)- Colours are emitted in xcolor's inline RGB form,
fill={rgb,255:red,68;green,1;blue,84}. The braces are required and always present: without them the commas inside would split the surrounding\draw[…]option list. nan_colortakes an xcolor spec (default"gray"), not a hex string — e.g."red!50". It is emitted verbatim.colorbarappends 32\fill[…] (x0,y0) rectangle (x1,y1);swatches plus two\node[anchor=west, font=\tiny]labels to the right of the drawing's bounding box. TikZ has no viewBox, so unlike SVG nothing at all about the mesh changes — the bar is a pure insertion before\end{tikzpicture}.linecells are never filled, so they are never coloured.
Reading
meshioplusplus.tikz.read(path, points_only=False, arrays=None, strict=True) (and read_tikz in C++, mio_read in the flat bindings) is the exact inverse of the writer and nothing more. A drawing is not a mesh, so anything else in the file, such as another tool's figure or a hand edit, is a ReadError naming the construct, never a guess.
- Cells. One
\draw[…] (x,y) -- … -- cycle;is a face (3 vertices atriangle, 4 aquad, more apolygon) and\draw[…] (x,y) -- (x,y);aline. Consecutive cells of one type and size form one block, so a flat write comes back block for block. The optionalstandalonewrapper and thetikzpictureoptions (scale=,line width=) are accepted; the picture scale is not applied. - Points are welded on the exact text of their coordinates, in order of first appearance. Coordinates are taken verbatim and TikZ has no y-flip, so planar input comes back exactly in x and y, to the digits
float_fmtkept (".17g"is lossless). Nothing in the file says two paths share a vertex, so a mesh's numbering and unused points are not recovered. zis 0. A 3-D mesh was drawn projected, and what comes back is that picture. The read warns once, either "planar drawing, z = 0 assumed" or "projected from 3-D (azimuth, elevation, roll), depth lost".- Fills. A
fill={rgb,255:red,R;green,G;blue,B}comes back as the cell arraytikz:fill(int32, shape(n, 3),-1 -1 -1for a cell whose fill is not an RGB literal, such as the flatgray!30, the NaN colour or a line), present only when some path has one. It is the colour, never the data it was coloured from. The colour bar (\fill … rectangleand\node) is skipped. - Refused:
\path,plot,circle,.. controls ..,to, named, polar, calc, unit-carrying and 3-D coordinates, relative (+,++) coordinates,\foreach,\drawoptions other thanfill,drawandline width, othertikzpictureoptions, more than one picture, and every command other than\documentclass,\usepackage,\begin/\end,\draw, the colour-bar\filland\node. - The marker. A file without the marker comment is refused, because only meshio++'s own drawings are read back;
strict=False(ReadOptions::mLenient,mio_read_opts.lenient,--lenienton the native CLI) reads it as a plain drawing with a warning. Files written by a release before the marker lack it too.points_onlyandarraysdroptikz:fill. - The C++ reader and the Python twin return identical meshes (
tests/python/test_tikz.pyreads every file through both and compares them), and a refusal in one is a refusal in the other.
3D input
A mesh whose points have a non-zero z extent takes the 3D rendering path: supported volume cells are skin-extracted first (extract_skin(mesh, linearize=True)); a 3D shell mesh is projected as-is (triangle6/quad8/quad9 corner-linearized). Faces are sorted back-to-front by view-space centroid depth (painter's algorithm) and drawn with the same \draw templates as the flat path — nearer filled faces cover the hidden edges of farther ones. No backface culling, no shading in v1.
File structure
The file opens with the marker, % comment lines: the provenance tag Written by meshio++ v…, one line Drawing: planar (or Drawing: projected azimuth=A elevation=E roll=R for a projected 3-D mesh), then whatever else the provenance block carries. It is there under every provenance mode, and C++ and Python write it byte for byte. Then one \draw command per drawable cell inside a single tikzpicture environment. Each cell's vertices are emitted as (x,y) coordinate pairs (float_fmt-formatted) joined by TikZ's -- path operator:
| cell type | \draw template |
|---|---|
line | \draw[draw=…] (x0,y0) -- (x1,y1); (open, no cycle) |
triangle | \draw[fill=…, draw=…] (x0,y0) -- (x1,y1) -- (x2,y2) -- cycle; |
quad | \draw[fill=…, draw=…] (x0,y0) -- (x1,y1) -- (x2,y2) -- (x3,y3) -- cycle; |
If points.shape[1] == 3 and every z coordinate is ~0 (atol=1e-14), the mesh is treated as flat 2D and drawn exactly as in previous releases (byte-identical); otherwise the 3D projected path above applies.
Unlike the SVG writer, the y-coordinate is not flipped — TikZ/PGF already uses the math convention (y grows upward), so mesh (or projected) coordinates map straight onto the canvas.
Cell types
line, triangle, quad (plus, on the 3D path, corner-linearized triangle6/quad8/quad9 and the volume types accepted by extract_skin). Any other cell block present in the mesh is dropped with a warning naming it (matching the SVG writer's behaviour).
Data mapping
No data array is written to the file. One array can be read to drive the face colours via color_by (see above); everything else — and all of field_data — is ignored, so only geometry and connectivity affect an uncoloured figure.
Quirks & limitations
- No winding correction on
quadcells — a "crossed" (bowtie) node ordering renders incorrectly with no error raised. - Unsupported cells are dropped from the output with a warning naming them.
- The painter's algorithm sorts whole faces by centroid depth — mutually intersecting faces (which a closed skin never has) can stack in the wrong order; there is no per-pixel depth test.
- Reading is limited to meshio++'s own figures, as planar meshes: see Reading.
- Colouring is a Python + C++-direct + CLI feature. The C API, Fortran and WebAssembly surfaces reach this writer through the shared registry, whose
(path, mesh)writer entries structurally cannot carry parameters, so they always emit the fixed default styling — a documented gap of the same kind as the point/cell-set gaps indiff/merge/split. - Only one array can drive the colours; there is no multi-field or per-block colouring.
- The colorbar's labels are the range endpoints only — there are no intermediate ticks.
Notes
- Backed by the C++ core (
write_tikz) with a pure-Python fallback:meshioplusplus.tikz.writeuses the C++ writer for real file paths and falls back to Python for file-object/buffer targets or on any error. The C++ writer is byte-for-byte identical to the Python reference — including the 3D projected path (the camera arithmetic indetail/projection.hppand_projection.pyis kept expression-for-expression identical for this reason). Registered in the shared dispatch registry, so it is also reachable from the WASM, C API, and Fortran flat bindings (fixed default styling, the default isometric camera and no colouring; the flat surface always emits the standalone document). tests/python/test_tikz.pychecks the document/tikzpicturewrappers and\drawcount, cross-checks the C++ and Python writers are byte-identical (2D, 3D and coloured, across a matrix of colouring options), and covers thestandalone=Falsesnippet, volume-skin rendering, camera angles, the golden colour spelling,nan_color, clamping and the append-only colorbar.tests/cpp/test_svg_tikz.cppcovers the C++ writer directly (standalone vs snippet, filled faces vs open lines,\drawcount, style/scale options, the projected 3D paths).