diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6d80fa84..dfeb053a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,7 @@ Added - Option to pass background image to ``utils.io.load_data``. - Option to set image resolution with ``hardware.utils.display`` function. +- Add utility for mask adapter generation in ``lenseless.hardware.fabrication`` - Option to add simulated background in ``util.dataset`` - Auxiliary of reconstructing output from pre-processor (not working). - Option to set focal range for MultiLensArray. @@ -62,6 +63,7 @@ Added - Fallback for normalization if data not in 8bit range (``lensless.utils.io.save_image``). - Add utilities for fabricating masks with 3D printing (``lensless.hardware.fabrication``). - WandB support. +- Script for Mask adapter generation and update new mount in doc Changed ~~~~~~~ diff --git a/docs/source/fabrication.rst b/docs/source/fabrication.rst index 83fc3963..d4ac9bdd 100644 --- a/docs/source/fabrication.rst +++ b/docs/source/fabrication.rst @@ -7,6 +7,14 @@ :alt: Mount components. :align: center + + Note that the most recent version of the mount looks like this, with the addition of stoppers, + to prevent the mask from scratching the Pi Camera. + This new version of the mount can be found `here `_ + + .. image:: mount_V4.png + :alt: New Inner Mount w/ Stopper. + :align: center Mask3DModel ~~~~~~~~~~~ @@ -22,6 +30,14 @@ :members: :special-members: __init__ + Because newer versions of the masks' size are smaller, the following adapter enables + them to be used with the current mounts design. + + .. image:: mask_adapter.png + :alt: Mask Adapter. + :align: center + + MultiLensMold ~~~~~~~~~~~~~ diff --git a/docs/source/mask_adapter.png b/docs/source/mask_adapter.png new file mode 100644 index 00000000..e8cb7eab Binary files /dev/null and b/docs/source/mask_adapter.png differ diff --git a/docs/source/mount_V4.png b/docs/source/mount_V4.png new file mode 100644 index 00000000..1f8d7703 Binary files /dev/null and b/docs/source/mount_V4.png differ diff --git a/lensless/hardware/fabrication.py b/lensless/hardware/fabrication.py index 39425fd8..411d9f96 100644 --- a/lensless/hardware/fabrication.py +++ b/lensless/hardware/fabrication.py @@ -520,3 +520,74 @@ def generate(self, mask: np.ndarray, mask_size, depth: float) -> cq.Workplane: ) return model + + +def create_mask_adapter( + fp, mask_w, mask_h, mask_d, adapter_w=12.90, adapter_h=9.90, support_w=0.4, support_d=0.4 +): + """ + Create and store an adapter for a mask given its measurements. + Warning: Friction-fitted parts are to be made 0.05-0.1 mm smaller + (ex: mask's width must fit in adapter's, adapter's width must fit in mount's, ...) + + Parameters + ---------- + fp : string + Folder in which to store the generated stl file. + mask_w : float + Length of the mask's width in mm. + mask_h : float + Length of the mask's height in mm. + mask_d : float + Thickness of the mask in mm. + adapter_w : float + Length of the adapter's width in mm. + default: current mount dim (13 - 0.1 mm) + adapter_h : float + Length of the adapter's height in mm. + default: current mount dim (1.5 - 0.1 mm) + support_w : float + Width of the small extrusion to support the mask in mm + default : current mount's dim (10 - 0.1 mm) + support_d : float + Thickness of the small extrusion to support the mask in mm + """ + epsilon = 0.2 + + # Make sure the dimension are realistic + assert mask_w < adapter_w - epsilon, "mask's width too big" + assert mask_h < adapter_h - epsilon, "mask's height too big" + assert mask_w - 2 * support_w > epsilon, "mask's support too big" + assert mask_h - 2 * support_w > epsilon, "mask's support too big" + assert os.path.exists(fp), "folder does not exist" + + file_name = os.path.join(fp, "mask_adapter.stl") + + # Prevent accidental overwrite + if os.path.isfile(file_name): + print("Warning: already find mask_adapter.stl at " + fp) + if input("Overwrite ? y/n") != "y": + print("Abort adapter generation.") + return + + # Construct the outer layer of the mask + adapter = ( + cq.Workplane("front") + .rect(adapter_w, adapter_h) + .rect(mask_w, mask_h) + .extrude(mask_d + support_d) + ) + + # Construct the dent to keep the mask secure + support = ( + cq.Workplane("front") + .rect(mask_w, mask_h) + .rect(mask_w - 2 * support_w, mask_h - 2 * support_w) + .extrude(support_d) + ) + + # Join the 2 shape in one + adapter = adapter.union(support) + + # Save into path + cq.exporters.export(adapter, file_name)