大家好,欢迎来到IT知识分享网。
1、简易矩形板
result = cadquery.Workplane("front").box(2.0, 2.0, 0.5)
2、带孔板
一个矩形框,但添加了一个孔。
“>Z”选择盒子的最顶面。 孔位于中心,因为工作平面的默认原点是最后一个工作平面的投影原点,最后一个工作平面的原点为 (0,0,0),投影位于面的中心。 默认孔深贯穿整个零件。
# The dimensions of the box. These can be modified rather than changing the # object's code directly. length = 80.0 height = 60.0 thickness = 10.0 center_hole_dia = 22.0 # Create a box based on the dimensions above and add a 22mm center hole result = (cq.Workplane("XY").box(length, height, thickness) .faces(">Z").workplane().hole(center_hole_dia))
3、挤压棱柱体
使用挤压构建棱柱体。 一次绘制操作后,将前一个对象的中心放入栈中,作为下一次操作的参考。 所以在这种情况下, rect() 以先前绘制的圆为中心绘制。
result = cq.Workplane("front").circle(2.0).rect(0.5, 0.75).extrude(0.5)
4、使用线和弧构建轮廓
有时你需要使用直线和圆弧构建复杂的轮廓。 此示例通过 2D 操作构建棱柱实体。
result = (cq.Workplane("front").lineTo(2.0, 0).lineTo(2.0, 1.0).threePointArc((1.0, 1.5), (0.0, 1.0)) .close().extrude(0.25))
5、移动当前工作点
在这个例子中,需要一个封闭的轮廓,以及一些内部特征。
此示例还演示了使用多行代码而不是较长的链式命令,当然在这种情况下也可以在一长行中完成。
result = cq.Workplane("front").circle(3.0) # current point is the center of the circle, at (0, 0) result = result.center(1.5, 0.0).rect(0.5, 0.5) # new work center is (1.5, 0.0) result = result.center(-1.5, 1.5).circle(0.25) # new work center is (0.0, 1.5). # The new center is specified relative to the previous center, not global coordinates! result = result.extrude(0.25)
6、使用点列表
有时你需要在不同位置创建多个特征,使用 Workplane.center() 太麻烦了。
r = cq.Workplane("front").circle(2.0) # make base r = r.pushPoints([(1.5, 0), (0, 1.5), (-1.5, 0), (0, -1.5)]) # now four points are on the stack r = r.circle(0.25) # circle will operate on all four points result = r.extrude(0.125) # make prism
7、多边形
result = (cq.Workplane("front").box(3.0, 4.0, 0.25) .pushPoints([(0, 0.75), (0, -0.75)]) .polygon(6, 1.0).cutThruAll())
8、折线
Workplane.polyline() 允许用连线的大量点创建形状。
此示例使用多段线创建工字梁形状的一半,对其进行镜像以创建最终轮廓。
(L, H, W, t) = (100.0, 20.0, 20.0, 1.0) pts = [ (0, H/2.0), (W/2.0, H/2.0), (W/2.0, (H/2.0 - t)), (t/2.0, (H/2.0 - t)), (t/2.0, (t - H/2.0)), (W/2.0, (t - H/2.0)), (W/2.0, H/-2.0), (0, H/-2.0) ] result = cq.Workplane("front").polyline(pts).mirrorY().extrude(L)
9、用样条曲线定义边
s = cq.Workplane("XY") sPnts = [ (2.75, 1.5), (2.5, 1.75), (2.0, 1.5), (1.5, 1.0), (1.0, 1.25), (0.5, 1.0), (0, 1.0) ] r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(sPnts, includeCurrent=True).close() result = r.extrude(0.5)
10、镜像几何形状
r = cq.Workplane("front").hLine(1.0) # 1.0 is the distance, not coordinate r = r.vLine(0.5).hLine(-0.25).vLine(-0.25).hLineTo(0.0) # hLineTo allows using xCoordinate not distance result = r.mirrorY().extrude(0.25) # mirror the geometry and extrude
11、镜像三维对象
result0 = (cadquery.Workplane("XY") .moveTo(10, 0) .lineTo(5, 0) .threePointArc((3.9393, 0.4393), (3.5, 1.5)) .threePointArc((3.0607, 2.5607), (2, 3)) .lineTo(1.5, 3) .threePointArc((0.4393, 3.4393), (0, 4.5)) .lineTo(0, 13.5) .threePointArc((0.4393, 14.5607), (1.5, 15)) .lineTo(28, 15) .lineTo(28, 13.5) .lineTo(24, 13.5) .lineTo(24, 11.5) .lineTo(27, 11.5) .lineTo(27, 10) .lineTo(22, 10) .lineTo(22, 13.2) .lineTo(14.5, 13.2) .lineTo(14.5, 10) .lineTo(12.5, 10) .lineTo(12.5, 13.2) .lineTo(5.5, 13.2) .lineTo(5.5, 2) .threePointArc((5.793, 1.293), (6.5, 1)) .lineTo(10, 1) .close()) result = result0.extrude(100) result = result.rotate((0, 0, 0), (1, 0, 0), 90) result = result.translate(result.val().BoundingBox().center.multiply(-1)) mirXY_neg = result.mirror(mirrorPlane="XY", basePointVector=(0, 0, -30)) mirXY_pos = result.mirror(mirrorPlane="XY", basePointVector=(0, 0, 30)) mirZY_neg = result.mirror(mirrorPlane="ZY", basePointVector=(-30, 0, 0)) mirZY_pos = result.mirror(mirrorPlane="ZY", basePointVector=(30, 0, 0)) result = result.union(mirXY_neg).union(mirXY_pos).union(mirZY_neg).union(mirZY_pos)
12、参考面镜像
result = (cq.Workplane("XY") .line(0, 1) .line(1, 0) .line(0, -.5) .close() .extrude(1)) result = result.mirror(result.faces(">X"), union=True)
13、在面上创建工作平面
此示例说明如何在先前创建的特征的面上定位新工作平面。
以这种方式使用工作平面是 CadQuery 的一个关键特性。 与典型的 3d 脚本语言不同,使用工作平面使你无需跟踪变量中各种特征的位置,并允许模型通过删除冗余尺寸进行自我调整。
Workplane.faces() 方法允许你选择生成的实体的面。 它接受一个选择器字符串或对象,允许你以单个面为目标,并使工作平面朝向该面。
result = cq.Workplane("front").box(2, 3, 0.5) # make a basic prism result = result.faces(">Z").workplane().hole(0.5) # find the top-most face and make a hole
14、在顶点上定位工作平面
通常, Workplane.workplane() 方法需要选择一个面。 但是,如果在选中一个面后立即选择顶点,则将 centerOption 参数设置为 CenterOfMass 的 Workplane.workplane() 会将工作平面定位在面上,原点位于顶点而不是面的中心。
本示例还介绍了 Workplane.cutThruAll(),它对整个零件进行切割,无论零件有多深。
result = cq.Workplane("front").box(3,2, 0.5) # make a basic prism result = result.faces(">Z").vertices("<XY").workplane(centerOption="CenterOfMass") # select the lower left vertex and make a workplane result = result.circle(1.0).cutThruAll() # cut the corner out
15、偏移工作平面
工作平面不必正好位于面上。 创建工作平面时,可以在距现有面一定偏移处定义。
result = cq.Workplane("front").box(3, 2, 0.5) # make a basic prism result = result.faces("<X").workplane(offset=0.75) # workplane is offset from the object surface result = result.circle(1.0).extrude(0.5) # disc
16、复制工作平面
result = (cq.Workplane("front").circle(1).extrude(10) # make a cylinder # We want to make a second cylinder perpendicular to the first, # but we have no face to base the workplane off .copyWorkplane( # create a temporary object with the required workplane cq.Workplane("right", origin=(-5, 0, 0)) ).circle(1).extrude(10))
17、旋转工作平面
可以通过指定相对于另一个工作平面的旋转角度来创建旋转的工作平面。
result = (cq.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z").workplane() .transformed(offset=cq.Vector(0, -1.5, 1.0),rotate=cq.Vector(60, 0, 0)) .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.25))
18、使用构造几何
你可以绘制形状以将顶点用作定位其他特征的点。 用于定位其他特征而不是创建它们的特征称为构造几何。
在下面的示例中,绘制了一个矩形,其顶点用于定位一组孔。
result = (cq.Workplane("front").box(2, 2, 0.5).faces(">Z").workplane() .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.125))
19、抽壳创建薄壁特征
抽壳将实体对象转换为厚度均匀的壳。
要给对象脱壳并“挖空”内部,请将负厚度参数传递给形状的 Workplane.shell() 方法。
result = cq.Workplane("front").box(2, 2, 2).shell(-0.1)
result = cq.Workplane("front").box(2, 2, 2).shell(0.1)
使用面选择器选择要从生成的空心形状中删除的面。
result = cq.Workplane("front").box(2, 2, 2).faces("+Z").shell(0.1)
可以使用更复杂的选择器删除多个面。
result = ( cq.Workplane("front") .box(2, 2, 2) .faces("+Z or -X or +X") .shell(0.1) )
20、放样
放样是一组线扫掠得到实体。 此示例在矩形和圆形截面之间创建放样截面。
result = (cq.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z").circle(1.5) .workplane(offset=3.0).rect(0.75, 0.5).loft(combine=True))
21、挤压至指定面
有时你会想要挤出一条线直到给定的面,这个面可能不是平面,或者你可能不容易知道必须挤出到的距离。 在这种情况下,可以使用 next、 last 甚至为 extrude() 的 until 参数提供一个 面对象。
result = (cq.Workplane(origin = (20,0,0)) .circle(2) .revolve(180, (-20,0,0),(-20,-1,0)) .center(-20,0) .workplane() .rect(20,4) .extrude("next") )
cutBlind() 也有相同的行为,如你所见,也可以一次处理多个 Wire 对象, extrude() 也是如此。
skyscrapers_locations = [(-16,1),(-8,0),(7,0.2),(17,-1.2)] angles = iter([15,0,-8,10]) skyscrapers = (cq.Workplane() .pushPoints(skyscrapers_locations) .eachpoint(lambda loc: (cq.Workplane() .rect(5,16) .workplane(offset=10) .ellipse(3,8) .workplane(offset=10) .slot2D(20,5, 90) .loft() .rotateAboutCenter((0,0,1),next(angles)) .val().located(loc) ) ) ) result = (skyscrapers .transformed((0,-90,0)) .moveTo(15,0) .rect(3,3, forConstruction=True) .vertices() .circle(1) .cutBlind("last") )
import cadquery as cq sphere = cq.Workplane().sphere(5) base = (cq.Workplane(origin=(0,0,-2)) .box(12,12,10) .cut(sphere) .edges("|Z") .fillet(2) ) sphere_face = base.faces(">>X[2] and (not |Z) and (not |Y)").val() base = (base .faces("<Z") .workplane() .circle(2) .extrude(10) ) shaft = (cq.Workplane() .sphere(4.5) .circle(1.5) .extrude(20) ) spherical_joint = (base.union(shaft) .faces(">X") .workplane(centerOption="CenterOfMass") .move(0,4) .slot2D(10,2,90) .cutBlind(sphere_face) .workplane(offset=10) .move(0,2) .circle(0.9) .extrude("next") ) result = spherical_joint
22、制作沉头孔和埋头孔
沉头孔和埋头孔非常常见,以至于 CadQuery 专门创建宏以在一个步骤中创建它们。
与 Workplane.hole() 类似,这些函数对点列表以及单个点进行操作。
result = ( cq.Workplane(cq.Plane.XY()) .box(4, 2, 0.5) .faces(">Z") .workplane() .rect(3.5, 1.5, forConstruction=True) .vertices() .cboreHole(0.125, 0.25, 0.125, depth=None) )
23、2D 中的偏移线
original = cq.Workplane().polygon(5, 10).extrude(0.1).translate((0, 0, 2)) arc = ( cq.Workplane() .polygon(5, 10) .offset2D(1, "arc") .extrude(0.1) .translate((0, 0, 1)) ) intersection = cq.Workplane().polygon(5, 10).offset2D(1, "intersection").extrude(0.1) result = original.add(arc).add(intersection)
result = ( cq.Workplane() .box(4, 2, 0.5) .faces(">Z") .edges() .toPending() .offset2D(-0.25, forConstruction=True) .vertices() .cboreHole(0.125, 0.25, 0.125, depth=None) )
请注意, Workplane.edges() 用于选择对象。 它不会将选定的边添加到建模上下文中的待定边,因为这会导致你的下一次挤压包括除了绘制的线条之外选择的所有内容。 如果希望这些边在 Workplane.offset2D() 中使用,可以调用 Workplane.toPending() 以明确地将它们放入待定边列表中。
24、圆角
圆角是通过选择实体的边并使用圆角功能完成的。
result = cq.Workplane("XY").box(3, 3, 0.5).edges("|Z").fillet(0.125)
25、标记对象
Workplane.tag() 方法可用于用字符串标记链中的特定对象,以便稍后在链中引用它。
Workplane.workplaneFromTagged() 方法将 Workplane.copyWorkplane() 应用于标记对象。 例如,当从一个表面挤出两个不同的实体时,在第一个实体被挤出后,很难用 CadQuery 的其他选择器重新选择原始表面。
result = (cq.Workplane("XY") # create and tag the base workplane .box(10, 10, 10).faces(">Z").workplane().tag("baseplane") # extrude a cylinder .center(-3, 0).circle(1).extrude(3) # to reselect the base workplane, simply .workplaneFromTagged("baseplane") # extrude a second cylinder .center(3, 0).circle(1).extrude(2))
result = (cq.Workplane("XY") # create a triangular prism and tag it .polygon(3, 5).extrude(4).tag("prism") # create a sphere that obscures the prism .sphere(10) # create features based on the prism's faces .faces("<X", tag="prism").workplane().circle(1).cutThruAll() .faces(">X", tag="prism").faces(">Y").workplane().circle(1).cutThruAll())
26、参数化轴承座
结合一些基本功能,只需几行代码就可以制作出非常好的参数化轴承座。
(length, height, bearing_diam, thickness, padding) = (30.0, 40.0, 22.0, 10.0, 8.0) result = (cq.Workplane("XY").box(length, height, thickness).faces(">Z").workplane().hole(bearing_diam) .faces(">Z").workplane() .rect(length-padding, height-padding, forConstruction=True) .vertices().cboreHole(2.4, 4.4, 2.1))
27、拆分对象
可以使用工作平面拆分对象,并保留其中一个或两个部分。
c = cq.Workplane("XY").box(1, 1, 1).faces(">Z").workplane().circle(0.25).cutThruAll() # now cut it in half sideways result = c.faces(">Y").workplane(-0.5).split(keepTop=True)
28、经典 OCC 瓶
CadQuery 基于 OpenCascade.org (OCC) 建模内核。 熟悉 OCC 的人都知道著名的瓶子示例。
此处列出了 pythonOCC 版本 的实现。
当然,此示例与 OCC 版本之间的一个区别是长度。 这个示例是 13 行的较长示例之一,但与 pythonOCC 版本相比非常短,后者长 10 倍!
(L, w, t) = (20.0, 6.0, 3.0) s = cq.Workplane("XY") # Draw half the profile of the bottle and extrude it p = (s.center(-L/2.0, 0).vLine(w/2.0) .threePointArc((L/2.0, w/2.0 + t), (L, w/2.0)).vLine(-w/2.0) .mirrorX().extrude(30.0, True)) # Make the neck p = p.faces(">Z").workplane(centerOption="CenterOfMass").circle(3.0).extrude(2.0, True) # Make a shell result = p.faces(">Z").shell(0.3)
29、参数化外壳
# parameter definitions p_outerWidth = 100.0 # Outer width of box enclosure p_outerLength = 150.0 # Outer length of box enclosure p_outerHeight = 50.0 # Outer height of box enclosure p_thickness = 3.0 # Thickness of the box walls p_sideRadius = 10.0 # Radius for the curves around the sides of the box p_topAndBottomRadius = 2.0 # Radius for the curves on the top and bottom edges of the box p_screwpostInset = 12.0 # How far in from the edges the screw posts should be place. p_screwpostID = 4.0 # Inner Diameter of the screw post holes, should be roughly screw diameter not including threads p_screwpostOD = 10.0 # Outer Diameter of the screw posts.\nDetermines overall thickness of the posts p_boreDiameter = 8.0 # Diameter of the counterbore hole, if any p_boreDepth = 1.0 # Depth of the counterbore hole, if p_countersinkDiameter = 0.0 # Outer diameter of countersink. Should roughly match the outer diameter of the screw head p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite sides, not from center to one side) p_flipLid = True # Whether to place the lid with the top facing down or not. p_lipHeight = 1.0 # Height of lip on the underside of the lid.\nSits inside the box body for a snug fit. # outer shell oshell = cq.Workplane("XY").rect(p_outerWidth, p_outerLength).extrude(p_outerHeight + p_lipHeight) # weird geometry happens if we make the fillets in the wrong order if p_sideRadius > p_topAndBottomRadius: oshell = oshell.edges("|Z").fillet(p_sideRadius) oshell = oshell.edges("#Z").fillet(p_topAndBottomRadius) else: oshell = oshell.edges("#Z").fillet(p_topAndBottomRadius) oshell = oshell.edges("|Z").fillet(p_sideRadius) # inner shell ishell = (oshell.faces("<Z").workplane(p_thickness, True) .rect((p_outerWidth - 2.0*p_thickness), (p_outerLength - 2.0*p_thickness)) .extrude((p_outerHeight - 2.0*p_thickness), False) # set combine false to produce just the new boss ) ishell = ishell.edges("|Z").fillet(p_sideRadius - p_thickness) # make the box outer box box = oshell.cut(ishell) # make the screw posts POSTWIDTH = (p_outerWidth - 2.0*p_screwpostInset) POSTLENGTH = (p_outerLength - 2.0*p_screwpostInset) box = (box.faces(">Z").workplane(-p_thickness) .rect(POSTWIDTH, POSTLENGTH, forConstruction=True) .vertices().circle(p_screwpostOD/2.0).circle(p_screwpostID/2.0) .extrude(-1.0*(p_outerHeight + p_lipHeight - p_thickness),True)) # split lid into top and bottom parts (lid, bottom) = box.faces(">Z").workplane(-p_thickness - p_lipHeight).split(keepTop=True, keepBottom=True).all() # splits into two solids # translate the lid, and subtract the bottom from it to produce the lid inset lowerLid = lid.translate((0, 0, -p_lipHeight)) cutlip = lowerLid.cut(bottom).translate((p_outerWidth + p_thickness, 0, p_thickness - p_outerHeight + p_lipHeight)) # compute centers for screw holes topOfLidCenters = (cutlip.faces(">Z").workplane(centerOption="CenterOfMass") .rect(POSTWIDTH, POSTLENGTH, forConstruction=True).vertices()) # add holes of the desired type if p_boreDiameter > 0 and p_boreDepth > 0: topOfLid = topOfLidCenters.cboreHole(p_screwpostID, p_boreDiameter, p_boreDepth, 2.0*p_thickness) elif p_countersinkDiameter > 0 and p_countersinkAngle > 0: topOfLid = topOfLidCenters.cskHole(p_screwpostID, p_countersinkDiameter, p_countersinkAngle, 2.0*p_thickness) else: topOfLid = topOfLidCenters.hole(p_screwpostID, 2.0*p_thickness) # flip lid upside down if desired if p_flipLid: topOfLid = topOfLid.rotateAboutCenter((1, 0, 0), 180) # return the combined result result = topOfLid.union(bottom)
30、乐高积木
# Inputs lbumps = 6 # number of bumps long wbumps = 2 # number of bumps wide thin = True # True for thin, False for thick # # Lego Brick Constants-- these make a Lego brick a Lego :) # pitch = 8.0 clearance = 0.1 bumpDiam = 4.8 bumpHeight = 1.8 if thin: height = 3.2 else: height = 9.6 t = (pitch - (2 * clearance) - bumpDiam) / 2.0 postDiam = pitch - t # works out to 6.5 total_length = lbumps*pitch - 2.0*clearance total_width = wbumps*pitch - 2.0*clearance # make the base s = cq.Workplane("XY").box(total_length, total_width, height) # shell inwards not outwards s = s.faces("<Z").shell(-1.0 * t) # make the bumps on the top s = (s.faces(">Z").workplane(). rarray(pitch, pitch, lbumps, wbumps, True).circle(bumpDiam / 2.0) .extrude(bumpHeight)) # add posts on the bottom. posts are different diameter depending on geometry # solid studs for 1 bump, tubes for multiple, none for 1x1 tmp = s.faces("<Z").workplane(invert=True) if lbumps > 1 and wbumps > 1: tmp = (tmp.rarray(pitch, pitch, lbumps - 1, wbumps - 1, center=True). circle(postDiam / 2.0).circle(bumpDiam / 2.0).extrude(height - t)) elif lbumps > 1: tmp = (tmp.rarray(pitch, pitch, lbumps - 1, 1, center=True). circle(t).extrude(height - t)) elif wbumps > 1: tmp = (tmp.rarray(pitch, pitch, 1, wbumps - 1, center=True). circle(t).extrude(height - t)) else: tmp = s
31、盲文示例
from collections import namedtuple
# text_lines is a list of text lines.
# Braille (converted with braille-converter:
# https://github.com/jpaugh/braille-converter.git).
text_lines = ['⠠ ⠋ ⠗ ⠑ ⠑ ⠠ ⠉ ⠠ ⠁ ⠠ ⠙']
# See http://www.tiresias.org/research/reports/braille_cell.htm for examples
# of braille cell geometry.
horizontal_interdot = 2.5
vertical_interdot = 2.5
horizontal_intercell = 6
vertical_interline = 10
dot_height = 0.5
dot_diameter = 1.3
base_thickness = 1.5
# End of configuration.
BrailleCellGeometry = namedtuple('BrailleCellGeometry',
('horizontal_interdot',
'vertical_interdot',
'intercell',
'interline',
'dot_height',
'dot_diameter'))
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __len__(self):
return 2
def __getitem__(self, index):
return (self.x, self.y)[index]
def __str__(self):
return '({}, {})'.format(self.x, self.y)
def brailleToPoints(text, cell_geometry):
# Unicode bit pattern (cf. https://en.wikipedia.org/wiki/Braille_Patterns).
mask1 = 0b00000001
mask2 = 0b00000010
mask3 = 0b00000100
mask4 = 0b00001000
mask5 = 0b00010000
mask6 = 0b00100000
mask7 = 0b01000000
mask8 = 0b10000000
masks = (mask1, mask2, mask3, mask4, mask5, mask6, mask7, mask8)
# Corresponding dot position
w = cell_geometry.horizontal_interdot
h = cell_geometry.vertical_interdot
pos1 = Point(0, 2 * h)
pos2 = Point(0, h)
pos3 = Point(0, 0)
pos4 = Point(w, 2 * h)
pos5 = Point(w, h)
pos6 = Point(w, 0)
pos7 = Point(0, -h)
pos8 = Point(w, -h)
pos = (pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8)
# Braille blank pattern (u'\u2800').
blank = '⠀'
points = []
# Position of dot1 along the x-axis (horizontal).
character_origin = 0
for c in text:
for m, p in zip(masks, pos):
delta_to_blank = ord(c) - ord(blank)
if (m & delta_to_blank):
points.append(p + Point(character_origin, 0))
character_origin += cell_geometry.intercell
return points
def get_plate_height(text_lines, cell_geometry):
# cell_geometry.vertical_interdot is also used as space between base
# borders and characters.
return (2 * cell_geometry.vertical_interdot +
2 * cell_geometry.vertical_interdot +
(len(text_lines) - 1) * cell_geometry.interline)
def get_plate_width(text_lines, cell_geometry):
# cell_geometry.horizontal_interdot is also used as space between base
# borders and characters.
max_len = max([len(t) for t in text_lines])
return (2 * cell_geometry.horizontal_interdot +
cell_geometry.horizontal_interdot +
(max_len - 1) * cell_geometry.intercell)
def get_cylinder_radius(cell_geometry):
"""Return the radius the cylinder should have
The cylinder have the same radius as the half-sphere make the dots (the
hidden and the shown part of the dots).
The radius is such that the spherical cap with diameter
cell_geometry.dot_diameter has a height of cell_geometry.dot_height.
"""
h = cell_geometry.dot_height
r = cell_geometry.dot_diameter / 2
return (r 2 + h 2) / 2 / h
def get_base_plate_thickness(plate_thickness, cell_geometry):
"""Return the height on which the half spheres will sit"""
return (plate_thickness +
get_cylinder_radius(cell_geometry) -
cell_geometry.dot_height)
def make_base(text_lines, cell_geometry, plate_thickness):
base_width = get_plate_width(text_lines, cell_geometry)
base_height = get_plate_height(text_lines, cell_geometry)
base_thickness = get_base_plate_thickness(plate_thickness, cell_geometry)
base = cq.Workplane('XY').box(base_width, base_height, base_thickness,
centered=False)
return base
def make_embossed_plate(text_lines, cell_geometry):
"""Make an embossed plate with dots as spherical caps
Method:
- make a thin plate on which sit cylinders
- fillet the upper edge of the cylinders so to get pseudo half-spheres
- make the union with a thicker plate so that only the sphere caps stay
"visible".
"""
base = make_base(text_lines, cell_geometry, base_thickness)
dot_pos = []
base_width = get_plate_width(text_lines, cell_geometry)
base_height = get_plate_height(text_lines, cell_geometry)
y = base_height - 3 * cell_geometry.vertical_interdot
line_start_pos = Point(cell_geometry.horizontal_interdot, y)
for text in text_lines:
dots = brailleToPoints(text, cell_geometry)
dots = [p + line_start_pos for p in dots]
dot_pos += dots
line_start_pos += Point(0, -cell_geometry.interline)
r = get_cylinder_radius(cell_geometry)
base = (base.faces('>Z').vertices('<XY').workplane()
.pushPoints(dot_pos).circle(r)
.extrude(r))
# Make a fillet almost the same radius to get a pseudo spherical cap.
base = (base.faces('>Z').edges()
.fillet(r - 0.001))
hidding_box = cq.Workplane('XY').box(
base_width, base_height, base_thickness, centered=False)
result = hidding_box.union(base)
return result
_cell_geometry = BrailleCellGeometry(
horizontal_interdot,
vertical_interdot,
horizontal_intercell,
vertical_interline,
dot_height,
dot_diameter)
if base_thickness < get_cylinder_radius(_cell_geometry):
raise ValueError('Base thickness should be at least {}'.format(dot_height))
result = make_embossed_plate(text_lines, _cell_geometry)
32、带各种连接孔的面板
# The dimensions of the model. These can be modified rather than changing the # object's code directly. width = 400 height = 500 thickness = 2 # Create a plate with two polygons cut through it result = cq.Workplane("front").box(width, height, thickness) h_sep = 60 for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(157, 210 - idx*h_sep).moveTo(-23.5, 0).circle(1.6).moveTo(23.5, 0).circle(1.6).moveTo(-17.038896, -5.7).threePointArc((-19.44306, -4.70416), (-20., -2.3)).lineTo(-21.25, 2.3).threePointArc((-20.25416, 4.70416), (-17.85, 5.7)).lineTo(17.85, 5.7).threePointArc((20.25416, 4.70416), (21.25, 2.3)).lineTo(20., -2.3).threePointArc((19.44306, -4.70416), (17.038896, -5.7)).close().cutThruAll() for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(157, -30 - idx*h_sep).moveTo(-16.65, 0).circle(1.6).moveTo(16.65, 0).circle(1.6).moveTo(-10.1889, -5.7).threePointArc((-12.59306, -4.70416), (-13.5889, -2.3)).lineTo(-14.4, 2.3).threePointArc((-13.40416, 4.70416), (-11, 5.7)).lineTo(11, 5.7).threePointArc((13.40416, 4.70416), (14.4, 2.3)).lineTo(13.5889, -2.3).threePointArc((12.59306, -4.70416), (10.1889, -5.7)).close().cutThruAll() h_sep4DB9 = 30 for idx in range(8): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(91, 225 - idx*h_sep4DB9).moveTo(-12.5, 0).circle(1.6).moveTo(12.5, 0).circle(1.6).moveTo(-6.038896, -5.7).threePointArc((-8.44306, -4.70416), (-9., -2.3)).lineTo(-10.25, 2.3).threePointArc((-9.25416, 4.70416), (-6.85, 5.7)).lineTo(6.85, 5.7).threePointArc((9.25416, 4.70416), (10.25, 2.3)).lineTo(9., -2.3).threePointArc((8.44306, -4.70416), (6.038896, -5.7)).close().cutThruAll() for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(25, 210 - idx*h_sep).moveTo(-23.5, 0).circle(1.6).moveTo(23.5, 0).circle(1.6).moveTo(-17.038896, -5.7).threePointArc((-19.44306, -4.70416), (-20., -2.3)).lineTo(-21.25, 2.3).threePointArc((-20.25416, 4.70416), (-17.85, 5.7)).lineTo(17.85, 5.7).threePointArc((20.25416, 4.70416), (21.25, 2.3)).lineTo(20., -2.3).threePointArc((19.44306, -4.70416), (17.038896, -5.7)).close().cutThruAll() for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(25, -30 - idx*h_sep).moveTo(-16.65, 0).circle(1.6).moveTo(16.65, 0).circle(1.6).moveTo(-10.1889, -5.7).threePointArc((-12.59306, -4.70416), (-13.5889, -2.3)).lineTo(-14.4, 2.3).threePointArc((-13.40416, 4.70416), (-11, 5.7)).lineTo(11, 5.7).threePointArc((13.40416, 4.70416), (14.4, 2.3)).lineTo(13.5889, -2.3).threePointArc((12.59306, -4.70416), (10.1889, -5.7)).close().cutThruAll() for idx in range(8): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(-41, 225 - idx*h_sep4DB9).moveTo(-12.5, 0).circle(1.6).moveTo(12.5, 0).circle(1.6).moveTo(-6.038896, -5.7).threePointArc((-8.44306, -4.70416), (-9., -2.3)).lineTo(-10.25, 2.3).threePointArc((-9.25416, 4.70416), (-6.85, 5.7)).lineTo(6.85, 5.7).threePointArc((9.25416, 4.70416), (10.25, 2.3)).lineTo(9., -2.3).threePointArc((8.44306, -4.70416), (6.038896, -5.7)).close().cutThruAll() for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(-107, 210 - idx*h_sep).moveTo(-23.5, 0).circle(1.6).moveTo(23.5, 0).circle(1.6).moveTo(-17.038896, -5.7).threePointArc((-19.44306, -4.70416), (-20., -2.3)).lineTo(-21.25, 2.3).threePointArc((-20.25416, 4.70416), (-17.85, 5.7)).lineTo(17.85, 5.7).threePointArc((20.25416, 4.70416), (21.25, 2.3)).lineTo(20., -2.3).threePointArc((19.44306, -4.70416), (17.038896, -5.7)).close().cutThruAll() for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(-107, -30 - idx*h_sep).circle(14).rect(24.7487, 24.7487, forConstruction=True).vertices().hole(3.2).cutThruAll() for idx in range(8): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(-173, 225 - idx*h_sep4DB9).moveTo(-12.5, 0).circle(1.6).moveTo(12.5, 0).circle(1.6).moveTo(-6.038896, -5.7).threePointArc((-8.44306, -4.70416), (-9., -2.3)).lineTo(-10.25, 2.3).threePointArc((-9.25416, 4.70416), (-6.85, 5.7)).lineTo(6.85, 5.7).threePointArc((9.25416, 4.70416), (10.25, 2.3)).lineTo(9., -2.3).threePointArc((8.44306, -4.70416), (6.038896, -5.7)).close().cutThruAll() for idx in range(4): result = result.workplane(offset=1, centerOption="CenterOfBoundBox").center(-173, -30 - idx*h_sep).moveTo(-2.9176, -5.3).threePointArc((-6.05, 0), (-2.9176, 5.3)).lineTo(2.9176, 5.3).threePointArc((6.05, 0), (2.9176, -5.3)).close().cutThruAll()
33、摆线齿轮
可以使用 parametricCurve 定义复杂的几何图形。 本实例生成螺旋摆线齿轮。
import cadquery as cq from math import sin, cos, pi, floor # define the generating function def hypocycloid(t, r1, r2): return ((r1-r2)*cos(t)+r2*cos(r1/r2*t-t), (r1-r2)*sin(t)+r2*sin(-(r1/r2*t-t))) def epicycloid(t, r1, r2): return ((r1+r2)*cos(t)-r2*cos(r1/r2*t+t), (r1+r2)*sin(t)-r2*sin(r1/r2*t+t)) def gear(t, r1=4, r2=1): if (-1)(1+floor(t/2/pi*(r1/r2))) < 0: return epicycloid(t, r1, r2) else: return hypocycloid(t, r1, r2) # create the gear profile and extrude it result = (cq.Workplane('XY').parametricCurve(lambda t: gear(t*2*pi, 6, 1)) .twistExtrude(15, 90).faces('>Z').workplane().circle(2).cutThruAll())
原文链接:33个CadQuery建模示例 — BimAnt
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/136410.html