From 17d75a33cc2cc6e4808979b600cc752c21976749 Mon Sep 17 00:00:00 2001 From: Aldo Ruiz Luna Date: Fri, 2 Oct 2026 15:19:11 -0600 Subject: [PATCH 1/2] feat(microscope-slide-hyperobject): explicit scale_comp parameters behind the legacy material injection Declare scale_comp_x/y/z (unitless, default 1.0) and read them in both kernels. While yantra4d RENDER_MATERIAL_INJECTION is on, an injected mat_shrinkage_* value still wins, so today's geometry is unchanged; the legacy branch is marked for removal at the flip. The library function slide_slot_width() gains the same precedence for fit_clearance_slide over mat_clear_slide. mat_clear_press and mat_clear_loose were never read and are no longer declared. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Aldo Ruiz Luna --- microscope-slide-hyperobject/project.json | 66 +++++++++++++++++++++++ microscope-slide-hyperobject/slide.py | 9 ++++ microscope-slide-hyperobject/slide.scad | 42 +++++++++++---- 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/microscope-slide-hyperobject/project.json b/microscope-slide-hyperobject/project.json index 5d78d510..115394df 100644 --- a/microscope-slide-hyperobject/project.json +++ b/microscope-slide-hyperobject/project.json @@ -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": [ diff --git a/microscope-slide-hyperobject/slide.py b/microscope-slide-hyperobject/slide.py index 18979000..4c78e097 100644 --- a/microscope-slide-hyperobject/slide.py +++ b/microscope-slide-hyperobject/slide.py @@ -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() diff --git a/microscope-slide-hyperobject/slide.scad b/microscope-slide-hyperobject/slide.scad index 4009aca9..388ab649 100644 --- a/microscope-slide-hyperobject/slide.scad +++ b/microscope-slide-hyperobject/slide.scad @@ -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) { @@ -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); From 429667e6dc4ec30cb262d4d5d02daefec2d33573 Mon Sep 17 00:00:00 2001 From: Aldo Ruiz Luna Date: Fri, 2 Oct 2026 15:21:20 -0600 Subject: [PATCH 2/2] docs(microscope-slide-hyperobject): document the scale and fit compensation parameters Co-Authored-By: Claude Opus 5.5 Signed-off-by: Aldo Ruiz Luna --- microscope-slide-hyperobject/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/microscope-slide-hyperobject/README.md b/microscope-slide-hyperobject/README.md index 50053f83..3460e42b 100644 --- a/microscope-slide-hyperobject/README.md +++ b/microscope-slide-hyperobject/README.md @@ -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: