def addReceiver( self, shape: cq.Workplane, face: str, location: Tuple[float, float, float] = (0, 0, 0), ) -> cq.Workplane: """ Add a receiver to the face of the shape passed. """ show(shape, name="shape") f = shape.faces(face) dbg(f"f={f}") show(f, name="f") r = self.receiver show(r, name="r") # f.cut(self.receiver.rotate((0, 0, 0), (1, 0, 0), 180).translate((0, 0, bodyLen)) # cq.SelectbodyLen = 30 # body = cq.Workplane("XY").circle(bodyDiameter / :2).extrude(bodyLen) # body1 = body.cut( # c.receiver.rotate((0, 0, 0), (1, 0, 0), 180).translate((0, 0, bodyLen)) # ).cut(c.receiver) # show(body1, name="body1") return shape
halfWingBb: cq.BoundBox = cast(cq.Shape, halfWing.val()).BoundingBox() # If workplane is >= 0.9902054 FAILS # splitWing = halfWing.faces("<Y").workplane(-chord*0.9902054).split(keepTop=True, keepBottom=False) splitWingA = (halfWing.faces("<Y").workplane(-chord * 0.50).split( keepTop=True, keepBottom=False)) # show(splitWingA) splitWing = (splitWingA.faces(">Y").workplane(-chord * 0.15).split( keepTop=True, keepBottom=False)) # show(splitWing) # Only works for polyline # halfWingShell = splitWing.shell(-0.73) # Fails even for polyline I wonder is a max % # with a negative thickness you can shell halfWingShell = splitWing.shell(-0.73) # OK with polyline show(halfWingShell) # Split the wing to determine where it can shelled. As it turns # if a spline is used out the problem is in the leading edge # AND: # If workplane is >= 0.9902054 FAILS # splitWing = halfWing.faces(">Y").workplane(-chord*0.9902054).split(keepTop=True, keepBottom=False) # # if workplace is < -chord*0.9902053 SUCCEEDS! # splitWing = halfWing.faces(">Y").workplane(-chord*0.9902053).split(keepTop=True, keepBottom=False) # #splitWing = halfWing.faces(">Y").workplane(-chord*0.8).split(keepTop=True, keepBottom=False) # # log(f'splitWing.isValid()={splitWing.val().isValid()}') # #show(splitWing) # splitWingShell = splitWing.shell(-0.0270)
return ft if __name__ == "__main__" or "show_object" in globals(): from wing_utils import setCtx setCtx(globals()) import airfoil as af from naca5305 import naca5305 from scale import scaleListOfTuple airfoilSection: af.AirfoilSeq = naca5305 chord: float = 50 scaleFactor: float = 1 / airfoilSection[0][0] nAirfoil: List[Tuple[float, float]] = af.scaleListOfTuple(airfoilSection, scaleFactor) sAirfoil: List[Tuple[float, float]] = af.scaleListOfTuple(nAirfoil, chord) # fattenTe fTeAirfoil: List[Tuple[float, float]] = fattenTe( af=sAirfoil, t=0.26 * 2, chord=chord, percentChordToFatten=0.20, ) airfoil = cq.Workplane("YZ").polyline(fTeAirfoil).close() show(airfoil, name="airfoil")
cabinLength: float = chord * 1.001 cabinDiameter: float = 4.0 cabinYOffset: float = -1.0 cabinZOffset: float = 0 cabin = (cq.Workplane("XZ").circle( cabinDiameter / 2).extrude(cabinLength).rotate( (0, 0, 0), (1, 0, 0), -90).translate((0, cabinYOffset, cabinZOffset))) # show(cabin, name="cabin") wingCabin = wing.union(cabin) # show(wingCabin, name="wingCabin") c = RectCon(xLen=2.25, yLen=2.25, zLen=6) # show(c.male, name="c.male") wing4 = wingCabin.cut( c.receiver.rotate((0, 0, 0), (1, 0, 0), 180).translate( (0, cabinYOffset, cabinLength))).cut( c.receiver.translate((0, cabinYOffset, cabinZOffset))) show(wing4, name="wing4") import io tolerance = 0.001 f = io.open( f"wing4.02-LE-down-tol_{tolerance}-ch_{chord}-span_{span}-di_{dihedral}-tk_{tk}.stl", "w+", ) cq.exporters.exportShape(wing4, cq.exporters.ExportTypes.STL, f, tolerance) f.close()
receiver_yLen = args.receiver_yLen receiver_zLen = args.receiver_zLen dowelAngleDegrees = args.dowelAngle dowelClearence = args.dowelClearence linearTolerance = args.linearTolerance angularToleranceDegrees = args.angularTolerance dbg(f"x={receiver_xLen}, y={receiver_yLen}, z={receiver_zLen}, a={dowelAngleDegrees}" ) # Create dowel c = RectCon( xLen=receiver_xLen, yLen=receiver_yLen, zLen=receiver_zLen, dowelAngle=dowelAngleDegrees, ) dowel = c.dowelHorz() show(dowel) import io fname = f"dowel-x_{c.dowel_xLen:.4f}-y_{c.dowel_yLen:.4f}-z_{c.dowel_zLen:.4f}-a_{c.dowelAngle:.4f}-lt_{linearTolerance:.4f}-at_{angularToleranceDegrees:.4f}.stl" dbg(f"fname={fname}") cq.exporters.export( dowel, fname, tolerance=linearTolerance, angularTolerance=math.radians(angularToleranceDegrees), )
bodyEllipse2d = Ellipse(xLen=8, yLen=12) bodyLen = 20 body = ( cq.Workplane("XY") .ellipse(bodyEllipse2d.xAxis(), bodyEllipse2d.yAxis()) .extrude(bodyLen) ) body = body.union(c.male.translate(cq.Vector(0, 0, bodyLen))) body1 = body.cut(c.female) # show(body1, name="body1") body2 = copy(body1).translate((20, 0, 0)) # show(body2, name="body2") result = ( body1.add(body2) .combine() .rotate((0, 0, 0), (1, 0, 0), 90) .translate((0, 0, bodyEllipse2d.yLen / 2)) ) show(result, name="result") import io tolerance = 0.001 f = io.open(f"elipcon-tol_{tolerance}.stl", "w+") cq.exporters.exportShape(result, cq.exporters.ExportTypes.STL, f, tolerance) f.close()
return wing if __name__ == "__main__" or "show_object" in globals(): from wing_utils import setCtx setCtx(globals()) shortCut: bool = True chord = 50 span = 200 incidenceAngle = 2 dihedral = 5 sweep = 10 tk = 0.25 ribCount = 0 shortCut = False wing = Wing.makeWing( airfoilSeq=naca5305, chord=chord, span=span, incidenceAngle=incidenceAngle, dihedral=dihedral, sweep=sweep, shellThickness=tk, ribCount=ribCount, shortCut=shortCut, ) show(wing)
import cadquery as cq from wing_utils import show result = cq.Workplane("front").ellipse(2, 4).extrude(2).shell(-1.5) show(result)
from typing import List, Sequence, Tuple import cadquery as cq import airfoil as af from fattenTe import fattenTe from naca0005 import naca0005 from naca0020 import naca0020 from scale import scaleListOfTuple from wing_utils import X, dbg, setCtx, show, translate_2d, updatePending, valid setCtx(globals()) # The path that we'll sweep path = cq.Workplane("XZ").moveTo(0, 30).radiusArc(endPoint=(30, 0), radius=30) show(path, name="path") # Sketch 1 # # I get an Stanhdard_NullObject in the sweep command with naca0005. # So I copied naca0005 to "t" below and commented out most of the # points and it worked. I then slowly added them back and found that # the problem is "fixed" if you comment out "Point TE 1 and Point TE 2". # You can also fix the problem by making the circle in s2 >= 1.0 radius! t: af.AirfoilSeq = af.AirfoilSeq([ (1.000000, 0.000525), (0.998459, 0.000615), # Point TE 1 (0.993844, 0.000884), (0.986185, 0.001326), (0.975528, 0.001934), (0.961940, 0.002699),
# show(stabilizer) boomLength: float = chord boomDiameter: float = 4.0 boomXOffset: float = chord / 2 boomYOffset: float = 0 boomZOffset: float = +boomDiameter / 2 boom = (cq.Workplane("XZ").circle(boomDiameter / 2).workplane( offset=chord).circle(boomDiameter / 6).loft(combine=True).rotate( (0, 0, 0), (0, 0, 1), -90).translate( (boomXOffset, boomYOffset, boomZOffset))) # show(boom) tail = stabilizer.union(boom) c = RectCon(xLen=2.25, yLen=2.25, zLen=6) cut = c.receiver.rotate((0, 0, 0), (0, 1, 0), 270).translate( (chord / 2, 0, boomDiameter / 2)) # show(c.male) # show(cut) tail4 = tail.cut(cut) show(tail4) import io tolerance = 0.001 f = io.open(f"tail4-tol_{tolerance}-ch_{chord}-span_{span}-tk_{tk}.stl", "w+") cq.exporters.exportShape(tail4, cq.exporters.ExportTypes.STL, f, tolerance) f.close()
for stubX, stubY in hf: if stubY > (0.5 * stubThickness): break stubLength: float = max(stubMinLength, (length - stubX) + stubProtuding) # dbg(f"stubX={stubX}") # dbg(f"stubY={stubY}") # dbg(f"stubLength={stubLength}") # Create stub stub = (cq.Workplane("YZ", origin=(stubX, 0, 0)).circle(stubDiameter / 2).extrude(stubLength)) # show(stub, "stub") ballastWithStub = ballast.union(stub) # show(ballastWithStub, "ballastWithStub") receiver = rc.RectCon(xLen=c_xLen, yLen=c_yLen, zLen=c_zLen).receiver # show(receiver, "receiver") result = ballastWithStub.cut( receiver.rotate((0, 0, 0), (0, 1, 0), -90).translate( (stubX + stubLength, 0, 0))) show(result, "result") import io tolerance = 0.001 fname = f"ballast-length_{length + stubLength}-tol_{tolerance}.stl" cq.exporters.export(result, fname, tolerance=tolerance)