CadQuery is an intuitive, easy-to-use Python module for building parametric 3D CAD models.

Overview

CadQuery logo

CadQuery

Appveyor Build status Build Status codecov Documentation Status DOI

What is CadQuery

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. 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) is much more powerful than the 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 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, and AMF faster than OpenSCAD.

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 and AMF.
  • Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser.
  • 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 quickly play around with CadQuery and see it's capabilities, see the CQ-editor GUI manual.
If you want to use CadQuery for your own project, keep reading:

It is currently possible to use CadQuery for your own projects in 3 different ways:

The easiest way to install CadQuery and its dependencies is using conda, which is included as part of an Anaconda/Miniconda installation. See the next section for an alternative to a full install of Anaconda that may be preferable to some users. The steps to install cadquery are as follows:

# Set up a new environment
conda create -n cadquery

# Activate the new environment
conda activate cadquery

# CadQuery development is moving quickly, so it is best to install the latest version from GitHub master
conda install -c conda-forge -c cadquery cadquery=master

For those who are interested, the OCP repository contains the current OCCT wrapper used by CQ.

Alternative Anaconda Installation Method

For those unfamiliar (or uncomfortable) with Anaconda, it is probably best to install Miniconda to a local directory and to avoid running conda init. After performing a local directory installation, Miniconda can be activated via the [scripts,bin]/activate scripts. This will help avoid polluting and breaking the local Python installation. In Linux, the local directory installation method looks something like this:

# Install the script to ~/miniconda
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
bash miniconda.sh -b -p $HOME/miniconda

# To activate and use Miniconda
source $HOME/miniconda/bin/activate

CQ-editor GUI

CQ-editor is an IDE that allows users to edit CadQuery model scripts in a GUI environment. It includes features such as:

  • A graphical debugger that allows you to step through your scripts.
  • A CadQuery stack inspector.
  • Export to various formats, including STEP and STL, directly from the menu.

The installation instructions for CQ-editor can be found here.

CQ editor screenshot

Jupyter

CadQuery supports Jupyter notebook out of the box using the jupyter-cadquery extension created by @bernhard-42:

CadQuery Jupyter extension screenshot

Docker

A list of Docker images can be found here, and includes images for the following projects.

  • Core CadQuery library, which allows users to run CadQuery Python scripts without a GUI.
  • cq-cli, a command line utility which is used to export the results of a CadQuery script to an output format (i.e. STL, STEP).
  • jupyter-cadquery, makes CadQuery accessible through Jupyter Labs and provides a web-based GUI. This is currently the only image that provides a GUI.

Standalone Stable Version

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. Use Anaconda/Miniconda to install CadQuery, and then add import cadquery to the top of your Python scripts. If the stable version of CadQuery is desired, the following command will install it. However, be aware that the stable version can fall significantly behind the current state of CadQuery, so in many cases the master installation method at the beginning of the Getting Started section is preferable.

conda install -c conda-forge -c cadquery cadquery=2

Getting help

You can find the full CadQuery documentation at cadquery.readthedocs.io.

We also have a Google Group to make it easy to get help from other CadQuery users. We want you to feel welcome and encourage you to join the group and introduce yourself. We would also love to hear what you are doing with CadQuery.

There is a Discord channel as well. A big thanks goes to the Elmer team for hosting us.

Projects using CadQuery

Here are just a few examples of how CadQuery is being used.

FxBricks Lego Train System

FxBricks 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. They have also assembled cq-kit, a library containing utility classes and functions to extend the capabilities of CadQuery. Thanks to @michaelgale and @fx-bricks for this example.

FxBricks Pipeline Diagram

Hexidor Board Game Development

Hexidor is an expanded take on the Quoridor board game, and the development process has been chronicled here. CadQuery was used to generate the game board. Thanks to Bruce for this example.

Hexidor Board Game

Spindle assembly

Thanks to @marcus7070 for this example from here.

3D Printed Resin Mold

Thanks to @eddieliberato for sharing this example of an anti-kink resin mold for a cable.

3D printed resin mold

License

CadQuery is licensed under the terms of the Apache Public License, version 2.0.

Contributing

Contributions from the community are welcome and appreciated.

