Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added docs for new extrude capabilities #894

Merged
merged 11 commits into from
Oct 30, 2021
8 changes: 7 additions & 1 deletion cadquery/cq.py
Original file line number Diff line number Diff line change
Expand Up @@ -2993,7 +2993,7 @@ def extrude(
to the normal of the plane. The string "next" extrudes until the next face orthogonal to
the wire normal. "last" extrudes to the last face. If a object of type Face is passed then
the extrusion will extend until this face.
:param boolean combine: True to combine the resulting solid with parent solids if found.
:param boolean combine: True to combine the resulting solid with parent solids if found. (Cannot be set to False when `until` is not set as a float)
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
:param boolean both: extrude in both directions symmetrically
:param float taper: angle for optional tapered extrusion
Expand Down Expand Up @@ -3070,6 +3070,12 @@ def revolve(
* if combine is False, the new value is pushed onto the stack.
* if combine is true, the value is combined with the context solid if it exists,
and the resulting solid becomes the new context solid.
.. note::
Keep in mind that `axisStart` and `axisEnd` are defined relative to the current Workplane center position.
So if for example you want to revolve a circle centered at (10,0,0) around the Y axis, be sure to either :py:meth:`move` (or :py:meth:`moveTo`)
the current Workplane position or specify `axisStart` and `axisEnd` with the correct vector position.
In this example (0,0,0), (0,1,0) as axis coords would fail.
"""
# Make sure we account for users specifying angles larger than 360 degrees
angleDegrees %= 360.0
Expand Down
4 changes: 2 additions & 2 deletions cadquery/selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
geom_LUT_FACE,
)
from pyparsing import (
pyparsing_common,
Literal,
Word,
nums,
Optional,
Combine,
oneOf,
upcaseTokens,
CaselessLiteral,
Group,
infixNotation,
Expand Down Expand Up @@ -637,7 +637,7 @@ def _makeGrammar():
cqtype = oneOf(
set(geom_LUT_EDGE.values()) | set(geom_LUT_FACE.values()), caseless=True,
)
cqtype = cqtype.setParseAction(upcaseTokens)
cqtype = cqtype.setParseAction(pyparsing_common.upcaseTokens)

# type operator
type_op = Literal("%")
Expand Down
3 changes: 2 additions & 1 deletion conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ requirements:
run:
- python {{ environ.get('PYTHON_VERSION') }}
- ocp 7.5.2
- pyparsing 2.*
- hdf5 1.10.6 *1114
- pyparsing >=2.1.9
- ezdxf
- ipython
- typing_extensions
Expand Down
131 changes: 124 additions & 7 deletions doc/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,19 @@ They are organized from simple to complex, so working through them in order is t
Each example lists the API elements used in the example for easy reference.
Items introduced in the example are marked with a **!**

.. note::

You may want to work through these examples by pasting the text into a code editor in a CadQuery .
If you do, make sure to take these steps so that they work:

1. paste the content into the build() method, properly indented, and
2. add the line 'return result' at the end. The samples below are autogenerated, but they use a different
syntax than the models on the website need to be.

.. note::

We strongly recommend installing `CQ-editor <https://github.com/CadQuery/CQ-editor>`_,
so that you can work along with these examples interactively. See :ref:`installation` for more info.

If you do, make sure to take these steps so that they work:

1. import cadquery as cq
2. add the line ``show_object(result)`` at the end. The samples below are autogenerated, but they use a different
syntax than the models on the website need to be.

.. warning::

* You have to have an svg capable browser to view these!
Expand Down Expand Up @@ -622,6 +621,124 @@ and a circular section.
* :py:meth:`Workplane.circle`
* :py:meth:`Workplane.rect`

Extruding until a given face
--------------------------------------------

Sometimes you will want to extrude a wire until a given face that can be not planar or where you
might not know easily the distance you have to extrude to. In such cases you can use `next`, `last`
or even give a :class:`~cadquery.Face` object for the `until` argument of
:meth:`~cadquery.Workplane.extrude`.


.. cadquery::

result = (cq.Workplane(origin = (20,0,0))
.circle(2)
.revolve(180, (-20,0,0),(-20,-1,0))
.center(-20,0)
.workplane()
.rect(20,4)
.extrude("next")
)

The same behaviour is available with :meth:`~cadquery.Workplane.cutBlind` and as you can see it is
also possible to work on several :class:`~cadquery.Wire` objects at a time (the
same is true for :meth:`~cadquery.Workplane.extrude`).

.. cadquery::

skycrappers_locations = [(-16,1),(-8,0),(7,0.2),(17,-1.2)]
angles = iter([15,0,-8,10])
skycrappers = (cq.Workplane()
.pushPoints(skycrappers_locations)
.eachpoint(lambda loc: (cq.Workplane()
.rect(5,16)
.workplane(offset=10)
.ellipse(3,8)
.workplane(offset=10)
.slot2D(20,5, 90)
.loft()
.rotateAboutCenter((0,0,1),next(angles))
.val().located(loc)
)
)
)

result = (skycrappers
.transformed((0,-90,0))
.moveTo(15,0)
.rect(3,3, forConstruction=True)
.vertices()
.circle(1)
.cutBlind("last")
)

Here is a typical situation where extruding and cuting until a given surface is very handy. It allows us to extrude or cut until a curved surface without overlapping issues.

.. cadquery::

import cadquery as cq

sphere = cq.Workplane().sphere(5)
base = (cq.Workplane(origin=(0,0,-2))
.box(12,12,10)
.cut(sphere)
.edges("|Z")
.fillet(2)
)
sphere_face = base.faces(">>X[2] and (not |Z) and (not |Y)").val()
base = (base
.faces("<Z")
.workplane()
.circle(2)
.extrude(10)
)
shaft = (cq.Workplane()
.sphere(4.5)
.circle(1.5)
.extrude(20)
)

spherical_joint = (base.union(shaft)
.faces(">X")
.workplane(centerOption="CenterOfMass")
.move(0,4)
.slot2D(10,2,90)
.cutBlind(sphere_face)
.workplane(offset=10)
.move(0,2)
.circle(0.9)
.extrude("next")
)

result = spherical_joint

.. warning::

If the wire you want to extrude cannot be fully projected on the target surface, the result will
be unpredictable. Furthermore the algorithm in charge of finding the candidates faces do it's
search by counting all the faces intersected by a line created from your wire center along your
extrusion direction. So make sure your wire can be projected on your target face to avoid
unexpected behaviour.

.. topic:: Api References

.. hlist::
:columns: 3

* :py:meth:`Workplane.cutBlind` **!**
* :py:meth:`Workplane.rect`
* :py:meth:`Workplane.ellipse`
* :py:meth:`Workplane.workplane`
* :py:meth:`Workplane.slot2D`
* :py:meth:`Workplane.loft`
* :py:meth:`Workplane.rotateAboutCenter`
* :py:meth:`Workplane.transformed`
* :py:meth:`Workplane.moveTo`
* :py:meth:`Workplane.circle`


Making Counter-bored and Counter-sunk Holes
----------------------------------------------

Expand Down
3 changes: 0 additions & 3 deletions doc/roadmap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,3 @@ primitive creation
* cone
* torus
* wedge

extrude/cut up to surface
allow a cut or extrude to terminate at another surface, rather than either through all or a fixed distance
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dependencies:
- python>=3.6
- ipython
- ocp=7.5.1
- pyparsing
- pyparsing>=2.1.9
- sphinx=3.2.1
- sphinx_rtd_theme
- sphinx-autodoc-typehints
Expand Down