Skip to content

Instantly share code, notes, and snippets.

@ajeddeloh
Created December 6, 2020 05:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajeddeloh/0fad161538e140770308cbfc6b662b04 to your computer and use it in GitHub Desktop.
Save ajeddeloh/0fad161538e140770308cbfc6b662b04 to your computer and use it in GitHub Desktop.
Split zmx files from a zmf catalog
import numpy as np
import sys
from struct import Struct
if len(sys.argv) != 3:
print("usage: zmf2zmx in.zmf zmx_dir")
with open(sys.argv[1], 'rb') as f:
zmf_bytes = f.read()
zmx_dir = sys.argv[2] + '/'
header = Struct('<100s24xIdd')
# from https://github.com/quartiq/rayopt/blob/master/rayopt/zemax.py#L79
def zmf_obfuscate(data, a, b):
iv = np.cos(6*a + 3*b)
iv = np.cos(655*(np.pi/180)*iv) + iv
p = np.arange(len(data))
k = 13.2*(iv + np.sin(17*(p + 3)))*(p + 1)
k = (int((f"{_:.8e}")[4:7]) for _ in k)
data = np.frombuffer(data, np.uint8)
data = data ^ np.fromiter(k, np.uint8, len(data))
return data.tobytes().decode()
# drop the first four bytes
cur = 4
while cur < len(zmf_bytes):
data = header.unpack(zmf_bytes[cur: cur+header.size])
name = data[0].rstrip(b'\0').decode()
size = data[1]
a, b = data[2], data[3]
try:
with open(zmx_dir + name, 'w') as f:
f.write(zmf_obfuscate(zmf_bytes[cur+header.size:cur+header.size+size], a, b))
except:
print("failed on", name)
cur += header.size + size
@juchlil
Copy link

juchlil commented Nov 24, 2022

Just signed in to say thank You!
Saved me a lot of time and trouble. Thanks for sharing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment