2013-04-15 21:22:54 -04:00
.. _quickstart:
***** ***** ***** ***** ***
2013-04-23 20:33:39 -04:00
CadQuery QuickStart
2013-04-15 21:22:54 -04:00
***** ***** ***** ***** ***
2015-12-09 21:01:14 -05:00
.. module :: cadquery
2019-01-17 13:25:51 -05:00
Want a quick glimpse of what CadQuery can do? This quickstart will demonstrate the basics of CadQuery using a simple example
2013-04-15 21:22:54 -04:00
2019-01-17 13:25:51 -05:00
Prerequisites: Anaconda/Miniconda + CQ-editor running from an environment
2015-11-28 21:05:20 -05:00
==============================================================
2013-04-15 21:22:54 -04:00
2019-01-17 13:25:51 -05:00
If you have not already done so, follow the :ref: `installation` , to install Anaconda/Miniconda and CQ-editor.
2013-04-15 21:22:54 -04:00
2019-01-17 13:25:51 -05:00
After installation, run CQ-editor:
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
.. image :: _static/quickstart/001.png
2013-04-15 21:22:54 -04:00
2019-01-17 13:25:51 -05:00
Find the CadQuery code editor, on the left side. You'll see that we start out with the script for a simple block.
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
What we'll accomplish
========================
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
We will build a fully parametric bearing pillow block in this quickstart. Our finished object will look like this:
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
.. image :: _static/quickstart/000.png
2013-04-15 21:22:54 -04:00
**We would like our block to have these features:**
1. It should be sized to hold a single 608 ( 'skate' ) bearing, in the center of the block.
2019-01-17 13:25:51 -05:00
2. It should have counter-bored holes for M2 socket head cap screws at the corners.
2013-04-15 21:22:54 -04:00
3. The length and width of the block should be configurable by the user to any reasonable size.
A human would describe this as:
2019-01-17 13:25:51 -05:00
"A rectangular block 80mm x 60mm x 10mm , with counter-bored holes for M2 socket head cap screws
at the corners, and a circular pocket 22mm in diameter in the middle for a bearing."
2013-04-15 21:22:54 -04:00
Human descriptions are very elegant, right?
Hopefully our finished script will not be too much more complex than this human-oriented description.
Let's see how we do.
2015-11-28 21:05:20 -05:00
Start With A single, simple Plate
======================================
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
Lets start with a simple model that makes nothing but a rectangular block, but
2019-01-17 13:25:51 -05:00
with place-holders for the dimensions. Paste this into the code editor:
2013-04-15 21:22:54 -04:00
.. code-block :: python
:linenos:
2015-11-28 21:05:20 -05:00
height = 60.0
width = 80.0
2013-04-15 21:22:54 -04:00
thickness = 10.0
2015-11-28 21:05:20 -05:00
# make the base
2015-12-09 21:01:14 -05:00
result = cq.Workplane("XY").box(height, width, thickness)
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
# Render the solid
2019-01-17 13:25:51 -05:00
show_object(result)
2013-04-15 21:22:54 -04:00
2019-01-17 13:25:51 -05:00
Press the green Render button in the toolbar to run the script. You should see our base object.
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
.. image :: _static/quickstart/002.png
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
Nothing special, but its a start!
2013-04-15 21:22:54 -04:00
Add the Holes
================
2019-01-17 13:25:51 -05:00
Our pillow block needs to have a 22mm diameter hole in the center to hold the bearing.
2013-04-15 21:22:54 -04:00
This modification will do the trick:
.. code-block :: python
:linenos:
2015-12-09 21:01:14 -05:00
:emphasize-lines: 4,8
2015-11-28 21:05:20 -05:00
height = 60.0
width = 80.0
thickness = 10.0
diameter = 22.0
# make the base
2015-12-09 21:01:14 -05:00
result = cq.Workplane("XY").box(height, width, thickness)\
2015-11-28 21:05:20 -05:00
.faces(">Z").workplane().hole(diameter)
# Render the solid
2019-01-17 13:25:51 -05:00
show_object(result)
2015-11-28 21:05:20 -05:00
2019-01-17 13:25:51 -05:00
Rebuild your model by clicking the Render button. Your block should look like this:
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
.. image :: _static/quickstart/003.png
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
The code is pretty compact, lets step through it.
2013-04-15 21:22:54 -04:00
2019-01-30 06:32:37 -05:00
**Line 4** adds a new parameter, diameter, for the diameter of the hole
2013-04-15 21:22:54 -04:00
2015-12-09 21:01:14 -05:00
**Line 8** , we're adding the hole.
2020-06-22 08:42:16 +02:00
: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
2019-01-17 13:25:51 -05:00
is located at the center of mass of the shape, which in this case is the center of the plate.
2019-01-30 06:32:37 -05:00
Finally, :py:meth: `cadquery.Workplane.hole` drills a hole through the part, 22mm in diameter.
2013-04-15 21:22:54 -04:00
.. note ::
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?
An M2 Socket head cap screw has these dimensions:
* **Head Diameter** : 3.8 mm
* **Head height** : 2.0 mm
* **Clearance Hole** : 2.4 mm
* **CounterBore diameter** : 4.4 mm
2019-11-21 14:15:45 +03:00
The centers of these holes should be 6mm from the edges of the block. And,
2013-04-15 21:22:54 -04:00
we want the block to work correctly even when the block is re-sized by the user.
**Don't tell me** we'll have to repeat the steps above 8 times to get counter-bored holes?
2019-01-17 13:25:51 -05:00
Good news!-- we can get the job done with just a few lines of code. Here's the code we need:
2013-04-15 21:22:54 -04:00
.. code-block :: python
:linenos:
2015-12-09 21:01:14 -05:00
:emphasize-lines: 5,10-13
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
height = 60.0
width = 80.0
thickness = 10.0
diameter = 22.0
padding = 12.0
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
# make the base
2015-12-09 21:01:14 -05:00
result = cq.Workplane("XY").box(height, width, thickness)\
2015-11-28 21:05:20 -05:00
.faces(">Z").workplane().hole(diameter)\
.faces(">Z").workplane() \
.rect(height - padding,width - padding,forConstruction=True)\
.vertices()\
.cboreHole(2.4, 4.4, 2.1)
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
# Render the solid
2019-01-17 13:25:51 -05:00
show_object(result)
2013-04-15 21:22:54 -04:00
2019-01-30 06:11:30 -05:00
After clicking the Render button to re-execute the model, you should see something like this:
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
.. image :: _static/quickstart/004.png
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
There is quite a bit going on here, so lets break it down a bit.
2013-04-15 21:22:54 -04:00
2015-12-09 21:01:14 -05:00
**Line 5** creates a new padding parameter that decides how far the holes are from the edges of the plate.
2013-04-15 21:22:54 -04:00
2015-12-12 15:08:38 -05:00
**Line 10** selects the top-most face of the block, and creates a workplane on the top of that face, which we'll use to
2015-11-28 21:05:20 -05:00
define the centers of the holes in the corners.
2013-04-15 21:22:54 -04:00
There are a couple of things to note about this line:
2015-12-09 21:01:14 -05:00
1. The :py:meth: `cadquery.Workplane.rect` function draws a rectangle. **forConstruction=True**
2013-04-15 21:22:54 -04:00
tells CadQuery that this rectangle will not form a part of the solid,
but we are just using it to help define some other geometry.
2. The center point of a workplane on a face is always at the center of the face, which works well here
3. Unless you specifiy otherwise, a rectangle is drawn with its center on the current workplane center-- in
2019-01-17 13:25:51 -05:00
this case, the center of the top face of the block. So this rectangle will be centered on the face.
2013-04-15 21:22:54 -04:00
2019-01-17 13:25:51 -05:00
**Line 11** draws a rectangle 12mm smaller than the overall length and width of the block, which we will use to
2015-11-28 21:05:20 -05:00
locate the corner holes. We'll use the vertices ( corners ) of this rectangle to locate the holes. The rectangle's
2019-01-30 06:32:37 -05:00
center is at the center of the workplane, which in this case coincides with the center of the bearing hole.
2013-04-15 21:22:54 -04:00
2015-12-09 21:01:14 -05:00
**Line 12** selects the vertices of the rectangle, which we will use for the centers of the holes.
2020-06-22 08:42:16 +02:00
The :py:meth: `cadquery.Workplane.vertices` function selects the corners of the rectangle.
2013-04-15 21:22:54 -04:00
2015-12-09 21:01:14 -05:00
**Line 13** uses the cboreHole function to draw the holes.
2019-01-17 13:25:51 -05:00
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
2015-11-28 21:05:20 -05:00
selected the four vertices before calling the function, the function operates on each of the four points--
2019-01-17 13:25:51 -05:00
which results in a counterbore hole at each of the rectangle corners.
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
Filleting
2013-04-15 21:22:54 -04:00
===========
2015-11-28 21:05:20 -05:00
Almost done. Let's just round the corners of the block a bit. That's easy, we just need to select the edges
and then fillet them:
2013-04-15 21:22:54 -04:00
We can do that using the preset dictionaries in the parameter definition:
.. code-block :: python
:linenos:
2015-12-09 21:01:14 -05:00
:emphasize-lines: 13
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
height = 60.0
width = 80.0
thickness = 10.0
diameter = 22.0
padding = 12.0
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
# make the base
2015-12-09 21:01:14 -05:00
result = cq.Workplane("XY").box(height, width, thickness)\
2015-11-28 21:05:20 -05:00
.faces(">Z").workplane().hole(diameter)\
.faces(">Z").workplane() \
.rect(height - padding, width - padding, forConstruction=True)\
.vertices().cboreHole(2.4, 4.4, 2.1)\
.edges("|Z").fillet(2.0)
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
# Render the solid
2019-01-17 13:25:51 -05:00
show_object(result)
2015-12-09 21:01:14 -05:00
2020-06-22 08:42:16 +02:00
**Line 13** fillets the edges using the :py:meth: `cadquery.Workplane.fillet` method.
2013-04-15 21:22:54 -04:00
2020-06-22 08:42:16 +02:00
To grab the right edges, the :py:meth: `cadquery.Workplane.edges` selects all of the
2015-12-09 21:01:14 -05:00
edges that are parallel to the Z axis ("\|Z"),
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
The finished product looks like this:
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
.. image :: _static/quickstart/005.png
2013-04-15 21:22:54 -04:00
2020-08-02 17:03:23 +02:00
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:
.. code-block :: python
:linenos:
:emphasize-lines: 13
height = 60.0
width = 80.0
thickness = 10.0
diameter = 22.0
padding = 12.0
# make the base
result = cq.Workplane("XY").box(height, width, thickness)\
.faces(">Z").workplane().hole(diameter)\
.faces(">Z").workplane() \
.rect(height - padding, width - padding, forConstruction=True)\
.vertices().cboreHole(2.4, 4.4, 2.1)\
.edges("|Z").fillet(2.0)
# Render the solid
show_object(result)
# Export
cq.exporters.export(result,'result.stl')
cq.exporters.export(result.section(),'result.dxf')
cq.exporters.export(result,'result.step')
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
Done!
============
2013-04-15 21:22:54 -04:00
2015-11-28 21:05:20 -05:00
You just made a parametric, model that can generate pretty much any bearing pillow block
with < 20 lines of code.
2013-04-15 21:22:54 -04:00
Want to learn more?
====================
* The :ref: `examples` contains lots of examples demonstrating cadquery features
* The :ref: `apireference` is a good overview of language features grouped by function
2019-11-21 14:15:45 +03:00
* The :ref: `classreference` is the hard-core listing of all functions available.