poc-stereoscope/documenter.py

644 lines
22 KiB
Python
Executable File

#!/usr/bin/env python
import os
import cadquery as cq
from cq_annotate import add_assembly_arrows, explode_assembly, add_safety_warning
from components.shims.victure_hc200_shims import centered_shim
from tools.mirror_cut_jig_50mm_inside import jig, jig_assembly
from tools.mirror_break_50mm_inside import mirror_break, break_assembly
from components.parameters import *
def document(base_dir, functions):
# Unpack the functions that have been passed in
build_stereo_assembly = functions["build_stereo_assembly"]
build_stereoscope_shim_assembly = functions["build_stereoscope_shim_assembly"]
outside_mirror = functions["outside_mirror"]
inside_mirror = functions["inside_mirror"]
svg_line_color = (10, 10, 10)
svg_hidden_color = (127, 127, 127)
# Create the docs/images directory if it does not exist
docs_images_path = os.path.join(base_dir, "docs", "images")
exists = os.path.exists(docs_images_path)
if not exists:
os.makedirs(docs_images_path)
# Create the docs/output/stl directory if it does not exist
docs_output_path = os.path.join(base_dir, "docs", "manufacturing_files")
exists = os.path.exists(docs_output_path)
if not exists:
os.makedirs(docs_output_path)
# Generate the shims that goes between the camera/phone/trap body and the stereoscope
shim = centered_shim()
cq.exporters.export(
shim,
os.path.join(docs_output_path, "hc200_centered_shim.stl"),
opt={"ascii": True},
)
cq.exporters.export(
shim, os.path.join(docs_output_path, "hc200_centered_shim.step"),
)
# shim = horizotal_offset_shim()
# cq.exporters.export(
# shim,
# os.path.join(docs_output_path, "hc200_horizontal_offset_shim.stl"),
# opt={"ascii": True},
# )
# shim = thin_shim()
# cq.exporters.export(
# shim,
# os.path.join(docs_output_path, "hc200_thin_shim.stl"),
# opt={"ascii": True},
# )
# Generate the mirror cut jig and export its STL
jig_only = jig(get_global_params())
cq.exporters.export(
jig_only,
os.path.join(docs_output_path, "mirror_cut_jig_50mm_inside.stl"),
opt={"ascii": True},
)
cq.exporters.export(
jig_only, os.path.join(docs_output_path, "mirror_cut_jig_50mm_inside.step"),
)
# Generate the mirror break and export its STL
break_only = mirror_break(get_global_params())
cq.exporters.export(
break_only,
os.path.join(docs_output_path, "mirror_break_50mm_inside.stl"),
opt={"ascii": True},
)
cq.exporters.export(
break_only, os.path.join(docs_output_path, "mirror_break_50mm_inside.step"),
)
# Generate the jig assembly to document the mirror cut step
jig_assy = jig_assembly(get_global_params(), outside_mirror, annotate=True)
explode_assembly(jig_assy)
jig_assy = add_assembly_arrows(jig_assy, arrow_scale_factor=0.5)
final_path = os.path.join(docs_images_path, "stereoscope_jig_assembly.svg")
cq.exporters.export(
jig_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 180)
.rotate((0, 0, 0), (0, 1, 0), -90)
.rotate((0, 0, 0), (1, 0, 1), -60),
final_path,
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Add the safety warning
add_safety_warning(
final_path,
"Safety precautitons are required when working with glass",
use_icon=True,
font_size=20,
)
# Generate the break assembly to document the mirror break assembly step
break_assy = break_assembly(get_global_params(), inside_mirror, annotate=True)
explode_assembly(break_assy)
break_assy = add_assembly_arrows(break_assy, arrow_scale_factor=0.5)
final_path = os.path.join(docs_images_path, "stereoscope_break_assembly.svg")
cq.exporters.export(
break_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 180)
.rotate((0, 0, 0), (0, 1, 0), -90)
.rotate((0, 0, 0), (1, 0, 1), -60),
final_path,
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Add the safety warning
add_safety_warning(
final_path,
"Safety precautitons are required when working with glass",
use_icon=True,
font_size=20,
)
# Generate the break assembly to document the mirror break being used to break the mirror at the score line
break_assy = break_assembly(
get_global_params(),
inside_mirror,
arrow_selector=">Z",
arrow_part="break",
annotate=True,
)
break_assy = add_assembly_arrows(break_assy, arrow_scale_factor=0.5)
final_path = os.path.join(docs_images_path, "stereoscope_break_operation.svg")
cq.exporters.export(
break_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 180)
.rotate((0, 0, 0), (0, 1, 0), -90)
.rotate((0, 0, 0), (1, 0, 1), -60),
final_path,
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Add the safety warning
add_safety_warning(
final_path,
"Safety precautitons are required when working with glass",
use_icon=True,
font_size=20,
)
# Step through the stereoscope assembly and output files to different formats as appropriate
stereo_assy = build_stereo_assembly()
for child in stereo_assy.children:
# Only export the file if there is a format set
if (
child.metadata
and "export_format" in child.metadata
and child.metadata["export_format"] != None
):
# Handle multiple export formats
if "," in child.metadata["export_format"]:
formats = child.metadata["export_format"].split(",")
else:
formats = child.metadata["export_format"]
if not isinstance(child.obj, cq.Assembly):
# Export each format
for format in formats:
# STL has some special handling
if format == "stl":
cq.exporters.export(
child.obj,
os.path.join(docs_output_path, child.name + "." + format,),
opt={"ascii": True},
)
else:
cq.exporters.export(
child.obj,
os.path.join(docs_output_path, child.name + "." + format,),
)
# Export an exploded assembly image of the center piece and how the nuts fit in the traps
center_assy = build_stereo_assembly(step=0)
explode_assembly(center_assy)
center_assy = add_assembly_arrows(center_assy, arrow_scale_factor=0.5)
cq.exporters.export(
center_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 25)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(
docs_images_path, "stereoscope_center_assembly_exploded_annotated.svg"
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export an exploded assembly image of the center piece and how the nuts fit in the traps
center_assy = build_stereo_assembly(step=0)
explode_assembly(center_assy)
center_assy = add_assembly_arrows(center_assy, arrow_scale_factor=0.5)
cq.exporters.export(
center_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(
docs_images_path,
"stereoscope_center_assembly_exploded_annotated_hidden_view.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": True,
},
)
# Export an exploded assembly image of how the center piece fits into the base
stereo_assy = build_stereo_assembly(step=3)
explode_assembly(stereo_assy)
center_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(
docs_images_path,
"stereoscope_center_fit_in_assembly_exploded_annotated.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
stereo_assy = build_stereo_assembly(step=3)
explode_assembly(stereo_assy)
center_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 0)
.rotate((0, 0, 0), (0, 0, 1), 0),
os.path.join(
docs_images_path,
"stereoscope_center_fit_in_assembly_exploded_annotated_side_view.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": True,
},
)
# Show the assembly with the base, mirrors and center piece
stereo_assy = build_stereo_assembly(step=3)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(
docs_images_path,
"stereoscope_center_piece_in_assembly_exploded_annotated.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Show the assembly with the base, mirrors and center piece with the side bolts
stereo_assy = build_stereo_assembly(step=4)
explode_assembly(stereo_assy)
center_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(
docs_images_path,
"stereoscope_center_piece_with_screws_in_assembly_exploded_annotated.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export the view of the side bolts from the side with hidden lines
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 90),
os.path.join(
docs_images_path,
"stereoscope_center_piece_with_screws_in_assembly_exploded_annotated_side_view.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": True,
},
)
# Show the assembly with the base, mirrors and center piece with the side bolts
stereo_assy = build_stereo_assembly(step=5)
explode_assembly(stereo_assy)
center_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 20),
os.path.join(
docs_images_path,
"stereoscope_front_piece_with_screws_in_assembly_exploded_annotated.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export the view of the side bolts from the side with hidden lines
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 0),
os.path.join(
docs_images_path,
"stereoscope_front_piece_with_screws_in_assembly_exploded_annotated_side_view.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": True,
},
)
# Export an exploded assembly image showing how the parts fit together
stereo_assy = build_stereo_assembly(annotate=True)
explode_assembly(stereo_assy)
stereo_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 25)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(docs_images_path, "stereoscope_assembly_exploded_annotated.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export an assembly image showing how the parts fit together in their final positions
stereo_assy = build_stereo_assembly(annotate=False)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 25)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(docs_images_path, "stereoscope_assembly.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export just step 1 of the assembly with the inside mirrors
stereo_assy = build_stereo_assembly(annotate=True, step=1)
explode_assembly(stereo_assy)
stereo_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(docs_images_path, "stereoscope_assembly_step_1.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export a side view with hidden lines to give another perspective of how the parts fit together
# Hidden line color/thickness is not consistent throughout the exported SVG - result of underlying software stack
cq.exporters.export(
stereo_assy.toCompound().rotate((0, 0, 0), (1, 0, 0), 90),
os.path.join(docs_images_path, "stereoscope_assembly_side_view_step_1.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": True,
},
)
# Export just step 1 of the assembly with the inside mirrors
stereo_assy = build_stereo_assembly(annotate=True, step=2)
explode_assembly(stereo_assy)
stereo_assy = add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(docs_images_path, "stereoscope_assembly_step_2.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export a side view with hidden lines to give another perspective of how the parts fit together
# Hidden line color/thickness is not consistent throughout the exported SVG - result of underlying software stack
cq.exporters.export(
stereo_assy.toCompound().rotate((0, 0, 0), (1, 0, 0), 90),
os.path.join(docs_images_path, "stereoscope_assembly_side_view_step_2.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": True,
},
)
# Export the assembly of the stereoscope with the shim and screws to show a sample assembly
stereo_shim_assy = build_stereoscope_shim_assembly()
cq.exporters.export(
stereo_shim_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(docs_images_path, "stereoscope_with_shim_assembly.svg"),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Export the exploded view of the stereoscope with the shim to help show this assembly step
stereo_shim_assy = build_stereoscope_shim_assembly(annotate=True)
# Set the exploded view of the assembly
explode_assembly(stereo_shim_assy)
# Create annotation assembly arrows, if requested
add_assembly_arrows(stereo_shim_assy, arrow_scale_factor=0.5)
cq.exporters.export(
stereo_shim_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), 45)
.rotate((0, 0, 0), (0, 0, 1), 10),
os.path.join(
docs_images_path, "stereoscope_with_shim_assembly_exploded_annotated.svg"
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)
# Same view as the last, but from underneath
cq.exporters.export(
stereo_shim_assy.toCompound()
.rotate((0, 0, 0), (1, 0, 0), 90)
.rotate((0, 0, 0), (0, 1, 0), -45)
.rotate((0, 0, 0), (0, 0, 1), -10),
os.path.join(
docs_images_path,
"stereoscope_with_shim_assembly_exploded_annotated_underneath.svg",
),
opt={
"width": 800,
"height": None,
"marginLeft": 10,
"marginTop": 10,
"showAxes": False,
"projectionDir": (1.0, 0.0, 0.0),
"strokeWidth": 0.5,
"strokeColor": svg_line_color,
"hiddenColor": svg_hidden_color,
"showHidden": False,
},
)