Read this model as text
A modern wall mounted light bar for above a bathroom mirror, 500 x 100 x 100 mm by default. Three GU10 spots point down through openings in a recessed bottom plate, hidden behind the front fascia. With tilting off the spots are fixed cups. With tilting on each spot becomes a separate cartridge that pivots forward and back on a piece of 1.75 mm filament as hinge pin, held in a ring on the bottom plate; the plate opening and ring bore are carved from the swept volume of the cartridge, so it clears at every angle up to max_tilt. Each ring pivot hole has a countersunk pocket on the outside as a seat for securing the pin with a drop of CA glue or a melted mushroom head, so the pins cannot walk out over time. The back is flat against the wall with rounded top corners that blend into the spherical front corners; one rounding radius for everything, sharp bottom edge, service window behind each spot, uniform bottom rim. The GU10 holder cups descend from mick/lamp-fittings. The bar splits into segments with dowel joints: at the defaults each segment is 167 x 100 x 100 mm, within an A1 Mini.
The image shows the solid OpenSCAD renders at part all · segment_index 1 · cutaway false · total_width 500 · height 100 · depth 100 · rounding 14 · spots 3 · lip 15 · rim 2.5 · tilting false · max_tilt 15 · tilt_angle 0 · segments 3 · wall 2.5 · plate_t 3 · gu10_hole_span 40 · smoothness 96 · color_body White.
Bathroom mirror light bar
mick/mirror-light@1.9.0
Report
For a legal or policy problem: a license violation, personal data, somebody else’s work republished as their own. A model that prints badly is a comment, not a report.
Parameters
from sourceDescription
What is this
A modern wall mounted light bar for above a bathroom mirror, 500 x 100 x 100 mm by default. Three GU10 spots point down through openings in a recessed bottom plate, hidden behind the front fascia. With tilting off the spots are fixed cups. With tilting on each spot becomes a separate cartridge that pivots forward and back on a piece of 1.75 mm filament as hinge pin, held in a ring on the bottom plate; the plate opening and ring bore are carved from the swept volume of the cartridge, so it clears at every angle up to max_tilt. Each ring pivot hole has a countersunk pocket on the outside as a seat for securing the pin with a drop of CA glue or a melted mushroom head, so the pins cannot walk out over time. The back is flat against the wall with rounded top corners that blend into the spherical front corners; one rounding radius for everything, sharp bottom edge, service window behind each spot, uniform bottom rim. The GU10 holder cups descend from mick/lamp-fittings. The bar splits into segments with dowel joints: at the defaults each segment is 167 x 100 x 100 mm, within an A1 Mini.
What you use it for
Print the segments and glue them on 4 mm dowels. With tilting on, also print one cartridge per spot (part = cartridge, printed cap down). Insert each cartridge from below through the plate slot into its ring, align the holes and push a short piece of 1.75 mm filament through the ring into the cartridge from each side, reaching in through the service window. Then secure each pin in its countersunk pocket with a drop of CA glue or by melting the end into a mushroom head with a soldering iron: press fit friction alone relaxes over time in a warm enclosure. The pin is then fixed to the ring and the cartridge turns on the pin; the remaining friction holds the aimed angle. Screw the sockets onto the cartridge caps, wire them with a loop of slack so the cartridge can swing, feed the mains through the nearest window and hang the bar on the keyholes. LED GU10 lamps only, PETG or ASA for a bathroom, out of the shower zones, and have the mains connection checked if you are not certain of it.
Design notes
The tilt axis runs along the width, through a pivot 15 mm above the lamp face, so the fitting swings within the cavity depth. The swept volume that shapes the ring bore and plate slot is the hull of the cartridge at minus max_tilt, zero and plus max_tilt with radial clearance, which flares the bore exactly where the cartridge needs room and keeps it tight at the pivot sides. At full forward tilt the lamp shows slightly below the fascia; raise lip if that bothers you. The shell is one convex hull with a flat back plate with rounded top corners blending into the front corner spheres. Keyholes sit in the columns between the service windows, offset from the segment cuts. part = segment exports one segment on its back; part = cartridge exports the tilt cartridge print ready.
Parameters
total_width, height and depth size the bar, lip sets the fascia drop, rim the bottom rim thickness and rounding the single radius for all rounded edges. tilting switches between fixed cups and tilt cartridges, max_tilt sets the designed tilt range and tilt_angle only poses the preview. spots and segments set the count of lights and print sections, segment_index picks the section shown. wall and plate_t shape the shell, gu10_hole_span matches the socket, cutaway opens the display view and color_body sets the display colour.
Use with your agent
{
"mcpServers": {
"remixcad": {
"type": "http",
"url": "https://remix-cad.vercel.app/api/mcp"
}
}
}get_model("mick/mirror-light@1.9.0")Returns the manifest, the source, the import closure and the license obligations. Full MCP setup.
Parameter table
Parsed from the Customizer annotations in main.scad| Name | Default | Range | Unit | Description |
|---|---|---|---|---|
| part | "all" | all, segment, cartridge | ||
| segment_index | 1 | 1 to 6 step 1 | ||
| cutaway | false | |||
| total_width | 500 | 300 to 800 step 10 | ||
| height | 100 | 70 to 140 step 5 | ||
| depth | 100 | 70 to 140 step 5 | ||
| rounding | 14 | 2 to 40 step 1 | ||
| spots | 3 | 2 to 5 step 1 | ||
| lip | 15 | 8 to 30 step 1 | ||
| rim | 2.5 | 2 to 12 step 0.5 | ||
| tilting | false | |||
| max_tilt | 15 | 5 to 20 step 1 | ||
| tilt_angle | 0 | -20 to 20 step 1 | ||
| segments | 3 | 1 to 6 step 1 | ||
| wall | 2.5 | 2 to 4 step 0.25 | ||
| plate_t | 3 | 2 to 5 step 0.5 | ||
| gu10_hole_span | 40 | 24 to 50 step 1 | ||
| smoothness | 96 | 24 to 160 step 8 | ||
| color_body | "White" | White, Silver, Gainsboro, DimGray, Black, SlateGray, FireBrick, SteelBlue, ForestGreen, Goldenrod |
Lineage
0 models depend on this oneOnly what this model came from and what came from it.
License
Whoever downloads this takes these obligations along- mick/mirror-light@1.9.0 is MIT
Source
main.scad is the entrypointmain.scad
// Bathroom mirror light bar. Remix of mick/lamp-fittings: the GU10 holder cups
// from that model are built into a wall mounted bar. Spots point down behind a
// front lip. Optional tilting: each spot becomes a cartridge pivoting fore and
// aft on 1.75 mm filament hinge pins in a ring on the bottom plate, with a
// countersunk pocket at each ring hole to secure the pin with glue or a melted
// mushroom head. Flat back with rounded top corners blending into spherical
// front corners, sharp bottom edge, service windows behind the spots. Split
// into printer bed sized segments joined on 4 mm dowels.
/* [Model] */
// The whole bar, one print segment laid flat, or one tilt cartridge print ready.
part = "all"; // [all, segment, cartridge]
// Which segment when part = segment.
segment_index = 1; // [1:1:6]
// Slice the display view open through the spots.
cutaway = false;
/* [Size] */
// Width of the bar in mm.
total_width = 500; // [300:10:800]
// Height of the front fascia in mm.
height = 100; // [70:5:140]
// Depth from the wall in mm.
depth = 100; // [70:5:140]
/* [Rounding] */
// One radius for all rounded edges: the top front edge, the vertical front edges, the corner blends and the top corners of the back outline. The back plane always stays flat against the wall and the bottom edge always stays sharp.
rounding = 14; // [2:1:40]
/* [Light] */
// Number of GU10 spots.
spots = 3; // [2:1:5]
// How far the front fascia drops past the lamp faces, hiding them from view.
lip = 15; // [8:1:30]
// Thickness of the visible rim around the bottom opening.
rim = 2.5; // [2:0.5:12]
/* [Tilting] */
// Make the spots tiltable: each spot becomes a cartridge that pivots forward and back on 1.75 mm filament hinge pins. Print one cartridge per spot with part = cartridge. Secure the pins in their pockets with CA glue or a melted end.
tilting = false;
// Designed tilt range in degrees to either side. The ring and plate opening are carved to clear this.
max_tilt = 15; // [5:1:20]
// Tilt of the cartridges in the preview only, degrees. Positive tilts forward.
tilt_angle = 0; // [-20:1:20]
/* [Build] */
// Number of print segments. Keep total_width / segments under your printer bed size.
segments = 3; // [1:1:6]
// Wall thickness of the shell.
wall = 2.5; // [2:0.25:4]
// Thickness of the bottom plate that carries the spots.
plate_t = 3; // [2:0.5:5]
/* [GU10 socket, measure yours] */
// Centre distance of the two fixing holes of your GU10 socket.
gu10_hole_span = 40; // [24:1:50]
/* [Quality] */
// Facets on round surfaces.
smoothness = 96; // [24:8:160]
/* [Colour] */
// Display colour of the body.
color_body = "White"; // [White, Silver, Gainsboro, DimGray, Black, SlateGray, FireBrick, SteelBlue, ForestGreen, Goldenrod]
/* [Hidden] */
$fn = smoothness;
eps = 0.01;
clearance = 0.3;
spot_len = 46; // GU10 lamp length without pins
cup_id = 50 + 2 * clearance; // bore for the 50 mm lamp face
cup_od = cup_id + 2 * wall;
plate_bot = lip;
plate_top = lip + plate_t;
cap_bot = lip + spot_len; // lamp face flush with the plate underside
seg_w = total_width / segments;
r_ = min(rounding, height / 2 - 2, depth / 2 - 2, total_width / 4);
r_i = max(r_ - wall, 1);
r_rim = max(r_ - rim, 1);
spacing = total_width / spots;
win_w = max(spacing - 56, 40); // service window width
win_z0 = plate_top + 4; // service window bottom
win_z1 = height - 14; // service window top
function sx(i) = (i + 0.5) * spacing;
kx1 = (sx(0) + sx(1)) / 2 - 12;
kx2 = (sx(spots - 2) + sx(spots - 1)) / 2 + 12;
// Tilting geometry
cart_od = cup_id + 2 * wall; // cartridge outer diameter
cart_h = spot_len + plate_t; // cartridge height including cap
pivot_rel = 15; // pivot above the lamp face
pivot_z = lip + pivot_rel;
gap_t = 1.5; // radial clearance cartridge to ring at the pivot
ring_wall = 2.5;
ring_od = cart_od + 2 * gap_t + 2 * ring_wall;
ring_top = pivot_z + 8;
tilt_show = max(-max_tilt, min(max_tilt, tilt_angle));
// ---- Shell: flat back with rounded top corners, rounded front, sharp bottom ----
module back_face_2d(x0, x1, z0, z1, r)
hull() {
translate([x0, z0]) square([x1 - x0, max(z1 - z0 - r, 0.1)]);
translate([x0 + r, z1 - r]) circle(r);
translate([x1 - r, z1 - r]) circle(r);
}
module bar_solid()
hull() {
translate([0, 1, 0]) rotate([90, 0, 0])
linear_extrude(1) back_face_2d(0, total_width, 0, height, r_);
for (px = [r_, total_width - r_]) {
translate([px, depth - r_, 0]) cylinder(r = r_, h = 1);
translate([px, depth - r_, height - r_]) sphere(r = r_);
}
translate([r_, depth - r_, height - r_])
rotate([0, 90, 0]) cylinder(r = r_, h = total_width - 2 * r_);
}
module cavity()
hull() {
translate([0, wall + 1, 0]) rotate([90, 0, 0])
linear_extrude(1)
back_face_2d(wall, total_width - wall, plate_top, height - wall, r_i);
for (px = [wall + r_i, total_width - wall - r_i]) {
translate([px, depth - wall - r_i, plate_top]) cylinder(r = r_i, h = 1);
translate([px, depth - wall - r_i, height - wall - r_i]) sphere(r = r_i);
}
translate([wall + r_i, depth - wall - r_i, height - wall - r_i])
rotate([0, 90, 0]) cylinder(r = r_i, h = total_width - 2 * (wall + r_i));
}
module plan_in()
hull() {
translate([rim, rim]) square([total_width - 2 * rim, 1]);
for (px = [rim + r_rim, total_width - rim - r_rim])
translate([px, depth - rim - r_rim]) circle(r = r_rim);
}
module trough()
translate([0, 0, -1]) linear_extrude(lip + 1) plan_in();
// ---- Service windows: one behind each spot, hidden by the wall ----
module rrect2(w, h, r)
hull()
for (dx = [r, w - r], dz = [r, h - r])
translate([dx, dz]) circle(r);
module service_windows()
for (i = [0:spots - 1])
translate([sx(i) - win_w / 2, wall + 1, win_z0])
rotate([90, 0, 0])
linear_extrude(wall + 2)
rrect2(win_w, win_z1 - win_z0, 6);
// ---- Fixed spot cups (construction from mick/lamp-fittings) ----
module cups()
for (i = [0:spots - 1])
translate([sx(i), depth / 2, plate_bot])
cylinder(d = cup_od, h = spot_len + plate_t);
module cup_bores()
for (i = [0:spots - 1])
translate([sx(i), depth / 2, -1])
cylinder(d = cup_id, h = cap_bot + 1);
module cap_holes()
for (i = [0:spots - 1])
translate([sx(i), depth / 2, cap_bot - 1]) {
cylinder(d = 30, h = plate_t + 2);
for (s = [-1, 1])
translate([s * gu10_hole_span / 2, 0, 0])
cylinder(d = 2.8, h = plate_t + 2);
}
// ---- Tilting: pivot rings, swept clearance and the cartridge ----
// The volume the cartridge sweeps between -max_tilt and +max_tilt, with clearance.
module cart_sweep()
hull()
for (a = [-max_tilt, 0, max_tilt])
translate([0, 0, pivot_rel])
rotate([a, 0, 0])
translate([0, 0, -pivot_rel - 1])
cylinder(d = cart_od + 2.4, h = cart_h + 2);
module rings()
for (i = [0:spots - 1])
translate([sx(i), depth / 2, plate_bot])
cylinder(d = ring_od, h = ring_top - plate_bot);
module ring_carve()
for (i = [0:spots - 1])
translate([sx(i), depth / 2, plate_bot])
cart_sweep();
module pivot_holes()
for (i = [0:spots - 1])
translate([sx(i), depth / 2, pivot_z]) {
rotate([0, 90, 0])
cylinder(d = 2.0, h = ring_od + 8, center = true);
// Countersunk pockets on the ring outside: seat for CA glue or a melted pin head.
for (s = [-1, 1])
translate([s * (ring_od / 2 - 0.6), 0, 0])
rotate([0, 90, 0])
cylinder(d = 4.5, h = 1.4, center = true);
}
// The tilt cartridge itself: the cup as a separate part with press fit pin holes.
module cartridge_part()
difference() {
cylinder(d = cart_od, h = cart_h);
translate([0, 0, -1]) cylinder(d = cup_id, h = spot_len + 1);
translate([0, 0, spot_len - 1]) cylinder(d = 30, h = plate_t + 2);
for (s = [-1, 1])
translate([s * gu10_hole_span / 2, 0, spot_len - 1])
cylinder(d = 2.8, h = plate_t + 2);
translate([0, 0, pivot_rel])
rotate([0, 90, 0])
cylinder(d = 1.7, h = cart_od + 2, center = true);
}
// ---- Segment joints ----
module join_blocks()
if (segments > 1)
for (j = [1:segments - 1]) {
xi = j * seg_w;
translate([xi - 12, wall, plate_top]) cube([24, 12, 12]);
translate([xi - 12, depth - wall - 12, plate_top]) cube([24, 12, 12]);
translate([xi - 12, depth / 2 - 6, height - wall - 12]) cube([24, 12, 12]);
}
module dowel_holes()
if (segments > 1)
for (j = [1:segments - 1]) {
xi = j * seg_w;
for (p = [[wall + 6, plate_top + 6],
[depth - wall - 6, plate_top + 6],
[depth / 2, height - wall - 6]])
translate([xi, p[0], p[1]])
rotate([0, 90, 0])
cylinder(d = 4.2, h = 24, center = true);
}
// ---- Wall mount ----
module keyholes()
for (kx = [kx1, kx2])
translate([kx, -1, 0]) rotate([-90, 0, 0]) {
translate([0, -(height - 35), 0]) cylinder(d = 9, h = wall + 2);
hull()
for (dz = [0, 12])
translate([0, -(height - 35) - dz, 0])
cylinder(d = 4.5, h = wall + 2);
}
// ---- Body ----
module body()
difference() {
union() {
difference() {
bar_solid();
cavity();
trough();
}
intersection() {
union() {
if (tilting) rings(); else cups();
join_blocks();
}
bar_solid();
}
}
if (tilting) {
ring_carve();
pivot_holes();
} else {
cup_bores();
cap_holes();
}
dowel_holes();
keyholes();
service_windows();
}
module spot_mock()
color("Gainsboro") {
cylinder(d = 50, h = 6);
translate([0, 0, 6]) cylinder(d1 = 50, d2 = 24, h = 32);
translate([0, 0, 38]) cylinder(d = 24, h = 8);
}
module display() {
color(color_body) body();
for (i = [0:spots - 1])
translate([sx(i), depth / 2, plate_bot])
if (tilting) {
translate([0, 0, pivot_rel])
rotate([tilt_show, 0, 0])
translate([0, 0, -pivot_rel]) {
color(color_body) cartridge_part();
spot_mock();
}
} else {
spot_mock();
}
}
// ---- Layout ----
if (part == "cartridge") {
translate([0, 0, cart_h]) rotate([180, 0, 0])
color(color_body) cartridge_part();
} else if (part == "segment") {
si = min(segment_index, segments);
rotate([90, 0, 0])
translate([-(si - 1) * seg_w, 0, 0])
intersection() {
color(color_body) body();
translate([(si - 1) * seg_w, -10, -10])
cube([seg_w, depth + 20, height + 20]);
}
} else {
if (cutaway)
difference() {
display();
translate([-10, -10, -10])
cube([total_width + 20, depth / 2 + 10, height + 20]);
}
else
display();
}
Comments
Context, not a score. Comments never move a model up or down the results.No comments yet
Printed it? A note about your material and the clearance you landed on saves the next person a failed print.
