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 straight down through openings in a recessed bottom plate. The front fascia runs 15 mm past that plate, so from the front you see a clean bar and no lamps: the light washes down over the mirror. The top edge, bottom edge and the vertical end edges each have their own rounding radius. The GU10 holder cups are the ones from mick/lamp-fittings, built into the body. The bar is split into three segments with dowel joints because a 500 mm part does not fit a small printer bed: 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 · r_top 18 · r_bottom 6 · r_side 10 · spots 3 · lip 15 · 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.1.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 straight down through openings in a recessed bottom plate. The front fascia runs 15 mm past that plate, so from the front you see a clean bar and no lamps: the light washes down over the mirror. The top edge, bottom edge and the vertical end edges each have their own rounding radius. The GU10 holder cups are the ones from mick/lamp-fittings, built into the body. The bar is split into three segments with dowel joints because a 500 mm part does not fit a small printer bed: at the defaults each segment is 167 x 100 x 100 mm, within an A1 Mini.
What you use it for
Print all segments, glue them on 4 mm dowels or filament pins, screw a store bought GU10 socket on top of each cup from inside, wire the sockets in parallel and hang the bar on two screws through the keyhole slots in the back. The lamp twists in from below and sits flush with the bottom plate. Use LED GU10 lamps only, print in PETG or ASA for a bathroom, keep the fixture out of the shower zones and have the mains connection checked if you are not certain of it.
Design notes
The shell is the intersection of three rounded profiles: the side view carries the top and bottom edge radii, the top view carries the vertical end edge radius and the end view softens the top corners. The back face stays flat against the wall in all three, and the cavity is the same intersection inset by one wall so the walls stay constant thickness under the rounding. The trough in the underside is inset past the bottom and end radii so the fascia never thins out. Each cup is a tube with a top cap that has the pin pass-through and two fixing holes for the socket, the same construction as the parent model. Join blocks carry three dowels per cut, keyhole slots and a cable entry go through the flat back. part = segment exports one segment on its back for printing; some support is needed inside. Choose spots and segments so the cuts miss the cups: three and three is safe.
Parameters
total_width, height and depth size the bar and lip sets how far the fascia drops past the lamp faces. r_top, r_bottom and r_side set the rounding of the top edge, the bottom edge and the vertical end edges. spots and segments set the count of lights and print sections, segment_index picks which section part = segment shows. 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.1.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 | ||
| 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 | ||
| r_top | 18 | 4 to 30 step 1 | ||
| r_bottom | 6 | 0 to 12 step 1 | ||
| r_side | 10 | 2 to 20 step 1 | ||
| spots | 3 | 2 to 5 step 1 | ||
| lip | 15 | 8 to 30 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.1.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, so the lamps are hidden from the front. The shell is rounded on the
// top edge, bottom edge and vertical end edges, flat against the wall at the back.
// Split into segments that fit a small printer bed and join on 4 mm dowels.
/* [Model] */
// The whole bar, or one print segment laid flat.
part = "all"; // [all, segment]
// 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.
total_width = 500; // [300:10:800]
// Height of the front fascia.
height = 100; // [70:5:140]
// Depth from the wall.
depth = 100; // [70:5:140]
/* [Rounding] */
// Rounding of the top front edge.
r_top = 18; // [4:1:30]
// Rounding of the bottom front edge.
r_bottom = 6; // [0:1:12]
// Rounding of the vertical end edges.
r_side = 10; // [2:1:20]
/* [Light] */
// Number of GU10 spots.
spots = 3; // [2:1:5]
// How far the fascia drops past the lamp faces.
lip = 15; // [8:1:30]
/* [Build] */
// Number of print segments. Keep total_width / segments under your bed size.
segments = 3; // [1:1:6]
// Wall thickness.
wall = 2.5; // [2:0.25:4]
// Thickness of the bottom plate.
plate_t = 3; // [2:0.5:5]
/* [GU10 socket, measure yours] */
// Centre distance of the socket fixing holes.
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 sits flush with the plate underside
seg_w = total_width / segments;
rt_ = min(r_top, height / 2 - 2, depth / 2 - 2);
rb_ = max(min(r_bottom, depth / 4), 0.3);
rs_ = min(r_side, total_width / 4, depth / 2 - 2);
rt_i = max(rt_ - wall, 1);
rs_i = max(rs_ - wall, 1);
function sx(i) = (i + 0.5) * total_width / spots;
// ---- Shell profiles: back edge square in all three views ----
// Side view (u = depth, v = height): top and bottom front rounding.
module prof_yz()
hull() {
translate([depth - rt_, height - rt_]) circle(r = rt_);
translate([depth - rb_, rb_]) circle(r = rb_);
square([1, height]);
}
module prof_yz_in()
hull() {
translate([depth - wall - rt_i, height - wall - rt_i]) circle(r = rt_i);
translate([wall, plate_top]) square([1, height - wall - plate_top]);
translate([depth - wall - 1, plate_top]) square(1);
}
// Top view (u = width, v = depth): vertical end edge rounding.
module prof_xy()
hull() {
for (px = [rs_, total_width - rs_])
translate([px, depth - rs_]) circle(r = rs_);
square([total_width, 1]);
}
module prof_xy_in()
hull() {
for (px = [wall + rs_i, total_width - wall - rs_i])
translate([px, depth - wall - rs_i]) circle(r = rs_i);
translate([wall, wall]) square([total_width - 2 * wall, 1]);
}
// End view (u = width, v = height): soften the top end corners.
module prof_xz()
hull() {
for (px = [rs_, total_width - rs_])
translate([px, height - rs_]) circle(r = rs_);
square([total_width, 1]);
}
module prof_xz_in()
hull() {
for (px = [wall + rs_i, total_width - wall - rs_i])
translate([px, height - wall - rs_i]) circle(r = rs_i);
translate([wall, wall]) square([total_width - 2 * wall, 1]);
}
module bar_solid()
intersection() {
rotate([90, 0, 90]) linear_extrude(total_width) prof_yz();
linear_extrude(height) prof_xy();
translate([0, depth, 0]) rotate([90, 0, 0]) linear_extrude(depth) prof_xz();
}
module cavity()
intersection() {
rotate([90, 0, 90]) linear_extrude(total_width) prof_yz_in();
linear_extrude(height) prof_xy_in();
translate([0, depth, 0]) rotate([90, 0, 0]) linear_extrude(depth) prof_xz_in();
}
module trough()
translate([wall + rs_, wall, -1])
cube([total_width - 2 * (wall + rs_), depth - 2 * wall - rb_, lip + 1]);
// ---- 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);
}
// ---- 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 and cable ----
module keyholes()
for (kx = [0.18 * total_width, 0.82 * total_width])
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);
}
module cable_hole()
translate([total_width / 2, -1, height - 25])
rotate([-90, 0, 0])
cylinder(d = 8, h = wall + 2);
// ---- Body ----
module body()
difference() {
union() {
difference() {
bar_solid();
cavity();
trough();
}
intersection() {
union() {
cups();
join_blocks();
}
bar_solid();
}
}
cup_bores();
cap_holes();
dowel_holes();
keyholes();
cable_hole();
}
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]) spot_mock();
}
// ---- Layout ----
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.
