571 lines
20 KiB
Python
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)
|