diff --git a/docs/blog/2020-10-31-curated-code-cad.md b/docs/blog/2020-10-31-curated-code-cad.md
index 64f0486..e5c2421 100644
--- a/docs/blog/2020-10-31-curated-code-cad.md
+++ b/docs/blog/2020-10-31-curated-code-cad.md
@@ -19,11 +19,11 @@ It's software that allows you to define 3D CAD models with code. It's a niche po
I recommend reading through the entire list below to see if one chimes with you and your needs, beyond that I can make the following recommendation and points:
-- My main recommendation is to use one of the packages that wrap OpenCascade (a mature C++ CAD library). Packages that do so are CadQuery, CascadeStudio, DeclaraCAD and pythonOCC. My reasons for recommending these are as follows:
- - Most of Code-CAD tools are plagued with a CSG mindset (that is unions, subtractions and intersections of primitive shapes; cubes spheres etc). This is an inherently limited paradigm (one simple example of this is how internal fillets, which are important for reducing stress concentrations in parts, become very difficult). While CadQuery, CascadeStudio, DeclaraCAD and pythonOCC still offer CSG functionality, you're also able to move beyond it with concepts like lofts and sweeps.
+- My main recommendation is to use one of the packages that uses a B-rep kernal (and for opensounce tools that means OpenCascade, a mature C++ CAD library). Packages that do so are CadQuery, CascadeStudio, DeclaraCAD and pythonOCC. My reasons for recommending these are as follows:
+ - Most of Code-CAD tools are plagued with a CSG mindset (that is unions, subtractions and intersections of primitive shapes; cubes spheres etc). This is an inherently limited paradigm (one simple example of this is how internal fillets, which are important for reducing stress concentrations in parts, become very difficult). While CadQuery, CascadeStudio, DeclaraCAD and pythonOCC still offer CSG functionality, you're also able to move beyond.
- OpenCascade uses a B-rep (boundary representation) kernel, In my opinion, this means you'll be learning a future-proof tool that won't limit the types of applications you can model for, which is likely the case for mesh kernels, which will cause trouble in for some applications like optics and injection moulding.
-- OpenSCAD is tried and true, with lots of examples and tutorials floating around the internet. It also has a very intuitive syntax that many people without prior programming experience have been able to quickly pick up. However, some reasons you might want to look elsewhere are:
+- OpenSCAD is tried and true, with lots of examples and tutorials floating around the internet. It also has a very intuitive syntax that folks without prior programming experience have been able to quickly pick up. However, some reasons you might want to look elsewhere are:
- It can be hard to build powerful abstractions since they've rolled their own language. Consequences of this include that it doesn't have a package manager like many modern languages, and the presence of quirks with the language, such as function definitions that aren't ergonomic.
- Performance can start to suffer with complex parts.
- Its mesh-based kernel has limitations if you want to move beyond 3d-printed parts.
@@ -35,14 +35,14 @@ No matter which one is your tool of choice, if you're here and you love Code-CAD
## Special mention
-### [OpenScad](http://www.openscad.org/)
+### [OpenSCAD](http://www.openscad.org/)
- [Repo](https://github.com/openscad/openscad)
- [Community](http://www.openscad.org/community.html)
- [Docs](http://www.openscad.org/documentation.html)
- License: GPL-2
- ~~Online editor~~
-The rest of the packages are in alphabetical order, but OpenScad gets a special mention because it's the OG. Many of the projects below were inspired by OpenScad and is the most well-known choice. If you're new to code-cad this is the safest choice. The syntax is easy to pick up and there lots of guides around the internet.
+The rest of the packages are in alphabetical order, but OpenSCAD gets a special mention because it's the OG. Many of the projects below were inspired by OpenSCAD and is the most well-known choice. If you're new to code-cad this is the safest choice. The syntax is easy to pick up and there lots of guides around the internet.
### [OpenCascade](https://www.opencascade.com/)
- [Repo](https://github.com/tpaviot/oce)
@@ -92,8 +92,9 @@ bitbybit is both a node editor and Code-CAD as they have exposed a [typescript](
- License: GPL-3
- [Online editor](https://cadhub.xyz/)
-A community hub for sharing code-cad projects. Currently integrates with the excellent [CascadeStudio](https://zalo.github.io/CascadeStudio/). Built and maintained by yours truly.
+A community hub for sharing code-cad projects. Currently integrates with [CadQuery](https://cadquery.readthedocs.io/en/latest/intro.html) and [OpenScad](http://www.openscad.org/). Built and maintained by yours truly.
+
### [CadQuery](https://cadquery.readthedocs.io/en/latest/intro.html)
- [Repo](https://github.com/CadQuery/cadquery)
- [Community](https://discord.gg/qz3uAdF)
@@ -125,7 +126,7 @@ A javascript wrapper for [OpenCascade](https://github.com/tpaviot/oce) that runs
- License: Apache, 2.0
- ~~Online editor~~
-Curv is a programming language for creating art using mathematics. It’s a 2D and 3D geometric modelling tool that supports full colour, animation and 3D printing. It was inspired by OpenScad and [shadertoy](https://www.shadertoy.com/).
+Curv is a programming language for creating art using mathematics. It’s a 2D and 3D geometric modelling tool that supports full colour, animation and 3D printing. It was inspired by OpenSCAD and [shadertoy](https://www.shadertoy.com/).
### [DeclaraCAD](https://declaracad.com/)
- [Repo](https://github.com/codelv/declaracad)
@@ -145,7 +146,7 @@ and [enaml](https://github.com/nucleic/enaml/).
- License: LGPLv2
- ~~Online editor~~
-FreeCad is a more traditional CAD package that supports python scripting, Both for modelling as well as controlling the FreeCAD GUI itself. Not only that it has a built in [OpenScad workbench](https://wiki.freecadweb.org/OpenSCAD_Module) as well as an external [CadQuery workbench](https://wiki.freecadweb.org/CadQuery_Workbench), making it the best in this list at interoperability. FreeCAD uses OpenCascade under-the-hood.
+FreeCad is a more traditional CAD package that supports python scripting, Both for modelling as well as controlling the FreeCAD GUI itself. Not only that it has a built in [OpenSCAD workbench](https://wiki.freecadweb.org/OpenSCAD_Module) as well as an external [CadQuery workbench](https://wiki.freecadweb.org/CadQuery_Workbench), making it the best in this list at interoperability. FreeCAD uses OpenCascade under-the-hood.
### [ImplicitCAD](http://www.implicitcad.org/)
- [Repo](https://github.com/colah/ImplicitCAD)
@@ -154,7 +155,7 @@ FreeCad is a more traditional CAD package that supports python scripting, Both f
- License: AGPL-3
- [Online editor](http://www.implicitcad.org/editor)
-Inspired by OpenScad with a very similar language, implemented in Haskell and includes the ability to write definitions in Haskell, instead of just OpenSCAD, and is part of an 'almost stack' of tools including ExplicitCAD (for a GUI), and HSlice (for an STL slicer).
+Inspired by OpenSCAD with a very similar language, implemented in Haskell and includes the ability to write definitions in Haskell, instead of just OpenSCAD, and is part of an 'almost stack' of tools including ExplicitCAD (for a GUI), and HSlice (for an STL slicer).
### [JSCAD](http://www.jscad.xyz/)
- [Repo](https://github.com/jscad/OpenJSCAD.org)
@@ -203,12 +204,12 @@ Python-based, Also uses [OpenCascade](https://github.com/tpaviot/oce).
- License: GPL-3
- ~~Online editor~~
-Another project inspired by OpenScad. The author considers key differences to be procedural vs functional programming language style, (i.e variables can be modified) and the use of arbitrary precision arithmetic throughout (meaning there are no unexpected double/float rounding errors). There is a handy [feature matrix](https://github.com/GilesBathgate/RapCAD/blob/master/doc/feature_matrix.asciidoc) between RapCAD, OpenScad and ImplicitCad.
+Another project inspired by OpenSCAD. The author considers key differences to be procedural vs functional programming language style, (i.e variables can be modified) and the use of arbitrary precision arithmetic throughout (meaning there are no unexpected double/float rounding errors). There is a handy [feature matrix](https://github.com/GilesBathgate/RapCAD/blob/master/doc/feature_matrix.asciidoc) between RapCAD, OpenSCAD and ImplicitCad.
### [scad-clj](https://github.com/farrellm/scad-clj)
- [Repo](https://github.com/farrellm/scad-clj)
- ~~Community~~
-- ~~Docs~~ (No docs but mirrors openscad functions)
+- ~~Docs~~ (No docs but mirrors OpenSCAD functions)
- License: EPL-1.0
- ~~Online editor~~
@@ -217,7 +218,7 @@ OpenSCAD DSL in Clojure. Functions generally mirror OpenSCAD, with a couple of n
### [scad-hs](https://github.com/farrellm/scad-hs)
- [Repo](https://github.com/farrellm/scad-hs)
- ~~Community~~
-- ~~Docs~~ (No docs but mirrors openscad functions)
+- ~~Docs~~ (No docs but mirrors OpenSCAD functions)
- License: BSD-3-Clause License
- ~~Online editor~~
@@ -239,7 +240,7 @@ Go-based Code-CAD package that uses a signed distance functions (SDFs) kernel. I
- License: GPL-2 or later
- ~~Online editor~~
-Python-based library that wraps OpenScad, i.e. it outputs OpenScad code.
+Python-based library that wraps OpenSCAD, i.e. it outputs OpenSCAD code.
### [Tovero](https://www.gitlab.com/kavalogic-inc/tovero)
- [Repo](https://www.gitlab.com/kavalogic-inc/tovero)
diff --git a/docs/blog/2021-03-16-3d-diffs.mdx b/docs/blog/2021-03-16-3d-diffs.mdx
index 572200e..54b5d4b 100644
--- a/docs/blog/2021-03-16-3d-diffs.mdx
+++ b/docs/blog/2021-03-16-3d-diffs.mdx
@@ -1,5 +1,5 @@
---
-slug: 3d-diffs - CAD code reviews
+slug: 3d-diffs
title: 3d-diffs - CAD code reviews
author: Kurt Hutten
author_title: CadHub Core Team
@@ -10,21 +10,23 @@ tags: []
import Image from '@theme/IdealImage';
-import threedDiffExampleCode from '../static/img/blog/3d-diff/3dDiffExampleCode.jpg';
-import threedDiffExample from '../static/img/blog/3d-diff/3dDiffExample.jpg';
+import example3dDiffCode from '../static/img/blog/3d-diff/3dDiffExampleCode.jpg';
+import example3dDiff from '../static/img/blog/3d-diff/3dDiffExample.jpg';
-When making a change to a repo, we're probably all familir with code diffs, so common we don't give them a second thought.
+When making a change to a repo, we're all familiar with code diffs, so common we don't give them a second thought.
What's so powerful about code-diffs is they let us to apply our entire conceptual model of how the software functions to a laser focused section the code, to both check that the change is good, as well as giving us a chance to update that mental model incrementally.
CodeCAD is in a unique position that it outputs a 3d artifact, but we can also produce diff artifacts for the purpose of reviewing, it's so intuitive that it needs little explanation, so here's an example:
-
-
+
+
-Green represents where material has been added to the model, and red where it's been removed. Because the hole count has gond from 3 to 2, the middle hole has been filled in. The holes have also increased in diameter which is why there are red rings around the two outer holes where material has been removed.
+
-The process for creating these diffs is rather elegant, here's some psudo-code:
+Green represents where material has been added to the model, and red where it's been removed. Because the hole count has decreased from 3 to 2, the middle hole has been filled in. The holes have also increased in diameter which is why there are red rings around the two outer holes where material has been removed.
+
+The process for creating these diffs is rather elegant, here's some pseudo-code:
```
noChange = intersection(newShape, oldShape)
@@ -35,3 +37,5 @@ colorGray(noChange)
colorGreen(addedMaterial)
colorRed(removedMaterial)
```
+
+3d diffs are part of the reason why Github integration is on the [road-map](https://github.com/Irev-Dev/cadhub/discussions/212) for Cadhub, it's such a low hanging fruit that will immediately make code reviews better, I'm excited to make them happen.
diff --git a/docs/blog/2021-03-30-code-cad-testing.md b/docs/blog/2021-03-30-code-cad-testing.md
new file mode 100644
index 0000000..a06f13f
--- /dev/null
+++ b/docs/blog/2021-03-30-code-cad-testing.md
@@ -0,0 +1,39 @@
+---
+slug: testing-code-cad
+title: What should we test?
+author: Kurt Hutten
+author_title: CadHub Core Team
+author_url: https://github.com/Irev-Dev
+author_image_url: https://avatars.githubusercontent.com/u/29681384?v=4
+tags: []
+---
+
+CodeCad is software, and software should have tests right? is it that simple? Yes but also no.
+
+Yes because unit tests will be fundamentally the same for testing any small part of the CAD code. But No because CodeCAD is a unique application of software, it brings with it it's own unique tests. Though tests might be too vague of a term. Let's keep "tests" for unit tests, but introduce "checks" and "analyses" to encompass other processes that we want to run as part of verifying changes to our CAD software.
+
+
+
+## Checks
+
+Are sanity checks to makes sure your part can actually be made, these checks might be written in a similar fashion to unit tests but because they encompass checking things that are not strickly part of the model, but more to do with how it's manufactured, they could be instead supplied by equipment manufacture instead of written in-house. Easiest to show with some thought experiments:
+
+### Check if the part can be machined on XYZ milling machine?
+
+A bad commit removed a 4mm fillet so now there is a sharp internal corner. From the position the part is intended to be machined, this corner is impossible. In order to preform this check lots of context about the machine is needed, perhaps the code for the check is provided by the vertical-mill manufacturer where a config file with the intended milling bits is provided by you, or perhaps a third party manufacture-on-demand company provides an endpoint for models to be sent to so they can do their own checks.
+
+Another example might be, "is our 3d printer able to print an overhang that steep or bridge a gap that large".
+
+The idea of tooling manufacturers providing code to run verification checks implies that CodeCAD has gone mainstream and so manufactures can see the benefit of providing this to their customers. I don't know how likely this is, but I do know I'm allowed to dream.
+
+### Various sanity checks.
+
+- Check the part is no longer than six meters, because that's how long the rems of material are.
+- Check the part weighs no more than 5 kilograms, because that's the weight budget for our team in a larger weight constrained project.
+
+These border on unit tests. They're bespoke therefore likely to be written in house. Though because they are asking questions about the overall project and not internal logic, that I think they fit better as checks rather than unit-tests.
+
+## Analyses
+
+This is for running all the typical simulations that are done on CAD parts, FEM, fluid, thermal . . .
+Having these re-run on pull-requests or changes to the main branch is useful enough. But it's worth considering their relation to our code as well. Ideally we're able to setup the conditions of the simulations in code as well. In the process of modeling our part we have [tagged specific surfaces](/blog/right-level-of-abstraction#where-has-codecad-gone-wrong----its-csg) of our model, those can intern be used to define the specifics of an FEM simulation for example, ie where forces are applied and so on.
diff --git a/docs/blog/2021-05-22-why-I-started-codhub.md b/docs/blog/2021-05-22-why-I-started-codhub.md
index c21f8ab..a8fb8ab 100644
--- a/docs/blog/2021-05-22-why-I-started-codhub.md
+++ b/docs/blog/2021-05-22-why-I-started-codhub.md
@@ -10,10 +10,10 @@ tags: []
# Why I started CadHub
-Like many, OpenSCAD was my portal into the world of Code-CAD. Once I started making parts with deterministic scripts there was no going back. That doesn't mean that I wasn't frustrated by certain things, a big one for me was how difficult fillets and chamfers can be with OpenSCAD so much to the point that [created a library](https://github.com/Irev-Dev/Round-Anything) to help with this and I even contemplated creating my own Code-CAD tool/language, in particular I was interested in introducing [sketch mechanics](https://github.com/zalo/CascadeStudio/pull/56).
+Like many, OpenSCAD was my portal into the world of CodeCAD. Once I started making parts with deterministic scripts there was no going back. That doesn't mean that I wasn't frustrated by certain things, a big one for me was how difficult fillets and chamfers can be with OpenSCAD. So much so, I was driven to [create a library](https://github.com/Irev-Dev/Round-Anything) to help with this and I even contemplated creating my own Code-CAD tool/language, in particular I was interested in introducing [sketch mechanics](https://github.com/zalo/CascadeStudio/pull/56).
Ultimately it was seeing how [many different projects](/blog/curated-code-cad) there were for this style of CAD and yet there was no central home for them all that I decided that the best way to contribute to the community was to make a hub for our projects.
## The road map
-Because the focus is one Code-CAD, we can introduce some awesome features that leverage the best the paradigm has to offer, like github integration or embed-able Customizers. Check out the [road-map](https://github.com/Irev-Dev/cadhub/discussions/212) if you interested in what we have planned.
+Because the focus is on Code-CAD, we can introduce some awesome features that leverage the best the paradigm has to offer, like github integration or embed-able Customizers. Check out the [road-map](https://github.com/Irev-Dev/cadhub/discussions/212) if you interested in what we have planned.
diff --git a/docs/blog/2021-05-29-artifacts.md b/docs/blog/2021-05-29-artifacts.md
new file mode 100644
index 0000000..8b3c026
--- /dev/null
+++ b/docs/blog/2021-05-29-artifacts.md
@@ -0,0 +1,24 @@
+---
+slug: codecad-artifacts
+title: Artifacts - STEP, png, BOM . . .
+author: Kurt Hutten
+author_title: CadHub Core Team
+author_url: https://github.com/Irev-Dev
+author_image_url: https://avatars.githubusercontent.com/u/29681384?v=4
+tags: []
+---
+
+CI/CD pipelines usually have at most two types of artifacts. Primarily it will be the program, (an executable, web-app static files etc), and also often test reports. If the process is a bit more exotic it might have a couple other outputs. CodeCAD however, has a multitude of different types of artifacts that can be produced.
+
+- The 3d files is obviously the primary output.
+- Test reports would be the same too but with some [subtleties](/blog/testing-code-cad).
+- Images/renders reproduced each merge would allow reports or webpages to stay up today with the latest model
+- Bill of materials (BOM)
+- GCODE or similar artifacts used for manufacture
+
+
+
+The good news is much of this could be setup today with a pipeline. Similar to [3d diffs](blog/3d-diffs) they are why we're excited to build a github integration with CadHub so that we can make producing these artifacts easy. One simple example beyond 3d-files is the renders. Putting nice renders of your project in your readme that automatically stay up-to-date brings a level of professionalism. Two good examples of projects that already do this are:
+- The [open flexure microscope](https://gitlab.com/openflexure/openflexure-microscope)
+- Scott Bezek's [Splitflap project](https://github.com/scottbez1/splitflap)
+
diff --git a/docs/blog/2021-06-17-right-level-of-abstraction.mdx b/docs/blog/2021-06-17-right-level-of-abstraction.mdx
new file mode 100644
index 0000000..dcce61e
--- /dev/null
+++ b/docs/blog/2021-06-17-right-level-of-abstraction.mdx
@@ -0,0 +1,318 @@
+---
+slug: right-level-of-abstraction
+title: The right level of abstraction
+author: Kurt Hutten
+author_title: CadHub Core Team
+author_url: https://github.com/Irev-Dev
+author_image_url: https://avatars.githubusercontent.com/u/29681384?v=4
+tags: []
+---
+
+import Image from '@theme/IdealImage';
+
+import selectByAxis from '../static/img/blog/abstraction-level/select-by-axis.jpg';
+import badSelection from '../static/img/blog/abstraction-level/bad-selection.jpg';
+import sketch from '../static/img/blog/abstraction-level/sketch.jpg';
+import extrudeCube from '../static/img/blog/abstraction-level/extrude-cube.jpg';
+import handlesFromTag from '../static/img/blog/abstraction-level/handles-from-tag.jpg';
+import surgicalFillet from '../static/img/blog/abstraction-level/surgical-fillet.jpg';
+import combineExtrusions from '../static/img/blog/abstraction-level/combine-extrusions.jpg';
+import unionRadius from '../static/img/blog/abstraction-level/union-radius.jpg';
+import faceIntersection from '../static/img/blog/abstraction-level/face-intersection.jpg';
+import extrudeToFace3 from '../static/img/blog/abstraction-level/extrudeToFace3.jpg';
+import extrudeToFace6 from '../static/img/blog/abstraction-level/extrudeToFace6.jpg';
+import csgTransfer1 from '../static/img/blog/abstraction-level/csgTransfer1.jpg';
+import csgTransfer2 from '../static/img/blog/abstraction-level/csgTransfer2.jpg';
+import tangentalArcSketch from '../static/img/blog/abstraction-level/tangentalArcSketch.png';
+
+import complexSketchExample from '../static/img/blog/abstraction-level/complexSketchExample.png';
+import duplication from '../static/img/blog/abstraction-level/duplication.png';
+
+
+One of many aspects that makes the world of software unique is there is a limitless horizon of abstractions possible, "turtles all the way down" so to speak.
+It's truly an awesome tool, it allows use to move quicker, create expressive APIs for our users, "deploy anywhere™️" and more.
+
+
+I know when I first made this discovery, I had a palpable sense that I'd be able to create beautiful software, where not a single piece of logic would ever repeat, from the power of my abstractions.
+But they come at a cost, it might be performance, it might be debuggablity or observability.
+Or to my horror, maybe the beautiful code I was writing was actually harder to understand, and more [brittle](https://overreacted.io/goodbye-clean-code/) than if I hadn't got so high on the abstraction drug.
+
+
+
+All this is to say that, like anything, it has pros and cons. Once we've had our come down, we're left with the hard work of figuring out what the right level of abstraction is for any given application.
+Just as I found myself over-estimating the usefulness of my abstractions, the software industry is starting wind back some abstraction.
+For example the growing popularity of Typescript speaks to the fact that we're starting to collectively regret dynamic types (somewhat contradictory since typescript is an abstraction of javascript).
+
+## Low-code, a case-study in abstraction levels
+
+Then there is the so called "nocode" movement.
+In case the name isn't self explanatory enough, in essence it describes tools that allow non-programmers to make applications without code, and it's gaining traction, with [conferences](https://zeroqode.com/zerocodeconf) and the whole 9-yards.
+
+Personally I don't like these tools, which, to be clear, is not because I think that real programers write
+
+> Raw, unadorned, inscrutable hexadecimal numbers.
+
+> Directly. [*](https://www.cs.utah.edu/~elb/folklore/mel.html)
+
+
+It's great these tools are available, but ultimately I believe they are the wrong level of abstraction. In fact if one starts using these tools for anything non-trivial, it becomes evident that you're still authoring logic, only without the benefit of version control or tests.
+
+How about low-code as an alternative? Start-up [Retool](https://retool.com/) is making a low-code tool aimed at developers.
+The tool is a mix of drag-n-drop UI elements that can be hooked up to data with SQL queries or customised with your own code.
+It's a fundamentally different approach where abstractions are not used to shield user's from the under-lying complexities, since the audience are devs and can handle it. They are instead used to remove onerous parts of UI development, but still allowing users to hook back into code for anything custom.
+
+The fact that Retool is marketed for internal tooling is telling, as this unique abstraction level is intended for a specific use-case, again supporting that the level of abstraction should be tailored to the situation.
+
+
+## How does this apply to CodeCAD?
+
+It goes without saying that I think click-n-drag GUIs are the wrong abstractions for CAD. The potential benefits of:
+- [3d diffs](blog/3d-diffs)
+- Proper version control
+- [Automated tests](/blog/testing-code-cad) (unit tests, FEM, or "can this be produced by X machine, mill, 3d-printer etc")
+- Build pipelines for [artefacts](/blog/codecad-artifacts) (3d files, BOMs and more)
+
+are too great to ignore, but that doesn't mean we have throw out all UI interactions.
+
+"Sketch-n-extrude" mechanics is the work-horse of traditional CAD packages for a reason, and a UI interface for roughing out these sketches and generating some boilerplate code for the developer to then fill in with variables is a great balance of between UI and code.
+
+Aero-surfaces or stylised-surfaces are cumbersome to create with code, particularly because they often need lots of tweaks, so UI helpers would be of great benefit.
+
+Aside from areas where UI can make up for the weak areas of CodeCAD, there's opportunity for a symbiotic relationship.
+Leveraging a languages AST, CodeCAD software that understands the relationship between specific sections of code an the corresponding sections of the model and vise-versa. Hovering over the model could highlight relevant code or the opposite. Straddling code and GUI like this allows its users to effortlessly develop a rich mental model of how the software works.
+
+## Where has CodeCAD gone wrong? . . . it's CSG
+
+It's no secret I have concerns about [CSG](https://us10.campaign-archive.com/?e=__test_email__&u=cbd8888e924bdd99d06c14fa5&id=bd044935d6) and working primarily with 3d-primitives. It has its place but it's been over-emphasised.
+
+Being able to get a 3d shape from a single line like `cube()` might feel productive, but it's too much of an abstraction.
+
+How do you deal with the cube once it's created? Lets say you want to select one of the faces to do more work, is there system of for selecting faces by what axis they're aligned with?
+
+
+
+Is it deterministic? What would happen if we rotate before we select?
+
+
+
+Or do we simply order the faces so you can learn the convention and then select one of the 6?
+
+```javascript
+cube().getFace(5)
+```
+
+Both of these feel cumbersome. A "sketch" is a much better place to start from; it's a better primitive. Let use the cube again by extruding a 2d sketch.
+The following examples use an object-oriented style syntax, but it's all hypothetical so don't take it too seriously.
+
+```javascript
+square = sketch([0,0])
+ .verticalLineTo(10)
+ .horizontalLineTo(10)
+ .verticalLineTo(0)
+ .close()
+```
+
+
+
+```javascript
+square = sketch([0,0])
+ .verticalLineTo(10)
+ .horizontalLineTo(10)
+ .verticalLineTo(0)
+ .close()
+
+// highlight-next-line
+extrude(square, 10)
+```
+
+
+
+Because we've constructed each edge of a square before extruding we can label/tag those edges, giving us an intuitive way of selecting both edges from the sketch and the face that edge forms.
+
+```javascript
+square = sketch([0,0])
+// highlight-next-line
+ .verticalLineTo(10).tag('myEdge')
+ .horizontalLineTo(10)
+ .verticalLineTo(0)
+ .close()
+
+cube = extrude(square, 10)
+
+// highlight-start
+cube.baseEdge('myEdge')
+cube.face('myEdge')
+cube.headEdge('myEdge')
+// highlight-end
+```
+
+
+
+We are now able to take surgical actions on any edge or face we like. We could start a new sketch on one of the existing faces, or fillet one of the edges.
+
+```javascript
+cube.headEdge('myEdge').fillet(3)
+```
+
+
+
+Filleting edges are interesting because edges don't always come directly from sketches, but instead from combining shapes. Imagine two intersecting extrusions (labels `A` & `B` show the extrusion direction, and there are two arbitrary faces labeled we want to fillet between).
+
+
+
+If we needed to add a fillet to where the two shapes meet, we could develop a syntax for defining a minimum radius when two shapes are merged.
+
+```javascript
+minRadius = 2
+// highlight-next-line
+union(minRadius, [
+ extrusionA,
+ extrusionB,
+])
+```
+
+
+
+However, this is rather crude, and it's important we're able to be specific about what edges are filleted (the above shows two edges that got filleted together). Because any given edge is formed where two faces intersect, if we have previously tagged those faces we can use that to select and surgically fillet the edge.
+
+```javascript
+edgeFromFaces(
+ extrusionA.face('nameA')
+ extrusionB.face('nameA')
+).fillet(2)
+```
+
+
+
+This approach would be robust against minor changes in the rest of the program. In the situation the extrusions no longer overlap and hence the faces don't intersect to form an edge, a descriptive error can be thrown.
+
+```
+Line XYZ: Unable to find edge:
+
+ edgeFromFaces(
+....^
+ extrusionA.face('nameA')
+ extrusionB.face('nameB')
+ ).fillet(2)
+
+Faces with tags 'nameA' and 'nameB' do not intersect.
+```
+
+So far we've talked about the `sketch`, `edge` and `face` concepts. The reason these are so useful is that they're conceptually linked to a boundary-representation, pairing well with a B-Rep kernel. Extending these, `surface` and `vertice` would also be useful. Once we've used two faces to fillet an edge, we could use a face to determine the length of an extrusion.
+
+Let's say we had a existing shape and a new sketch that we wanted to extrude through to the last column.
+
+
+
+If we had previously tagged that last face, instead of calculating how long to make the extrusion we can instead extrude to that face.
+
+```javascript
+sketch.extrudeToFace(
+ otherShape.face('myFace')
+)
+```
+
+
+
+Similarly, `extrudeToSurface`, `extrudeToVertice` etc. would work.
+
+## Applied to CSG
+
+In cases where CSG is a good idea, we can still carry our tagged faces, edges etc. through the operation. Let's say we want to subtract the rectangular prism on the right away from the cylinder.
+
+
+
+```javascript
+subtract(
+ myCylinder,
+ myRectangularPrism
+)
+```
+
+Any tagged faces will transfer over, i.e `'myFace'` in this example.
+
+
+
+## The nitty gritty of sketches
+
+The previous square sketch example I gave is simplistic to say the least. Once you mix in radii, splines, tangents and all manner of constraints, it quickly becomes complex, and a good API to capture all the subtleties is challenging. I see two main approaches to this problem.
+
+### Option a) direct conversion for GUI CAD
+
+The workflow GUI-CAD is generally
+- Draw a sketch that's roughly in the right shape, it will include all the arcs and edges it needs but dimensions won't be correct.
+- Add constraints, such as forcing two lines to be parallel, defining the length of a section or the radius of an arc etc.
+
+Trying to capture this workflow directly in an API is, in my opinion, challenging, and my attempts so far have resulted in hard to read code. For example one approach would be to give each point in a closed sketch a name and then add an array of constraints that apply to those names.
+
+Given a simple shape made of two lines connected by tangential arcs
+
+
+
+The resulting code is hard to read and decipher (especially for a simple case).
+
+```javascript
+{
+ points: ['A', 'B', 'C', 'D'],
+ constraints: {
+ tangent: ['A', 'B', 'C', 'D'],
+ line: [['A', 'B'], ['C', 'D']],
+ arc: [
+ {
+ points: ['B', 'C'],
+ radius: 1,
+ centerPointName: 'centerBC'
+ },
+ {
+ points: ['D', 'A'],
+ radius: 1.89,
+ centerPointName: 'centerDA'
+ }
+ ],
+ vertical: [['B', 'C'], ['D', 'A']]
+ horizontal: [['centerBC', 'centerDA']]
+ coordinates: [{
+ point: 'centerDA',
+ coords: [0, 0],
+ }]
+ horizontalDistance:[{
+ points: ['centerBC', 'centerDA'],
+ // assuming the radiuses were in variables this would become something like:
+ // partLength - keyOuterRadius - radius2
+ distance: 9.75 - (1.89 + 1)
+ }]
+ }
+}
+```
+
+It's possible that I'm just going about it wrong, and there is a much more intuitive API I haven't thought of.
+
+### Option b) polygon inspired sketch system
+
+The closest thing to "sketch" in most Code-CAD is the polygon, i.e. listing out a number of points. This is both easy and hard to read:
+
+- Easy because following from one point to the next is an easy way to keep track of what's going on.
+- Hard because it's not intuitive to read points, plus there is inherently a lot of "duplication" for horizontal and vertical lines. For example the points for a square might be:
+
+
+
+Plotting points with a polygon can often be difficult as it requires calculating complex interactions of geometry i.e. getting a point to land on the tangent of an arc or where two lines would intersect. These aren't difficult to calculate in any one situation, but a part could contain hundreds of these kinds of calculations, so helpers of some kind are needed.
+
+An approach I've tried by [extending the cascadeStudio API](https://github.com/zalo/CascadeStudio/pull/56) keeps the "series of points forming a close shape" of the polygon with a series of helpers. Here's a sample:
+
+
+
+One major challenge with this approach is how to make it play nice with a GUI process, as it relies more on the author to take implicit care of constraints instead of explicitly stating them. "Constraining" two lines to be parallel with this approach doesn't make much sense since the author would have defined both lines as having the same angle, in fact both lines could simply use the same variable that defines the angle.
+
+## There's still hard work to be done
+
+You're now privy to a bunch of ideas that have been kicking around and developing in my head for some time. Some of them are good while others need more development, like the discussion of sketches at the end. But that's the rub, CodeCAD is a great level of abstraction for CAD, but it's going to take some work to see it fully form.
+
+## Other resources
+
+- I was recently inspired by [Jessie Frazelle's blog post](https://medium.com/embedded-ventures/mechanical-cad-yesterday-today-and-tomorrow-981cef7e06b1) on the topic to put much of my own ideas out there
+- To see more of my sketch-API attempt with more code examples the [CascadeStudio PR](https://github.com/zalo/CascadeStudio/pull/56) is worth reading through
+- Here's a maintained [list of opensource CodeCAD](/blog/curated-code-cad) tools
+- [CadQuery](https://cadquery.readthedocs.io/) has escaped the CSG mindset and deserves credit for that
+- The urge for a good sketch API has been with me for some time, first starting with my [Round-Anything](http://localhost:3000/docs/round-anything/overview) library
+
diff --git a/docs/static/img/blog/abstraction-level/bad-selection.jpg b/docs/static/img/blog/abstraction-level/bad-selection.jpg
new file mode 100644
index 0000000..5951496
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/bad-selection.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/combine-extrusions.jpg b/docs/static/img/blog/abstraction-level/combine-extrusions.jpg
new file mode 100644
index 0000000..8356d80
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/combine-extrusions.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/complexSketchExample.png b/docs/static/img/blog/abstraction-level/complexSketchExample.png
new file mode 100644
index 0000000..953c780
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/complexSketchExample.png differ
diff --git a/docs/static/img/blog/abstraction-level/csgTransfer1.jpg b/docs/static/img/blog/abstraction-level/csgTransfer1.jpg
new file mode 100644
index 0000000..974a66c
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/csgTransfer1.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/csgTransfer2.jpg b/docs/static/img/blog/abstraction-level/csgTransfer2.jpg
new file mode 100644
index 0000000..513a55d
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/csgTransfer2.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/duplication.png b/docs/static/img/blog/abstraction-level/duplication.png
new file mode 100644
index 0000000..7e4e6fe
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/duplication.png differ
diff --git a/docs/static/img/blog/abstraction-level/extrude-cube.jpg b/docs/static/img/blog/abstraction-level/extrude-cube.jpg
new file mode 100644
index 0000000..f2188df
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/extrude-cube.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/extrudeToFace3.jpg b/docs/static/img/blog/abstraction-level/extrudeToFace3.jpg
new file mode 100644
index 0000000..bfeaaa1
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/extrudeToFace3.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/extrudeToFace6.jpg b/docs/static/img/blog/abstraction-level/extrudeToFace6.jpg
new file mode 100644
index 0000000..a863155
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/extrudeToFace6.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/face-intersection.jpg b/docs/static/img/blog/abstraction-level/face-intersection.jpg
new file mode 100644
index 0000000..b36d351
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/face-intersection.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/handles-from-tag.jpg b/docs/static/img/blog/abstraction-level/handles-from-tag.jpg
new file mode 100644
index 0000000..0abf010
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/handles-from-tag.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/select-by-axis.jpg b/docs/static/img/blog/abstraction-level/select-by-axis.jpg
new file mode 100644
index 0000000..b7d6b7b
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/select-by-axis.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/sketch.jpg b/docs/static/img/blog/abstraction-level/sketch.jpg
new file mode 100644
index 0000000..2400d47
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/sketch.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/surgical-fillet.jpg b/docs/static/img/blog/abstraction-level/surgical-fillet.jpg
new file mode 100644
index 0000000..869506b
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/surgical-fillet.jpg differ
diff --git a/docs/static/img/blog/abstraction-level/tangentalArcSketch.png b/docs/static/img/blog/abstraction-level/tangentalArcSketch.png
new file mode 100644
index 0000000..bf6747c
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/tangentalArcSketch.png differ
diff --git a/docs/static/img/blog/abstraction-level/union-radius.jpg b/docs/static/img/blog/abstraction-level/union-radius.jpg
new file mode 100644
index 0000000..3128e12
Binary files /dev/null and b/docs/static/img/blog/abstraction-level/union-radius.jpg differ
diff --git a/docs/static/img/blog/curated-code-cad/CadHubSS.jpg b/docs/static/img/blog/curated-code-cad/CadHubSS.jpg
new file mode 100644
index 0000000..604d5f6
Binary files /dev/null and b/docs/static/img/blog/curated-code-cad/CadHubSS.jpg differ