Constraints¶
Constraints limit the location & orientation of a Component
relative to its parent Assembly
.
A completely unconstrained component could be anywhere, and with any rotation. Conversely, a fully constrained component can only be at one specific location & orientation.
Constraints consist of, at a minimum:
- the
Component
being constrained. - one or more
Mate
instances. - constraint specific parameters (if any)
Types of Constraints¶
Fixed¶
The Fixed
explicitly sets a component’s location
and orientation relative to its parent’s origin:
import cadquery
from cqparts import Assembly, Part
from cqparts.constraint import Fixed
from cqparts.utils.geometry import CoordSystem
class Box(Part):
def make(self):
# a unit cube centered on 0,0,0
return cadquery.Workplane('XY').box(1, 1, 1)
class Thing(Assembly):
def make_components(self):
return {
'box_a': Box(),
'box_b': Box(),
}
def make_constraints(self):
return [
Fixed( # boxA 10mm up, no change to rotation
self.components['box_a'].mate_origin,
CoordSystem((0,0,10), (1,0,0), (0,0,1))
),
Fixed( # boxB at origin, rotate around z 45deg ccw
self.components['box_b'].mate_origin,
CoordSystem((0,0,0), (1,1,0), (0,0,1))
),
]
thing = Thing()
thing.build() # creates and places all components recursively
Coincident¶
The Coincident
sets a
component’s coordinate system relative to another part’s world coordinate
system.
In order to solve a relative offset, the relative coordinates need to be
solved first. So for the coordinates A + B = C
, where:
A
is therelative_to
object’s coordinate system.B
is the offset (explicitly set; always known)C
is the coordinate system being solved.
We can only know what C
is if we know the values of both A
and B
.
import cadquery
from cqparts import Assembly, Part
from cqparts.constraint import (
Fixed, Coincident, Mate
)
from cqparts.utils.geometry import CoordSystem
class Box(Part):
def make(self):
# a unit cube placed on top of XY plane
return cadquery.Workplane('XY') \
.box(10, 10, 10, centered=(True, True, False))
@property
def mate_top(self):
return Mate(self, CoordSystem.from_plane(
self.local_obj.faces(">Z").workplane().plane
))
class Thing(Assembly):
def make_components(self):
return {
'box_a': Box(),
'box_b': Box(),
}
def make_constraints(self):
return [
# boxA at zero, no rotation
Fixed(self.components['box_a'].mate_origin),
# boxB at on top of boxA, using boxA's mate_top attribute
Coincident(
self.components['box_b'].mate_origin,
self.components['box_a'].mate_top,
),
]
thing = Thing()
thing.build() # creates and places all components recursively