cqparts package¶
Subpackages¶
Submodules¶
cqparts.assembly module¶
-
class
cqparts.assembly.Assembly(*largs, **kwargs)¶ Bases:
cqparts.component.ComponentAn 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
dictofComponentinstances, after a successfulbuild()Returns: dict of named ComponentinstancesReturn type: dictFor more information read about the Assembly Build Cycle .
-
constraints¶ Returns full
listofConstraintinstances, after a successfulbuild()Returns: list of named ConstraintinstancesReturn type: listFor more information read about the Assembly Build Cycle .
-
find(keys, _index=0)¶ Parameters: keys ( strorlist) – key path.'a.b'is equivalent to['a', 'b']Find a nested
Componentby 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,
bearingis anAssembly, andringis aPart.Note
For a key path of
a.b.ctheckey can referernce anyComponenttype.Everything prior (in this case
aandb) 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
dictofComponentinstances.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: dictofComponentinstances
-
make_constraints()¶ Create and return
listofConstraintinstancesTip
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: listofConstraintinstancesDefault behaviour returns an empty list; assumes assembly is entirely unconstrained.
-
solve()¶ Run the solver and assign the solution’s
CoordSysteminstances 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.ParametricObjectNote
Both the
PartandAssemblyclasses inherit fromComponent.Wherever the term “component” is used, it is in reference to an instance of either
PartorAssembly.-
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
ThreejsJSONExporterinstance to import ajsonfile:>>> 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
Partfrom aSTEPfile:>>> 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, Noneif not set.Return type: CoordSystem
-
cqparts.errors module¶
-
exception
cqparts.errors.AssemblyFindError¶ Bases:
exceptions.ExceptionRaised when an assembly element cannot be found
-
exception
cqparts.errors.MakeError¶ Bases:
exceptions.ExceptionRaised when there are issues during the make() process of a Part or Assembly
-
exception
cqparts.errors.ParameterError¶ Bases:
exceptions.ExceptionRaised when an invalid parameter is specified
-
exception
cqparts.errors.SearchError¶ Bases:
exceptions.ExceptionRaised 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.SearchErrorRaised when multiple results are found by
cqparts.search.find()
-
exception
cqparts.errors.SearchNoneFoundError¶ Bases:
cqparts.errors.SearchErrorRaised when no results are found by
cqparts.search.find()
-
exception
cqparts.errors.SolidValidityError¶ Bases:
exceptions.ExceptionRaised 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_objattribute.Running
.build()is optional, it’s mostly used to test that there aren’t any critical runtime issues with it’s construction.Parameters: recursive – ( Parthas no children, parameter ignored)
-
local_obj¶ Buffered result of
make()which is (probably) acadquery.Workplaneinstance. If_simpleisTrue, 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.WorkplaneImportant
This must be overridden in your
PartThe outcome of this function should be accessed via cqparts.Part.object
-
make_simple()¶ Create and return simplified solid part.
The simplified representation of a
Partis to lower the export quality of anAssemblyorPartfor 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
Fastenerparts, allmake_simplemethods 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
commonnamed 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
PartorAssemblyto thecqpartssearch 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: setWill return an empty
setif 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.ParametricObjectNote
Both the
PartandAssemblyclasses inherit fromComponent.Wherever the term “component” is used, it is in reference to an instance of either
PartorAssembly.-
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
ThreejsJSONExporterinstance to import ajsonfile:>>> 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
Partfrom aSTEPfile:>>> 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, Noneif 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_objattribute.Running
.build()is optional, it’s mostly used to test that there aren’t any critical runtime issues with it’s construction.Parameters: recursive – ( Parthas no children, parameter ignored)
-
local_obj¶ Buffered result of
make()which is (probably) acadquery.Workplaneinstance. If_simpleisTrue, 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.WorkplaneImportant
This must be overridden in your
PartThe outcome of this function should be accessed via cqparts.Part.object
-
make_simple()¶ Create and return simplified solid part.
The simplified representation of a
Partis to lower the export quality of anAssemblyorPartfor 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
Fastenerparts, allmake_simplemethods are overridden to provide 2 cylinders, one for the bolt’s head, and another for the thread.
-
world_obj¶ The
local_objobject in theworld_coordscoordinate system.Note
This is automatically generated when called, and
world_coordsis notNull.
-
-
class
cqparts.Assembly(*largs, **kwargs)¶ Bases:
cqparts.component.ComponentAn 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
dictofComponentinstances, after a successfulbuild()Returns: dict of named ComponentinstancesReturn type: dictFor more information read about the Assembly Build Cycle .
-
constraints¶ Returns full
listofConstraintinstances, after a successfulbuild()Returns: list of named ConstraintinstancesReturn type: listFor more information read about the Assembly Build Cycle .
-
find(keys, _index=0)¶ Parameters: keys ( strorlist) – key path.'a.b'is equivalent to['a', 'b']Find a nested
Componentby 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,
bearingis anAssembly, andringis 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
dictofComponentinstances.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: dictofComponentinstances
-
make_constraints()¶ Create and return
listofConstraintinstancesTip
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: listofConstraintinstancesDefault behaviour returns an empty list; assumes assembly is entirely unconstrained.
-
solve()¶ Run the solver and assign the solution’s
CoordSysteminstances 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
-