Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions microscope-slide-hyperobject/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ The following standard parameters are available in the configurator, rendering t
- **3: ISO 8255 #1 Cover Glass:** 22.0mm x 22.0mm x 0.15mm
- **4: Custom:** Dynamically adjust length, width (10-55mm), and thickness (down to 0.1mm for microfluidics coverslips).

### Scale and fit compensation
- **`scale_comp_x`, `scale_comp_y`, `scale_comp_z`** (unitless, default 1.0, range 0.9-1.1): scale factors applied to the slide body in both kernels. A caller that resolves shrinkage elsewhere (for example a semantic layer that knows the print material) passes the numbers here; the cartridge itself names no material.
- **`fit_clearance_slide`** (mm, default 0.0): extra clearance that the library function `slide_slot_width()` adds to a slot. It is a library input for cartridges that build slots from `slide.scad`, such as `microscope-slide-holder`; this cartridge renders no slot and does not declare it.
- Legacy: while the Yantra4D flag `RENDER_MATERIAL_INJECTION` is on, a request naming `target_material` still injects `mat_shrinkage_*` and `mat_clear_slide`, and an injected value wins over the explicit parameter, so those renders are unchanged. That branch is marked in `slide.scad` for removal when the flag is turned off.

## Using as a CDG Library (Backward Compatibility)
To include the slide retention geometries in your own Yantra4D project, add this repository as a submodule:

