#!/usr/bin/env python ############################################################################################ # Hellen-One: A script to create a 3D components view (VRML). # (c) andreika ############################################################################################ import os, sys, re import configparser import gzip ### Unfortunately PyVRML97 (vrml.vrml97) is not capable of properly processing Altium-exported VRML-files... if len(sys.argv) < 3: print "Error! Please specify the place+board files and vrml filename." sys.exit(1) mergePlaceFile = sys.argv[1] mergeBoardFile = sys.argv[2] fileOutName = sys.argv[3] # read board config config = configparser.ConfigParser() config.read(mergeBoardFile) # read place file fragments = [] with open(mergePlaceFile, 'rb') as fmp: for line in fmp: m = line.split() m = {"name": m[0], "x": m[1], "y": m[2], "path": config[m[0]]["Prefix"] } fragments.append(m) print "* Starting merge of " + str(len(fragments)) + " board fragments..." outf = gzip.open(fileOutName, 'wb') outf.write("#VRML V2.0 utf8\n") pat_hdr = re.compile('^#VRML.*') pat_idx = re.compile(r'(DEF|USE)\s+(Shape|_)(\w)') pat_trans = re.compile(r'(translation)\s+([+\-0-9\.]+)\s+([+\-0-9\.]+)') def trans_repl(m): x = float(m.group(2)) y = float(m.group(3)) return m.group(1) + " " + str(x + off_x_mm) + " " + str(y + off_y_mm) fId = 1 for frag in fragments: # convert to mm off_x_mm = float(frag["x"]) * 25.4 off_y_mm = float(frag["y"]) * 25.4 fileName = frag["path"] + "-vrml.wrl" print "* Adding " + frag["name"] + " (" + fileName + ")..." with open(fileName, 'rb') as f: for line in f: line = line.rstrip() # skip the headers (we write our own because there should be only 1 header) if pat_hdr.match(line): continue fragId = str(fId).zfill(2) line = pat_idx.sub(r'\g<1> \g<2>' + fragId + '\g<3>', line) line = pat_trans.sub(trans_repl, line) outf.write(line + "\n") f.close() fId = fId + 1 outf.close() print "Done!"