# Mako: the docking interface, where the user's red line put it (over the canopy's rear and the collar). Exec'd by build_mako.py # after mk_fittings.py. # The docking arm (models/docking-arm) closes four claws at 45/135/225/315 deg round the clamp axis (0, -0.09), wrist 1.94 m # over the origin, claw pads r 0.555 at z 1.24-1.34. As on the Manta and the Spearfish: an arc of the Kazah collar's outer # profile at each claw (wall r 0.535 z 1.18-1.335, hook lip r 0.552, top z 1.375) on a disc at z 1.15. The disc stands on a # flared saddle that sits on the hood and the collar. Inside the clips is the hatch, as on the Kazah, whose clamp closes on # its hatch collar: a round lid (r 0.31) on a ledge in a coaming, a trunk (r 0.295) down through the hull's square hatch hole # into the cockpit, and a trim plate round the trunk under the lining. clip = MB("_clamp", [PAINT, GRAPH, YELLOW, STEEL]) CL_C = Vector((0.0, Y_CL, 0.0)) MC = 32 SK_R0, SK_R1, SK_Z1 = 0.47, 0.42, 1.10 bmc2 = bmesh.new() crow = [] for t in [j / 5 for j in range(6)]: ring = [] for a in range(MC): ph = 2 * math.pi * a / MC r = SK_R1 + (SK_R0 - SK_R1) * (1 - math.sin(t * math.pi / 2)) zb = hull_z_at(CL_C.x + SK_R0 * math.cos(ph), CL_C.y + SK_R0 * math.sin(ph)) - 0.02 z = zb + (SK_Z1 - zb) * (1 - math.cos(t * math.pi / 2)) ring.append(bmc2.verts.new((CL_C.x + r * math.cos(ph), CL_C.y + r * math.sin(ph), z))) crow.append((ring, clip.mi(PAINT))) def cring(r, z): return [bmc2.verts.new((CL_C.x + r * math.cos(2 * math.pi * a / MC), CL_C.y + r * math.sin(2 * math.pi * a / MC), z)) for a in range(MC)] LID_R, COAM_R, TRUNK_R = 0.312, 0.318, 0.295 LEDGE_Z, COAM_Z = 1.135, 1.168 for (r, z), m_ in (((0.50, 1.118), PAINT), ((0.53, 1.128), PAINT), ((0.53, 1.150), PAINT), ((0.46, 1.150), PAINT), ((0.40, 1.150), YELLOW), ((0.36, 1.150), GRAPH), ((0.335, 1.150), GRAPH), ((0.335, COAM_Z), GRAPH), ((COAM_R, COAM_Z), STEEL), ((COAM_R, LEDGE_Z), GRAPH), ((TRUNK_R, LEDGE_Z), GRAPH)): crow.append((cring(r, z), clip.mi(m_))) # the trunk: straight down to the cockpit's ceiling, where it meets the trim plate (both follow the lining's curve) def lining_z(x, y): return hull_z_at(x, y, True, LINER) - 0.010 trunk_bot = [bmc2.verts.new((CL_C.x + TRUNK_R * math.cos(2 * math.pi * a / MC), CL_C.y + TRUNK_R * math.sin(2 * math.pi * a / MC), lining_z(CL_C.x + TRUNK_R * math.cos(2 * math.pi * a / MC), CL_C.y + TRUNK_R * math.sin(2 * math.pi * a / MC)))) for a in range(MC)] crow.append((trunk_bot, clip.mi(GRAPH))) for (ra, ma), (rb, mb_) in zip(crow, crow[1:]): ring_rows(bmc2, [ra, rb], mat_index=mb_) # trim plate: a ring of quads from the trunk's foot to a square that covers the hull's hatch hole and its sleeve TRIM = HATCH_R + 0.07 sq = [] for a in range(MC): ph = 2 * math.pi * a / MC c, s = math.cos(ph), math.sin(ph) m = TRIM / max(abs(c), abs(s)) x, y = CL_C.x + m * c, CL_C.y + m * s sq.append(bmc2.verts.new((x, y, lining_z(x, y)))) ring_rows(bmc2, [trunk_bot, sq], mat_index=clip.mi(GRAPH)) # one sheet (skirt, disc, coaming, ledge, trunk, trim plate): consistent winding, then the disc's top faces up bmc2.normal_update() bmesh.ops.recalc_face_normals(bmc2, faces=bmc2.faces[:]) bmc2.normal_update() probe = min((f for f in bmc2.faces if abs(f.calc_center_median().z - 1.150) < 1e-3), key=lambda f: abs((f.calc_center_median() - CL_C).to_2d().length - 0.43)) if probe.normal.z < 0: bmesh.ops.reverse_faces(bmc2, faces=bmc2.faces[:]) clip.merge(bmc2, None) # the hatch's hinge axis runs across just outside the coaming's aft edge; its fixed knuckle stands on the disc there HATCH_HINGE = Vector((0.0, CL_C.y + 0.350, 1.182)) HATCH_MAX = 70.0 # deg: past about 75 the lid's corners reach the two aft clips (motion_check.py) qcyl(clip, 0.017, 0.11, HATCH_HINGE, STEEL, rot=(0, math.pi / 2, 0), segs=8) qbox(clip, (0.09, 0.040, 0.034), HATCH_HINGE + Vector((0, 0.004, -0.017)), GRAPH, bevel=0.006) # the four holder clips: the Kazah collar's outer profile in 40 deg arcs at the claws CLIP_LOOP = [(0.400, 1.150), (0.520, 1.150), (0.535, 1.180), (0.535, 1.335), (0.548, 1.350), (0.552, 1.365), (0.545, 1.375), (0.400, 1.375)] CLIP_HALF = math.radians(20.0) def revolve_arc(mb, loop, a0, a1, segs, mat): bm2 = bmesh.new() cols = [[bm2.verts.new((CL_C.x + r * math.cos(a0 + (a1 - a0) * j / segs), CL_C.y + r * math.sin(a0 + (a1 - a0) * j / segs), z)) for (r, z) in loop] for j in range(segs + 1)] n = len(loop) for j in range(segs): for q in range(n): bm2.faces.new((cols[j][q], cols[j + 1][q], cols[j + 1][(q + 1) % n], cols[j][(q + 1) % n])) for c in (cols[0], cols[-1]): bm2.faces.new((c[0], c[1], c[2], c[7])); bm2.faces.new((c[7], c[2], c[3], c[6])); bm2.faces.new((c[6], c[3], c[4], c[5])) bm2.normal_update() bmesh.ops.recalc_face_normals(bm2, faces=bm2.faces[:]) mb.merge(bm2, mat) CLIP_AZ = (45.0, 135.0, 225.0, 315.0) for az in CLIP_AZ: a = math.radians(az) revolve_arc(clip, CLIP_LOOP, a - CLIP_HALF, a + CLIP_HALF, 6, STEEL) qbox(clip, (0.05, 0.05, 0.006), (CL_C.x + 0.47 * math.cos(a), CL_C.y + 0.47 * math.sin(a), 1.378), YELLOW, rot=(0, 0, a)) # ------------------------------------------------------------------ the hatch lid (moves: hinged on its aft edge) hatch = MB("SM_Mako_Hatch", [PAINT, GRAPH, STEEL, YELLOW]) LID_Z0, LID_Z1 = LEDGE_Z + 0.002, 1.176 # the lid stands 8 mm proud of the coaming bmh = bmesh.new() top_r = [bmh.verts.new((CL_C.x + LID_R * math.cos(2 * math.pi * a / MC), CL_C.y + LID_R * math.sin(2 * math.pi * a / MC), LID_Z1)) for a in range(MC)] bot_r = [bmh.verts.new((v.co.x, v.co.y, LID_Z0)) for v in top_r] ring_rows(bmh, [top_r, bot_r], mat_index=0) coons_cap(bmh, top_r, 0) coons_cap(bmh, bot_r[::-1], 1) bmh.normal_update() for f in bmh.faces: c = f.calc_center_median() want = Vector((0, 0, 1 if c.z > (LID_Z0 + LID_Z1) / 2 + 1e-4 else -1)) if abs(f.normal.z) > 0.7 else Vector((c.x - CL_C.x, c.y - CL_C.y, 0)) if f.normal.dot(want) < 0: f.normal_flip() hatch.merge(bmh, None) # handwheel on top: a rim and three spokes on a hub, and the hinge's two knuckles at the aft edge wheel_c = Vector((CL_C.x, CL_C.y - 0.04, LID_Z1 + 0.030)) hatch.sweep([wheel_c + Vector((0.11 * math.cos(2 * math.pi * q / 24), 0.11 * math.sin(2 * math.pi * q / 24), 0)) for q in range(25)], 0.012, STEEL, sides=8, caps=False) qcyl(hatch, 0.030, 0.05, wheel_c - Vector((0, 0, 0.02)), GRAPH, segs=12) for q in range(3): a = 2 * math.pi * q / 3 + math.pi / 2 hatch.sweep([wheel_c, wheel_c + Vector((0.105 * math.cos(a), 0.105 * math.sin(a), 0))], 0.009, STEEL, sides=6, caps=True) for sx in (-0.13, 0.13): # the lid's two knuckles on arms from its aft edge to the axis qcyl(hatch, 0.016, 0.07, HATCH_HINGE + Vector((sx, 0, 0)), GRAPH, rot=(0, math.pi / 2, 0), segs=8) qbox(hatch, (0.05, 0.11, 0.014), Vector((sx, (HATCH_HINGE.y + CL_C.y + 0.25) / 2, LID_Z1 + 0.007)), GRAPH, bevel=0.004) REPORT["stage"] = "clamp"