-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerator.py
More file actions
154 lines (125 loc) · 5.69 KB
/
Copy pathgenerator.py
File metadata and controls
154 lines (125 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python
import os
import logging
import sys
import argparse
import subprocess
import json
import pathlib
logger = logging.getLogger(__name__)
if os.name == 'nt':
import winreg
def read_install_location(software_name):
# Need to traverse the two registry
sub_key = [r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
r'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall']
for i in sub_key:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, i, 0, winreg.KEY_READ)
for j in range(0, winreg.QueryInfoKey(key)[0] - 1):
try:
key_name = winreg.EnumKey(key, j)
key_path = i + '\\' + key_name
each_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path, 0, winreg.KEY_READ)
displayName, _ = winreg.QueryValueEx(each_key, 'DisplayName')
if software_name.lower() in displayName.lower() or software_name.lower() in key_name.lower():
installLocation, _ = winreg.QueryValueEx(each_key, 'InstallLocation')
return installLocation
except WindowsError:
pass
raise Exception("Install location not found for %s" % software_name)
kicad_python_program = os.path.join(read_install_location('KiCad 5.1'), 'bin', 'python.exe')
blender_program = os.path.join(read_install_location('Blender'), 'blender.exe')
else:
kicad_python_program = 'python'
blender_program = 'blender'
def mkdir_p(path):
if not os.path.exists(path):
os.makedirs(path)
return path
def call_program(*args, **kwargs):
exec_env = os.environ.copy()
for v in ['VIRTUAL_ENV', 'PYTHONPATH', 'PYTHONUNBUFFERED']:
exec_env.pop(v, None)
exec_env['PATH'] = os.pathsep.join([a for a in exec_env['PATH'].split(os.pathsep) if a not in sys.path])
kwargs = kwargs.copy()
kwargs.update(env=exec_env)
ret = subprocess.call(*args, **kwargs)
if ret != 0:
raise Exception("Error occurs in a subprogram")
def _main(argv=sys.argv):
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
format='%(asctime)s - %(threadName)s - %(name)s - %(levelname)s - %(message)s')
parser = argparse.ArgumentParser(prog=argv[0], description='KicadBlender',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-v', '--verbose', dest='verbose_count', action='count', default=1,
help="increases log verbosity for each occurrence.")
parser.add_argument('-q', '--quality', default=100, type=int,
help="texture quality")
parser.add_argument('-o', '--output', default=None,
help="output directory")
parser.add_argument('input',
help="input kicad file")
# Parse
args, unknown_args = parser.parse_known_args(argv[1:])
# Set logging level
logging.getLogger().setLevel(max(3 - args.verbose_count, 0) * 10)
verbose_args = 'v' * args.verbose_count
if len(verbose_args):
verbose_args = ['-' + verbose_args]
else:
verbose_args = []
if args.output is None:
args.output = os.path.join(os.path.dirname(args.input), "blender")
tmp_path = mkdir_p(os.path.join(args.output, "tmp"))
textures_path = mkdir_p(os.path.join(args.output, "textures"))
if getattr(sys, 'frozen', False):
script_path = os.path.dirname(sys.executable)
else:
script_path = pathlib.Path(__file__).parent.resolve()
blender_file = os.path.join(args.output, os.path.basename(os.path.splitext(args.input)[0] + '.blend'))
logger.info("Export boards SVGs and VRML")
# Call kicad script with kicad python executable
sub_args = [kicad_python_program, os.path.join(script_path, "kicad.py")]
sub_args += verbose_args
sub_args += [args.input, tmp_path]
logger.debug("Call " + " ".join(sub_args))
call_program(sub_args)
logger.debug("Opening SVG data output")
with open(os.path.join(tmp_path, "data.json")) as json_file:
data = json.load(json_file)
logger.debug("Data: %s" % data)
logger.info("SVGs to PNGs")
svg_files = pathlib.Path(tmp_path).glob('*.svg')
for path in svg_files:
svg_file = str(path)
png_file = os.path.join(textures_path, path.with_suffix(".png").name)
# Call inkscape script with current python env
if getattr(sys, 'frozen', False):
sub_args = [os.path.join(script_path, "inkscape.exe")]
else:
sub_args = [sys.executable, os.path.join(script_path, "inkscape.py")]
sub_args += verbose_args
sub_args += [svg_file, "-o", png_file]
sub_args += ["-s", str(args.quality)]
sub_args += ["-u", data['units']]
sub_args += ["--", "%f:%f:%f:%f" % (data['x'], data['y'], data['width'], data['height'])]
logger.debug("Call " + " ".join(sub_args))
call_program(sub_args)
logger.info("Create Blender file")
# Call blender script with blender executable
sub_args = [blender_program, "--background", "--python", os.path.join(script_path, "blender.py"), '--']
sub_args += verbose_args
sub_args += ["-d", "%f:%f:%f" % (data['width'], data['height'], data['thickness'])]
sub_args += [os.path.join(script_path, "Template.blend"), data['vrml'], textures_path, blender_file]
logger.debug("Call " + " ".join(sub_args))
call_program(sub_args)
def main():
try:
sys.exit(_main(sys.argv))
except Exception as e:
logger.exception(e)
sys.exit(-1)
finally:
logging.shutdown()
if __name__ == "__main__":
main()