enable import of raw binary VTU
@@ -8,6 +8,7 @@ import logging
import lzma
import sys
import zlib
+import re
import numpy
@@ -100,6 +101,43 @@ def get_grid(root):
raise ReadError("No UnstructuredGrid found.")
return grid, appended_data
+def _parse_raw_binary(filename):
+ import xml.etree.ElementTree as ET
+
+ with open(filename, "rb") as f:
+ raw = f.read()
+
+ try:
+ i_start = re.search(re.compile(b"<AppendedData[^>]+(?:\">)"), raw).end()
+ i_stop = raw.find(b"</AppendedData>")
+ except Exception:
+ raise ReadError()
+
+ header = raw[:i_start].decode()
+ footer = raw[i_stop:].decode()
+ data = raw[i_start:i_stop].split(b"_",1)[1].rsplit(b"\n",1)[0]
+
+ root = ET.fromstring(header + footer)
+
+ if "compressor" in root.attrib:
+ raise ReadError("Compressed raw binary VTU files not supported.")
+
+ byteorder = ("little" if root.attrib["byte_order"] == "LittleEndian" else "big")
+
+ appended_data_tag = root.find("AppendedData")
+ appended_data_tag.set("encoding", "base64")
+
+ blocks = []
+ i = 0
+ while i < len(data):
+ block_size = int.from_bytes(data[i:i+4], byteorder=byteorder, signed=True)
+ da_tag = root.find(".//DataArray[@offset='%d']" % i)
+ da_tag.set("offset", "%d" % sum(map(lambda x: len(x), blocks)))
+ blocks.append(base64.b64encode(data[i:i+block_size+4]).decode())
+ i += block_size + 4
+
+ appended_data_tag.text = "_" + "".join(blocks)
+ return root
vtu_to_numpy_type = {
"Float32": numpy.dtype(numpy.float32),
@@ -126,8 +164,11 @@ class VtuReader:
import xml.etree.ElementTree as ET
parser = ET.XMLParser()
+ try:
tree = ET.parse(filename, parser)
root = tree.getroot()
+ except ET.ParseError:
+ root = _parse_raw_binary(filename)
if root.tag != "VTKFile":
raise ReadError()
@@ -138,6 +179,10 @@ class VtuReader:
"Unknown VTU file version '{}'.".format(root.attrib["version"])
)
+ # fix empty NumberOfComponents attributes as produced by Firedrake
+ for da_tag in root.findall(".//DataArray[@NumberOfComponents='']"):
+ da_tag.attrib.pop("NumberOfComponents")
+
if "compressor" in root.attrib:
assert root.attrib["compressor"] in [
"vtkLZMADataCompressor",