Expand Down
66 changes: 66 additions & 0 deletions microscope-slide-hyperobject/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,72 @@
"en": "Custom Thickness (mm)"
},
"group": "slide"
},
{
"id": "scale_comp_x",
"type": "slider",
"default": 1.0,
"min": 0.9,
"max": 1.1,
"step": 0.001,
"label": {
"en": "Scale compensation X (factor)",
"es": "Compensación de escala X (factor)",
"fr": "Compensation d'échelle X (facteur)",
"pt": "Compensação de escala X (fator)"
},
"tooltip": {
"en": "Unitless factor applied to the slide body along X; 1.0 leaves it unscaled. A caller that resolves shrinkage elsewhere passes the number here.",
"es": "Factor sin unidades aplicado al cuerpo de la laminilla en X; 1.0 lo deja sin escalar. Quien resuelve la contracción en otro lugar pasa aquí el número.",
"fr": "Facteur sans unité appliqué au corps de la lame selon X ; 1,0 le laisse inchangé. Un appelant qui calcule le retrait ailleurs transmet ici la valeur.",
"pt": "Fator sem unidade aplicado ao corpo da lâmina em X; 1,0 não altera a escala. Quem resolve a contração em outro lugar passa aqui o número."
},
"group": "compensation",
"visibility_level": "advanced"
},
{
"id": "scale_comp_y",
"type": "slider",
"default": 1.0,
"min": 0.9,
"max": 1.1,
"step": 0.001,
"label": {
"en": "Scale compensation Y (factor)",
"es": "Compensación de escala Y (factor)",
"fr": "Compensation d'échelle Y (facteur)",
"pt": "Compensação de escala Y (fator)"
},
"tooltip": {
"en": "Unitless factor applied to the slide body along Y; 1.0 leaves it unscaled. A caller that resolves shrinkage elsewhere passes the number here.",
"es": "Factor sin unidades aplicado al cuerpo de la laminilla en Y; 1.0 lo deja sin escalar. Quien resuelve la contracción en otro lugar pasa aquí el número.",
"fr": "Facteur sans unité appliqué au corps de la lame selon Y ; 1,0 le laisse inchangé. Un appelant qui calcule le retrait ailleurs transmet ici la valeur.",
"pt": "Fator sem unidade aplicado ao corpo da lâmina em Y; 1,0 não altera a escala. Quem resolve a contração em outro lugar passa aqui o número."
},
"group": "compensation",
"visibility_level": "advanced"
},
{
"id": "scale_comp_z",
"type": "slider",
"default": 1.0,
"min": 0.9,
"max": 1.1,
"step": 0.001,
"label": {
"en": "Scale compensation Z (factor)",
"es": "Compensación de escala Z (factor)",
"fr": "Compensation d'échelle Z (facteur)",
"pt": "Compensação de escala Z (fator)"
},
"tooltip": {
"en": "Unitless factor applied to the slide body along Z; 1.0 leaves it unscaled. A caller that resolves shrinkage elsewhere passes the number here.",
"es": "Factor sin unidades aplicado al cuerpo de la laminilla en Z; 1.0 lo deja sin escalar. Quien resuelve la contracción en otro lugar pasa aquí el número.",
"fr": "Facteur sans unité appliqué au corps de la lame selon Z ; 1,0 le laisse inchangé. Un appelant qui calcule le retrait ailleurs transmet ici la valeur.",
"pt": "Fator sem unidade aplicado ao corpo da lâmina em Z; 1,0 não altera a escala. Quem resolve a contração em outro lugar passa aqui o número."
},
"group": "compensation",
"visibility_level": "advanced"
}
],
"constraints": [
Expand Down
9 changes: 9 additions & 0 deletions microscope-slide-hyperobject/slide.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ def build(params):
else:
length, width, thickness = SLIDE_DIMS.get(standard, SLIDE_DIMS[0])

# Scale compensation (unitless, 1.0 = none), the explicit parameters that
# slide.scad applies with scale() about the origin. The body is centred,
# so scaling its dimensions is the same transform. This twin never read
# the legacy injected mat_shrinkage_* values and still does not: its
# output with yantra4d RENDER_MATERIAL_INJECTION on is unchanged.
length *= float(params.get('scale_comp_x', 1.0))
width *= float(params.get('scale_comp_y', 1.0))
thickness *= float(params.get('scale_comp_z', 1.0))

# CQ box() is centered by default, matching OpenSCAD center=true.
result = cq.Workplane("XY").box(length, width, thickness)
return result.clean()
Expand Down
42 changes: 31 additions & 11 deletions microscope-slide-hyperobject/slide.scad
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
// ----------------------------------------------------
// Material Hyperobject Compensations
// (Passed dynamically by the Commons API)
// Fit and scale compensation (explicit geometry inputs)
// ----------------------------------------------------
mat_shrinkage_x = 1.0;
mat_shrinkage_y = 1.0;
mat_shrinkage_z = 1.0;
// scale_comp_x/y/z: unitless scale factors applied to the slide body
// (1.0 = none). Manifest parameters of microscope-slide-hyperobject.
scale_comp_x = 1.0;
scale_comp_y = 1.0;
scale_comp_z = 1.0;
// fit_clearance_slide: extra slot clearance in mm that slide_slot_width()
// adds for a sliding fit (0 = none). A library input: microscope-slide-holder
// declares it; microscope-slide-hyperobject renders no slot, so it does not.
fit_clearance_slide = 0.0;

mat_clear_press = 0.0;
mat_clear_slide = 0.0;
mat_clear_loose = 0.0;
// LEGACY material injection. REMOVE AT THE FLIP of the yantra4d flag
// RENDER_MATERIAL_INJECTION (owner ruling "flag now, flip later").
// While that flag is on, a render request naming target_material makes the
// platform pass the material card's mat_shrinkage_x/y/z and mat_clear_slide
// with -D. They are undef unless injected, and an injected value WINS over
// the explicit parameter above, so a render with the flag on is unchanged.
// At the flip, delete these four assignments and _legacy_or() and read the
// explicit parameters directly. mat_clear_press and mat_clear_loose were
// declared here but never read, so they are no longer declared.
mat_shrinkage_x = undef;
mat_shrinkage_y = undef;
mat_shrinkage_z = undef;
mat_clear_slide = undef;
function _legacy_or(legacy, explicit) = is_undef(legacy) ? explicit : legacy;

// Standard Microscope Slide Dimensions (ISO 8037)
function slide_slot_width(thickness, tolerance) = thickness + tolerance + mat_clear_slide + 0.1;
function slide_slot_width(thickness, tolerance) =
thickness + tolerance + _legacy_or(mat_clear_slide, fit_clearance_slide) + 0.1;
function slide_pitch(slot_w, rib_w) = slot_w + rib_w;

module slide_retention_rib(height, depth, root_w, tip_w, chamfer_h) {
Expand Down Expand Up @@ -72,8 +89,11 @@ render_mode = 0; // [0:main]
if (render_mode == 0) {
// Material simulation logic for transparency via OpenSCAD nightly alpha
color([0.8, 0.9, 0.9, 0.4]) {
// Apply Material Hyperobject Shrinkage Compensation
scale([mat_shrinkage_x, mat_shrinkage_y, mat_shrinkage_z]) {
// Scale compensation: the explicit scale_comp_* parameters, or the legacy
// injected mat_shrinkage_* while the platform still injects them.
scale([_legacy_or(mat_shrinkage_x, scale_comp_x),
_legacy_or(mat_shrinkage_y, scale_comp_y),
_legacy_or(mat_shrinkage_z, scale_comp_z)]) {
if (slide_standard == 0) {
// ISO 8037-1 Primary
iso_8037_slide(76.0, 26.0, 1.0);
Expand Down
Loading