You do not need to be a software developer to have a big impact on this project. Contributions can take many forms including, but not limited to, the following:

  • Writing and improving documentation
  • Triaging bugs
  • Submitting bugs and feature requests
  • Creating tutorial videos and blog posts
  • Helping other users get started and solve problems
  • Telling others about this project
  • Helping with translations and internationalization
  • Helping with accessibility
  • Contributing bug fixes and new features

It is asked that all contributions to this project be made in a respectful and considerate way. Please use the Python Community Code of Conduct's guidelines as a reference.

Contributing code

If you are going to contribute code, make sure to follow this steps:

  • Consider opening an issue first to discuss what you have in mind
  • Try to keep it as short and simple as possible (if you want to change several things, start with just one!)
  • 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
  • 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):
    • conda install -c cadquery -c conda-forge cq-editor=master Installing cq-editor adds another instance of cadquery which overrides the clone just added. Fix this by reinstalling cadquery using pip:
    • pip install -e .
  • Before making any changes verify that the current tests pass. Run pytest from the root of your cadquery clone, there should be no failures and the output will look similar to this:
    • ======= 215 passed, 57 warnings in 13.95s =======
  • Start with the tests! How should CadQuery behave after your changes? Make sure to add some tests to the test suite to ensure proper behavior
  • Make sure your tests have assertions checking all the expected results
  • Add a nice docstring to the test indicating what the test is doing; if there is too much to explain, consider splitting the test in two!
  • Go ahead and implement the changes
  • Add a nice docstring to the functions/methods/classes you implement describing what they do, what the expected parameters are and what it returns (if anything)
  • Update the documentation if there is any change to the public API
  • Consider adding an example to the documentation showing your cool new feature!
  • Make sure nothing is broken (run the complete test suite with pytest)
  • Run black to autoformat your code and make sure your code style complies with CadQuery's
  • Push the changes to your fork and open a pull-request upstream
  • Keep an eye on the automated feedback you will receive from the CI pipelines; if there is a test failing or some code is not properly formatted, you will be notified without human intervention
  • Be prepared for constructive feedback and criticism!
  • Be patient and respectful, remember that those reviewing your code are also working hard (sometimes reviewing changes is harder than implementing them!)

How to Report a Bug

When filing a bug report issue, please be sure to answer these questions:

  1. What version of the software are you running?
  2. What operating system are you running the software on?
  3. What are the steps to reproduce the bug?

How to Suggest a Feature or Enhancement

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 which describes the feature you would like to see, why you need it, and how it should work.

