Reputation: 198
When I use vtkPolyDataWriter to create a vtk legacy file, I obtain the new version of the data file (5.1) with connectivities and offsets. Is it possible to change that and get the 'legacy' old format?
It seems gmsh is not able to read vtk file with the new format version..
(I work with python 3.8 and vtk package version 9.0.1)
Upvotes: 3
Views: 1445
Reputation: 198
For those interested, I post the code I used to convert new to old format. It works for polydata and unstructured grid vtk meshes.
import math
import re
def convert_to_old_format(mesh_fname: str, save_fname: str, copy_lines: bool = False):
conv = Converter(mesh_fname, save_fname, copy_lines)
conv.read()
conv.replace()
conv.write()
def change_vtk_version(filename: str, v: float = 5.1):
with open(filename, "r") as f:
x = f.read()
x = re.sub(r"(# vtk DataFile Version) (.+)", f"\\1 {v}", x)
with open(filename, "w") as f:
f.write(x)
class Converter:
def __init__(self, inp, out=None, copy_lines=False):
if out is None:
out = inp
self.inp = inp
self.out = out
self.copy_lines = copy_lines # if line cells should be copied
self.original = None
self.lines = None
self.polys = None
self.cells = None
def read(self):
with open(self.inp, "r") as f:
self.original = f.read().split("\n")
lines_original = list(map(lambda x: x.strip().split(), self.original))
for i, l in enumerate(self.original):
if "LINES" in l:
self.lines = NewContent("LINES", lines_original, i)
elif "POLYGONS" in l:
self.polys = NewContent("POLYGONS", lines_original, i)
elif "CELLS" in l:
self.cells = NewContent("CELLS", lines_original, i)
def replace(self):
if self.polys is not None:
self.original = self.polys.replace(self.original)
if self.cells is not None:
self.original = self.cells.replace(self.original)
if self.lines is not None:
self.original = self.lines.replace(self.original, replace=self.copy_lines)
def write(self):
with open(self.out, "w") as f:
f.write("\n".join(self.original))
change_vtk_version(self.out, 4.2)
class NewContent:
def __init__(self, kw, content, ln):
self.kw = kw
self.ln = ln
self.name = content[ln][0]
self.no = int(content[ln][1])
self.nc = int(content[ln][2])
flat_list = [item for line in content[ln + 2 :] for item in line]
flat_list = list(filter("".__ne__, flat_list))
self.offsets = list(map(int, flat_list[0 : self.no]))
self.connectivity = list(
map(int, flat_list[self.no + 2 : self.no + 2 + self.nc])
)
@property
def remove(self):
return self.ln, self.ln + math.ceil(self.no / 9) + math.ceil(self.nc / 9) + 3
def replace(self, lines, replace=True):
nb_cells = self.no - 1
new_content = []
if replace:
new_content = [f"{self.kw} {nb_cells} {nb_cells + self.nc}"]
for i in range(nb_cells):
nb_points = self.offsets[i + 1] - self.offsets[i]
ids = self.connectivity[self.offsets[i] : self.offsets[i + 1]]
new_content.append(f"{nb_points} {' '.join(map(str, ids))}")
lines_to_keep = lines
a, b = self.remove
del lines_to_keep[a:b]
lines_to_keep[a:a] = new_content
lines_to_keep = list(filter("".__ne__, lines_to_keep))
return lines_to_keep
if __name__ == "__main__":
convert_to_old_format("mesh.vtk", "mesh_old_format.vtk")
# change_vtk_version("mesh.vtk", 8.6)
Upvotes: 0
Reputation: 2488
Nope, you cannot programmatically choose the version. The only way to write with an old format is to downgrade vtk to the desired version.
Upvotes: 3