poc-stereoscope/stereoscope.py

571 lines
20 KiB
Python

from math import cos, radians
import argparse
import cadquery as cq
from components.base import base
from components.mirrors import inside_mirror, outside_mirror
from components.fasteners import *
from components.center_piece import center_piece
from components.front_cover import front_cover
from components.lens import lens
from components.cameras.victure_hc200 import camera
from components.shims.victure_hc200_shims import centered_shim as shim
from cq_annotate import add_assembly_arrows, explode_assembly
from components.parameters import *
from documenter import document
# Display parameters
explode = False
annotate = False
def build_stereo_assembly(annotate=None, step=None):
"""
Generates the stereoscope assembly of base, mirrors, center piece, etc.
"""
stereo_assy = cq.Assembly()
# Make sure that the assembly step we are visualizing needs these inside mirrors
if step == None or step == 0:
# Center piece for inside mirrors
stereo_assy.add(
center_piece(
mirror_size,
inside_mirror_size,
inside_projected_length,
arrow_face_selector=">Z",
),
name="center_piece",
loc=cq.Location((0.0, 0.0, mirror_size / 2.0 - 20.0)),
color=cq.Color(0.9, 0.5, 0.1, 0.5),
metadata={
"explode_loc": cq.Location((0, 0, 40)),
"export_format": "stl,step",
},
)
# Add the sqaure nuts that hold the center piece in place
stereo_assy.add(
m3_square_nut().rotateAboutCenter((0, 1, 0), 90),
name="center_piece_nut_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((20.0, 1.25, 16.55), (1, 0, 0), 90),
metadata={"explode_loc": cq.Location((0, 60, 0))},
)
stereo_assy.add(
m3_square_nut().rotateAboutCenter((0, 1, 0), 90),
name="center_piece_nut_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-20.0, 1.25, 16.55), (1, 0, 0), 90),
metadata={"explode_loc": cq.Location((0, 60, 0))},
)
# Add the nuts to the nut traps for the front cover
stereo_assy.add(
m3_nut(),
name="hex_nut_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((7.0, 0, 25.0), (0, 1, 0), 180),
metadata={"explode_loc": cq.Location((0, 0, -15))},
)
stereo_assy.add(
m3_nut(),
name="hex_nut_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-7.0, 0, 25.0), (0, 1, 0), 180),
metadata={"explode_loc": cq.Location((0, 0, -15))},
)
if step == None or step == 1:
stereo_assy.add(
inside_mirror(
mirror_size,
inside_mirror_size,
mirror_thickness,
">Y",
annotate=annotate,
),
name="right_inside_mirror",
loc=cq.Location(
(0.0, -projected_length / 2.0 + 0.5, mirror_size / 2.0 - 9.0),
(1, 0, 0),
inside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1.0),
metadata={"explode_loc": cq.Location((0, 60, 0)), "export_format": None},
)
stereo_assy.add(
inside_mirror(
mirror_size,
inside_mirror_size,
mirror_thickness,
"<Y",
annotate=annotate,
).rotateAboutCenter((0, 0, 1), 180),
name="left_inside_mirror",
loc=cq.Location(
(0, projected_length / 2.0 - 0.5, mirror_size / 2.0 - 9.0),
(1, 0, 0),
-inside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1.0),
metadata={"explode_loc": cq.Location((0, -60, 0)), "export_format": None},
)
# Make sure that the assembly step we are visualizing needs these outside mirrors
if step == None or step == 2:
stereo_assy.add(
outside_mirror(mirror_size, mirror_thickness, ">Y", annotate=annotate),
name="right_outside_mirror",
loc=cq.Location(
(
0,
inside_projected_length
+ (projected_length / 2.0)
+ outside_mirror_ext_offset
+ 0.95,
mirror_size / 2.0 - 2.5,
),
(1, 0, 0),
outside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1),
metadata={"explode_loc": cq.Location((0, 60, 0)), "export_format": None},
)
stereo_assy.add(
outside_mirror(
mirror_size, mirror_thickness, "<Y", annotate=annotate
).rotateAboutCenter((0, 0, 1), 180),
name="left_outside_mirror",
loc=cq.Location(
(
0,
-inside_projected_length
- (projected_length / 2.0)
- outside_mirror_ext_offset
- 0.95,
mirror_size / 2.0 - 2.5,
),
(1, 0, 0),
-outside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1),
metadata={"explode_loc": cq.Location((0, -60, 0))},
)
# make sure that the assembly step we are visualizing needs the center piece
if step == 3 or step == 4 or step == 5:
# Center piece offset and face selectors are different for step 3 and 4
if step == 3:
center_piece_offset = 10.0
arrow_face_selector = ">Z"
else:
center_piece_offset = 0.0
arrow_face_selector = None
stereo_assy.add(
center_piece(
mirror_size,
inside_mirror_size,
inside_projected_length,
arrow_face_selector=arrow_face_selector,
),
name="center_piece",
color=cq.Color(0.8, 0.0, 0.05, 1),
loc=cq.Location((0, 0, 5.0)),
metadata={
"explode_loc": cq.Location((0, 0, center_piece_offset)),
"export_format": "stl,step",
},
)
# Add the inside mirrors
stereo_assy.add(
inside_mirror(
mirror_size,
inside_mirror_size,
mirror_thickness,
arrow_face_selector=None,
annotate=annotate,
),
name="right_inside_mirror",
loc=cq.Location(
(0.0, -projected_length / 2.0 + 0.5, mirror_size / 2.0 - 9.0),
(1, 0, 0),
inside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1.0),
metadata={"explode_loc": cq.Location((0, 0, 0)), "export_format": None},
)
stereo_assy.add(
inside_mirror(
mirror_size,
inside_mirror_size,
mirror_thickness,
arrow_face_selector=None,
annotate=annotate,
).rotateAboutCenter((0, 0, 1), 180),
name="left_inside_mirror",
loc=cq.Location(
(0, projected_length / 2.0 - 0.5, mirror_size / 2.0 - 9.0),
(1, 0, 0),
-inside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1.0),
metadata={"explode_loc": cq.Location((0, 0, 0)), "export_format": None},
)
# Add the outside mirrors
stereo_assy.add(
outside_mirror(
mirror_size,
mirror_thickness,
arrow_face_selector=None,
annotate=annotate,
),
name="right_outside_mirror",
loc=cq.Location(
(
0,
inside_projected_length
+ (projected_length / 2.0)
+ outside_mirror_ext_offset
+ 0.95,
mirror_size / 2.0 - 2.5,
),
(1, 0, 0),
outside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1),
metadata={"explode_loc": cq.Location((0, 0, 0)), "export_format": None},
)
stereo_assy.add(
outside_mirror(
mirror_size,
mirror_thickness,
arrow_face_selector=None,
annotate=annotate,
).rotateAboutCenter((0, 0, 1), 180),
name="left_outside_mirror",
loc=cq.Location(
(
0,
-inside_projected_length
- (projected_length / 2.0)
- outside_mirror_ext_offset
- 0.95,
mirror_size / 2.0 - 2.5,
),
(1, 0, 0),
-outside_mirror_angle,
),
color=cq.Color(0.75, 0.75, 0.75, 1),
metadata={"explode_loc": cq.Location((0, 0, 0))},
)
# Step 4 adds the side bolts to hold the center piece in place
if step == 4:
# Add the screws that hold the center piece in place
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="center_piece_screw_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((30.0, 0, 16.55), (0, 1, 0), -90),
metadata={"explode_loc": cq.Location((0, 0, -20))},
)
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="center_piece_screw_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-30.0, 0, 16.55), (0, 1, 0), 90),
metadata={"explode_loc": cq.Location((0, 0, -20))},
)
# The step to add the front face
if step == 5:
# Add the screws that hold the center piece in place
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="center_piece_screw_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((30.0, 0, 16.55), (0, 1, 0), -90),
metadata={"explode_loc": cq.Location((0, 0, 0))},
)
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="center_piece_screw_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-30.0, 0, 16.55), (0, 1, 0), 90),
metadata={"explode_loc": cq.Location((0, 0, 0))},
)
# Add the front cover
stereo_assy.add(
front_cover(arrow_face_selector=">Z[-3]"),
name="front_cover",
color=cq.Color(0.8, 0.0, 0.05, 1),
loc=cq.Location((-(mirror_size + 4.0) / 2.0, 0, 28.25)),
metadata={
"explode_loc": cq.Location((0, 0, 15)),
"export_format": "stl,step",
},
)
# Add the screws that hold the front cover in place
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="front_cover_screw_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((7.0, 0.0, 34.25), (0, 1, 0), 180),
metadata={"explode_loc": cq.Location((0, 0, -30))},
)
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="front_cover_screw_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-7.0, 0.0, 34.25), (0, 1, 0), 180),
metadata={"explode_loc": cq.Location((0, 0, -30))},
)
# Make sure that the assembly step we are visualizing needs this center piece
if step == None or step > 5:
# Add the front cover
stereo_assy.add(
front_cover(),
name="front_cover",
color=cq.Color(0.8, 0.0, 0.05, 1),
loc=cq.Location((-(mirror_size + 4.0) / 2.0, 0, 28.25)),
metadata={
"explode_loc": cq.Location((0, 0, 80)),
"export_format": "stl,step",
},
)
# Add the lenses
stereo_assy.add(
lens(),
name="lens1",
color=cq.Color(0.0, 0.0, 0.0, 0.5),
loc=cq.Location((0.0, 43.75, 42.5), (1, 0, 0), 23.75),
metadata={
"explode_loc": cq.Location((0, 0, 100)),
"export_format": "stl,step",
},
)
stereo_assy.add(
lens(),
name="lens2",
color=cq.Color(0.0, 0.0, 0.0, 0.5),
loc=cq.Location((0.0, -43.75, 42.5), (1, 0, 0), -23.75),
metadata={
"explode_loc": cq.Location((0, 0, 100)),
"export_format": "stl,step",
},
)
# Add the screws that hold the center piece in place
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="center_piece_screw_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((30.0, 0, 16.55), (0, 1, 0), -90),
metadata={"explode_loc": cq.Location((0, 0, -20))},
)
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="center_piece_screw_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-30.0, 0, 16.55), (0, 1, 0), 90),
metadata={"explode_loc": cq.Location((0, 0, -20))},
)
# Add the screws that hold the front cover in place
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="front_cover_screw_1",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((7.0, 0.0, 36.25), (0, 1, 0), 180),
metadata={"explode_loc": cq.Location((0, 0, -110))},
)
stereo_assy.add(
m3x12_bolt(arrow_face_selector="<Z"),
name="front_cover_screw_2",
color=cq.Color(0.298, 0.73, 0.09, 1),
loc=cq.Location((-7.0, 0.0, 36.25), (0, 1, 0), 180),
metadata={"explode_loc": cq.Location((0, 0, -110))},
)
if step == None or step > 0:
# Add the base that holds the mirrors in place
stereo_assy.add(
base(),
name="base",
color=cq.Color(0.8, 0, 0.05, 1),
loc=cq.Location((0, 0, 0)),
metadata={
"explode_loc": cq.Location((0, 0, 0)),
"export_format": "stl,step",
},
)
return stereo_assy
def build_stereoscope_shim_assembly(annotate=None):
"""
Generates the assembly of the stereoscope, shim and screws.
"""
# Put together the assembly
assy = cq.Assembly()
# The stereoscope assembly
stereo_assy = build_stereo_assembly()
# Add the camera shim to the assembly that adapts the stereoscope to the camera
assy.add(
shim().faces("<Z").tag("arrow").end(),
name="camera_shim",
loc=cq.Location((0, 0, -3.5), (1, 0, 0), 0),
color=cq.Color(0.04, 0.5, 0.67, 1),
metadata={"explode_loc": cq.Location((0, 0, 10))},
)
# Add the stereoscope itself to the assembly
assy.add(
stereo_assy,
loc=cq.Location((0.0, 0.0, 0.0), (0, 0, 1), 90),
metadata={"explode_loc": cq.Location((0, 0, 20))},
)
# Add the metric hex nuts to the assembly
assy.add(
m3_nut(),
name="hex_nut_1",
loc=cq.Location((-45, 20, 2.5), (0, 0, 1), 90),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, 25))},
)
assy.add(
m3_nut(),
name="hex_nut_2",
loc=cq.Location((-45, -20, 2.5), (0, 0, 1), 90),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, 25))},
)
assy.add(
m3_nut(),
name="hex_nut_3",
loc=cq.Location((45, 20, 2.5), (0, 0, 1), 90),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, 25))},
)
assy.add(
m3_nut(),
name="hex_nut_4",
loc=cq.Location((45, -20, 2.5), (0, 0, 1), 90),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, 25))},
)
# Add the metric bolts to the assembly
assy.add(
m3x12_bolt().faces("<Z").tag("arrow").end(),
name="bolt_1",
loc=cq.Location((-45, 20, -6.5), (1, 0, 0), 0),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, -8))},
)
assy.add(
m3x12_bolt().faces("<Z").tag("arrow").end(),
name="bolt_2",
loc=cq.Location((-45, -20, -6.5), (1, 0, 0), 0),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, -8))},
)
assy.add(
m3x12_bolt().faces("<Z").tag("arrow").end(),
name="bolt_3",
loc=cq.Location((45, -20, -6.5), (1, 0, 0), 0),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, -8))},
)
assy.add(
m3x12_bolt().faces("<Z").tag("arrow").end(),
name="bolt_4",
loc=cq.Location((45, 20, -6.5), (1, 0, 0), 0),
color=cq.Color(0.298, 0.73, 0.09, 1),
metadata={"explode_loc": cq.Location((0, 0, -8))},
)
return assy
# Show the object in the viewer if this script is being run by CQ-editor
if "show_object" in globals():
# The assembly of the stereoscope and camera shim
stereo_shim_assy = build_stereoscope_shim_assembly(annotate=annotate)
# Set the exploded view of just the stereoscope if it has been requested
if explode:
explode_assembly(stereo_shim_assy)
# Create annotation assembly arrows, if requested
if annotate:
add_assembly_arrows(stereo_shim_assy, arrow_scale_factor=0.5)
show_camera = False
# Show the camera, if desired
if show_camera:
# Put together the assembly
# assy = cq.Assembly()
stereo_shim_assy.add(
camera(),
name="camera",
loc=cq.Location((0.0, 2.5, -20.0,), (1, 0, 0), 0,),
color=cq.Color(0.13, 0.545, 0.13, 1.0),
metadata={"explode_loc": cq.Location((0, 0, 0))},
)
show_object(stereo_shim_assy)
def main(args):
# Determine whether the user wants to generate documentation/output, or display the model
if args.document == True:
functions = {}
functions["build_stereo_assembly"] = build_stereo_assembly
functions["build_stereoscope_shim_assembly"] = build_stereoscope_shim_assembly
functions["inside_mirror"] = inside_mirror
functions["outside_mirror"] = outside_mirror
document(".", functions)
else:
from cadquery.vis import show
# The stereoscope assembly
stereo_assy = build_stereo_assembly()
if explode:
explode_assembly(stereo_assy)
if annotate:
add_assembly_arrows(stereo_assy, arrow_scale_factor=0.5)
show(stereo_assy)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Displays and/or generates documentation and output files for this model."
)
parser.add_argument(
"--document",
dest="document",
action="store_true",
help="Tells the app whether or not to generate documentation and output files. If present, the model will not be displayed in a window.",
)
args = parser.parse_args()
main(args)