CadQuery is an open-source Python ecosystem for parametric 3D modeling. It's a great tool for creating customizable and shareable parts. However, there is no clear standard for formatting and organization of projects. CQ Style is here to help! Please read both sections below for our approach to designing parts and keeping your projects organized and accessible.
Parametric CAD is a wonderful tool for designing your next project. One of its great advantages is the ability to customize and re-use parts, combining them to create sophisticated assemblies which retain their organization and flexibility. Our approach to setting up your development environment should reflect this approach, we want you to be able to create your own parts and use others as well to make your designs come to life. We recommend the following approach to make that possible:
- Create a root CadQuery projects folder. We recommend you keep all of your CadQuery projects in one place so you can easily import parts from other projects using relative paths.
- Load
cq_style
into your CadQuery projects folder using the following:
mkdir CadQueryDesigns
cd CadQueryDesigns
git clone https://github.com/jpoles1/cq_style.git
- Each project should get its own uniquely named folder; we recommend prefacing all project folder names with
cqs
(Ex: cqs_project/part.py). This indicates to other users that this project iscq_style
enabled. A project folder can contain as many CadQuery python files as you'd like; we encourage separating each component out into its own file where reasonable, and using a clear naming schema for each file to describe the part it contains.
mkdir cqs_project
cd cqs_project
touch part.py
- In order to import
cq_style
from the parent folder you'll using the following:
import sys
sys.path.append("../cq_style")
from cq_style import StylishPart
- In order to import a part from another project in the parent folder you'll using the following:
import sys
sys.path.append("../cqs_otherproject")
# If your part is contained under the filename "cqs_otherproject.py":
from cqs_otherproject import PartName
p = PartName()
# If your part is contained under any other filename such as "otherpart.py":
from cqs_otherproject import otherpart
p = otherpart.PartName()
# OR you could use:
from cqs_otherproject.otherpart import PartName
p = PartName()
- If using version control, we recommend creating a new git repo for every project rather than using a repo for your entire project directory.
You're now up and running creating your own flexible and nicely organized CadQuery design environment! Your final file structure should appear as follows:
~/
├─ CadQueryDesigns/
│ ├─ cqs_project1/
│ │ ├─ part.py
│ ├─ cqs_project2/
│ │ ├─ otherpart.py
│ ├─ cq_style/
│ │ ├─ Files from: git clone https://github.com/jpoles1/cq_style.git
As noted above, CadQuery is a great tool for creating customizable, parametric CAD models. It's great to have the ability to make designs parametric, but how do we keep things clean and organized, while exposing the right variables for yourself and other users to customize? This is where cq_style
comes in!
- Every part is a class and thus comes with the usual benefits of OOP design: modularity, reusability, flexibility, inheritance, etc.
- The
cq_style
approach means code across the CadQuery community can be more uniform allowing the community to build and innovate together! - In particular
cq_style
uses the Python _dataclass which makes it easy to specify which variables are intended to be edited by the user (as well as what type the variable should contain). Dataclasses also make writing the code a breeze and cuts down on excessive boilerplate code. - Within cq_style are a handful of helper functions, which supplement CadQuery's core functionality and help users to hit the ground running with more easily designing their projects.
If you've followed the above instructions to setup your project directory and download cq_style
you're all set to get started! We recommend you take a look over example.py
for a demonstration of how a standard cq_style
part is written and what each part of the file is used for. You can also jump right in by copying boilerplate.py
into a file in your new project directory to get things rolling.
An "optional" user-defined function which calculates class/self variables which are dependent on the values of params set during instatiation of the class. Ex: you want to define a dimension as a fraction of a customizable dimension which is input by a user when instantiating the part
def calc_vars(self):
#Example: L is equal to 2x W
#self.L = 2 * self.W
return
An "optional" user-defined function which checks over params from instantiation of the class. Should be used to throw warnings/errors if variables are configured incorrectly.
Note: Runs after calc_vars() on default init so can be used to check calculated variables too_
Ex: You want to make sure that one dimension is always smaller than the other for a customizable part
def check_config(self):
#Example: L should always be greater than H
#if self.H > self.L:
# raise ValueError("Invalid Config: self.H > self.L; height should always be less than length!)")
return
Main function where final part is assembled. Should return either an Assembly OR Workplane.
Note: It is recommended to avoid calling make() directly on an instantiated StylishPart, instead use part() as below.
This function should be used to access the part created by make(). This function caches the part so if it has already been computed during this run you do not need to recompute the design, saving time, especially when working with complex geometries.
Note: You can regenerate the part rather than using the cached version by setting regen = True
Display the part, can be used as part of the function chain (Ex: StylishPart().export().display(show_object)
) rather than having to wrap with the display function (Ex: show_object(StylishPart().part())
).
Note: _show_object can be set to any function that renders a CadQuery part (like debug()
in CQ Editor or show()
in Jupyter CadQuery).
As above, displays the part after splitting it using the provided axis (Ex: "XZ", "YZ", "XY"). You can offset this cutting axis from (0, 0, 0) by setting the offset param. This works with both Workplane and Assembly objects.
Exports your part to the specified filepath, identifies export format based on extension in the filepath (Ex: part.stl, part.step)
As above, exports the part after splitting it using the provided axis (Ex: "XZ", "YZ", "XY"). You can offset this cutting axis from (0, 0, 0) by setting the offset param. This works with both Workplane and Assembly objects.