Skip to content

Commit

Permalink
Merge branch 'master' into docs-mamba-install
Browse files Browse the repository at this point in the history
* README.md - Add link to Mambaforge, note on mamba install
* installation.rst - Version 2.3.1 install example, conda vs mamba, add link to mamba docs
  • Loading branch information
lorenzncode committed Jul 23, 2023
2 parents 7d9535f + 5bce8d0 commit 069c73c
Show file tree
Hide file tree
Showing 29 changed files with 1,493 additions and 755 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ There are also videos covering installation:

### CadQuery Installation Via Conda

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).
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 [Mambaforge](https://github.com/conda-forge/miniforge#mambaforge) for a minimal installer.

The steps to install cadquery with conda are as follows:
``mamba install`` is recommended over ``conda install`` for faster and less memory intensive cadquery installation.

```
# Set up a new environment
Expand Down Expand Up @@ -188,7 +188,7 @@ If you are going to contribute code, make sure to follow this steps:
- Fork the CadQuery repository, clone your fork and create a new branch to
start working on your changes
- Create a conda development environment with something like:
- `conda env create -n cq-dev -f environment.yml`
- `mamba env create -n cq-dev -f environment.yml`
- Activate the new conda environment:
- `conda activate cq-dev`
- If desired, install the master branch of cq-editor (Note; a release version may not be compatible with the master branch of cadquery):
Expand Down
2 changes: 1 addition & 1 deletion cadquery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
__version__ = version("cadquery")
except PackageNotFoundError:
# package is not installed
__version__ = "2.3.1"
__version__ = "2.4-dev"

# these items point to the OCC implementation
from .occ_impl.geom import Plane, BoundBox, Vector, Matrix, Location
Expand Down
32 changes: 27 additions & 5 deletions cadquery/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

PATH_DELIM = "/"

# entity selector grammar definiiton
# entity selector grammar definition
def _define_grammar():

from pyparsing import (
Expand Down Expand Up @@ -121,8 +121,8 @@ def __init__(
To create one constraint a root object::
b = Workplane().box(1,1,1)
assy = Assembly(b, Location(Vector(0,0,1)), name="root")
b = Workplane().box(1, 1, 1)
assy = Assembly(b, Location(Vector(0, 0, 1)), name="root")
"""

Expand Down Expand Up @@ -385,7 +385,7 @@ def solve(self, verbosity: int = 0) -> "Assembly":
] not in locked:
locked.append(ents[name])

# Lock the first occuring entity if needed.
# Lock the first occurring entity if needed.
if not locked:
unary_objects = [
c.objects[0]
Expand All @@ -402,7 +402,7 @@ def solve(self, verbosity: int = 0) -> "Assembly":
locked.append(ents[b])
break

# Lock the first occuring entity if needed.
# Lock the first occurring entity if needed.
if not locked:
locked.append(0)

Expand Down Expand Up @@ -543,6 +543,28 @@ def _flatten(self, parents=[]):

return rv

def __iter__(
self,
loc: Optional[Location] = None,
name: Optional[str] = None,
color: Optional[Color] = None,
) -> Iterator[Tuple[Shape, str, Location, Optional[Color]]]:
"""
Assembly iterator yielding shapes, names, locations and colors.
"""

name = f"{name}/{self.name}" if name else self.name
loc = loc * self.loc if loc else self.loc
color = self.color if self.color else color

if self.obj:
yield self.obj if isinstance(self.obj, Shape) else Compound.makeCompound(
s for s in self.obj.vals() if isinstance(s, Shape)
), name, loc, color

for ch in self.children:
yield from ch.__iter__(loc, name, color)

def toCompound(self) -> Compound:
"""
Returns a Compound made from this Assembly (including all children) with the
Expand Down
67 changes: 35 additions & 32 deletions cadquery/cq.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def split(self: T, *args, **kwargs) -> T:
a split bushing::
# drill a hole in the side
c = Workplane().box(1,1,1).faces(">Z").workplane().circle(0.25).cutThruAll()
c = Workplane().box(1, 1, 1).faces(">Z").workplane().circle(0.25).cutThruAll()
# now cut it in half sideways
c = c.faces(">Y").workplane(-0.5).split(keepTop=True)
Expand Down Expand Up @@ -1248,7 +1248,7 @@ def fillet(self: T, radius: float) -> T:
This example will create a unit cube, with the top edges filleted::
s = Workplane().box(1,1,1).faces("+Z").edges().fillet(0.1)
s = Workplane().box(1, 1, 1).faces("+Z").edges().fillet(0.1)
"""
# TODO: ensure that edges selected actually belong to the solid in the chain, otherwise,
# TODO: we segfault
Expand Down Expand Up @@ -1282,11 +1282,11 @@ def chamfer(self: T, length: float, length2: Optional[float] = None) -> T:
This example will create a unit cube, with the top edges chamfered::
s = Workplane("XY").box(1,1,1).faces("+Z").chamfer(0.1)
s = Workplane("XY").box(1, 1, 1).faces("+Z").chamfer(0.1)
This example will create chamfers longer on the sides::
s = Workplane("XY").box(1,1,1).faces("+Z").chamfer(0.2, 0.1)
s = Workplane("XY").box(1, 1, 1).faces("+Z").chamfer(0.2, 0.1)
"""
solid = self.findSolid()

Expand Down Expand Up @@ -1515,8 +1515,13 @@ def pushPoints(self: T, pntList: Iterable[Union[VectorLike, Location]]) -> T:
circles or holes. This example creates a cube, and then drills three holes through it,
based on three points::
s = Workplane().box(1,1,1).faces(">Z").workplane().\
pushPoints([(-0.3,0.3),(0.3,0.3),(0,0)])
s = (
Workplane()
.box(1, 1, 1)
.faces(">Z")
.workplane()
.pushPoints([(-0.3, 0.3), (0.3, 0.3), (0, 0)])
)
body = s.circle(0.05).cutThruAll()
Here the circle function operates on all three points, and is then extruded to create three
Expand Down Expand Up @@ -1547,12 +1552,12 @@ def center(self: T, x: float, y: float) -> T:
In this example, we adjust the workplane center to be at the corner of a cube, instead of
the center of a face, which is the default::
#this workplane is centered at x=0.5,y=0.5, the center of the upper face
s = Workplane().box(1,1,1).faces(">Z").workplane()
# this workplane is centered at x=0.5,y=0.5, the center of the upper face
s = Workplane().box(1, 1, 1).faces(">Z").workplane()
s = s.center(-0.5,-0.5) # move the center to the corner
s = s.center(-0.5, -0.5) # move the center to the corner
t = s.circle(0.25).extrude(0.2)
assert ( t.faces().size() == 9 ) # a cube with a cylindrical nub at the top right corner
assert t.faces().size() == 9 # a cube with a cylindrical nub at the top right corner
The result is a cube with a round boss on the corner
"""
Expand Down Expand Up @@ -1822,15 +1827,15 @@ def spline(
s = Workplane(Plane.XY())
sPnts = [
(2.75,1.5),
(2.5,1.75),
(2.0,1.5),
(1.5,1.0),
(1.0,1.25),
(0.5,1.0),
(0,1.0)
(2.75, 1.5),
(2.5, 1.75),
(2.0, 1.5),
(1.5, 1.0),
(1.0, 1.25),
(0.5, 1.0),
(0, 1.0),
]
r = s.lineTo(3.0,0).lineTo(3.0,1.0).spline(sPnts).close()
r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(sPnts).close()
r = r.extrude(0.5)
*WARNING* It is fairly easy to create a list of points
Expand Down Expand Up @@ -2207,7 +2212,7 @@ def mirrorY(self: T) -> T:
Typically used to make creating wires with symmetry easier. This line of code::
s = Workplane().lineTo(2,2).threePointArc((3,1),(2,0)).mirrorX().extrude(0.25)
s = Workplane().lineTo(2, 2).threePointArc((3, 1), (2, 0)).mirrorX().extrude(0.25)
Produces a flat, heart shaped object
"""
Expand Down Expand Up @@ -2488,7 +2493,7 @@ def rect(
A common use case is to use a for-construction rectangle to define the centers of a hole
pattern::
s = Workplane().rect(4.0,4.0,forConstruction=True).vertices().circle(0.25)
s = Workplane().rect(4.0, 4.0, forConstruction=True).vertices().circle(0.25)
Creates 4 circles at the corners of a square centered on the origin.
Expand Down Expand Up @@ -2538,7 +2543,7 @@ def circle(self: T, radius: float, forConstruction: bool = False) -> T:
A common use case is to use a for-construction rectangle to define the centers of a
hole pattern::
s = Workplane().rect(4.0,4.0,forConstruction=True).vertices().circle(0.25)
s = Workplane().rect(4.0, 4.0, forConstruction=True).vertices().circle(0.25)
Creates 4 circles at the corners of a square centered on the origin. Another common case is
to use successive circle() calls to create concentric circles. This works because the
Expand Down Expand Up @@ -2582,9 +2587,7 @@ def ellipse(
the center of mass (equals center for next shape) is shifted. To create concentric ellipses
use::
Workplane("XY")
.center(10, 20).ellipse(100,10)
.center(0, 0).ellipse(50, 5)
Workplane("XY").center(10, 20).ellipse(100, 10).center(0, 0).ellipse(50, 5)
"""

e = Wire.makeEllipse(
Expand Down Expand Up @@ -2699,7 +2702,7 @@ def close(self: T) -> T:
the group of edges into a wire. This example builds a simple triangular
prism::
s = Workplane().lineTo(1,0).lineTo(1,1).close().extrude(0.2)
s = Workplane().lineTo(1, 0).lineTo(1, 1).close().extrude(0.2)
"""
endPoint = self._findFromPoint(True)

Expand Down Expand Up @@ -3461,7 +3464,7 @@ def cutBlind(
# Handling of `until` passed values
s: Union[Compound, Solid, Shape]
if isinstance(both, float) and taper == None:
# Because inserting a new paramater "both" in front of "taper",
# Because inserting a new parameter "both" in front of "taper",
# existing code calling this function with position arguments will
# pass the taper argument (float) to the "both" argument. This
# warning is to catch that.
Expand Down Expand Up @@ -3592,7 +3595,7 @@ def _extrude(
Make a prismatic solid from the existing set of pending wires.
:param distance: distance to extrude
:param both: extrude in both directions symetrically
:param both: extrude in both directions symmetrically
:param upToFace: if specified, extrude up to a face: 0 for the next, -1 for the last face
:param additive: specify if extruding or cutting, required param for uptoface algorithm
Expand Down Expand Up @@ -3882,11 +3885,11 @@ def box(
# create 4 small square bumps on a larger base plate:
s = (
Workplane().
box(4, 4, 0.5).
faces(">Z").
workplane().
rect(3, 3, forConstruction=True)
Workplane()
.box(4, 4, 0.5)
.faces(">Z")
.workplane()
.rect(3, 3, forConstruction=True)
.vertices()
.box(0.25, 0.25, 0.25, combine=True)
)
Expand Down
10 changes: 7 additions & 3 deletions cadquery/cqgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,9 +560,13 @@ def visit_Assign(self, node):
if type(node.value) in astTypes:
self.handle_assignment(left_side.id, node.value)
elif type(node.value) == ast.Tuple:
# we have a multi-value assignment
for n, v in zip(left_side.elts, node.value.elts):
self.handle_assignment(n.id, v)
if isinstance(left_side, ast.Name):
# skip unsupported parameter type
pass
else:
# we have a multi-value assignment
for n, v in zip(left_side.elts, node.value.elts):
self.handle_assignment(n.id, v)
except:
traceback.print_exc()
print("Unable to handle assignment for node '%s'" % ast.dump(left_side))
Expand Down
Loading

0 comments on commit 069c73c

Please sign in to comment.