Comments
  • Allow other ways to install cadquery

    Allow other ways to install cadquery

    I have had nothing but trouble with conda. Everytime I have to reconfigure my machine I basically have to take a day to get conda working. Is there a possibility to move away from it and just starting using pypi?

    infrastructure 
    opened by rowanG077 71
  • Assembly support

    Assembly support

    This PR will eventually resolve #276, #20

    What's left

    • [x] ~~Exact jacobian~~ , finite diff jacobian by hand
    • [x] Finalize solver choice -> BFGS it is
    • [x] Implement parameters handling (e.g. specific angle or distance constraint)
    • [x] Visually attractive example in docs/README
    enhancement OCC feature assembly 
    opened by adam-urbanczyk 42
  • Integrate `sphinxcadquery` to visualize 3D parts

    Integrate `sphinxcadquery` to visualize 3D parts

    Closes #105.

    Seems to be working almost fine:

    https://peertube.social/videos/watch/b922711c-b6d1-45d9-b44b-897b489e2781

    Do not merge yet, just for discussion/impressions/feedback...

    • https://github.com/Peque/sphinxcadquery/issues/4
    • https://github.com/Peque/sphinxcadquery/issues/5
    opened by Peque 42
  • Investigate using VTK for web based visualization

    Investigate using VTK for web based visualization

    Current approach is based on x3dom functionality of python-occ. It will probably be not available in the future but it would be good to keep the simple ipython visuaization capabilities. One way to achieve this woulde be to use VTK and some additional tools. Relevant materials

    • https://lorensen.github.io/VTKExamples/site/Python/DataManipulation/Cube.py
    • https://k3d-jupyter.org/index.html
    • https://docs.pyvista.org/index.html

    Note that OCCT has (in some versions) VTK related functionalities:

    • https://www.opencascade.com/doc/occt-7.0.0/refman/html/toolkit_tkivtk.html --> has it been removed in 7.4 ?
    R&D 
    opened by adam-urbanczyk 41
  • After installing ipython/jupyter cadquery crashes on macos under Python 3.6

    After installing ipython/jupyter cadquery crashes on macos under Python 3.6

    Somehow the installation of ipython kills cadquery:

    I use miniconda as base with conda 4.5.2

    1. Install conda environment and cadquery-occ
    $ conda create -n py3occ python=3.6
    $ source activate py3occ
    $ conda install -c pythonocc -c oce -c conda-forge -c dlr-sc -c CadQuery cadquery-occ
    
    
    1. Test
    $ python
    
    Python 3.6.6 | packaged by conda-forge | (default, Jul 26 2018, 09:55:02)
    [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import cadquery
    >>>
    
    1. Install ipython
    $ conda install ipython
    
    Solving environment: done
    
    ## Package Plan ##
    
      environment location: /opt/miniconda/envs/py3occ
    
      added / updated specs:
        - ipython
    
    
    The following NEW packages will be INSTALLED:
    
        appnope:          0.1.0-py36hf537a9a_0
        backcall:         0.1.0-py36_0
        decorator:        4.3.0-py36_0
        ipython:          7.2.0-py36h39e3cac_0
        ipython_genutils: 0.2.0-py36h241746c_0
        jedi:             0.13.2-py36_0
        parso:            0.3.1-py36_0
        pexpect:          4.6.0-py36_0
        pickleshare:      0.7.5-py36_0
        prompt_toolkit:   2.0.7-py36_0
        ptyprocess:       0.6.0-py36_0
        pygments:         2.3.1-py36_0
        six:              1.12.0-py36_0
        traitlets:        4.3.2-py36h65bd3ce_0
        wcwidth:          0.1.7-py36h8c6ec74_0
    
    The following packages will be UPDATED:
    
        openssl:          1.0.2p-h470a237_2     conda-forge --> 1.1.1a-h1de35cc_0
        python:           3.6.6-h5001a0f_0      conda-forge --> 3.6.8-haf84260_0
    
    The following packages will be DOWNGRADED:
    
        ca-certificates:  2018.11.29-ha4d7672_0 conda-forge --> 2018.03.07-0
        certifi:          2018.11.29-py36_1000  conda-forge --> 2018.11.29-py36_0
    
    1. Test
    $ ipython
    Python 3.6.8 |Anaconda, Inc.| (default, Dec 29 2018, 19:04:46)
    Type 'copyright', 'credits' or 'license' for more information
    IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.
    
    In [1]: import cadquery as cq
    Fatal Python error: PyThreadState_Get: no current thread
    
    Abort trap: 6
    
    opened by bernhard-42 36
  • Self-contained OCP wheel to enable installation via pip

    Self-contained OCP wheel to enable installation via pip

    I have found a way to create self-contained OCP wheels on Linux, allowing cadquery and all its dependencies to be installed via pip. I am sharing it here in the hopes that others may find it helpful, either for personal pip workflows or as a step towards official PyPI wheels.

    I note that https://github.com/CadQuery/cadquery/issues/153#issuecomment-1033053777 requests a working pipeline, presumably Azure pipelines for all platforms. This is NOT that yet; this is only a way to build a wheel, and has only been tested on Linux.

    The wheel is created from a conda environment with OCP installed. The OCP and vtk files in the python import path are blindly copied into a wheel. This wheel is of course unusable, but then we simply use auditwheel to bundle external libraries and produce a working manylinux_2_31_x86_64 wheel. This wheel is 160 MB, which is large but probably can be accommodated by PyPI.

    A working cadquery venv can be created by pip installing this wheel along with git+https://github.com/CadQuery/cadquery, ezdxf, ipython, multimethod, nlopt, and nptyping<2. Thanks to @roipoussiere who has also tested this.

    The code is available in this gist; see the docstring of setup.py for details. Testers on macOS and Windows will have to replace the use of auditwheel with delocate and delvewheel respectively. The created wheels may not be distributed until the requisite license files have been added into the wheel.

    opened by fpq473 35
  • Test: BRepOffsetAPI_MakeFilling implementation

    Test: BRepOffsetAPI_MakeFilling implementation

    I made an implementation of BRepOffsetAPI_MakeFilling into CadQuery in order to produce a plate surface with a thickness, enclosed by edge points, and going through interpolation points. To this end I added these 2 functions to shapes.py:

    from OCC.Core.GeomAbs import GeomAbs_C0 
    from OCC.Extend.TopologyUtils import TopologyExplorer, WireExplorer 
    from OCC.GeomAbs import GeomAbs_Intersection 
    from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeFilling 
    from OCC.BRepOffset import BRepOffset_MakeOffset, BRepOffset_Skin
    
    class Face(Shape):
        @classmethod
        def makeNSidedSurface(cls, edges, points, continuity=GeomAbs_C0, Degree=2, NbPtsOnCur=20, NbIter=2, Anisotropie=False, Tol2d=0.00001, Tol3d=0.0001, TolAng=0.01, TolCurv=0.1, MaxDeg=8, MaxSegments=9):
            """
            makeNSidedSurface() creates a surface enclosed by a closed polygon defined by 'edges' and going through 'points'.
            """
            n_sided = BRepOffsetAPI_MakeFilling(Degree, NbPtsOnCur, NbIter, Anisotropie, Tol2d, Tol3d, TolAng, TolCurv, MaxDeg, MaxSegments)
            for edg in edges:
                n_sided.Add(edg, continuity)
            for pt in points:
                n_sided.Add(pt)
            n_sided.Build()
            face = n_sided.Shape()
            return cls.cast(face).fix()
    
    class Solid(Shape, Mixin3D):
        @classmethod
        def interpPlate(cls, surf_pts, surf_edge_pts, thickness, Degree=2, NbPtsOnCur=20, NbIter=2, Anisotropie=False, Tol2d=0.00001, Tol3d=0.0001, TolAng=0.01, TolCurv=0.1, MaxDeg=8, MaxSegments=9):
            """
            interpPlate(): creates a plate surface that is 'thickness' thick, enclosed by 'surf_edge_pts' points,  and going through 'surf_pts' points.
            """
            # BOUNDARIES
            xmax, ymax, zmax = max(surf_pts[:,0]), max(surf_pts[:,1]), max(surf_pts[:,2]) 
            xmin, ymin, zmin = min(surf_pts[:,0]), min(surf_pts[:,1]), min(surf_pts[:,2])
            # POINTS CONSTRAINTS
            pts_array = [gp_Pnt(*pt) for pt in surf_pts]   
            # EDGE CONSTRAINTS: build closed polygon
            e_array = [Vector(*e) for e in surf_edge_pts]
            wire_builder = BRepBuilderAPI_MakePolygon()
            for e in e_array:
                wire_builder.Add(e.toPnt())
            wire_builder.Close()
            w = wire_builder.Wire()
            edges = [i for i in TopologyExplorer(w).edges()] 
            # MAKE SURFACE
            continuity = GeomAbs_C0 # Fixed, changing to anything else crashes.
            face = Face.makeNSidedSurface(edges, pts_array, continuity, Degree, NbPtsOnCur, NbIter, Anisotropie, Tol2d, Tol3d, TolAng, TolCurv, MaxDeg, MaxSegments) 
            # THICKEN SURFACE
            solid = BRepOffset_MakeOffset()
            solid.Initialize(face.wrapped, thickness, 1.e-5, BRepOffset_Skin, False, False, GeomAbs_Intersection, True) #The last True is important to make solid
            solid.MakeOffsetShape()
            
            return cls(solid.Shape())
    

    and this function to cq.py

    class Workplane(CQ):
        def interpPlate(self, surf_pts, surf_edge_pts, thickness, combine=True, clean=True, Degree=2, NbPtsOnCur=20, NbIter=2, Anisotropie=False, Tol2d=0.00001, Tol3d=0.0001, TolAng=0.01, TolCurv=0.1, MaxDeg=8, MaxSegments=9):
            """
            interpPlate(): creates a plate surface that is 'thickness' thick, enclosed by 'surf_edge_pts' points,  and going through 'surf_pts' points.
            :Array of [x,y,z] Real coordinates: surf_pts
            :Array of [x,y,z] Real ordered coordinates: edges_pts
            :Real: thickness
            :Integer: Degree = 3 (OCCT default value, 2 works better for Gyroids)
            :Integer: NbPtsOnCur = 15 (OCCT default value, 20 works better for thickening)
            :Integer: NbIter = 2
            :Boolean: Anisotropie = False
            :Real: Tol2d = 0.00001
            :Real: Tol3d = 0.0001
            :Real: TolAng = 0.01
            :Real: TolCurv = 0.1
            :Integer: MaxDeg = 8
            :Integer: MaxSegments = 9
            :type combine: true to combine shapes, false otherwise.
            :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
            """
            
            def _makeplate(pnt):
                return Solid.interpPlate(surf_pts, surf_edge_pts, thickness, Degree, NbPtsOnCur, NbIter, Anisotropie, Tol2d, Tol3d, TolAng, TolCurv, MaxDeg, MaxSegments)
    
            plates = self.eachpoint(_makeplate, True)
    
            # if combination is not desired, just return the created boxes
            if not combine:
                return plates
            else:
                # combine everything
                return self.union(plates, clean=clean)
    

    As an example the attached script cq_InterpPlate_example.py, produces the Gyroid elementary plate of the attached screenshot through the use of cq.Workplane('XY').interpPlate(gxyz, xyz_max, AFT)

    The surface needs to be relatively simple, and the number of interpolation points limited, otherwise it crashes. Also, the points defining the edges need to be ordered correctly to create a closed polygon. Do you think this could be a useful addition to CadQuery?

    Gyroid_Cell

    cq_InterpPlate_example.py.txt

    opened by bragostin 30
  • Feature discussion: construct workplanes on top of faces

    Feature discussion: construct workplanes on top of faces

    This is a follow up of https://github.com/CadQuery/cadquery/issues/709.

    Here we had a cube which's six faces were selected, a circle constructed on each and those extruded. My expectation from a beginners perspective was that the resulting cylinders would be perpendicular to the individual faces. I learned that this is not the current behavior (the circles seem to be on planes parallel to the base workplane through some (?) point on the respective face - which creates overlaps). Is there already a convenient way to achieve the desired behavior? If not, would it perhaps make sense to introduce a new option for the inPlane parameter of workplanes? E.g. "parent"? This could align the workplane parallel to the respective parent plane instead of taking over the orientation of the base plane.

    So the example from the issue above could look like that: result = (cq.Workplane("XY") .box(10.0,10.0,10.0,centered=(True,True,True)) .faces() .workplane("parent") .circle(1.0,forConstruction=False) .extrude(1.0,combine=True,clean=False)) show_object(result)

    That would create a box with six cylinders coming out of the six faces perpendicularly - easy to understand and potentially helpful in many cases. The other option would be to change the default behavior. But not sure whether people rely on the current alignment behavior or whether most consider the behavior just as "undefined" for non-parallel selected faces? But if people rely on the current behavior then the propsal above would allow to keep the current default behavior. Would this make sense and be desirable?

    enhancement question won't do 
    opened by NothanUmber 26
  • Tagging objects in the chain

    Tagging objects in the chain

    In implementing this feature I've had to touch some pretty fundamental CQ code, so I'm going to write a detailed description of what I've been up to here, because I'd really like others to follow along, provide good feedback, and hopefully get this merged without treading on other's toes.

    Tags

    The main feature I'm implementing is the abilty to tag an object (method CQ.tag) within the chain, and reload that object at a later point (method CQ.getTagged).

    I've also created a method to create a workplane in the current CQ object by copying the workplane from another CQ object (method CQ.copyWorkplane). This is combined with tags in method CQ.copyWorkplaneFromTagged, allowing things like:

    result = (
        # create a base solid for others to be built upon
        cq.Workplane("XY")
        .box(10, 10, 1, centered=(True, True, False))
        .faces(">Z").workplane()
        .tag("base")
        # build ontop of base solid
        .center(3, 0).rect(2, 2).extrude(4)
        .faces(">Z").workplane().circle(1).extrude(6)
        # go back to the base workplane
        .copyWorkplaneFromTagged("base")
        # build a different solid ontop of the base solid
        .center(-3, 0).circle(1).extrude(11)
    )
    

    tagExample

    A good example of a use case is modelling a PCB.

    Construction geometry using tags

    CadQuery shares the modelling context between all objects in the chain. This has an interesting interaction with tags, in that you can easily:

    1. set a tag,
    2. create some solids and workplanes, or any other CAD operations,
    3. create some edges (which are added to the modelling context's pending edges),
    4. go back to the tagged object with getTagged,
    5. the solids created in step 2 are gone, but your pending edges are still there and can be used in eg. a loft operation

    This could be very useful when step 2 involves creating complicated geometry, and you can't be bothered doing the maths to figure out where the edges need to go in step 3.

    I wrote a test for this use case if you want to read some example code.

    Other changes

    This process of returning to tagged objects is a bit of an edge case for the existing CadQuery code, so I had to make a couple of changes to handle some errors that popped up.

    • Workplane.newObject previously referenced the parent's plane. This made copyWorkplaneFromTagged produce some very confusing results, where the plane of a tagged object could be modified by objects further down the chain. I changed newObject to copy the plane instead. I acknowledge this increases the memory requirements, but I think it's worth it and also newObject is now more in line with how the user would expect it to function.
    • Workplane.center previously changed the current object's plane before creating a new object with the current object's plane. I changed it such that the current object's plane is not modified. It's not as neat, but I think it's how users expect center to function.
    • testWorkplaneCenter in test_selectors previously relied upon the mutable plane. The style of that test didn't seem to follow CadQuery's chained calls, so I changed it. I don't understand why the original code was written in that style, so I'm bringing attention to it here in case I messed with something I shouldn't. I see that test was some of the earliest CQ2.0 code written, and perhaps that was why it didn't use chained calls?

    Todo

    • [x] Add some examples for the docs
    • [x] Further testing (I mean in regular use with CQ-editor, not just pytest)
    • [x] See if I can think up of some other use cases for this. It's a pretty flexible method, the use cases are broad and I'm sure there are lots I'm missing. More use cases would let me write more tests and examples as well, which I would like to do.
    • [x] Include feedback?

    PS. I'm loving CadQuery. It's a light layer over OCC, so it's just so flexible. Extending it like this has been really enjoyable. None of that "smashing my head against the keyboard" as I struggle against heavy, opaque code I can't understand.

    opened by marcus7070 26
  • Update assembledEdges in shapes.py

    Update assembledEdges in shapes.py

    BRepBuilderAPI_MakeWire::Add(const TopTools_ListOfShape & L) offers the option to accept a list of shapes directly as argument: Adds the edges of <L> to the current wire. The edges are not to be consecutive. But they are to be all connected geometrically or topologically. If some of them are not connected the Status give DisconnectedWire but the "Maker" is Done() and you can get the partial result. (ie connected to the first edgeof the list <L>) Following this I modified the assembledEdges in shapes.py to be able to provide a list of unordered edges to BRepBuilderAPI_MakeWire. This way, when the list of edges is generated by another function, there is not need to make them consecutive.

    opened by bragostin 25
  • 3D rendering in the online documentation

    3D rendering in the online documentation

    We could use what @Peque has done ( https://github.com/Peque/sphinxcadquery ) to make the online documentation more appealing.

    Cf. #13 for initial discussion

    infrastructure 
    opened by adam-urbanczyk 25
  • OCP 7.7.0

    OCP 7.7.0

    Update to OCCT/OCP 7.7.0

    I'm not sure if the changes in the project test are some kind of regression or are due to wrong usage of the BRepProj_Projection.

    opened by adam-urbanczyk 1
  • Colors not displayed correctly in some GLTF viewers

    Colors not displayed correctly in some GLTF viewers

    As mentioned in #993, the GLTF exported file now displays correctly in blender.

    I tried a few other viewers and found the colors are not displayed correctly using: CAD Assistant 1.6.0 Mayo 0.6.0.997-e1bebb0

    Here is a screenshot of CAD Assistant import of the GLTF file exported with master (example code from #993):

    image

    Both cones are displayed as green. The expected result is one green cone and one blue cone.

    I'm testing changes to the STEP color handling that should also fix the GLTF color display issue in these viewers.

    bug assembly 
    opened by lorenzncode 0
  • use constraints to place a cut

    use constraints to place a cut

    Is it possible to use constraints to place objects for a cut operation? Or else some kind of undocumented way to "subtract" instead of "add" in an Assembly?

    enhancement assembly 
    opened by ndaman 4
  • cutting operation TopoDS_Vertex hasn't gp_Pnt

    cutting operation TopoDS_Vertex hasn't gp_Pnt

    Hello, I'm new to cadquery and can not get a cutting with a circle profile working (test1). A "cylindric" cut out works fine (test2, test1 also works in Freecad). What I'm doing wrong? Error is TopoDS_Vertex hasn't gp_Pnt, but, sorry, I don't understand what it means and why is it different to the cylindric cut out...

    outerring = cq.Workplane('XY').circle(20).circle(30).extrude(10).translate((0,0,-5)) cuttingring1 = (cq.Workplane('XZ').center(18,0).circle(3).sweep(cq.Workplane('XY').circle(16), isFrenet=True)) test1=outerring.cut(cuttingring1) #not working cuttingring2 = cq.Workplane('XY').circle(18).circle(25).extrude(6).translate((0,0,-2)) #test2=outerring.cut(cuttingring2) #working

    Thank you, Markus

    question ShapeUpgrade_UnifySameDomain 
    opened by mukral 1
  • Possible offset2D bug

    Possible offset2D bug

    In this scenario I am trying to transfer an offset wire from a cylinder to a box. Performing a 2D offset I would expect that the dimensions of the wire will change but that it will remain on the same plane as the original wire. This is not the case as the offset2D operation changes the z component of the wire by 10 points (as much as the dimension of the box). The seems to be that the location of the wire does not match the CenterOfBoundBox. I am currently correcting it using center-offset.CenterofBoundBox() but it feels more of a hack than the intended behaviour. Shouldn't the location of a wire and its center be at least coplanar?

    from cadquery import *
    from cadquery.selectors import *
    from math import *
    
    from dataclasses import dataclass
    
    box = Workplane('XY').box(10,10,10, centered=(True,True,False))
    cylinder = box.faces('>Z').workplane(offset = 1).cylinder(10,5, centered=(True, True, False), combine=False)
    
    center = box.faces('>Z').val().CenterOfBoundBox()
    
    wire = cylinder.wires('<Z').val()
    offset = wire.offset2D(-2)[0]
    
    loc = Location(center-offset.CenterOfBoundBox())
    wire_loc = offset.located(loc)
    
    box = box.faces('>Z').add(wire_loc).toPending().cutBlind(-1)
    
    opened by giannissc 7
Releases(2.1)
  • 2.1(Feb 3, 2021)

    This is the first release featuring OCP, which is our own set of bindings to the OCCT CAD kernel. This will allow us to make custom binding changes related to CadQuery, and also help us keep up better with the OCCT release schedule. Another major change for this release is the addition of assemblies. It is now possible to build an assembly of two or more CadQuery models, and define constraints between the models to position them.

    The updates that have been made since the last version was released can be found in the changelog.

    Thank you to the community for their contributions to make CadQuery what it is. A big thanks also goes to @adam-urbanczyk for the continued leadership of the community as we settle in with CadQuery 2.x.

    Source code(tar.gz)
    Source code(zip)
  • 2.1RC1(Dec 19, 2020)

    This is the first release candidate after moving from PythonOCC to OCP. OCP is our own set of bindings for the Open CASCADE Technology (OCCT) CAD kernel. OCP allows us to update to new OCCT versions more quickly, and provides us with better capability to make customizations specifically for CadQuery. This release includes many notable new features, including assembly support, DXF import/export, improved 3D views in the documentation, and additional 2D sketching functionality.

    With this being a release candidate, please help us by testing it thoroughly and reporting any issues.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Jul 21, 2020)

  • 2.0(Apr 24, 2020)

    This is the first stable release after moving from FreeCAD to PythonOCC. Please see the changelog for a synopsis of what has gone into this release.

    Thank you to the community for their contributions to make CadQuery what it is. A big thanks also goes to @adam-urbanczyk for the continued leadership of the community during this transition.

    Source code(tar.gz)
    Source code(zip)
  • 2.0RC2(Apr 11, 2020)

    This release candidate is mainly to test the CI pipeline to be sure releases are handled properly. After that is verified we can do the 2.0 release.

    Source code(tar.gz)
    Source code(zip)
Easy to use Python module to extract Exif metadata from digital image files.

Easy to use Python module to extract Exif metadata from digital image files.

ianaré sévi 719 Jan 5, 2023
Blender addon to generate better building models from satellite imagery.

Blender addon to generate better building models from satellite imagery.

Ivan Ereshchenko 24 Apr 14, 2022
Photini - A free, easy to use, digital photograph metadata (Exif, IPTC, XMP) editing application for Linux, Windows and MacOS.

A free, easy to use, digital photograph metadata (Exif, IPTC, XMP) editing application for Linux, Windows and MacOS. "Metadata" is said to mea

Jim Easterbrook 120 Dec 20, 2022
Ascify-Art - An easy to use, GUI based and user-friendly colored ASCII art generator from images!

Ascify-Art This is a python based colored ASCII art generator for free! How to Install? You can download and use the python version if you want, modul

Akash Bora 14 Dec 31, 2022
A not exist person image generator python module

A not exist person image generator python module

Fayas Noushad 2 Dec 3, 2021
A QR Code encode and decode python module

A QR Code encode and decode python module

Fayas Noushad 4 Feb 10, 2022
A small Python module for BMP image processing.

micropython-microbmp A small Python module for BMP image processing. It supports BMP image of 1/2/4/8/24-bit colour depth. Loading supports compressio

Quan Lin 4 Nov 2, 2022
Hacking github graph with a easy python script

Hacking-Github-Graph Hacking github graph with a easy python script Requirements git latest version installed. A text editor (eg: vs code, sublime tex

SENPAI LEGEND 1 Nov 1, 2021
An add to make adding screenshots and copied images to the scene easy

Blender Clipboard to Scene It doesn't work with version 2.93 and higher (I tested it on 2.91 and 2.83) There is an issue with importing the Pillow mod

Mohammad Mehdi Afkhami 3 Dec 29, 2021
Simple Python / ImageMagick script to package images into WAD3s for use as GoldSrc textures.

WADs Out For [The] Ladies Simple Python / ImageMagick script to package images into WAD3s for use as GoldSrc textures. Development mostly focused on L

null 5 Apr 9, 2022
A pure python implementation of the GIMP XCF image format. Use this to interact with GIMP image formats

Pure Python implementation of the GIMP image formats (.xcf projects as well as brushes, patterns, etc)

FHPyhtonUtils 8 Dec 30, 2022
Simple to use image handler for python sqlite3.

SQLite Image Handler Simple to use image handler for python sqlite3. Functions Function Name Parameters Returns init databasePath : str tableName : st

Mustafa Ozan Çetin 7 Sep 16, 2022
A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos.

font2png A little Python tool to convert a TrueType (ttf/otf) font into a PNG for use in demos. To use from command line it expects python3 to be at /

Rich Elmes 3 Dec 22, 2021
Pyconvert is a python script that you can use to convert image files to another image format! (eg. PNG to ICO)

Pyconvert is a python script that you can use to convert image files to another image format! (eg. PNG to ICO)

null 1 Jan 16, 2022
An automated Comic Book downloader (cbr/cbz) for use with SABnzbd, NZBGet and torrents

Mylar Note that feature development has stopped as we have moved to Mylar3. EOL for this project is the end of 2020 and will no longer be supported. T

null 979 Dec 13, 2022
A quick and dirty QT Statusbar implementation for grabbing GIFs from Tenor, since there is no offical or unofficial one I found. This was intended for use under Linux, however it was also functional enough on MacOS.

Statusbar-TenorGIF App for Linux A quick and dirty QT Statusbar implementation for grabbing GIFs from Tenor, since there is no offical one and I didnt

Luigi DaVinci 1 Nov 1, 2021
Generate your own QR Code and scan it to see the results! Never use it for malicious purposes.

QR-Code-Generator-Python Choose the name of your generated QR .png file. If it happens to open the .py file (the application), there are specific comm

null 1 Dec 23, 2021
An executor that wraps 3D mesh models and encodes 3D content documents to d-dimension vector.

3D Mesh Encoder An Executor that receives Documents containing point sets data in its blob attribute, with shape (N, 3) and encodes it to embeddings o

Jina AI 11 Dec 14, 2022
㊙️ Create standard barcodes with Python. No external dependencies. 100% Organic Python.

python-barcode python-barcode provides a simple way to create barcodes in Python. There are no external dependencies when generating SVG files. Pillow

Hugo Barrera 419 Dec 26, 2022