Open lenianiva opened 1 week ago
First, here is an example without using constraints (also an example using Sketch).
import cadquery as cq
base_height = 60
radius = 60
radius_centre = 30
radius_inner = 40
n_tooth = 10
offset = 2 * radius - 20
angle = 3
def create():
teeth_sk = (
cq.Sketch()
.parray(radius_inner + (radius - radius_inner) / 2, 0, 360, n_tooth)
.rect(radius - radius_inner, 2)
)
teeth = (
cq.Workplane(origin=(0, 0, base_height))
.placeSketch(teeth_sk)
.extrude(2)
.tag("teeth")
)
base = (
cq.Workplane()
.sketch()
.circle(radius)
.circle(radius_centre, "s")
.finalize()
.extrude(base_height)
.tag("base")
)
gear = base.union(teeth)
return gear
obj1 = create()
obj2 = create()
result = (
cq.Assembly()
.add(obj1, name="obj1", color=cq.Color(0.8, 0.8, 0.5, 0.3))
.add(
obj2,
name="obj2",
color=cq.Color(0.5, 0.5, 0.5, 0.3),
loc=cq.Location((0, 0, 2 * base_height + 2))
* cq.Location((offset, 0, 0), (180, 0, angle)),
)
)
Here is a try with constraints. I'm not a gear expert and you may find other/better ways to do it.
Change contact
, and angle
values.
import cadquery as cq
from cadquery.occ_impl.shapes import vertex
base_height = 60
radius = 60
radius_centre = 30
radius_inner = 40
n_tooth = 10
contact = 0.8 # tooth contact point range [0, 1]
angle = -10
def create():
teeth_sk = (
cq.Sketch()
.parray(radius_inner + (radius - radius_inner) / 2, 0, 360, n_tooth)
.rect(radius - radius_inner, 2)
)
teeth = (
cq.Workplane(origin=(0, 0, base_height))
.placeSketch(teeth_sk)
.extrude(2)
.tag("teeth")
)
base = (
cq.Workplane()
.sketch()
.circle(radius)
.circle(radius_centre, "s")
.finalize()
.extrude(base_height)
.tag("base")
)
gear = base.union(teeth)
gear.solids(">X", tag="teeth").faces(">Z").edges("<Y").tag("edge1") # gear1 edge
gear.solids("<X", tag="teeth").faces("<Z").edges("<Y").tag("edge2") # gear2 vertex
gear.solids("<X", tag="teeth").faces("<Z").vertices("<XY").tag(
"vertex2"
) # gear2 vertex
return gear
obj1 = create()
obj2 = create()
p1 = obj1.edges(tag="edge1").val().positionAt(1 - contact)
vertex1 = vertex(p1)
vertex2 = obj2.vertices(tag="vertex2").val()
result = (
cq.Assembly()
.add(obj1, name="obj1", color=cq.Color(0.8, 0.8, 0.5, 0.3))
.add(
obj2,
name="obj2",
color=cq.Color(0.5, 0.5, 0.5, 0.3),
)
.constrain("obj1", "Fixed")
.constrain("obj2", "FixedRotation", (180, 0, angle))
.constrain("obj1", vertex1, "obj2", vertex2, "Point")
.solve()
)
gear1 = result.objects.get("obj1")
gear2 = result.objects.get("obj2")
gear1 = gear1.obj.val().moved(gear1.loc)
gear2 = gear2.obj.val().moved(gear2.loc)
# check for intersection
intersect = gear1.intersect(gear2)
if intersect.Volume() > 1e-6:
raise ValueError("Gears intersect!")
If you are not on the lastest master branch, remove the vertex import and change:
vertex1 = vertex(p1)
to
vertex1 = cq.Vertex.makeVertex(*p1.toTuple())
First, here is an example without using constraints (also an example using Sketch).
import cadquery as cq base_height = 60 radius = 60 radius_centre = 30 radius_inner = 40 n_tooth = 10 offset = 2 * radius - 20 angle = 3 def create(): teeth_sk = ( cq.Sketch() .parray(radius_inner + (radius - radius_inner) / 2, 0, 360, n_tooth) .rect(radius - radius_inner, 2) ) teeth = ( cq.Workplane(origin=(0, 0, base_height)) .placeSketch(teeth_sk) .extrude(2) .tag("teeth") ) base = ( cq.Workplane() .sketch() .circle(radius) .circle(radius_centre, "s") .finalize() .extrude(base_height) .tag("base") ) gear = base.union(teeth) return gear obj1 = create() obj2 = create() result = ( cq.Assembly() .add(obj1, name="obj1", color=cq.Color(0.8, 0.8, 0.5, 0.3)) .add( obj2, name="obj2", color=cq.Color(0.5, 0.5, 0.5, 0.3), loc=cq.Location((0, 0, 2 * base_height + 2)) * cq.Location((offset, 0, 0), (180, 0, angle)), ) )
Here is a try with constraints. I'm not a gear expert and you may find other/better ways to do it.
Change
contact
, andangle
values.import cadquery as cq from cadquery.occ_impl.shapes import vertex base_height = 60 radius = 60 radius_centre = 30 radius_inner = 40 n_tooth = 10 contact = 0.8 # tooth contact point range [0, 1] angle = -10 def create(): teeth_sk = ( cq.Sketch() .parray(radius_inner + (radius - radius_inner) / 2, 0, 360, n_tooth) .rect(radius - radius_inner, 2) ) teeth = ( cq.Workplane(origin=(0, 0, base_height)) .placeSketch(teeth_sk) .extrude(2) .tag("teeth") ) base = ( cq.Workplane() .sketch() .circle(radius) .circle(radius_centre, "s") .finalize() .extrude(base_height) .tag("base") ) gear = base.union(teeth) gear.solids(">X", tag="teeth").faces(">Z").edges("<Y").tag("edge1") # gear1 edge gear.solids("<X", tag="teeth").faces("<Z").edges("<Y").tag("edge2") # gear2 vertex gear.solids("<X", tag="teeth").faces("<Z").vertices("<XY").tag( "vertex2" ) # gear2 vertex return gear obj1 = create() obj2 = create() p1 = obj1.edges(tag="edge1").val().positionAt(1 - contact) vertex1 = vertex(p1) vertex2 = obj2.vertices(tag="vertex2").val() result = ( cq.Assembly() .add(obj1, name="obj1", color=cq.Color(0.8, 0.8, 0.5, 0.3)) .add( obj2, name="obj2", color=cq.Color(0.5, 0.5, 0.5, 0.3), ) .constrain("obj1", "Fixed") .constrain("obj2", "FixedRotation", (180, 0, angle)) .constrain("obj1", vertex1, "obj2", vertex2, "Point") .solve() ) gear1 = result.objects.get("obj1") gear2 = result.objects.get("obj2") gear1 = gear1.obj.val().moved(gear1.loc) gear2 = gear2.obj.val().moved(gear2.loc) # check for intersection intersect = gear1.intersect(gear2) if intersect.Volume() > 1e-6: raise ValueError("Gears intersect!")
If you are not on the lastest master branch, remove the vertex import and change:
vertex1 = vertex(p1)
tovertex1 = cq.Vertex.makeVertex(*p1.toTuple())
Are the teeth of the gear automatically fused with the base during .union
? If I were to 3d print them I want them to be fused as one
You can check yourself: len(gear1.Solids())
. They are fused into one solid (this is how union works). BTW: if you don't want them to be fused use compound(...)
I have two gears that have teeth on them:
How would I make tagged objects and constraints so that the gears will mesh? Ideally I want to supply two values for this assembly:
forConstruction
but wires cannot be used as axis or plane constraints.