Python wrapper for running instances of trisurf-ng
Samo Penic
2019-07-15 7f64589f9f172b7965a086bcceed8c47a51daca7
commit | author | age
c18b7b 1 """
SP 2 Binary data in the file are compressed when the VTKFile element is of the form
3
4  <VTKFile ... compressor="vtkZLibDataCompressor">
5
6 The data corresponding to a data array are stored in a set of blocks which are each compressed using the zlib library. The block structure allows semi-random access without decompressing all data. In uncompressed form all the blocks have the same size except possibly the last block which might be smaller. The data for one array begin with a header of the form
7
8  [#blocks][#u-size][#p-size][#c-size-1][#c-size-2]...[#c-size-#blocks][DATA]
9
10 Each token is an integer value whose type is specified by "header_type" at the top of the file (UInt32 if no type specified). The token meanings are:
11
12  [#blocks] = Number of blocks
13  [#u-size] = Block size before compression
14  [#p-size] = Size of last partial block (zero if it not needed)
15  [#c-size-i] = Size in bytes of block i after compression
16
17 The [DATA] portion stores contiguously every block appended together. The offset from the beginning of the data section to the beginning of a block is computed by summing the compressed block sizes from preceding blocks according to the header. 
18
19
20 Usage example:
21 compressvtkfile('timestep_000099.vtu')
22 """
23
24 import xml.etree.ElementTree as ET
25 import struct
26 import base64
27 import zlib
28
29 def element2binary(element, pack_type):
30     t=element.text.split()
31     if(pack_type=='q' or pack_type=='B'): #Int64 or UInt8
32         s=[int(i) for i in t]
33     elif(pack_type=='d'): #double
34         s=[float(i) for i in t]    
35     else:
36         print("wrong type")
37         exit(1)
38
39     if(pack_type in 'qd'):
40         mult=8
41     else:
42         mult=1
43
44     #if(pack_type=='q'): #reduce integer to int32
45     #    mult=4
46     #    pack_type='L'
47     #    element.set('type','UInt32')    
48     b=struct.pack(pack_type*len(s),*s)
49     #blen=struct.pack('I',mult*len(s))
50     cmprs=zlib.compress(b,6)
51     sizes=[1,len(b),len(b),len(cmprs)]
52     header=struct.pack('I'*4,*sizes)
53     element.text=base64.b64encode(header).decode('ascii')+base64.b64encode(cmprs).decode('ascii')
54     element.set('format','binary')    
55     
56 def compressvtkfile(filename):
57     try:
58         tree = ET.parse(filename)
59     except:
60         print("Error reading snapshot file")
61
62     iterator=tree.iter()
63
64     for element in iterator:
65         #UInt8, Int64, Float64
66         if element.get('type')=='UnstructuredGrid':
67             element.set('compressor','vtkZLibDataCompressor')
68         if element.get('type')=='Int64':
69             element2binary(element,'q')
70
71         if element.get('type')=='UInt8':
72             element2binary(element,'B')
73         if element.get('type')=='Float64':
74             element2binary(element,'d')
75
76     tree.write("test.vtu")
77
78     #now compress the trisurf part:
79     with open('test.vtu', 'r') as file:
80         c=file.read()
81     i=c.find('<trisurf ')
82     j=c.find('>',i)
83     k=c.find('</trisurf>',j)
84     cs=c[j+1:k]
85     fields=c[i:j+1].split()
86     fields=[s.replace('false','true') for s in fields]
87     starttag=' '.join(fields)
88     cmprs=zlib.compress(cs.encode('ascii'),6)
89     cmprs=base64.b64encode(cmprs)
90     cc=c[0:i]+starttag+cmprs.decode('ascii')+c[k:]
91     with open('test1.vtu', 'w') as file:
92         file.write(cc)
93