v0.15.5
Loading...
Searching...
No Matches
make_mesh_png.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import argparse
5from glob import glob
6from pathlib import Path
7
8import matplotlib.pyplot as plt
9import numpy as np
10import pyvista as pv
11
12
14 files = []
15 for entry in inputs:
16 matches = sorted(glob(entry))
17 if matches:
18 files.extend(matches)
19 else:
20 files.append(entry)
21 return files
22
23
25 return [file for file in files if file.lower().endswith(".vtk")]
26
27
28def select_field_component(mesh, field_name, component):
29 if field_name in mesh.point_data:
30 data = mesh.point_data[field_name]
31 target = mesh.point_data
32 elif field_name in mesh.cell_data:
33 data = mesh.cell_data[field_name]
34 target = mesh.cell_data
35 else:
36 raise KeyError(f"Field '{field_name}' was not found in point or cell data.")
37
38 values = np.asarray(data)
39 if values.ndim == 1:
40 values = values.reshape(-1, 1)
41 else:
42 values = values.reshape(values.shape[0], -1)
43
44 component_index = component
45
46 if component_index < 0 or component_index >= values.shape[1]:
47 raise ValueError(
48 f"Field '{field_name}' has {values.shape[1]} component(s), "
49 f"so component {component} is out of range. "
50 f"Use 0..{values.shape[1] - 1}."
51 )
52
53 component_name = f"{field_name}[{component_index}]"
54 target[component_name] = values[:, component_index]
55 return component_name
56
57
58def make_png(file, args):
59 my_cmap = plt.cm.get_cmap("turbo", 124)
60 mesh = pv.read(file)
61 output_file = str(Path(file).with_suffix(".png"))
62
63 if args.wrap_vector:
64 mesh = mesh.warp_by_vector(args.wrap_vector, factor=args.wrap_factor)
65
66 plotter = pv.Plotter(notebook=False, off_screen=True)
67 try:
68 if args.field:
69 scalar_name = args.field
70 if args.field_component is not None:
71 scalar_name = select_field_component(
72 mesh, args.field, args.field_component
73 )
74 plotter.add_mesh(
75 mesh,
76 scalars=scalar_name,
77 show_edges=args.show_edges,
78 smooth_shading=False,
79 cmap=my_cmap,
80 )
81 else:
82 plotter.add_mesh(
83 mesh,
84 show_edges=args.show_edges,
85 edge_color="white",
86 color="white",
87 )
88 if args.d2:
89 plotter.camera_position = args.d2
90 plotter.camera.zoom(args.zoom)
91 plotter.camera.roll += args.roll
92 plotter.camera.azimuth += args.azimuth
93 plotter.screenshot(output_file)
94 finally:
95 plotter.close()
96
97
99 try:
100 from pyvirtualdisplay import Display
101 except ImportError:
102 return None
103
104 try:
105 display = Display(backend="xvfb", visible=False, size=(800, 800))
106 display.start()
107 except Exception:
108 return None
109 return display
110
111
112if __name__ == "__main__":
113 parser = argparse.ArgumentParser(
114 description="Convert multiple vtk files to png files using PyVista."
115 )
116 parser.add_argument(
117 "files",
118 help="list of vtk files or glob masks",
119 nargs="+",
120 )
121 parser.add_argument("-d2", "--d2", dest="d2", default="")
122 parser.add_argument("-f", "--field", dest="field", default="", type=str)
123 parser.add_argument(
124 "--field-component",
125 dest="field_component",
126 default=None,
127 type=int,
128 help="0-based component index for vector/tensor fields",
129 )
130 parser.add_argument("-wv", "--wrap_vector", dest="wrap_vector", default="", type=str)
131 parser.add_argument("--wrap-factor", dest="wrap_factor", default=1.0, type=float)
132 parser.add_argument("--zoom", dest="zoom", default=1.2, type=float)
133 parser.add_argument("--roll", dest="roll", default=0, type=float)
134 parser.add_argument("--azimuth", dest="azimuth", default=0, type=float)
135 parser.add_argument("--show-edges", dest="show_edges", action="store_true", default=True, help="Show mesh edges (default)")
136 parser.add_argument("--no-show-edges", dest="show_edges", action="store_false", help="Hide mesh edges")
137 parser.add_argument("--debug", dest="debug", action="store_true")
138 args = parser.parse_args()
139
140 if args.debug:
141 print(args)
142
143 file_list = filter_vtk_files(expand_input_files(args.files))
144 if not file_list:
145 parser.error("No vtk files were found with the given names or glob masks.")
146
148 try:
149 for file_name in file_list:
150 make_png(file_name, args)
151 finally:
152 if display is not None:
153 display.stop()
make_png(file, args)
select_field_component(mesh, field_name, component)
maybe_start_virtual_display()
expand_input_files(inputs)
filter_vtk_files(files)