{"id":1084,"date":"2020-02-26T11:25:03","date_gmt":"2020-02-26T10:25:03","guid":{"rendered":"https:\/\/www.pschatzmann.ch\/home\/?p=1084"},"modified":"2020-11-21T22:22:46","modified_gmt":"2020-11-21T21:22:46","slug":"an-openscad-kernel-in-jupyter","status":"publish","type":"post","link":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/","title":{"rendered":"An OpenSCAD Kernel for Jupyter"},"content":{"rendered":"<p>I was missing a <a href=\"https:\/\/jupyter.org\/\">Jupyter<\/a> Kernel for <a href=\"https:\/\/www.openscad.org\/\">OpenSCAD<\/a>. There are already different existing projects that try to bring the OpenSCAD functionality to Jupyter:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/nickc92\/ViewSCAD\">ViewSCAD<\/a> is providing a Python API over OpenSCAD<\/li>\n<li><a href=\"https:\/\/github.com\/pschatzmann\/scad4j\">SCAD4<\/a> is providing an API for JVM based Languages<\/li>\n<\/ul>\n<p>But you can&#8217;t use the OpenSCAD language itself in the Jupyter cells. So I decided to take up the challenge and spend a couple of days on this topic.<\/p>\n<p>The initial idea was to use the the OpenSCAD source code which has been implemented in C++ together with the <a href=\"https:\/\/github.com\/jupyter-xeus\/xeus\">Xeus C++ Kernel framework<\/a> to implement the Kernel. Not knowing the OpenSCAD API, the first step would be to compile OpenSCAD as dynamic library so that I can explore the functionality in <a href=\"https:\/\/jupyter.org\/\">Jupyter<\/a> using the <a href=\"https:\/\/github.com\/jupyter-xeus\/xeus-cling\">Xeus Cling Kernel<\/a>. Unfortunately the process to compile into dynamic libraries seems to be broken. In addition I found some statements that OpenSCAD as API is not supported, so I gave up on this approach.<\/p>\n<p>The easier way seems to be to be to implement a simple <a href=\"https:\/\/jupyter-client.readthedocs.io\/en\/stable\/wrapperkernels.html\">Python Wrapper Kernel<\/a> over the openscad command line tool. So it was time to think about the <strong>overall logic.<\/strong><\/p>\n<p>Usually you can integrate an existing runtime environment that is helping you to manage state. In our case however we have one input (the openSCAD code) which is translated into one single output 2d or 3d file. A Jupyter notebook consists of multiple cells and each submits code to be evaluated. So we have <strong>many inputs<\/strong> that we need to match with <strong>many outputs.<\/strong><\/p>\n<p>A <strong>first idea<\/strong> was to build a <strong>complete OpenSCAD parser<\/strong> that is used to manage the overall state and that can also be used to render only the sub-parts that need be displayed as a result of a cell evaluation.\u00a0 Unfortunately I did not find any complete BNF or Extended BNF definitions on the internet that I could use to generate the parser in Python. So I did not like the effort that would be needed to implement this approach either.<\/p>\n<p>Finally I went for a <strong>simplified<\/strong> <strong>parser<\/strong> which supports some <strong>magic commands<\/strong> &#8211; mainly to drive the <strong>display<\/strong> and that is able to handle <strong>modules<\/strong> and <strong>function:<\/strong> When we submit the same cell that contains module definitions (potentially multiple times) we need to make sure that in the end the same module exists only once in the overall state.<\/p>\n<p>Here is a <strong>demo workbook<\/strong> which demonstrates the functionality. The the installation instructions and source code can be found on <a href=\"https:\/\/github.com\/pschatzmann\/IOpenSCAD\">Github<\/a><\/p>\n<p><script src=\"https:\/\/gist.github.com\/pschatzmann\/d3d043161f255be90f22dc4d19969f09.js\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was missing a Jupyter Kernel for OpenSCAD. There are already different existing projects that try to bring the OpenSCAD functionality to Jupyter: ViewSCAD is providing a Python API over OpenSCAD SCAD4 is providing an API for JVM based Languages But you can&#8217;t use the OpenSCAD language itself in the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1088,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[17],"tags":[],"class_list":["post-1084","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-3d-printing"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>An OpenSCAD Kernel for Jupyter - Phil Schatzmann<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An OpenSCAD Kernel for Jupyter - Phil Schatzmann\" \/>\n<meta property=\"og:description\" content=\"I was missing a Jupyter Kernel for OpenSCAD. There are already different existing projects that try to bring the OpenSCAD functionality to Jupyter: ViewSCAD is providing a Python API over OpenSCAD SCAD4 is providing an API for JVM based Languages But you can&#8217;t use the OpenSCAD language itself in the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/\" \/>\n<meta property=\"og:site_name\" content=\"Phil Schatzmann\" \/>\n<meta property=\"article:published_time\" content=\"2020-02-26T10:25:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-11-21T21:22:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2020\/02\/Demo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"pschatzmann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"pschatzmann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/\"},\"author\":{\"name\":\"pschatzmann\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"headline\":\"An OpenSCAD Kernel for Jupyter\",\"datePublished\":\"2020-02-26T10:25:03+00:00\",\"dateModified\":\"2020-11-21T21:22:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/\"},\"wordCount\":421,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Demo.png\",\"articleSection\":[\"3D Printing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/\",\"name\":\"An OpenSCAD Kernel for Jupyter - Phil Schatzmann\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Demo.png\",\"datePublished\":\"2020-02-26T10:25:03+00:00\",\"dateModified\":\"2020-11-21T21:22:46+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Demo.png\",\"contentUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Demo.png\",\"width\":512,\"height\":512},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2020\\\/02\\\/26\\\/an-openscad-kernel-in-jupyter\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"An OpenSCAD Kernel for Jupyter\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#website\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/\",\"name\":\"Phil Schatzmann Consulting\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\",\"name\":\"pschatzmann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\",\"contentUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\",\"width\":305,\"height\":305,\"caption\":\"pschatzmann\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"An OpenSCAD Kernel for Jupyter - Phil Schatzmann","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/","og_locale":"en_US","og_type":"article","og_title":"An OpenSCAD Kernel for Jupyter - Phil Schatzmann","og_description":"I was missing a Jupyter Kernel for OpenSCAD. There are already different existing projects that try to bring the OpenSCAD functionality to Jupyter: ViewSCAD is providing a Python API over OpenSCAD SCAD4 is providing an API for JVM based Languages But you can&#8217;t use the OpenSCAD language itself in the [&hellip;]","og_url":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/","og_site_name":"Phil Schatzmann","article_published_time":"2020-02-26T10:25:03+00:00","article_modified_time":"2020-11-21T21:22:46+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2020\/02\/Demo.png","type":"image\/png"}],"author":"pschatzmann","twitter_card":"summary_large_image","twitter_misc":{"Written by":"pschatzmann","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#article","isPartOf":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/"},"author":{"name":"pschatzmann","@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"headline":"An OpenSCAD Kernel for Jupyter","datePublished":"2020-02-26T10:25:03+00:00","dateModified":"2020-11-21T21:22:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/"},"wordCount":421,"commentCount":1,"publisher":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"image":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2020\/02\/Demo.png","articleSection":["3D Printing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/","url":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/","name":"An OpenSCAD Kernel for Jupyter - Phil Schatzmann","isPartOf":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#primaryimage"},"image":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2020\/02\/Demo.png","datePublished":"2020-02-26T10:25:03+00:00","dateModified":"2020-11-21T21:22:46+00:00","breadcrumb":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#primaryimage","url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2020\/02\/Demo.png","contentUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2020\/02\/Demo.png","width":512,"height":512},{"@type":"BreadcrumbList","@id":"https:\/\/www.pschatzmann.ch\/home\/2020\/02\/26\/an-openscad-kernel-in-jupyter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pschatzmann.ch\/home\/"},{"@type":"ListItem","position":2,"name":"An OpenSCAD Kernel for Jupyter"}]},{"@type":"WebSite","@id":"https:\/\/www.pschatzmann.ch\/home\/#website","url":"https:\/\/www.pschatzmann.ch\/home\/","name":"Phil Schatzmann Consulting","description":"","publisher":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pschatzmann.ch\/home\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1","name":"pschatzmann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png","url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png","contentUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png","width":305,"height":305,"caption":"pschatzmann"},"logo":{"@id":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png"}}]}},"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/1084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/comments?post=1084"}],"version-history":[{"count":29,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/1084\/revisions"}],"predecessor-version":[{"id":1137,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/1084\/revisions\/1137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/media\/1088"}],"wp:attachment":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/media?parent=1084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/categories?post=1084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/tags?post=1084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}