diff --git a/.github/workflows/apptainer_build.yml b/.github/workflows/apptainer_build.yml
new file mode 100644
index 000000000..aa212b6b1
--- /dev/null
+++ b/.github/workflows/apptainer_build.yml
@@ -0,0 +1,75 @@
+name: Build Apptainer and Docker images with CQ using micromamba
+
+on:
+ pull_request:
+ push:
+ branches: master
+
+env:
+ BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
+
+jobs:
+ build-test-container:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ container:
+ image: ghcr.io/apptainer/apptainer:1.4.1
+ options: --privileged
+
+ name: Build Apptainer
+ steps:
+
+ - name: Check out code for the container builds
+ uses: actions/checkout@v6
+
+ - name: Build Container
+ run: |
+ apptainer build cq.sif images/cq.def
+
+ - name: Test Container
+ run: |
+ apptainer run cq.sif pytest tests/
+
+ - name: Store sif
+ uses: actions/upload-artifact@v6
+ with:
+ path: cq.sif
+
+ - name: Deploy to GHCR
+ if: contains( env.BRANCH_NAME, 'master')
+ run: |
+ echo ${{ secrets.GITHUB_TOKEN }} | apptainer registry login -u ${{ secrets.GHCR_USERNAME }} --password-stdin oras://ghcr.io
+ apptainer push cq.sif oras://ghcr.io/cadquery/cadquery-apptainer:${BRANCH_NAME}
+
+ build-docker-container:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ name: Build Docker
+ steps:
+
+ - name: Check out code for the container builds
+ uses: actions/checkout@v6
+
+ - name: Authenticate
+ run: |
+ echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ secrets.GHCR_USERNAME }} --password-stdin
+
+ - name: Build Container
+ run: |
+ docker build -t ghcr.io/cadquery/cadquery-docker:${BRANCH_NAME} -f images/dockerfile .
+
+ - name: Test
+ run: |
+ docker run --rm -v $(pwd):/host -w /host ghcr.io/cadquery/cadquery-docker:${BRANCH_NAME} pytest tests/
+
+ - name: Deploy to GHCR
+ #if: contains(env.BRANCH_NAME, 'master')
+ run: |
+ docker push ghcr.io/cadquery/cadquery-docker:${BRANCH_NAME}
+
diff --git a/README.md b/README.md
index 1ac49c148..604ba263d 100644
--- a/README.md
+++ b/README.md
@@ -18,19 +18,13 @@
CadQuery is an intuitive, easy-to-use Python module for building parametric 3D CAD models. Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized.
-CadQuery is often compared to [OpenSCAD](http://www.openscad.org/). Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. However, CadQuery stands out in many ways and has several key advantages:
-
-1. The scripts use a standard programming language, Python, and thus can benefit from the associated infrastructure. This includes many standard libraries and IDEs.
-2. CadQuery's CAD kernel Open CASCADE Technology ([OCCT](https://en.wikipedia.org/wiki/Open_Cascade_Technology)) is much more powerful than the [CGAL](https://en.wikipedia.org/wiki/CGAL) used by OpenSCAD. Features supported natively by OCCT include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, in addition to the standard CSG operations supported by CGAL
-3. Ability to import/export [STEP](https://en.wikipedia.org/wiki/ISO_10303) and the ability to begin with a STEP model, created in a CAD package, and then add parametric features. This is possible in OpenSCAD using STL, but STL is a lossy format.
-4. CadQuery scripts require less code to create most objects, because it is possible to locate features based on the position of other features, workplanes, vertices, etc.
-5. CadQuery scripts can build STL, STEP, AMF and 3MF faster than OpenSCAD.
-
-CadQuery was built to be used as a Python library without any GUI. This makes it great for use cases such as integration into servers, or creating scientific and engineering scripts. Options for visualization are also available including CQ-Editor and JupyterLab.
+CadQuery was built to be used as a Python library without any GUI. This makes it great for use cases such as integration into servers, or creating scientific and engineering scripts. However, it includes internal visualization capabilities.
+Additionally, other options for visualization are also available including CQ-Editor and JupyterLab.
For those who are interested, the [OCP repository](https://github.com/CadQuery/OCP) contains the current OCCT wrapper used by CQ.
### Key features
+
* Build 3D models with scripts that are as close as possible to how you would describe the object to a human.
* Create parametric models that can be very easily customized by end users.
* Output high quality (loss-less) CAD formats like STEP and DXF in addition to STL, VRML, AMF and 3MF.
@@ -38,18 +32,24 @@ For those who are interested, the [OCP repository](https://github.com/CadQuery/O
* Offer advanced modeling capabilities such as fillets, curvilinear extrudes, parametric curves and lofts.
* Build nested assemblies out of individual parts and other assemblies.
-### Why this fork
-
-The original version of CadQuery was built on the FreeCAD API. This was great because it allowed for fast development and easy cross-platform capability. However, we eventually started reaching the limits of the API for some advanced operations and selectors. This 2.0 version of CadQuery is based directly on a Python wrapper of the OCCT kernel. This gives us a great deal more control and flexibility, at the expense of some simplicity and having to handle the cross-platform aspects of deployment ourselves. We believe this is a worthwhile trade-off to allow CadQuery to continue to grow and expand in the future.
-
## Getting started
To learn more about designing with CadQuery, visit the [documentation](https://cadquery.readthedocs.io/en/latest/intro.html), [examples](https://cadquery.readthedocs.io/en/latest/examples.html), and [cheatsheet](https://cadquery.readthedocs.io/en/latest/_static/cadquery_cheatsheet.html).
-To get started playing around with CadQuery and see its capabilities, take a look at the [CQ-editor GUI](https://github.com/CadQuery/CQ-editor). This easy-to-use IDE is a great way to get started desiging with CadQuery. The CQ-editor installer bundles both CQ-editor and CadQuery (recommended). See the [CQ-editor installation instructions](https://cadquery.readthedocs.io/en/latest/installation.html#adding-a-nicer-gui-via-cq-editor).
+To quickly get started you can use apptainer
+```
+apptainer run oras://ghcr.io/cadquery/cadquery-apptainer:master ipython -i -c"from cadquery.func import *; form cadquery.vis import show; show(box(1,1,1))"
+```
+
+or docker/podman.
+
+```
+podman run -it -v /tmp:/tmp -e DISPLAY=$DISPLAY -t ghcr.io/cadquery/cadquery-docker:master ipython -i -c"from cadquery.func import *; from cadquery.vis import show; show(box(1,1,1))"
+```
-The CadQuery library (with or without CQ-editor) and its dependencies may be installed using conda, or pip. Note that conda (or the CQ-editor installer) is the better supported option.
+The CadQuery library (with or without CQ-editor) and its dependencies may be installed using conda/mamba/micromamba/pixi, or pip.
+Note that conda-based installation (or the CQ-editor installer) is the better supported option.
See the documentation for detailed CadQuery [installation instructions](https://cadquery.readthedocs.io/en/latest/installation.html).
@@ -57,7 +57,7 @@ See the documentation for detailed CadQuery [installation instructions](https://
To first install the Conda package manager see [Install the Conda Package Manager](https://cadquery.readthedocs.io/en/latest/installation.html#install-the-conda-package-manager), and [Miniforge](https://github.com/conda-forge/miniforge) for a minimal installer.
-``mamba install`` is recommended over ``conda install`` for faster and less memory intensive cadquery installation.
+``mamba install`` is recommended over ``conda install`` for faster and less memory intensive CadQuery installation.
```
# Set up a new environment
@@ -91,6 +91,29 @@ It is also possible to install the very latest changes directly from CadQuery's
pip install git+https://github.com/CadQuery/cadquery.git
```
+### Built-in visualization
+
+CadQuery has built in visualization capabilities using trame and vtk.
+
+```
+from cadquery.func import box, fillet
+from cadquery.vis import show
+
+b = box(1,1,1)
+show(fillet(b, b.edges("|Z"), 0.1))
+
+```
+
+For non-blocking and persistent view one can use.
+
+```
+from cadquery.func import box, fillet
+from cadquery.fig import show
+
+b = box(1,1,1)
+show(fillet(b, b.edges("|Z"), 0.1))
+
+```
### CQ-editor GUI
@@ -124,33 +147,10 @@ We also have a [Google Group](https://groups.google.com/forum/#!forum/cadquery)
There is also a [Discord](https://discord.com/invite/Bj9AQPsCfx) server, but the other methods of getting help are much better for newcomers.
-## Projects using CadQuery
-
-Here are just a few examples of how CadQuery is being used.
-
-### FxBricks Lego Train System
-
-[FxBricks](https://fxbricks.com/) uses CadQuery in the product development pipeline for their Lego train system. FxBricks has also given back to the community by creating [documentation for their CAD pipeline](https://github.com/fx-bricks/fx-cad-notes). They have also assembled [cq-kit](https://github.com/michaelgale/cq-kit), a library containing utility classes and functions to extend the capabilities of CadQuery. Thanks to @michaelgale and @fx-bricks for this example.
-
-
-
-### Hexidor Board Game Development
-
-Hexidor is an expanded take on the Quoridor board game, and the development process has been chronicled [here](https://bruceisonfire.net/2020/04/23/my-adventure-with-flosscad-the-birth-of-hexidor/). CadQuery was used to generate the game board. Thanks to Bruce for this example.
-
-
-
-### Spindle assembly
-
-Thanks to @marcus7070 for this example from [here](https://github.com/marcus7070/spindle-assy-example).
-
-
-
-### 3D Printed Resin Mold
+## Citing
-Thanks to @eddieliberato for sharing [this example](https://jungletools.blogspot.com/2017/06/an-anti-kink-device-for-novel-high-tech.html) of an anti-kink resin mold for a cable.
+Please use our Zenodo DOI if you use CadQuery for scientific research: https://doi.org/10.5281/zenodo.3955118.
-
## License
@@ -227,6 +227,3 @@ When filing a bug report [issue](https://github.com/CadQuery/cadquery/issues), p
If you find yourself wishing for a feature that does not exist, you are probably not alone. There are bound to be others out there with similar needs. Open an [issue](https://github.com/CadQuery/cadquery/issues) which describes the feature you would like to see, why you need it, and how it should work.
-## Citing
-
-Please use our Zenodo DOI if you use CadQuery for scientific research: https://doi.org/10.5281/zenodo.3955118.
diff --git a/doc/_static/quickstart/002.png b/doc/_static/quickstart/002.png
index 8dc03d06c..3ef57151d 100644
Binary files a/doc/_static/quickstart/002.png and b/doc/_static/quickstart/002.png differ
diff --git a/doc/_static/quickstart/003.png b/doc/_static/quickstart/003.png
index 212fc94ed..0b46080b3 100644
Binary files a/doc/_static/quickstart/003.png and b/doc/_static/quickstart/003.png differ
diff --git a/doc/_static/quickstart/004.png b/doc/_static/quickstart/004.png
index 47e8dc0c3..0713f1b37 100644
Binary files a/doc/_static/quickstart/004.png and b/doc/_static/quickstart/004.png differ
diff --git a/doc/_static/quickstart/005.png b/doc/_static/quickstart/005.png
index 279ffcab0..e136b468c 100644
Binary files a/doc/_static/quickstart/005.png and b/doc/_static/quickstart/005.png differ
diff --git a/doc/quickstart.rst b/doc/quickstart.rst
index 44776a6b1..3a57e6b5a 100644
--- a/doc/quickstart.rst
+++ b/doc/quickstart.rst
@@ -8,23 +8,35 @@ QuickStart
Want a quick glimpse of what CadQuery can do? This quickstart will demonstrate the basics of CadQuery using a simple example
-Prerequisites: CadQuery and CQ-editor installation
-==================================================
+Prerequisites: CadQuery installation
+====================================
-If you have not already done so, follow the :ref:`installation`, to install CadQuery and CQ-editor.
+If you want to quickly try out CadQuery you can do so by running apptainer,
-After installation, run CQ-editor:
+.. code-block::
-.. image:: _static/quickstart/001.png
+ apptainer run oras://ghcr.io/cadquery/cadquery-apptainer:master ipython -i your_script.py
-Find the CadQuery code editor, on the left side. You'll see that we start out with the script for a simple block.
+
+or docker/podman. Note that on Windows this will require using WSL.
+
+.. code-block::
+
+ podman run -it -v /tmp:/tmp -e DISPLAY=$DISPLAY -v $(pwd):/data ghcr.io/cadquery/cadquery-docker:master ipython -i /data/your_script.py
+
+
+Otherwise, follow the :ref:`installation`, to install CadQuery.
+
+
+You can use any editor of your choice to edit CadQuery (i.e. Python) scripts.
+You'll see that we start out with the script for a simple block.
What we'll accomplish
-========================
+=====================
We will build a fully parametric bearing pillow block in this quickstart. Our finished object will look like this:
-.. image:: _static/quickstart/000.png
+.. image:: _static/quickstart/005.png
**We would like our block to have these features:**
@@ -46,11 +58,14 @@ Start With A single, simple Plate
======================================
Let's start with a simple model that makes nothing but a rectangular block, but
-with place-holders for the dimensions. Paste this into the code editor:
+with place-holders for the dimensions. Add this code to your script file:
.. code-block:: python
:linenos:
+ import cadquery as cq
+ from cadquery.vis import show
+
height = 60.0
width = 80.0
thickness = 10.0
@@ -59,9 +74,9 @@ with place-holders for the dimensions. Paste this into the code editor:
result = cq.Workplane("XY").box(height, width, thickness)
# Render the solid
- show_object(result)
+ show(result)
-Press the green Render button in the toolbar to run the script. You should see our base object.
+Run the script. You should see our base object.
.. image:: _static/quickstart/002.png
@@ -76,7 +91,10 @@ This modification will do the trick:
.. code-block:: python
:linenos:
- :emphasize-lines: 4,10-12
+ :emphasize-lines: 7,13-15
+
+ import cadquery as cq
+ from cadquery.vis import show
height = 60.0
width = 80.0
@@ -93,18 +111,18 @@ This modification will do the trick:
)
# Render the solid
- show_object(result)
+ show(result)
-Rebuild your model by clicking the Render button. Your block should look like this:
+Rebuild your model by rerunning the script. Your block should look like this:
.. image:: _static/quickstart/003.png
The code is pretty compact, let's step through it.
-**Line 4** adds a new parameter, diameter, for the diameter of the hole
+**Line 7** adds a new parameter, diameter, for the diameter of the hole
-**Lines 10-12**, we're adding the hole.
+**Lines 13-15**, we're adding the hole.
:py:meth:`cadquery.Workplane.faces` selects the top-most face in the Z direction, and then
:py:meth:`cadquery.Workplane.workplane` begins a new workplane located on this face. The center of this workplane
is located at the center of mass of the shape, which in this case is the center of the plate.
@@ -115,7 +133,7 @@ Finally, :py:meth:`cadquery.Workplane.hole` drills a hole through the part, 22mm
Don't worry about the CadQuery syntax now.. you can learn all about it in the :ref:`apireference` later.
More Holes
-============
+==========
Ok, that hole was not too hard, but what about the counter-bored holes in the corners?
@@ -134,7 +152,10 @@ Good news!-- we can get the job done with just a few lines of code. Here's the c
.. code-block:: python
:linenos:
- :emphasize-lines: 5,14-18
+ :emphasize-lines: 8,17-21
+
+ import cadquery as cq
+ from cadquery.vis import show
height = 60.0
width = 80.0
@@ -156,22 +177,22 @@ Good news!-- we can get the job done with just a few lines of code. Here's the c
.cboreHole(2.4, 4.4, 2.1)
)
# Render the solid
- show_object(result)
+ show(result)
-After clicking the Render button to re-execute the model, you should see something like this:
+After running the script again, you should see something like this:
.. image:: _static/quickstart/004.png
There is quite a bit going on here, so let's break it down a bit.
-**Line 5** creates a new padding parameter that decides how far the holes are from the edges of the plate.
+**Line 8** creates a new padding parameter that decides how far the holes are from the edges of the plate.
-**Lines 14-15** selects the top-most face of the block, and creates a workplane on the top of that face, which we'll use to
+**Lines 17-18** selects the top-most face of the block, and creates a workplane on the top of that face, which we'll use to
define the centers of the holes in the corners.
-**Line 16** draws a rectangle 12mm smaller than the overall length and width of the block, which we will use to
+**Line 19** draws a rectangle 12mm smaller than the overall length and width of the block, which we will use to
locate the corner holes. We'll use the vertices ( corners ) of this rectangle to locate the holes. The rectangle's
center is at the center of the workplane, which in this case coincides with the center of the bearing hole.
@@ -183,10 +204,10 @@ There are a couple of things to note about this line:
2. Unless you specify otherwise, a rectangle is drawn with its center on the current workplane center-- in
this case, the center of the top face of the block. So this rectangle will be centered on the face.
-**Line 17** selects the vertices of the rectangle, which we will use for the centers of the holes.
+**Line 20** selects the vertices of the rectangle, which we will use for the centers of the holes.
The :py:meth:`cadquery.Workplane.vertices` function selects the corners of the rectangle.
-**Line 18** uses the cboreHole function to draw the holes.
+**Line 21** uses the cboreHole function to draw the holes.
The :py:meth:`cadquery.Workplane.cboreHole` function is a handy CadQuery function that makes a counterbored hole.
Like most other CadQuery functions, it operates on the values on the stack. In this case, since we
selected the four vertices before calling the function, the function operates on each of the four points--
@@ -203,7 +224,10 @@ We can do that using the preset dictionaries in the parameter definition:
.. code-block:: python
:linenos:
- :emphasize-lines: 19-20
+ :emphasize-lines: 22-23
+
+ import cadquery as cq
+ from cadquery.vis import show
height = 60.0
width = 80.0
@@ -224,16 +248,16 @@ We can do that using the preset dictionaries in the parameter definition:
.vertices()
.cboreHole(2.4, 4.4, 2.1)
.edges("|Z")
- .fillet(2.0)
+ .fillet(10.0)
)
# Render the solid
- show_object(result)
+ show(result)
-**Line 19** To grab the right edges, the :py:meth:`cadquery.Workplane.edges` selects all of the
+**Line 22** To grab the right edges, the :py:meth:`cadquery.Workplane.edges` selects all of the
edges that are parallel to the Z axis ("\|Z").
-**Line 20** fillets the edges using the :py:meth:`cadquery.Workplane.fillet` method.
+**Line 23** fillets the edges using the :py:meth:`cadquery.Workplane.fillet` method.
The finished product looks like this:
@@ -244,11 +268,13 @@ Exporting
If you want to fabricate a physical object you need to export the result to STL or DXF. Additionally, exporting as STEP for post-processing in another CAD tool is also possible.
-This can be easily accomplished using the :py:meth:`cadquery.exporters.export` function:
+This can be easily accomplished using the :py:meth:`cadquery.Workplane.export` function:
.. code-block:: python
:linenos:
:emphasize-lines: 27-29
+ import cadquery as cq
+ from cadquery.vis import show
height = 60.0
width = 80.0
@@ -273,12 +299,12 @@ This can be easily accomplished using the :py:meth:`cadquery.exporters.export` f
)
# Render the solid
- show_object(result)
+ show(result)
# Export
- cq.exporters.export(result, "result.stl")
- cq.exporters.export(result.section(), "result.dxf")
- cq.exporters.export(result, "result.step")
+ result.export("result.stl")
+ result.section().export("result.dxf")
+ result.export("result.step")
Done!
============
diff --git a/environment.yml b/environment.yml
index 0e1b50492..4608af03b 100644
--- a/environment.yml
+++ b/environment.yml
@@ -33,5 +33,5 @@ dependencies:
- pip
- pip:
- sphinx_rtd_theme==3.1.0
- - --editable=.
- git+https://github.com/cadquery/black.git@cq
+ - --editable=.
diff --git a/images/cq.def b/images/cq.def
new file mode 100644
index 000000000..f7265180b
--- /dev/null
+++ b/images/cq.def
@@ -0,0 +1,32 @@
+Bootstrap: docker
+From: mambaorg/micromamba:latest
+
+%files
+ environment.yml /opt
+ images/install_gl.sh /opt/install_gl.sh
+ images/install_env.sh /opt/install_env.sh
+ environment.yml /opt
+ ./ /opt/cq
+
+%post -c /bin/bash
+ export MYDIR=/opt
+ source /opt/install_gl.sh
+ source /opt/install_env.sh
+
+%labels
+ EnvironmentFile: environment.yml
+
+%help
+ This container container a Python environment with CadQuery.
+
+ To run Python from the environment:
+
+ apptainer run my_environment.sif ipython
+
+ To see the environment file used to create the environment:
+
+ apptainer run my_environment.sif cat /opt/environment.yml
+
+ To see what packages are in the environment:
+
+ apptainer run micromamba list
diff --git a/images/dockerfile b/images/dockerfile
new file mode 100644
index 000000000..421a307db
--- /dev/null
+++ b/images/dockerfile
@@ -0,0 +1,15 @@
+FROM mambaorg/micromamba:latest
+
+COPY --chown=$MAMBA_USER:$MAMBA_USER environment.yml /tmp/environment.yml
+COPY --chown=$MAMBA_USER:$MAMBA_USER ./images/install_gl.sh /tmp/install_gl.sh
+COPY --chown=$MAMBA_USER:$MAMBA_USER ./images/install_env.sh /tmp/install_env.sh
+COPY --chown=$MAMBA_USER:$MAMBA_USER ./ /tmp/cq
+
+USER root
+RUN source /tmp/install_gl.sh
+
+USER $MAMBA_USER
+RUN export MYDIR=/tmp && source /tmp/install_env.sh
+
+ARG MAMBA_DOCKERFILE_ACTIVATE=1 # (otherwise python will not be found)
+
diff --git a/images/install_env.sh b/images/install_env.sh
new file mode 100644
index 000000000..365a933e5
--- /dev/null
+++ b/images/install_env.sh
@@ -0,0 +1,7 @@
+head -n -1 $MYDIR/environment.yml > $MYDIR/environment_.yml
+micromamba install -y -q -n base git
+micromamba install -y -q -n base -f $MYDIR/environment_.yml
+micromamba install -y -q -n base jupyterlab
+micromamba run pip install $MYDIR/cq
+micromamba list
+micromamba clean --all --yes
diff --git a/images/install_gl.sh b/images/install_gl.sh
new file mode 100644
index 000000000..1ee3bdb10
--- /dev/null
+++ b/images/install_gl.sh
@@ -0,0 +1,9 @@
+apt update
+apt install -y \
+ libgl1 \
+ libglx-mesa0 \
+ libegl1 \
+ libgl1-mesa-dri \
+ mesa-utils \
+ xauth
+rm -rf /var/lib/apt/lists/*