-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvert_xmf_to_x3d.py
137 lines (112 loc) · 5.06 KB
/
convert_xmf_to_x3d.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
"""Converter from XMF to X3D."""
import argparse
import os
import pathlib
def convert_particle_file_to_x3d(xmf_path,
render_view_size=None,
mesh_smoothing=300):
"""Converts a XMF particle file to X3D scene for Blender import."""
assert os.path.exists(xmf_path), "File `{xmf_path}` does not exist."
print(f'Converting: \"{xmf_path}\"...')
filename = xmf_path.name.replace('.xmf', '.x3d')
outfile = xmf_path.parent.joinpath('x3d').joinpath(filename)
# create a new 'XDMF Reader'
cell = XDMFReader(FileNames=[str(xmf_path)])
# get active view
renderView1 = GetActiveViewOrCreate('RenderView')
if render_view_size is not None:
renderView1.ViewSize = render_view_size
# get layout
layout1 = GetLayout()
# show data in view
cell_display = Show(cell, renderView1, 'UnstructuredGridRepresentation')
# reset view to fit data
renderView1.ResetCamera()
# get the material library
materialLibrary1 = GetMaterialLibrary()
# update the view to ensure updated data information
renderView1.Update()
# create a new 'Extract Surface'
extractSurface1 = ExtractSurface(Input=cell)
# create a new 'Smooth'
smooth1 = Smooth(Input=extractSurface1)
# Properties modified on smooth1
smooth1.NumberofIterations = mesh_smoothing
# show data in view
smooth1Display = Show(smooth1, renderView1, 'GeometryRepresentation')
# hide data in view
Hide(extractSurface1, renderView1)
# update the view to ensure updated data information
renderView1.Update()
# export view
ExportView(str(outfile), view=renderView1)
Delete(layout1)
Delete(renderView1)
Delete(smooth1)
Delete(smooth1Display)
Delete(extractSurface1)
Delete(cell)
Delete(cell_display)
def is_valid_cell_file(cell_file):
"""Returns True for possibly valid cell XMF files.
Any file matching `cell-type.*.xmf` is considered valid, where the
cell-type can be RBC, PLT, etc. """
if not cell_file.endswith('.xmf'):
return False
if 'Fluid' in cell_file:
return False
return True
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="""Convert XMF particle files to X3D scenes.\n
This script converts XMF particle files generated by HemoCell[0] to X3D scenes
for rendering with Blender[1]. The script automatically discovers all particles
files for all outputted iterations at the provided path. For each of these
files a specific X3D[2] file is generated.
The script relies on Paraview[3] and the corresponding `Paraview.simple` Python
interface. This is used to load the XMF particle files and generate the
corresponding X3D scenes. The original Paraview processing is based on a trace
generated with Paraview version 5.8.0.RC2, which is also tested on 5.9.1.
The script automatically discovers all `*.xmf` to convert in the provided path.
The resulting output is stored in nested `x3d` directory where the filenames of
the original XMF files are maintained, only with their file extension changed
from `.xmf` to `.x3d`.
[0] https://www.hemocell.eu/
[1] https://www.blender.org/
[2] https://en.wikipedia.org/wiki/X3D
[3] https://www.paraview.org/
""",
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('path',
help="""Directories containing XMF output files to
convert to X3D scenes""",
nargs='+')
parser.add_argument('--view-size',
help="Set the render view-size in Paraview",
nargs=2,
type=int,
metavar=("width", "height"))
parser.add_argument('--smooth',
help="Number of mesh smoothing iterations",
type=int,
default=300)
args = parser.parse_args()
# fully resolve the user-provided paths and ensure they exist
input_paths = list(map(lambda p: pathlib.Path(p).resolve(), args.path))
for path in input_paths:
if not os.path.exists(path):
parser.error(f'Specified input path \"{path}\" does not exist.')
view_size = None if args.view_size is None else tuple(args.view_size)
# Load Paraview just before rendering as this causes slower startup to
# maintain a fast response on other arguments, e.g. `--help`.
from paraview.simple import *
# Disables the automatic camera reset when calling `Show`.
paraview.simple._DisableFirstRenderCameraReset()
for path in input_paths:
print(f'Processing: \"{path}\"')
os.makedirs(path.joinpath('x3d'), exist_ok=True)
for particle_file in filter(is_valid_cell_file, os.listdir(path)):
convert_particle_file_to_x3d(path.joinpath(particle_file),
render_view_size=view_size,
mesh_smoothing=args.smooth)