572 lines
18 KiB
OpenSCAD
572 lines
18 KiB
OpenSCAD
// ============================================================================
|
|
// Companion Cube — Pièces Modulaires Séparées
|
|
// Version : 0.3.0
|
|
// ============================================================================
|
|
// Toutes les pièces à imprimer, définies comme modules indépendants.
|
|
// Ce fichier sera inclus par cube-assembly.scad
|
|
// ============================================================================
|
|
|
|
include <cube-config.scad>
|
|
|
|
// ============================================================================
|
|
// UTILITAIRES GÉOMÉTRIQUES
|
|
// ============================================================================
|
|
|
|
// Cube arrondi (hull de 8 sphères aux coins)
|
|
module rounded_cube(size, r) {
|
|
hull() {
|
|
c = size/2 - r;
|
|
for (x = [-1, 1], y = [-1, 1], z = [-1, 1])
|
|
translate([x*c, y*c, z*c])
|
|
sphere(r=r);
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// PIÈCE 1 : FRAME (Squelette Principal)
|
|
// ============================================================================
|
|
// Structure porteuse avec plots de fixation pour les PCB Carriers.
|
|
// 4 plots M3 par face (24 total).
|
|
// ============================================================================
|
|
|
|
module frame() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
opening = CUBE_SIZE - 2 * edge_d;
|
|
|
|
difference() {
|
|
union() {
|
|
// --- Coque arrondie évidée ---
|
|
difference() {
|
|
rounded_cube(CUBE_SIZE, CORNER_RADIUS);
|
|
cube([opening, opening, opening], center=true);
|
|
// Ouvertures pour les 6 faces
|
|
cube([opening, opening, CUBE_SIZE + 2], center=true); // ±Z
|
|
cube([CUBE_SIZE + 2, opening, opening], center=true); // ±X
|
|
cube([opening, CUBE_SIZE + 2, opening], center=true); // ±Y
|
|
}
|
|
|
|
// --- Corniches plates (assise pour PCB Carriers) ---
|
|
_frame_ledges();
|
|
|
|
// --- Plots de fixation M3 (4 par face) ---
|
|
_frame_mount_posts();
|
|
}
|
|
|
|
// --- Trous traversants M3 ---
|
|
_frame_mount_holes();
|
|
|
|
// --- Canaux de câblage ---
|
|
_cable_channels();
|
|
}
|
|
}
|
|
|
|
// Corniches planes pour l'assise des PCB Carriers
|
|
module _frame_ledges() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
lw = FRAME_LEDGE_WIDTH;
|
|
lh = FRAME_LEDGE_HEIGHT;
|
|
opening = CUBE_SIZE - 2 * edge_d;
|
|
outer = opening + 2 * lw;
|
|
|
|
// +Z et -Z
|
|
for (z = [-1, 1]) {
|
|
translate([0, 0, z * (half - edge_d + (z > 0 ? 0 : -lh))])
|
|
difference() {
|
|
linear_extrude(lh)
|
|
offset(r=CORNER_RADIUS)
|
|
offset(delta=-CORNER_RADIUS)
|
|
square([outer, outer], center=true);
|
|
translate([0, 0, -0.5])
|
|
linear_extrude(lh + 1)
|
|
square([opening, opening], center=true);
|
|
}
|
|
}
|
|
// +Y et -Y
|
|
for (y_dir = [-1, 1]) {
|
|
translate([0, y_dir * (half - edge_d + (y_dir > 0 ? 0 : -lh)), 0])
|
|
rotate([90, 0, 0])
|
|
difference() {
|
|
linear_extrude(lh)
|
|
offset(r=CORNER_RADIUS)
|
|
offset(delta=-CORNER_RADIUS)
|
|
square([outer, outer], center=true);
|
|
translate([0, 0, -0.5])
|
|
linear_extrude(lh + 1)
|
|
square([opening, opening], center=true);
|
|
}
|
|
}
|
|
// +X et -X
|
|
for (x_dir = [-1, 1]) {
|
|
translate([x_dir * (half - edge_d + (x_dir > 0 ? 0 : -lh)), 0, 0])
|
|
rotate([0, 90, 0])
|
|
difference() {
|
|
linear_extrude(lh)
|
|
offset(r=CORNER_RADIUS)
|
|
offset(delta=-CORNER_RADIUS)
|
|
square([outer, outer], center=true);
|
|
translate([0, 0, -0.5])
|
|
linear_extrude(lh + 1)
|
|
square([opening, opening], center=true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Plots de fixation (poteau cylindrique + base renforcée)
|
|
module _frame_mount_posts() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
post_h = 8;
|
|
post_d = 7;
|
|
|
|
mount_positions = [
|
|
[ (half - edge_d - 10), (half - edge_d - 10)],
|
|
[-(half - edge_d - 10), (half - edge_d - 10)],
|
|
[ (half - edge_d - 10), -(half - edge_d - 10)],
|
|
[-(half - edge_d - 10), -(half - edge_d - 10)]
|
|
];
|
|
|
|
// Face +Z et -Z
|
|
for (z = [-1, 1]) {
|
|
for (xy = mount_positions) {
|
|
translate([xy[0], xy[1], z * (half - edge_d + (z > 0 ? 0 : -post_h))])
|
|
cylinder(d=post_d, h=post_h);
|
|
}
|
|
}
|
|
// Face +Y et -Y
|
|
for (y_dir = [-1, 1]) {
|
|
for (xz = mount_positions) {
|
|
translate([xz[0], y_dir * (half - edge_d + (y_dir > 0 ? 0 : -post_h)), xz[1]])
|
|
rotate([90, 0, 0])
|
|
cylinder(d=post_d, h=post_h);
|
|
}
|
|
}
|
|
// Face +X et -X
|
|
for (x_dir = [-1, 1]) {
|
|
for (yz = mount_positions) {
|
|
translate([x_dir * (half - edge_d + (x_dir > 0 ? 0 : -post_h)), yz[0], yz[1]])
|
|
rotate([0, 90, 0])
|
|
cylinder(d=post_d, h=post_h);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Trous traversants M3 dans les plots
|
|
module _frame_mount_holes() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
|
|
mount_positions = [
|
|
[ (half - edge_d - 10), (half - edge_d - 10)],
|
|
[-(half - edge_d - 10), (half - edge_d - 10)],
|
|
[ (half - edge_d - 10), -(half - edge_d - 10)],
|
|
[-(half - edge_d - 10), -(half - edge_d - 10)]
|
|
];
|
|
|
|
for (z = [-1, 1]) {
|
|
for (xy = mount_positions) {
|
|
translate([xy[0], xy[1], z * half])
|
|
cylinder(d=FRAME_MOUNT_DIAM, h=20, center=true);
|
|
}
|
|
}
|
|
for (y_dir = [-1, 1]) {
|
|
for (xz = mount_positions) {
|
|
translate([xz[0], y_dir * half, xz[1]])
|
|
rotate([90, 0, 0])
|
|
cylinder(d=FRAME_MOUNT_DIAM, h=20, center=true);
|
|
}
|
|
}
|
|
for (x_dir = [-1, 1]) {
|
|
for (yz = mount_positions) {
|
|
translate([x_dir * half, yz[0], yz[1]])
|
|
rotate([0, 90, 0])
|
|
cylinder(d=FRAME_MOUNT_DIAM, h=20, center=true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Canaux pour câbles JST
|
|
module _cable_channels() {
|
|
ch_w = 10;
|
|
ch_h = 6;
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
|
|
for (z = [-1, 1]) {
|
|
translate([0, 0, z * (half - edge_d/2)])
|
|
cube([ch_w, ch_h, edge_d + 2], center=true);
|
|
}
|
|
for (y = [-1, 1]) {
|
|
translate([0, y * (half - edge_d/2), 0])
|
|
cube([ch_w, edge_d + 2, ch_h], center=true);
|
|
}
|
|
for (x = [-1, 1]) {
|
|
translate([x * (half - edge_d/2), 0, 0])
|
|
cube([edge_d + 2, ch_w, ch_h], center=true);
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// PIÈCE 2 : BATTERY CRADLE (Support Batterie)
|
|
// ============================================================================
|
|
// Berceau pour batterie LiPo, se visse au frame via 4 vis M2.5.
|
|
// ============================================================================
|
|
|
|
module battery_cradle() {
|
|
bw = BATT_WIDTH + 2 * BATT_TOLERANCE;
|
|
bl = BATT_LENGTH + 2 * BATT_TOLERANCE;
|
|
bh = BATT_HEIGHT + BATT_TOLERANCE;
|
|
wall = 2;
|
|
|
|
difference() {
|
|
// Berceau avec parois
|
|
union() {
|
|
cube([bl + 2*wall, bw + 2*wall, bh + wall], center=true);
|
|
// Pieds de fixation (4 coins)
|
|
for (x = [-1, 1], y = [-1, 1]) {
|
|
translate([x * (bl/2), y * (bw/2), -(bh + wall)/2])
|
|
cylinder(d=6, h=2);
|
|
}
|
|
}
|
|
// Évidement
|
|
translate([0, 0, wall])
|
|
cube([bl, bw, bh + wall], center=true);
|
|
// Ouverture pour les fils
|
|
translate([0, bw/2 + wall, 0])
|
|
cube([20, wall*3, bh - wall], center=true);
|
|
// Trous de fixation M2.5
|
|
for (x = [-1, 1], y = [-1, 1]) {
|
|
translate([x * (bl/2), y * (bw/2), 0])
|
|
cylinder(d=2.7, h=20, center=true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// PIÈCE 3 : PCB CENTRAL MOUNT (Support PCB Central)
|
|
// ============================================================================
|
|
// Plateforme avec 4 entretoises pour le PCB central (ESP32-S3).
|
|
// ============================================================================
|
|
|
|
module pcb_central_mount() {
|
|
pcb_l = CENTRAL_PCB_LENGTH;
|
|
pcb_w = CENTRAL_PCB_WIDTH;
|
|
standoff_h = 5;
|
|
standoff_d = 6;
|
|
hole_d = 2.5;
|
|
base_h = 2;
|
|
|
|
difference() {
|
|
union() {
|
|
// Base
|
|
cube([pcb_l + 10, pcb_w + 10, base_h], center=true);
|
|
// 4 entretoises
|
|
for (x = [-1, 1], y = [-1, 1]) {
|
|
translate([x * (pcb_l/2 - 5), y * (pcb_w/2 - 5), base_h/2])
|
|
cylinder(d=standoff_d, h=standoff_h);
|
|
}
|
|
}
|
|
// Trous dans les entretoises (M2.5)
|
|
for (x = [-1, 1], y = [-1, 1]) {
|
|
translate([x * (pcb_l/2 - 5), y * (pcb_w/2 - 5), 0])
|
|
cylinder(d=hole_d, h=20, center=true);
|
|
}
|
|
// Trous de fixation au frame (4 vis M2.5)
|
|
for (x = [-1, 1], y = [-1, 1]) {
|
|
translate([x * (pcb_l/2 + 3), y * (pcb_w/2 + 3), 0])
|
|
cylinder(d=2.7, h=20, center=true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// PIÈCE 4-9 : PCB CARRIERS (Supports PCB pour chaque face)
|
|
// ============================================================================
|
|
// Support qui porte le PCB Anneau + PCB Bouchon, se visse sur les 4 plots du frame.
|
|
// ============================================================================
|
|
|
|
module pcb_carrier_standard() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
carrier_depth = 10; // Profondeur du support
|
|
opening = CUBE_SIZE - 2 * edge_d;
|
|
|
|
difference() {
|
|
union() {
|
|
// Plaque de base
|
|
linear_extrude(carrier_depth)
|
|
offset(r=CORNER_RADIUS - 2)
|
|
offset(delta=-(CORNER_RADIUS - 2))
|
|
square([opening - 4, opening - 4], center=true);
|
|
|
|
// Rebord pour PCB Anneau
|
|
translate([0, 0, carrier_depth - LED_RING_HEIGHT - 0.5])
|
|
_ring_holder();
|
|
|
|
// Support PCB Bouchon (central)
|
|
translate([0, 0, carrier_depth - LED_RING_HEIGHT - CAP_CONNECTOR_H - CAP_PCB_HEIGHT - 0.5])
|
|
cylinder(d=CAP_PCB_DIAM + 2, h=CAP_CONNECTOR_H + CAP_PCB_HEIGHT + 0.5);
|
|
|
|
// Oreilles de fixation (4 coins)
|
|
_carrier_mount_ears();
|
|
}
|
|
|
|
// Ouverture centrale (air + câblage)
|
|
translate([0, 0, -0.5])
|
|
cylinder(d=AIR_HOLE_DIAM, h=carrier_depth + 1);
|
|
|
|
// Évidement pour le PCB Anneau
|
|
translate([0, 0, carrier_depth - LED_RING_HEIGHT])
|
|
difference() {
|
|
cylinder(d=LED_RING_DIAM_EXT - 2, h=LED_RING_HEIGHT + 1);
|
|
cylinder(d=LED_RING_DIAM_INT + 2, h=LED_RING_HEIGHT + 2, center=true);
|
|
}
|
|
|
|
// Évidement pour le PCB Bouchon
|
|
translate([0, 0, carrier_depth - LED_RING_HEIGHT - CAP_CONNECTOR_H - CAP_PCB_HEIGHT])
|
|
cylinder(d=CAP_PCB_DIAM, h=CAP_CONNECTOR_H + CAP_PCB_HEIGHT + 1);
|
|
|
|
// Trous de fixation M3
|
|
_carrier_mount_holes();
|
|
}
|
|
}
|
|
|
|
// Rebord de maintien pour le PCB Anneau
|
|
module _ring_holder() {
|
|
ext = LED_RING_DIAM_EXT + 1;
|
|
int_ = LED_RING_DIAM_INT - 1;
|
|
h = 2;
|
|
|
|
difference() {
|
|
cylinder(d=ext, h=h);
|
|
translate([0, 0, -0.5])
|
|
cylinder(d=int_, h=h + 1);
|
|
// Encoches pour les connecteurs
|
|
for (a = [0, 90, 180, 270]) {
|
|
rotate([0, 0, a])
|
|
translate([ext/2-1, 0, 0])
|
|
cube([4, 6, h + 1], center=true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Oreilles de fixation pour les PCB Carriers
|
|
module _carrier_mount_ears() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
ear_size = 12;
|
|
ear_h = 10;
|
|
|
|
mount_positions = [
|
|
[ (half - edge_d - 10), (half - edge_d - 10)],
|
|
[-(half - edge_d - 10), (half - edge_d - 10)],
|
|
[ (half - edge_d - 10), -(half - edge_d - 10)],
|
|
[-(half - edge_d - 10), -(half - edge_d - 10)]
|
|
];
|
|
|
|
for (xy = mount_positions) {
|
|
translate([xy[0], xy[1], ear_h/2])
|
|
cube([ear_size, ear_size, ear_h], center=true);
|
|
}
|
|
}
|
|
|
|
// Trous de fixation dans les oreilles
|
|
module _carrier_mount_holes() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
|
|
mount_positions = [
|
|
[ (half - edge_d - 10), (half - edge_d - 10)],
|
|
[-(half - edge_d - 10), (half - edge_d - 10)],
|
|
[ (half - edge_d - 10), -(half - edge_d - 10)],
|
|
[-(half - edge_d - 10), -(half - edge_d - 10)]
|
|
];
|
|
|
|
for (xy = mount_positions) {
|
|
translate([xy[0], xy[1], -1])
|
|
cylinder(d=FRAME_MOUNT_DIAM, h=20);
|
|
}
|
|
}
|
|
|
|
// Variante NFC (dessus)
|
|
module pcb_carrier_nfc() {
|
|
difference() {
|
|
union() {
|
|
pcb_carrier_standard();
|
|
// Ajout d'un support renforcé pour le PN532
|
|
translate([0, 0, 10 - NFC_PCB_HEIGHT - 0.5])
|
|
_nfc_holder();
|
|
}
|
|
// Évidement pour le module NFC
|
|
translate([0, 0, 10 - NFC_PCB_HEIGHT - 0.5])
|
|
cube([NFC_PCB_SIZE, NFC_PCB_SIZE, NFC_PCB_HEIGHT + 1], center=true);
|
|
}
|
|
}
|
|
|
|
module _nfc_holder() {
|
|
wall = 1.5;
|
|
size = NFC_PCB_SIZE + 2 * wall;
|
|
h = NFC_PCB_HEIGHT + 2;
|
|
|
|
difference() {
|
|
cube([size, size, h], center=true);
|
|
translate([0, 0, wall])
|
|
cube([NFC_PCB_SIZE, NFC_PCB_SIZE, h], center=true);
|
|
}
|
|
}
|
|
|
|
// Variante Qi (dessous)
|
|
module pcb_carrier_qi() {
|
|
difference() {
|
|
union() {
|
|
pcb_carrier_standard();
|
|
// Support pour bobine Qi
|
|
translate([0, 0, 2])
|
|
_qi_holder();
|
|
}
|
|
// Évidement pour la bobine Qi
|
|
translate([0, 0, 2])
|
|
cylinder(d=QI_COIL_DIAM, h=QI_COIL_HEIGHT + 1);
|
|
}
|
|
}
|
|
|
|
module _qi_holder() {
|
|
wall = 1.5;
|
|
h = QI_COIL_HEIGHT + 1;
|
|
|
|
difference() {
|
|
cylinder(d=QI_COIL_DIAM + 2*wall, h=h);
|
|
translate([0, 0, -0.5])
|
|
cylinder(d=QI_COIL_DIAM, h=h + 1);
|
|
}
|
|
// Support PCB récepteur
|
|
translate([0, QI_COIL_DIAM/2 + 5, 0])
|
|
difference() {
|
|
cube([QI_PCB_LENGTH + 2*wall, QI_PCB_WIDTH + 2*wall, QI_PCB_HEIGHT + 1], center=true);
|
|
cube([QI_PCB_LENGTH, QI_PCB_WIDTH, QI_PCB_HEIGHT + 2], center=true);
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// PIÈCE 10-15 : FACE COVERS (Coques extérieures)
|
|
// ============================================================================
|
|
// Coque visible avec membrane tactile centrale + gorge joint O-ring.
|
|
// Se visse sur le PCB Carrier (4 vis M3).
|
|
// ============================================================================
|
|
|
|
module face_cover_standard() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
face_size = CUBE_SIZE - 2 * PRINT_TOLERANCE;
|
|
cover_depth = 6; // Profondeur de la coque (hors membrane)
|
|
|
|
difference() {
|
|
union() {
|
|
// Coque extérieure arrondie
|
|
difference() {
|
|
linear_extrude(cover_depth)
|
|
offset(r=CORNER_RADIUS)
|
|
offset(delta=-CORNER_RADIUS)
|
|
square([face_size - 2*edge_d + 6, face_size - 2*edge_d + 6], center=true);
|
|
translate([0, 0, WALL_THICKNESS])
|
|
linear_extrude(cover_depth)
|
|
offset(r=max(0.5, CORNER_RADIUS - WALL_THICKNESS))
|
|
offset(delta=-max(0.5, CORNER_RADIUS - WALL_THICKNESS))
|
|
square([face_size - 2*edge_d + 6 - 2*WALL_THICKNESS,
|
|
face_size - 2*edge_d + 6 - 2*WALL_THICKNESS], center=true);
|
|
}
|
|
|
|
// Membrane tactile centrale
|
|
cylinder(d=FACE_CENTER_DIAM + 10, h=FACE_MEMBRANE_T);
|
|
|
|
// Oreilles de fixation
|
|
_cover_mount_ears(cover_depth);
|
|
}
|
|
|
|
// Zone tactile amincie
|
|
translate([0, 0, FACE_MEMBRANE_T])
|
|
cylinder(d=FACE_CENTER_DIAM, h=cover_depth);
|
|
|
|
// Gorge joint O-ring (intérieure)
|
|
translate([0, 0, cover_depth - FACE_SEAL_GROOVE_D])
|
|
_seal_groove(face_size - 2*edge_d + 2);
|
|
|
|
// Trous de fixation M3
|
|
_cover_mount_holes();
|
|
}
|
|
}
|
|
|
|
module _cover_mount_ears(depth) {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
ear_size = 12;
|
|
|
|
mount_positions = [
|
|
[ (half - edge_d - 10), (half - edge_d - 10)],
|
|
[-(half - edge_d - 10), (half - edge_d - 10)],
|
|
[ (half - edge_d - 10), -(half - edge_d - 10)],
|
|
[-(half - edge_d - 10), -(half - edge_d - 10)]
|
|
];
|
|
|
|
for (xy = mount_positions) {
|
|
translate([xy[0], xy[1], depth/2])
|
|
cube([ear_size, ear_size, depth], center=true);
|
|
}
|
|
}
|
|
|
|
module _cover_mount_holes() {
|
|
half = CUBE_SIZE / 2;
|
|
edge_d = FRAME_EDGE_DEPTH;
|
|
|
|
mount_positions = [
|
|
[ (half - edge_d - 10), (half - edge_d - 10)],
|
|
[-(half - edge_d - 10), (half - edge_d - 10)],
|
|
[ (half - edge_d - 10), -(half - edge_d - 10)],
|
|
[-(half - edge_d - 10), -(half - edge_d - 10)]
|
|
];
|
|
|
|
for (xy = mount_positions) {
|
|
translate([xy[0], xy[1], -1])
|
|
cylinder(d=FRAME_MOUNT_DIAM, h=20);
|
|
// Lamage tête de vis
|
|
translate([xy[0], xy[1], -1])
|
|
cylinder(d=FRAME_MOUNT_HEAD, h=FRAME_MOUNT_DEPTH + 1);
|
|
}
|
|
}
|
|
|
|
// Gorge joint O-ring
|
|
module _seal_groove(size) {
|
|
w = FACE_SEAL_GROOVE_W;
|
|
d = FACE_SEAL_GROOVE_D;
|
|
inset = 3;
|
|
|
|
linear_extrude(d + 0.1)
|
|
difference() {
|
|
offset(r=CORNER_RADIUS - inset)
|
|
offset(delta=-(CORNER_RADIUS - inset))
|
|
square([size - 2*inset, size - 2*inset], center=true);
|
|
offset(r=max(0.5, CORNER_RADIUS - inset - w))
|
|
offset(delta=-max(0.5, CORNER_RADIUS - inset - w))
|
|
square([size - 2*inset - 2*w, size - 2*inset - 2*w], center=true);
|
|
}
|
|
}
|
|
|
|
// Variantes NFC et Qi (identiques à standard pour l'extérieur)
|
|
module face_cover_nfc() {
|
|
difference() {
|
|
face_cover_standard();
|
|
// Amincissement supplémentaire pour l'antenne NFC (optionnel)
|
|
translate([0, 0, -0.5])
|
|
cylinder(d=NFC_ANTENNA_DIAM, h=FACE_MEMBRANE_T + 0.5);
|
|
}
|
|
}
|
|
|
|
module face_cover_qi() {
|
|
difference() {
|
|
face_cover_standard();
|
|
// Amincissement supplémentaire pour la bobine Qi
|
|
translate([0, 0, -0.5])
|
|
cylinder(d=QI_COIL_DIAM + 4, h=WALL_THICKNESS);
|
|
}
|
|
}
|