cqparts package¶
Subpackages¶
Submodules¶
cqparts.assembly module¶
-
class
cqparts.assembly.
Assembly
(*largs, **kwargs)¶ Bases:
cqparts.component.Component
An assembly is a group of parts, and other assemblies (called components)
-
build
(recursive=True)¶ Building an assembly buffers the
components()
andconstraints()
.Running
build()
is optional, it’s automatically run when requestingcomponents()
orconstraints()
.Mostly it’s used to test that there aren’t any critical runtime issues with its construction, but doing anything like displaying or exporting will ultimately run a build anyway.
Parameters: recursive ( bool
) – if set, iterates through child components and builds those as well.
-
components
¶ Returns full
dict
ofComponent
instances, after a successfulbuild()
Returns: dict of named Component
instancesReturn type: dict
For more information read about the Assembly Build Cycle .
-
constraints
¶ Returns full
list
ofConstraint
instances, after a successfulbuild()
Returns: list of named Constraint
instancesReturn type: list
For more information read about the Assembly Build Cycle .
-
find
(keys, _index=0)¶ Parameters: keys ( str
orlist
) – key path.'a.b'
is equivalent to['a', 'b']
Find a nested
Component
by a “.” separated list of names. for example:>>> motor.find('bearing.outer_ring')
would return the Part instance of the motor bearing’s outer ring.
>>> bearing = motor.find('bearing') >>> ring = bearing.find('inner_ring') # equivalent of 'bearing.inner_ring'
the above code does much the same thing,
bearing
is anAssembly
, andring
is aPart
.Note
For a key path of
a.b.c
thec
key can referernce anyComponent
type.Everything prior (in this case
a
andb
) must reference anAssembly
.
-
make_alterations
()¶ Make necessary changes to components after the constraints solver has completed.
Tip
This can be overridden in inheriting class, read:
- Assembly Build Cycle for details.
- Make your own Assembly for an example.
-
make_components
()¶ Create and return
dict
ofComponent
instances.Tip
This must be overridden in inheriting class, read:
- Assembly Build Cycle for details.
- Make your own Assembly for an example.
Returns: {<name>: <Component>, …} Return type: dict
ofComponent
instances
-
make_constraints
()¶ Create and return
list
ofConstraint
instancesTip
This must be overridden in inheriting class, read:
- Assembly Build Cycle for details.
- Make your own Assembly for an example.
Returns: constraints for assembly children’s placement Return type: list
ofConstraint
instancesDefault behaviour returns an empty list; assumes assembly is entirely unconstrained.
-
solve
()¶ Run the solver and assign the solution’s
CoordSystem
instances as the corresponding part’s world coordinates.
-
tree_str
(name=None, prefix='', add_repr=False, _depth=0)¶ Return string listing recursively the assembly hierarchy
Parameters: Returns: Printable string of an assembly’s component hierarchy.
Return type: Example output from block_tree.py
>>> log = logging.getLogger(__name__) >>> isinstance(block_tree, Assembly) True >>> log.info(block_tree.tree_str(name="block_tree")) block_tree ├○ branch_lb ├○ branch_ls ├─ branch_r │ ├○ L │ ├○ R │ ├○ branch │ ├─ house │ │ ├○ bar │ │ └○ foo │ └○ split ├○ trunk └○ trunk_split
Where:
─
denotes anAssembly
, and○
denotes aPart
-
static
verify_components
(components)¶ Verify values returned from
make_components()
.Used internally during the
build()
process.Parameters: components ( dict
) – value returned frommake_components()
Raises: ValueError – if verification fails
-
static
verify_constraints
(constraints)¶ Verify values returned from
make_constraints()
.Used internally during the
build()
process.Parameters: constraints ( list
) – value returned frommake_constraints()
Raises: ValueError – if verification fails
-
cqparts.component module¶
-
class
cqparts.component.
Component
(*largs, **kwargs)¶ Bases:
cqparts.params.parametric_object.ParametricObject
Note
Both the
Part
andAssembly
classes inherit fromComponent
.Wherever the term “component” is used, it is in reference to an instance of either
Part
orAssembly
.-
build
(recursive=True)¶ Raises: NotImplementedError – must be overridden by inheriting classes to function
-
exporter
(exporter_name=None)¶ Get an exporter instance to write the component’s content to file.
Parameters: exporter_name ( str
) – registered name of exporter to use, seeregister_exporter()
for more information.For example, to get a
ThreejsJSONExporter
instance to import ajson
file:>>> from cqparts_misc.basic.primatives import Box >>> box = Box() >>> json_exporter = box.exporter('json') >>> # then each exporter will behave differently >>> json_exporter('out.json')
To learn more: Import / Export
-
classmethod
importer
(importer_name=None)¶ Get an importer instance to instantiate a component from file.
Parameters: importer_name ( str
) – registered name of importer to use, seeregister_importer()
for more information.For example, to get an importer to instantiate a
Part
from aSTEP
file:>>> from cqparts import Part >>> step_importer = Part.importer('step') >>> # then each importer will behave differently >>> my_part = step_importer('my_file.step')
To learn more: Import / Export
-
mate_origin
¶ Returns: mate at object’s origin Return type: Mate
-
world_coords
¶ Component’s placement in word coordinates (
CoordSystem
)Returns: coordinate system in the world, None
if not set.Return type: CoordSystem
-
cqparts.errors module¶
-
exception
cqparts.errors.
AssemblyFindError
¶ Bases:
exceptions.Exception
Raised when an assembly element cannot be found
-
exception
cqparts.errors.
MakeError
¶ Bases:
exceptions.Exception
Raised when there are issues during the make() process of a Part or Assembly
-
exception
cqparts.errors.
ParameterError
¶ Bases:
exceptions.Exception
Raised when an invalid parameter is specified
-
exception
cqparts.errors.
SearchError
¶ Bases:
exceptions.Exception
Raised by search algithms, for example
cqparts.search.find()
Parent of both
SearchNoneFoundError
&SearchMultipleFoundError
>>> from cqparts.errors import SearchError >>> from cqparts.search import find >>> try: ... part_a_class = find(a='common', b='criteria') # multiple results ... part_b_class = find(a="doesn't exist") # no results ... except SearchError: ... # error handling? ... pass
-
exception
cqparts.errors.
SearchMultipleFoundError
¶ Bases:
cqparts.errors.SearchError
Raised when multiple results are found by
cqparts.search.find()
-
exception
cqparts.errors.
SearchNoneFoundError
¶ Bases:
cqparts.errors.SearchError
Raised when no results are found by
cqparts.search.find()
-
exception
cqparts.errors.
SolidValidityError
¶ Bases:
exceptions.Exception
Raised when an unrecoverable issue occurs with a solid
cqparts.part module¶
-
class
cqparts.part.
Part
(*largs, **kwargs)¶ Bases:
cqparts.component.Component
-
bounding_box
¶ Generate a bounding box based on the full complexity part.
Returns: bounding box of part Return type: cadquery.BoundBox
-
build
(recursive=False)¶ Building a part buffers the
local_obj
attribute.Running
.build()
is optional, it’s mostly used to test that there aren’t any critical runtime issues with it’s construction.Parameters: recursive – ( Part
has no children, parameter ignored)
-
local_obj
¶ Buffered result of
make()
which is (probably) acadquery.Workplane
instance. If_simple
isTrue
, thenmake_simple()
is returned instead.Note
This is usually the correct way to get your part’s object for rendering, exporting, or measuring.
Only call
cqparts.Part.make()
directly if you explicitly intend to re-generate the model from scratch, then dispose of it.
-
make
()¶ Create and return solid part
Returns: cadquery.Workplane of the part in question Return type: subclass of cadquery.CQ
, usually acadquery.Workplane
Important
This must be overridden in your
Part
The outcome of this function should be accessed via cqparts.Part.object
-
make_simple
()¶ Create and return simplified solid part.
The simplified representation of a
Part
is to lower the export quality of anAssembly
orPart
for rendering.Overriding this is optional, but highly recommended.
The default behaviour returns the full complexity object’s bounding box. But to do this, theh full complexity object must be generated first.
There are 2 main problems with this:
- building the full complexity part is not efficient.
- a bounding box may not be a good representation of the part.
Bolts
A good example of this is a bolt.
- building a bolt’s thread is not a trivial task; it can take some time to generate.
- a box is not a good visual representation of a bolt
So for the
Fastener
parts, allmake_simple
methods are overridden to provide 2 cylinders, one for the bolt’s head, and another for the thread.
-
cqparts.search module¶
-
cqparts.search.
common_criteria
(**common)¶ Wrap a function to always call with the given
common
named parameters.Property common: criteria common to your function call Returns: decorator function Return type: function
>>> import cqparts >>> from cqparts.search import register, search, find >>> from cqparts.search import common_criteria >>> # Somebody elses (boring) library may register with... >>> @register(a='one', b='two') ... class BoringThing(cqparts.Part): ... pass >>> # But your library is awesome; only registering with unique criteria... >>> lib_criteria = { ... 'author': 'your_name', ... 'libname': 'awesome_things', ... } >>> awesome_register = common_criteria(**lib_criteria)(register) >>> @awesome_register(a='one', b='two') # identical to BoringThing ... class AwesomeThing(cqparts.Part): ... pass >>> # So lets try a search >>> len(search(a='one', b='two')) 2 >>> # oops, that returned both classes >>> # To narrow it down, we add something unique: >>> len(search(a='one', b='two', libname='awesome_things')) # finds only yours 1 >>> # or, we could use common_criteria again... >>> awesome_search = common_criteria(**lib_criteria)(search) >>> awesome_find = common_criteria(**lib_criteria)(find) >>> len(awesome_search(a='one', b='two')) 1 >>> awesome_find(a='one', b='two').__name__ 'AwesomeThing'
A good universal way to apply unique criteria is with
import cadquery, cqparts from cqparts.search import register, common_criteria _register = common_criteria(module=__name__)(register) @_register(shape='cube', scale='unit') class Cube(cqparts.Part): # just an example... def make(self): return cadquery.Workplane('XY').box(1, 1, 1)
-
cqparts.search.
find
(**criteria)¶ Find a single component class with the given criteria.
Finds classes indexed with
register()
Raises: - SearchMultipleFoundError – if more than one result found
- SearchNoneFoundError – if nothing found
from cqparts.search import find import cqparts_motors # example of a 3rd party lib # get a specific motor class motor_class = find(type='motor', part_number='ABC123X') motor = motor_class(shaft_diameter=6.0)
-
cqparts.search.
register
(**criteria)¶ class decorator to add
Part
orAssembly
to thecqparts
search index:import cqparts from cqparts.params import * # Created Part or Assembly @cqparts.search.register( type='motor', current_class='dc', part_number='ABC123X', ) class SomeMotor(cqparts.Assembly): shaft_diam = PositiveFloat(5) def make_components(self): return {} # build assembly content motor_class = cqparts.search.find(part_number='ABC123X') motor = motor_class(shaft_diam=6.0)
Then use
find()
&/orsearch()
to instantiate it.Warning
Multiple classes can be registered with identical criteria, but should be avoided.
If multiple classes share the same criteria,
find()
will never yield the part you want.Try adding unique criteria, such as make, model, part number, library name, &/or author.
To avoid this, learn more in Component Index.
-
cqparts.search.
search
(**criteria)¶ Search registered component classes matching the given criteria.
Parameters: criteria – search criteria of the form: a='1', b='x'
Returns: parts registered with the given criteria Return type: set
Will return an empty
set
if nothing is found.from cqparts.search import search import cqparts_motors # example of a 3rd party lib # Get all DC motor classes dc_motors = search(type='motor', current_class='dc') # For more complex queries: air_cooled = search(cooling='air') non_aircooled_dcmotors = dc_motors - air_cooled # will be all DC motors that aren't air-cooled
Module contents¶
Copyright 2018 Peter Boin
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
class
cqparts.
Component
(*largs, **kwargs)¶ Bases:
cqparts.params.parametric_object.ParametricObject
Note
Both the
Part
andAssembly
classes inherit fromComponent
.Wherever the term “component” is used, it is in reference to an instance of either
Part
orAssembly
.-
build
(recursive=True)¶ Raises: NotImplementedError – must be overridden by inheriting classes to function
-
exporter
(exporter_name=None)¶ Get an exporter instance to write the component’s content to file.
Parameters: exporter_name ( str
) – registered name of exporter to use, seeregister_exporter()
for more information.For example, to get a
ThreejsJSONExporter
instance to import ajson
file:>>> from cqparts_misc.basic.primatives import Box >>> box = Box() >>> json_exporter = box.exporter('json') >>> # then each exporter will behave differently >>> json_exporter('out.json')
To learn more: Import / Export
-
classmethod
importer
(importer_name=None)¶ Get an importer instance to instantiate a component from file.
Parameters: importer_name ( str
) – registered name of importer to use, seeregister_importer()
for more information.For example, to get an importer to instantiate a
Part
from aSTEP
file:>>> from cqparts import Part >>> step_importer = Part.importer('step') >>> # then each importer will behave differently >>> my_part = step_importer('my_file.step')
To learn more: Import / Export
-
mate_origin
¶ Returns: mate at object’s origin Return type: Mate
-
world_coords
¶ Component’s placement in word coordinates (
CoordSystem
)Returns: coordinate system in the world, None
if not set.Return type: CoordSystem
-
-
class
cqparts.
Part
(*largs, **kwargs)¶ Bases:
cqparts.component.Component
-
bounding_box
¶ Generate a bounding box based on the full complexity part.
Returns: bounding box of part Return type: cadquery.BoundBox
-
build
(recursive=False)¶ Building a part buffers the
local_obj
attribute.Running
.build()
is optional, it’s mostly used to test that there aren’t any critical runtime issues with it’s construction.Parameters: recursive – ( Part
has no children, parameter ignored)
-
local_obj
¶ Buffered result of
make()
which is (probably) acadquery.Workplane
instance. If_simple
isTrue
, thenmake_simple()
is returned instead.Note
This is usually the correct way to get your part’s object for rendering, exporting, or measuring.
Only call
cqparts.Part.make()
directly if you explicitly intend to re-generate the model from scratch, then dispose of it.
-
make
()¶ Create and return solid part
Returns: cadquery.Workplane of the part in question Return type: subclass of cadquery.CQ
, usually acadquery.Workplane
Important
This must be overridden in your
Part
The outcome of this function should be accessed via cqparts.Part.object
-
make_simple
()¶ Create and return simplified solid part.
The simplified representation of a
Part
is to lower the export quality of anAssembly
orPart
for rendering.Overriding this is optional, but highly recommended.
The default behaviour returns the full complexity object’s bounding box. But to do this, theh full complexity object must be generated first.
There are 2 main problems with this:
- building the full complexity part is not efficient.
- a bounding box may not be a good representation of the part.
Bolts
A good example of this is a bolt.
- building a bolt’s thread is not a trivial task; it can take some time to generate.
- a box is not a good visual representation of a bolt
So for the
Fastener
parts, allmake_simple
methods are overridden to provide 2 cylinders, one for the bolt’s head, and another for the thread.
-
world_obj
¶ The
local_obj
object in theworld_coords
coordinate system.Note
This is automatically generated when called, and
world_coords
is notNull
.
-
-
class
cqparts.
Assembly
(*largs, **kwargs)¶ Bases:
cqparts.component.Component
An assembly is a group of parts, and other assemblies (called components)
-
build
(recursive=True)¶ Building an assembly buffers the
components()
andconstraints()
.Running
build()
is optional, it’s automatically run when requestingcomponents()
orconstraints()
.Mostly it’s used to test that there aren’t any critical runtime issues with its construction, but doing anything like displaying or exporting will ultimately run a build anyway.
Parameters: recursive ( bool
) – if set, iterates through child components and builds those as well.
-
components
¶ Returns full
dict
ofComponent
instances, after a successfulbuild()
Returns: dict of named Component
instancesReturn type: dict
For more information read about the Assembly Build Cycle .
-
constraints
¶ Returns full
list
ofConstraint
instances, after a successfulbuild()
Returns: list of named Constraint
instancesReturn type: list
For more information read about the Assembly Build Cycle .
-
find
(keys, _index=0)¶ Parameters: keys ( str
orlist
) – key path.'a.b'
is equivalent to['a', 'b']
Find a nested
Component
by a “.” separated list of names. for example:>>> motor.find('bearing.outer_ring')
would return the Part instance of the motor bearing’s outer ring.
>>> bearing = motor.find('bearing') >>> ring = bearing.find('inner_ring') # equivalent of 'bearing.inner_ring'
the above code does much the same thing,
bearing
is anAssembly
, andring
is aPart
.
-
make_alterations
()¶ Make necessary changes to components after the constraints solver has completed.
Tip
This can be overridden in inheriting class, read:
- Assembly Build Cycle for details.
- Make your own Assembly for an example.
-
make_components
()¶ Create and return
dict
ofComponent
instances.Tip
This must be overridden in inheriting class, read:
- Assembly Build Cycle for details.
- Make your own Assembly for an example.
Returns: {<name>: <Component>, …} Return type: dict
ofComponent
instances
-
make_constraints
()¶ Create and return
list
ofConstraint
instancesTip
This must be overridden in inheriting class, read:
- Assembly Build Cycle for details.
- Make your own Assembly for an example.
Returns: constraints for assembly children’s placement Return type: list
ofConstraint
instancesDefault behaviour returns an empty list; assumes assembly is entirely unconstrained.
-
solve
()¶ Run the solver and assign the solution’s
CoordSystem
instances as the corresponding part’s world coordinates.
-
tree_str
(name=None, prefix='', add_repr=False, _depth=0)¶ Return string listing recursively the assembly hierarchy
Parameters: Returns: Printable string of an assembly’s component hierarchy.
Return type: Example output from block_tree.py
>>> log = logging.getLogger(__name__) >>> isinstance(block_tree, Assembly) True >>> log.info(block_tree.tree_str(name="block_tree")) block_tree ├○ branch_lb ├○ branch_ls ├─ branch_r │ ├○ L │ ├○ R │ ├○ branch │ ├─ house │ │ ├○ bar │ │ └○ foo │ └○ split ├○ trunk └○ trunk_split
Where:
-
static
verify_components
(components)¶ Verify values returned from
make_components()
.Used internally during the
build()
process.Parameters: components ( dict
) – value returned frommake_components()
Raises: ValueError – if verification fails
-
static
verify_constraints
(constraints)¶ Verify values returned from
make_constraints()
.Used internally during the
build()
process.Parameters: constraints ( list
) – value returned frommake_constraints()
Raises: ValueError – if verification fails
-