#! python # SPDX-License-Identifier: LGPL-2.1-or-later # (c) 2008 Werner Mayer LGPL import Part, math import FreeCAD, FreeCADGui App = FreeCAD Gui = FreeCADGui from FreeCAD import Base def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0): aPnt1 = Base.Vector(-myWidth / 2.0, 0, 0) aPnt2 = Base.Vector(-myWidth / 2.0, -myThickness / 4.0, 0) aPnt3 = Base.Vector(0, -myThickness / 2.0, 0) aPnt4 = Base.Vector(myWidth / 2.0, -myThickness / 4.0, 0) aPnt5 = Base.Vector(myWidth / 2.0, 0, 0) aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4) aSegment1 = Part.LineSegment(aPnt1, aPnt2) aSegment2 = Part.LineSegment(aPnt4, aPnt5) aEdge1 = aSegment1.toShape() aEdge2 = aArcOfCircle.toShape() aEdge3 = aSegment2.toShape() aWire = Part.Wire([aEdge1, aEdge2, aEdge3]) aTrsf = Base.Matrix() aTrsf.rotateZ(math.pi) # rotate around the z-axis aMirroredWire = aWire.copy() aMirroredWire.transformShape(aTrsf) myWireProfile = Part.Wire([aWire, aMirroredWire]) myFaceProfile = Part.Face(myWireProfile) aPrismVec = Base.Vector(0, 0, myHeight) myBody = myFaceProfile.extrude(aPrismVec) myBody = myBody.makeFillet(myThickness / 12.0, myBody.Edges) neckLocation = Base.Vector(0, 0, myHeight) neckNormal = Base.Vector(0, 0, 1) myNeckRadius = myThickness / 4.0 myNeckHeight = myHeight / 10 myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal) myBody = myBody.fuse(myNeck) faceToRemove = 0 zMax = -1.0 for xp in myBody.Faces: surf = xp.Surface if type(surf) == Part.Plane: z = surf.Position.z if z > zMax: zMax = z faceToRemove = xp # This doesn't work for any reason myBody = myBody.makeThickness([faceToRemove], -myThickness / 50, 1.0e-3) myThreading = Part.makeThread( myNeckHeight / 10, myNeckRadius * 0.06, myHeight / 10, myNeckRadius * 0.99 ) myThreading.translate(Base.Vector(0, 0, myHeight)) myCompound = Part.makeCompound([myBody, myThreading]) return myCompound def makeBoreHole(): # create a document if needed if App.ActiveDocument is None: App.newDocument("Solid") Group = App.ActiveDocument.addObject("App::DocumentObjectGroup", "Group") Group.Label = "Bore hole" V1 = Base.Vector(0, 10, 0) V2 = Base.Vector(30, 10, 0) V3 = Base.Vector(30, -10, 0) V4 = Base.Vector(0, -10, 0) VC1 = Base.Vector(-10, 0, 0) C1 = Part.Arc(V1, VC1, V4) # and the second one VC2 = Base.Vector(40, 0, 0) C2 = Part.Arc(V2, VC2, V3) L1 = Part.LineSegment(V1, V2) # and the second one L2 = Part.LineSegment(V4, V3) S1 = Part.Shape([C1, C2, L1, L2]) W = Part.Wire(S1.Edges) F = Part.makeFace(W) P = F.extrude(Base.Vector(0, 0, 5)) # add objects with the shape Wire = Group.newObject("Part::Feature", "Wire") Wire.Shape = W Face = Group.newObject("Part::Feature", "Face") Face.Shape = F Prism = Group.newObject("Part::Feature", "Extrude") Prism.Shape = P c = Part.Circle(Base.Vector(0, 0, -1), Base.Vector(0, 0, 1), 2.0) w = Part.Wire(c.toShape()) f = Part.makeFace(w) p = f.extrude(Base.Vector(0, 0, 7)) P = P.cut(p) # add first borer Bore1 = Group.newObject("Part::Feature", "Borer_1") Bore1.Shape = p Hole1 = Group.newObject("Part::Feature", "Borer_Hole1") Hole1.Shape = P c = Part.Circle(Base.Vector(0, -11, 2.5), Base.Vector(0, 1, 0), 1.0) w = Part.Wire(c.toShape()) f = Part.makeFace(w) p = f.extrude(Base.Vector(0, 22, 0)) P = P.cut(p) # add second borer Bore2 = Group.newObject("Part::Feature", "Borer_2") Bore2.Shape = p Hole2 = Group.newObject("Part::Feature", "Borer_Hole2") Hole2.Shape = P App.ActiveDocument.recompute() # hide all objects except of the final one Gui.ActiveDocument.getObject(Wire.Name).hide() Gui.ActiveDocument.getObject(Face.Name).hide() Gui.ActiveDocument.getObject(Prism.Name).hide() Gui.ActiveDocument.getObject(Bore1.Name).hide() Gui.ActiveDocument.getObject(Hole1.Name).hide() Gui.ActiveDocument.getObject(Bore2.Name).hide() Gui.ActiveDocument.ActiveView.fitAll()