{ "cells": [ { "cell_type": "markdown", "id": "dbc7c28a", "metadata": {}, "source": [ "# Tutorial 2 - Lens Export\n", "\n", "This notebook demonstrates how to create and export a lens geometry using the `diffinytrace` package.\n", "\n", "The workflow includes:\n", "- Setting up a B-spline surface for the lens geometry.\n", "- Converting the lens to a CAD solid.\n", "- Exporting the lens as an STL file for use in CAD software \n" ] }, { "cell_type": "code", "execution_count": 1, "id": "cfc21528", "metadata": {}, "outputs": [], "source": [ "import sys\n", "import os\n", "import gc\n", "import tqdm\n", "sys.path.insert(0, os.path.abspath(\"..\"))\n", "device = \"cuda:0\"\n", "results_folder = \"results/\"\n", "results_folder += \"lens_export/\"\n", "try:\n", " os.mkdir(results_folder)\n", "except:\n", " pass" ] }, { "cell_type": "markdown", "id": "e70c9088", "metadata": {}, "source": [ "Diffiny trace uses an older version of cadquery with which it is pretty easy to directly talk to open cascade. With this approach it is possible to export bspline lenses without fitting optical lens surfaces\n", "\n", "the function dit.export.cad.lens_to_solid returns an object that is understood by open cascade" ] }, { "cell_type": "code", "execution_count": 2, "id": "a3d748d2", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\marti\\anaconda3\\envs\\working\\Lib\\site-packages\\torch\\functional.py:505: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at C:\\actions-runner\\_work\\pytorch\\pytorch\\pytorch\\aten\\src\\ATen\\native\\TensorShape.cpp:4383.)\n", " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n" ] }, { "data": { "application/javascript": "\n\nfunction render(data, parent_element, ratio){\n \n // Initial setup\n const renderWindow = vtk.Rendering.Core.vtkRenderWindow.newInstance();\n const renderer = vtk.Rendering.Core.vtkRenderer.newInstance({ background: [1, 1, 1 ] });\n renderWindow.addRenderer(renderer);\n \n // iterate over all children children\n for (var el of data){ \n var trans = el.position;\n var rot = el.orientation;\n var rgba = el.color;\n var shape = el.shape;\n \n // load the inline data\n var reader = vtk.IO.XML.vtkXMLPolyDataReader.newInstance();\n const textEncoder = new TextEncoder();\n reader.parseAsArrayBuffer(textEncoder.encode(shape));\n\n // setup actor,mapper and add\n const mapper = vtk.Rendering.Core.vtkMapper.newInstance();\n mapper.setInputConnection(reader.getOutputPort());\n mapper.setResolveCoincidentTopologyToPolygonOffset();\n mapper.setResolveCoincidentTopologyPolygonOffsetParameters(0.9,20);\n\n const actor = vtk.Rendering.Core.vtkActor.newInstance();\n actor.setMapper(mapper);\n\n // set color and position\n actor.getProperty().setColor(rgba.slice(0,3));\n actor.getProperty().setOpacity(rgba[3]);\n \n actor.rotateZ(rot[2]*180/Math.PI);\n actor.rotateY(rot[1]*180/Math.PI);\n actor.rotateX(rot[0]*180/Math.PI);\n \n actor.setPosition(trans);\n\n renderer.addActor(actor);\n\n };\n \n renderer.resetCamera();\n \n const openglRenderWindow = vtk.Rendering.OpenGL.vtkRenderWindow.newInstance();\n renderWindow.addView(openglRenderWindow);\n\n // Add output to the \"parent element\"\n var container;\n var dims;\n \n if(typeof(parent_element.appendChild) !== \"undefined\"){\n container = document.createElement(\"div\");\n parent_element.appendChild(container);\n dims = parent_element.getBoundingClientRect();\n }else{\n container = parent_element.append(\"
\").children(\"div:last-child\").get(0);\n dims = parent_element.get(0).getBoundingClientRect();\n };\n\n openglRenderWindow.setContainer(container);\n \n // handle size\n if (ratio){\n openglRenderWindow.setSize(dims.width, dims.width*ratio);\n }else{\n openglRenderWindow.setSize(dims.width, dims.height);\n };\n \n // Interaction setup\n const interact_style = vtk.Interaction.Style.vtkInteractorStyleManipulator.newInstance();\n\n const manips = {\n rot: vtk.Interaction.Manipulators.vtkMouseCameraTrackballRotateManipulator.newInstance(),\n pan: vtk.Interaction.Manipulators.vtkMouseCameraTrackballPanManipulator.newInstance(),\n zoom1: vtk.Interaction.Manipulators.vtkMouseCameraTrackballZoomManipulator.newInstance(),\n zoom2: vtk.Interaction.Manipulators.vtkMouseCameraTrackballZoomManipulator.newInstance(),\n roll: vtk.Interaction.Manipulators.vtkMouseCameraTrackballRollManipulator.newInstance(),\n };\n\n manips.rot.setUseFocalPointAsCenterOfRotation(true);\n manips.zoom1.setControl(true);\n manips.zoom2.setScrollEnabled(true);\n manips.roll.setShift(true);\n manips.pan.setButton(2);\n\n for (var k in manips){\n interact_style.addMouseManipulator(manips[k]);\n };\n\n const interactor = vtk.Rendering.Core.vtkRenderWindowInteractor.newInstance();\n interactor.setView(openglRenderWindow);\n interactor.initialize();\n interactor.bindEvents(container);\n interactor.setInteractorStyle(interact_style);\n\n // Orientation marker\n\n const axes = vtk.Rendering.Core.vtkAnnotatedCubeActor.newInstance();\n axes.setXPlusFaceProperty({text: '+X'});\n axes.setXMinusFaceProperty({text: '-X'});\n axes.setYPlusFaceProperty({text: '+Y'});\n axes.setYMinusFaceProperty({text: '-Y'});\n axes.setZPlusFaceProperty({text: '+Z'});\n axes.setZMinusFaceProperty({text: '-Z'});\n\n const orientationWidget = vtk.Interaction.Widgets.vtkOrientationMarkerWidget.newInstance({\n actor: axes,\n interactor: interactor });\n orientationWidget.setEnabled(true);\n orientationWidget.setViewportCorner(vtk.Interaction.Widgets.vtkOrientationMarkerWidget.Corners.BOTTOM_LEFT);\n orientationWidget.setViewportSize(0.2);\n\n};\n\n\nfunction load_and_render(parent_element)\n{\nnew Promise(\n function(resolve, reject)\n {\n if (typeof(require) !== \"undefined\" ){\n require.config({\n \"paths\": {\"vtk\": \"https://unpkg.com/vtk\"},\n });\n require([\"vtk\"], resolve, reject);\n } else if ( typeof(vtk) === \"undefined\" ){\n var script = document.createElement(\"script\");\n \tscript.onload = resolve;\n \tscript.onerror = reject;\n \tscript.src = \"https://unpkg.com/vtk.js\";\n \tdocument.head.appendChild(script);\n } else { resolve() };\n }\n).then(() => {\n var data = [{\"shape\": \"\\n