120 lines
3.6 KiB
Python
Executable File
120 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
toplevel file used for interactive modeling.
|
|
|
|
- `cq-editor ./cq_toplevel.py`
|
|
- then press green play button to render
|
|
- edit files externally, and press render again to refresh the view
|
|
"""
|
|
|
|
import cadquery as cq
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
sys.path.append(os.path.join(os.getcwd(), "src"))
|
|
|
|
import case
|
|
import pinephone
|
|
import ldtek_battery
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def svg_export_options(view: str):
|
|
proj = (1, 1, 1)
|
|
if view == "front":
|
|
proj = (0.00, -0.05, 0.10)
|
|
elif view == "back":
|
|
proj = (0.00, -0.05, -0.10)
|
|
elif view == "right":
|
|
proj = (-0.10, 0.00, 0.00)
|
|
return dict(
|
|
width = 1024,
|
|
height = 1024,
|
|
marginLeft = 100,
|
|
marginTop = 10,
|
|
showAxes = False,
|
|
# projectionDir controls both the angle and the distance from the camera to the model
|
|
projectionDir = proj,
|
|
strokeWidth = 0.25,
|
|
strokeColor = (255, 0, 0),
|
|
hiddenColor = (0, 0, 255),
|
|
showHidden = True,
|
|
)
|
|
|
|
def model():
|
|
render_phone = os.environ.get("CASE_RENDER_PHONE", "") not in ("", "0")
|
|
render_phone_only = os.environ.get("CASE_RENDER_PHONE_ONLY", "") not in ("", "0")
|
|
|
|
phone = pinephone.PinePhone()
|
|
|
|
if render_phone_only:
|
|
return case.orient_for_printing(phone)
|
|
|
|
battery = ldtek_battery.LdtekBattery()
|
|
return case.case(phone, battery=battery, render_phone=render_phone)
|
|
|
|
def main():
|
|
logging.basicConfig()
|
|
logging.getLogger().setLevel(logging.INFO)
|
|
|
|
parser = argparse.ArgumentParser(description="toplevel cadquery interface")
|
|
parser.add_argument("--render-phone", action="store_true", help="render the case and also the phone within it; useful to confirm fit visually before printing")
|
|
parser.add_argument("--render-phone-only", action="store_true", help="render *only* the phone, not even the case")
|
|
parser.add_argument("--export-stl")
|
|
parser.add_argument("--export-svg")
|
|
parser.add_argument("--export-vtk")
|
|
parser.add_argument("--editor", action="store_true", help="view in cq-editor")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.render_phone:
|
|
os.environ["CASE_RENDER_PHONE"] = "1"
|
|
|
|
if args.render_phone_only:
|
|
os.environ["CASE_RENDER_PHONE_ONLY"] = "1"
|
|
|
|
logger.info("computing model ...")
|
|
model_ = model()
|
|
|
|
if args.export_stl:
|
|
logger.info("exporting stl to %s", args.export_stl)
|
|
cq.exporters.export(model_, args.export_stl)
|
|
|
|
if args.export_svg:
|
|
view = None
|
|
if "front" in args.export_svg:
|
|
view = "front"
|
|
elif "back" in args.export_svg:
|
|
view = "back"
|
|
elif "right" in args.export_svg:
|
|
view = "right"
|
|
logger.info("exporting svg to %s (view: %s)", args.export_svg, str(view))
|
|
cq.exporters.export(model_, args.export_svg, opt=svg_export_options(view))
|
|
|
|
if args.export_vtk:
|
|
vtk_file = args.export_vtk
|
|
js_var, _ext = os.path.splitext(os.path.basename(vtk_file))
|
|
js_file = f'{vtk_file}.js'
|
|
logger.info("exporting VTK (for web rendering) to %s", vtk_file)
|
|
cq.exporters.export(model_, vtk_file, cq.exporters.ExportTypes.VTP)
|
|
|
|
logger.info("wrapping VTK data in a javascript variable (var %s) in %s", js_var, js_file)
|
|
vtk_data = open(vtk_file).read()
|
|
with open(js_file, 'w') as js:
|
|
js.write(f"var {js_var} = `\n")
|
|
js.write(vtk_data)
|
|
js.write("`;\n")
|
|
|
|
if args.editor:
|
|
logger.info("launching cq-editor")
|
|
subprocess.check_call(["cq-editor", __file__])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
else:
|
|
result = model()
|