更改 vtk 数据文件版本
Change vtk DataFile version
当我使用 vtkPolyDataWriter 创建 vtk 遗留文件时,我获得了具有连接性和偏移量的新版本数据文件 (5.1)。是否可以更改它并获得 'legacy' 旧格式?
gmsh 似乎无法读取新格式版本的 vtk 文件..
(我使用 python 3.8 和 vtk 包版本 9.0.1)
不,您不能以编程方式选择版本。使用旧格式编写的唯一方法是将 vtk 降级到所需版本。
对于那些感兴趣的人,我 post 用于将新格式转换为旧格式的代码。它适用于多数据和非结构化网格 vtk 网格。
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)
当我使用 vtkPolyDataWriter 创建 vtk 遗留文件时,我获得了具有连接性和偏移量的新版本数据文件 (5.1)。是否可以更改它并获得 'legacy' 旧格式?
gmsh 似乎无法读取新格式版本的 vtk 文件..
(我使用 python 3.8 和 vtk 包版本 9.0.1)
不,您不能以编程方式选择版本。使用旧格式编写的唯一方法是将 vtk 降级到所需版本。
对于那些感兴趣的人,我 post 用于将新格式转换为旧格式的代码。它适用于多数据和非结构化网格 vtk 网格。
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)