def test_project_curve_to_plane():
    # Projects a line of length 1 from above the XOY plane, and tests points
    # on the resulting line
    from OCC.Geom import Geom_Plane, Geom_TrimmedCurve
    from OCC.GC import GC_MakeSegment
    from OCC.gp import gp_Ax3, gp_XOY, gp_Pnt, gp_Dir
    XOY = Geom_Plane(gp_Ax3(gp_XOY()))
    curve = GC_MakeSegment(gp_Pnt(0, 0, 5),
                           gp_Pnt(1, 0, 5)).Value()
    direction = gp_Dir(0, 0, 1)

    Hproj_curve = act.project_curve_to_plane(curve, XOY.GetHandle(),
                                            direction)

    proj_curve = Hproj_curve.GetObject()

    # The start and end points of the curve
    p1 = proj_curve.Value(0)
    p2 = proj_curve.Value(1)

    p1_array = np.array([p1.X(), p1.Y(), p1.Z()])
    p2_array = np.array([p2.X(), p2.Y(), p2.Z()])

    # The expected start and end points
    start = np.array([0, 0, 0])
    end = np.array([1, 0, 0])

    # Assert that neither points have a Y or Z component, and that
    assert((np.all(p1_array == start) and np.all(p2_array == end)) or
           (np.all(p1_array == end) and np.all(p2_array == start)))
Пример #2
0
    def _fitAirfoiltoPoints(self, x, z):
        """ Fits an OCC curve to airfoil x, z points

        Parameters
        ----------
        x : array
            airfoil curve x points

        z : array
            airfoil curve z points
            
        Returns
        -------
        spline_2d : OCC.Geom.Geom_BSplineCurve
            the generated spline
        """
        N = len(x)
        y = [0. for i in xrange(N)]
        pnts = np.vstack([x, y, z]).T
        #       periodic=False
        #       tangents=
        Curve = act.points_to_bspline(pnts, True)
        # Saving the points for visualisation (need to remove this)
        self._points = [gp_Pnt(*pnt) for pnt in pnts]
        return Curve
def test_CalculateSurfaceArea():
    """Use a few simple shapes to test the surface area function.

    Notes
    -----
    This isnt testing the area building algorithm, just that my setup of the
    function works for a variety of different OCC objects - PChambers
    """
    # A flat square edge lengths 1
    from OCC.BRepBuilderAPI import BRepBuilderAPI_MakePolygon
    p1 = gp_Pnt(0, 0, 0)
    p2 = gp_Pnt(1, 0, 0)
    p3 = gp_Pnt(1, 1, 0)
    p4 = gp_Pnt(0, 1, 0)
    surf1 = act.make_face(
        BRepBuilderAPI_MakePolygon(p1, p2, p3, p4, True).Wire())
    # The tolerance for difference between output and expected area
    tol = 1e-12
    assert(np.abs(act.CalculateSurfaceArea(surf1) - 1) < tol)

    # A sphere with radius 1
    from OCC.BRepPrimAPI import BRepPrimAPI_MakeSphere
    r = 1
    # The tolerance need to be relaxed a bit for this case
    tol = 1e-04
    sphere = BRepPrimAPI_MakeSphere(r).Shape()
    assert(np.abs(act.CalculateSurfaceArea(sphere) - 4 * np.pi * (r**2)) < tol)
def test_project_curve_to_surface():
    """Returning object rather than handle from this function gave bugs
    between 0.16.3 and 0.16.5 - adding test to preempt future oddness"""
    # Edge to project:
    h = 5
    pnts = np.array([[0, h, 0], [1, h, 2], [2, h, 3], [4, h, 3], [5, h, 5]])
    spline = act.points_to_bspline(pnts)

    # Surface to project onto:
    from OCC.GC import GC_MakeCircle
    circle = GC_MakeCircle(gp_Pnt(0,0,0), gp_Dir(0, 1, 0), 10).Value()
    edge = act.make_edge(circle)
    face = act.make_face(act.make_wire(edge))

    Hprojected_curve = act.project_curve_to_surface(spline, face,
                                                  gp_Dir(0, -1, 0))

    # Check that the curve created is not null
    check_valid_object(Hprojected_curve)
def test_points_to_bspline_nparray():
    # This is just to check my function will succeed to create a bspline - 
    #  Hopefully PythonOCC tests will test the values of curves generated
    pnts = np.array([[0, 0, 0], [1, 0, 2], [2, 0, 3], [4, 0, 3], [5, 0, 5]])
    spline = act.points_to_bspline(pnts)

    # test the curve is not null
    assert(not spline.IsNull())

    # This will raise an error if the curve creation didn't work - don't need
    #  to add an assert statement here
    o = spline.GetObject()
def test_coslin():
    abscissa = act.coslin(0.5, 8, 8)[0]
    ans = np.array([0.0,
                    0.01253604390908819,
                    0.04951556604879043,
                    0.1090842587659851,
                    0.1882550990706332,
                    0.2830581304412209,
                    0.3887395330218428,
                    0.49999999999999994,
                    0.5625,
                    0.625,
                    0.6875,
                    0.75,
                    0.8125,
                    0.875,
                    0.9375,
                    1.0])
    assert(np.all(np.abs(abscissa - ans) < 1e-10))
Пример #7
0
    def _NACA4cambercurve(self, MaxCamberLocTenthChord, MaxCamberPercChord):
        """ Generates the camber curve of a NACA 4-digit airfoil

        Paramters
        ---------
        MaxCamberLocTenthChord : int
        
        MaxCamberPercChord : int
        
        Returns
        -------
        
        """
        # Using the original notation of Jacobs et al.(1933)
        xmc = MaxCamberLocTenthChord / 10.0
        zcammax = MaxCamberPercChord / 100.0

        # Protect against division by zero on airfoils like NACA0012
        if xmc == 0:
            xmc = 0.2

        # Sampling the chord line
        ChordCoord, NCosPoints = act.coslin(xmc)

        # Compute the two sections of the camber curve and its slope
        #        zcam = []
        #        dzcamdx = []
        cos_pts = ChordCoord[0:NCosPoints]
        lin_pts = ChordCoord[NCosPoints:]

        zcam = np.hstack(( (zcammax/(xmc ** 2)) * (2*xmc*cos_pts - cos_pts**2),
                           (zcammax/((1-xmc)**2)) * \
                             (1-2*xmc+2*xmc*lin_pts-(lin_pts ** 2)) ))

        dzcamdx = np.hstack(
            ((zcammax / xmc**2) * (2 * xmc - 2 * cos_pts),
             (zcammax / (1 - xmc)**2) * (2 * xmc - 2 * lin_pts)))

        return ChordCoord, zcam, dzcamdx
Пример #8
0
def Rendering(obj):

    display, start_display, add_menu, add_function_to_menu = init_display()

    # Printing the variables from the aircraft object...
    #    attrs = vars(aircraft)
    #    pprint.pprint(attrs,width=1)

    #-------------       WING    --------------------
    # Add NACA 4 digit airfoils to loft between:

    x0 = float(obj.geo['Kink_wing']['x'][0])
    y0 = float(obj.geo['Kink_wing']['y'][0])
    z0 = 0.0
    c0 = float(obj.geo['Kink_wing']['chords'][0])
    #    z0 = obj.geo['Kink_wing']['zu'][0]

    x1 = float(obj.geo['Kink_wing']['x'][1])
    y1 = float(obj.geo['Kink_wing']['y'][1])
    z1 = 0.0
    c1 = float(obj.geo['Kink_wing']['chords'][1])
    #
    x2 = float(obj.geo['Kink_wing']['x'][2])
    y2 = float(obj.geo['Kink_wing']['y'][2])
    z2 = 0.0
    c2 = float(obj.geo['Kink_wing']['chords'][2])
    #
    x3 = float(obj.geo['Kink_wing']['x'][3])
    y3 = float(obj.geo['Kink_wing']['y'][3])
    z3 = 0.0
    c3 = float(obj.geo['Kink_wing']['chords'][3])

    # Profiles...
    Af0 = airconics.primitives.Airfoil([x0, y0, z0],
                                       ChordLength=c0,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af0.Curve, update=True, color='GREEN')

    Af1 = airconics.primitives.Airfoil([x1, y1, z1],
                                       ChordLength=c1,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af1.Curve, update=True, color='GREEN')

    Af2 = airconics.primitives.Airfoil([x2, y2, z2],
                                       ChordLength=c2,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af2.Curve, update=True, color='GREEN')

    Af3 = airconics.primitives.Airfoil([x3, y3, z3],
                                       ChordLength=c3,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af3.Curve, update=True, color='GREEN')

    surf_wingin = act.AddSurfaceLoft([Af0, Af1, Af2])
    surf_wingout = act.AddSurfaceLoft([Af2, Af3])

    #-------------       HT    --------------------
    # Add NACA 4 digit airfoils to loft between:

    x0 = float(obj.geo['horz']['x'][0])
    y0 = float(obj.geo['horz']['y'][0])
    z0 = 0.0
    c0 = float(obj.geo['horz']['chords'][0])
    #    z0 = obj.geo['Kink_wing']['zu'][0]

    x1 = float(obj.geo['horz']['x'][1])
    y1 = float(obj.geo['horz']['y'][1])
    z1 = 0.0
    c1 = float(obj.geo['horz']['chords'][1])

    x2 = float(obj.geo['horz']['x'][2])
    y2 = float(obj.geo['horz']['y'][2])
    z2 = 0.0
    c2 = float(obj.geo['horz']['chords'][2])

    # Profiles...
    Af0 = airconics.primitives.Airfoil([x0, y0, z0],
                                       ChordLength=c0,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af0.Curve, update=True, color='GREEN')

    Af1 = airconics.primitives.Airfoil([x1, y1, z1],
                                       ChordLength=c1,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af1.Curve, update=True, color='GREEN')

    Af2 = airconics.primitives.Airfoil([x2, y2, z2],
                                       ChordLength=c2,
                                       Rotation=0,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af2.Curve, update=True, color='GREEN')

    surf_HT = act.AddSurfaceLoft([Af0, Af1, Af2])

    #-------------       VT    --------------------
    # Add NACA 4 digit airfoils to loft between:

    #  x0 = float(obj.geo['vert']['x'][0])
    #  y0 = 0.0
    #  z0 = float(obj.geo['vert']['z'][0])
    x0 = float(obj.geo['vert']['x'][0])
    y0 = 0.0
    z0 = 1.0
    c0 = float(obj.geo['vert']['chords'][0])
    #    z0 = obj.geo['Kink_wing']['zu'][0]

    #x1 = float(obj.geo['vert']['x'][1])
    #y1 = 0.0
    #  z1 = float(obj.geo['vert']['z'][0])
    x1 = float(obj.geo['vert']['x'][1])
    y0 = 0.0
    z1 = 5.5
    c1 = float(obj.geo['vert']['chords'][1])

    # Profiles...

    Af0 = airconics.primitives.Airfoil([x0, y0, z0],
                                       ChordLength=c0,
                                       Rotation=90,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af0.Curve, update=True, color='GREEN')

    Af1 = airconics.primitives.Airfoil([x1, y1, z1],
                                       ChordLength=c1,
                                       Rotation=90,
                                       Twist=0,
                                       Naca4Profile='0012')
    display.DisplayShape(Af1.Curve, update=True, color='GREEN')

    surf_VT = act.AddSurfaceLoft([Af0, Af1])

    #-------------       FUSELAGE    --------------------
    ##
    #    fus = fuselage_oml.Fuselage(NoseLengthRatio=0.182,
    #                                TailLengthRatio=0.293,
    #                                Scaling=[55.902, 55.902, 55.902],
    #                                NoseCoordinates=[0.0, 0.0, 0],
    #                                CylindricalMidSection=False,
    #                                SimplificationReqd=False,
    #                                Maxi_attempt=5,
    #                                construct_geometry=True)

    # Current Display of the WHTVT
    display.DisplayShape(surf_wingin, update=True)
    display.DisplayShape(surf_wingout, update=True)
    display.DisplayShape(surf_HT, update=True)
    display.DisplayShape(surf_VT, update=True)
    #display.DisplayShape(fus, update=True)
    # fus.Display()
    start_display()
Пример #9
0
def transonic_airliner(display=None,
                       Propulsion=1,
                       EngineDia=2.9,
                       FuselageScaling=[55.902, 55.902, 55.902],
                       NoseLengthRatio=0.182,
                       TailLengthRatio=0.293,
                       WingScaleFactor=44.56,
                       WingChordFactor=1.0,
                       Topology=1,
                       SpanStation1=0.35,
                       SpanStation2=0.675,
                       EngineCtrBelowLE=0.3558,
                       EngineCtrFwdOfLE=0.9837,
                       Scarf_deg=3):
    """
    Parameters
    ----------
    Propulsion - int
        1 - twin
        2 - quad
    EngineDia - float
        Diameter of engine intake highlight
    FuselageScaling - list, length 3
        Fx, Fy, Fz scaling factors of fuselage
    NoseLengthRatio - scalar
        Proportion of forward tapering section of the fuselage 
    TailLengthRatio - scalar
        Proportion of aft tapering section of the fuselage
    WingScaleFactor - scalar
        Scale Factor of the main wing
    WingChordFactor - scalar
        Chord factor of the main wing
    Topology - int
        Topology = 2 should yield a box wing airliner - use with caution
    SpanStation - float
        Inboard engine at this span station
    SpanStation2 - float
        Outboard engine at this span station (ignored if Propulsion=1)
    EngineCtrBelowLE - float
        Engine below leading edge, normalised by the length of the nacelle -
        range: [0.35,0.5]
    EngineCtrFwdOfLE - float
        Engine forward of leading edge, normalised by the length of the nacelle
        range: [0.85,1.5]
    Scarf_deg - scalar # Engine scarf angle
    
    Returns
    -------
    airliner - 'Aircraft' class instance
        The collection of aircraft parts
    
    See also
    --------
    class Aircraft
    """

    try:
        Fus = fuselage_oml.Fuselage(NoseLengthRatio,
                                    TailLengthRatio,
                                    Scaling=FuselageScaling,
                                    NoseCoordinates=[0, 0, 0])
    except:
        print "Fuselage fitting failed - stopping."
        return None

    FuselageHeight = FuselageScaling[2] * 0.105
    FuselageLength = FuselageScaling[0]
    FuselageWidth = FuselageScaling[1] * 0.106

    if Fus['OML'] is None:
        print "Failed to fit fuselage surface, stopping."
        return None

#    FSurf = rs.CopyObject(FuselageOMLSurf)

# Position of the apex of the wing
    if FuselageHeight < 8.0:
        #787:[9.77,0,-0.307]
        WingApex = [0.1748 * FuselageLength, 0, -0.0523 * FuselageHeight]
    else:
        WingApex = [0.1748 * FuselageLength, 0,
                    -0.1 * FuselageHeight]  #787:[9.77,0,-0.307]

    # Set up the wing object, including the list of user-defined functions that
    # describe the spanwise variations of sweep, dihedral, etc.
    if Topology == 1:
        NSeg = 10
        Wing = liftingsurface.LiftingSurface(WingApex,
                                             mySweepAngleFunctionAirliner,
                                             myDihedralFunctionAirliner,
                                             myTwistFunctionAirliner,
                                             myChordFunctionAirliner,
                                             myAirfoilFunctionAirliner,
                                             SegmentNo=NSeg,
                                             ScaleFactor=WingScaleFactor,
                                             ChordFactor=WingChordFactor)
        RootChord = Wing.RootChord
    elif Topology == 2:
        NSeg = 101
        Wing = liftingsurface.LiftingSurface(WingApex,
                                             mySweepAngleFunctionAirliner,
                                             bw.myDihedralFunctionBoxWing,
                                             myTwistFunctionAirliner,
                                             myChordFunctionAirliner,
                                             myAirfoilFunctionAirliner,
                                             SegmentNo=NSeg,
                                             ScaleFactor=WingScaleFactor,
                                             ChordFactor=WingChordFactor)
        RootChord = Wing.RootChord

    if Topology == 1:

        # Add wing to body fairing
        WTBFXCentre = WingApex[
            0] + RootChord / 2.0 + RootChord * 0.1297  # 787: 23.8
        if FuselageHeight < 8.0:
            #Note: I made changes to this in OCC Airconics to get a better fit
            # - Paul
            WTBFZ = RootChord * 0.009  #787: 0.2
            WTBFheight = 1.8 * 0.1212 * RootChord  #787:2.7
            WTBFwidth = 1.08 * FuselageWidth
        else:

            WTBFZ = WingApex[2] + 0.005 * RootChord
            WTBFheight = 0.09 * RootChord
            WTBFwidth = 1.15 * FuselageWidth

        WTBFlength = 1.167 * RootChord  #787:26
        WBF_shape = act.make_ellipsoid([WTBFXCentre, 0, WTBFZ], WTBFlength,
                                       WTBFwidth, WTBFheight)
        WBF = AirconicsShape(components={'WBF': WBF_shape})

        #        Trim wing inboard section
        CutCirc = act.make_circle3pt([0, WTBFwidth / 4., -45],
                                     [0, WTBFwidth / 4., 45],
                                     [90, WTBFwidth / 4., 0])
        CutCircDisk = act.PlanarSurf(CutCirc)
        Wing['Surface'] = act.TrimShapebyPlane(Wing['Surface'], CutCircDisk)
    elif Topology == 2:
        #        Overlapping wing tips
        CutCirc = act.make_circle3pt((0, 0, -45), (0, 0, 45), (90, 0, 0))
        CutCircDisk = act.PlanarSurf(CutCirc)
        Wing['Surface'] = act.TrimShapebyPlane(Wing['Surface'], CutCircDisk)

#   Engine installation (nacelle and pylon)
    NacelleLength = 1.95 * EngineDia
    if Propulsion == 1:
        SpanStations = [SpanStation1]
    elif Propulsion == 2:
        SpanStations = [SpanStation1, SpanStation2]

    engines = []
    for i, SpanStation in enumerate(SpanStations):
        EngineSection, Chord = act.CutSect(Wing['Surface'], SpanStation)
        CEP = Chord.EndPoint()
        Centreloc = [
            CEP.X() - EngineCtrFwdOfLE * NacelleLength,
            CEP.Y(),
            CEP.Z() - EngineCtrBelowLE * NacelleLength
        ]
        eng = engine.Engine(Chord,
                            CentreLocation=Centreloc,
                            ScarfAngle=Scarf_deg,
                            HighlightRadius=EngineDia / 2.0,
                            MeanNacelleLength=NacelleLength)

        engines.append(eng)

#    # Script for generating and positioning the fin
#    # Position of the apex of the fin
    P = [0.6524 * FuselageLength, 0.003, FuselageHeight * 0.384]
    #P = [36.47,0.003,2.254]55.902

    if Topology == 1:
        ScaleFactor = WingScaleFactor / 2.032  #787:21.93
    elif Topology == 2:
        ScaleFactor = WingScaleFactor / 3.5

    SegmentNo = 100
    ChordFactor = 1.01  #787:1.01
    Fin = liftingsurface.LiftingSurface(P,
                                        mySweepAngleFunctionFin,
                                        myDihedralFunctionFin,
                                        myTwistFunctionFin,
                                        myChordFunctionFin,
                                        myAirfoilFunctionFin,
                                        SegmentNo=SegmentNo,
                                        ChordFactor=ChordFactor,
                                        ScaleFactor=ScaleFactor)

    #    Create the rotation axis centered at the apex point in the x direction
    RotAxis = gp_Ax1(gp_Pnt(*P), gp_Dir(1, 0, 0))

    Fin.RotateComponents(RotAxis, 90)

    if Topology == 1:
        #        Tailplane
        P = [0.7692 * FuselageLength, 0.000, FuselageHeight * 0.29]
        SegmentNo = 100
        ChordFactor = 1.01
        ScaleFactor = 0.388 * WingScaleFactor  #787:17.3
        TP = liftingsurface.LiftingSurface(P,
                                           mySweepAngleFunctionTP,
                                           myDihedralFunctionTP,
                                           myTwistFunctionTP,
                                           myChordFunctionTP,
                                           myAirfoilFunctionTP,
                                           SegmentNo=SegmentNo,
                                           ChordFactor=ChordFactor,
                                           ScaleFactor=ScaleFactor)

# OCC_AirCONICS Note: Nothing below here implemented in OCC_AirCONICS - See
# Rhino version for this functionality (largely for display only)
#
#    rs.DeleteObjects([EngineSection, Chord])
#    try:
#        rs.DeleteObjects([CutCirc])
#    except:
#        pass
#
#    try:
#        rs.DeleteObjects([CutCircDisk])
#    except:
#        pass
#
#    # Windows
#
#    # Cockpit windows:
    CockpitWindowTop = 0.305 * FuselageHeight

    print("Making Fuselage Windows...")

    #    solids = Fus.CockpitWindowContours(Height=CockpitWindowTop, Depth=6)
    #
    ##     Cut the windows out:
    #    for solid in solids:
    #        Fus['OML'] = act.SplitShape(Fus['OML'], solid)
    #
    #
    #    print("Cockpit Windows Done.")

    ##
    ##    (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) = act.ObjectsExtents([Win1, Win2, Win3, Win4])
    CockpitBulkheadX = NoseLengthRatio * FuselageLength * 0.9
    ##
    ##    CockpitWallPlane = rs.PlaneFromPoints([CockpitBulkheadX, -15,-15],
    ##    [CockpitBulkheadX,15,-15],
    ##    [CockpitBulkheadX,-15,15])
    ##
    ##    CockpitWall = rs.AddPlaneSurface(CockpitWallPlane, 30, 30)
    ##
    ##    if 'WTBF' in locals():
    ##        rs.TrimBrep(WTBF, CockpitWall)
    ##
    ##    rs.DeleteObject(CockpitWall)
    #
    ##    # Window lines
    WIN = [1]
    NOWIN = [0]
    ##
    ###    # A typical window pattern (including emergency exit windows)
    WinVec = WIN + 2 * NOWIN + 9 * WIN + 3 * NOWIN + WIN + NOWIN + 24 * WIN + 2 * NOWIN + WIN + NOWIN + 14 * WIN + 2 * NOWIN + WIN + 20 * WIN + 2 * NOWIN + WIN + NOWIN + 20 * WIN
    wires = []
    if FuselageHeight < 8.0:
        ###        # Single deck
        WindowLineHeight = 0.3555 * FuselageHeight
        WinX = 0.1157 * FuselageLength
        WindowPitch = 0.609
        WinInd = -1
        i = 0
        while WinX < 0.75 * FuselageLength:
            WinInd = WinInd + 1
            if WinVec[WinInd] == 1 and WinX > CockpitBulkheadX:
                i = i + 1
                print("Generating cabin window {}".format(i))
                WinCenter = [WinX, WindowLineHeight]
                W_wire = Fus.WindowContour(WinCenter)
                wires.append(W_wire)
#                display.DisplayShape(W_wire, color='black')
#                win_port, win_stbd = Fus.MakeWindow(*WinCenter)
#                print(type(win_port), type(win_stbd))
#
#                display.DisplayShape(win_port, color='Black')
#                display.DisplayShape(win_stbd, color='Black')
#
###                Note: Need to fix makewindow to return windows WinStbd,
##                # WinPort,
#                Fus.MakeWindow(WinX, WindowLineHeight)
###                act.AssignMaterial(WinStbd,"Plexiglass")
###                act.AssignMaterial(WinPort,"Plexiglass")
            WinX = WinX + WindowPitch
#
#    print("Cabin windows done")

#    else:
#        # TODO: Fuselage big enough to accommodate two decks
#        # Lower deck
#        WindowLineHeight = 0.17*FuselageHeight #0.166
#        WinX = 0.1*FuselageLength #0.112
#        WindowPitch = 0.609
#        WinInd = 0
#        while WinX < 0.757*FuselageLength:
#            WinInd = WinInd + 1
#            if WinVec[WinInd] == 1 and WinX > CockpitBulkheadX:
#                WinStbd, WinPort, FuselageOMLSurf = fuselage_oml.MakeWindow(FuselageOMLSurf, WinX, WindowLineHeight)
#                act.AssignMaterial(WinStbd,"Plexiglass")
#                act.AssignMaterial(WinPort,"Plexiglass")
#            WinX = WinX + WindowPitch
#        # Upper deck
#        WindowLineHeight = 0.49*FuselageHeight
#        WinX = 0.174*FuselageLength #0.184
#        WinInd = 0
#        while WinX < 0.757*FuselageLength:
#            WinInd = WinInd + 1
#            if WinVec[WinInd] == 1 and WinX > CockpitBulkheadX:
#                WinStbd, WinPort, FuselageOMLSurf = fuselage_oml.MakeWindow(FuselageOMLSurf, WinX, WindowLineHeight)
#                act.AssignMaterial(WinStbd,"Plexiglass")
#                act.AssignMaterial(WinPort,"Plexiglass")
#            WinX = WinX + WindowPitch
#
#
#
#
#
#    act.AssignMaterial(FuselageOMLSurf,"White_composite_external")
#    act.AssignMaterial(WingSurf,"White_composite_external")
#    try:
#        act.AssignMaterial(TPSurf,"ShinyBARedMetal")
#    except:
#        pass
#    act.AssignMaterial(FinSurf,"ShinyBARedMetal")
#    act.AssignMaterial(Win1,"Plexiglass")
#    act.AssignMaterial(Win2,"Plexiglass")
#    act.AssignMaterial(Win3,"Plexiglass")
#    act.AssignMaterial(Win4,"Plexiglass")
#
#
#    # Mirror the geometry as required
    Wing2 = Wing.MirrorComponents(plane='xz')
    try:
        # this try section allows box wing i.e. no tailplane
        TP2 = TP.MirrorComponents(plane='xz')
    except:
        pass

    engines_left = []
    for eng in engines:
        engines_left.append(eng.MirrorComponents(plane='xz'))


#    if Propulsion == 1:
#        for ObjId in EngineStbd:
#            act.MirrorObjectXZ(ObjId)
#        act.MirrorObjectXZ(PylonStbd)
#    elif Propulsion == 2:
#        raise NotImplementedError
#        for ObjId in EngineStbd1:
#            act.MirrorObjectXZ(ObjId)
#        act.MirrorObjectXZ(PylonStbd1)
#        for ObjId in EngineStbd2:
#            act.MirrorObjectXZ(ObjId)
#        act.MirrorObjectXZ(PylonStbd2)

#    Build the return assembly (could change this later based on input 'tree':
    airliner = AirconicsCollection(
        parts={
            'Wing_right': Wing,
            'Wing_left': Wing2,
            'Fuselage': Fus,
            'Fin': Fin,
            'Tailplane_right': TP,
            'Tailplane_left': TP2,
            'WBF': WBF
        })

    # Loop over the engines and write all components:
    for i, eng in enumerate(engines):
        name = 'engine_right' + str(i + 1)
        airliner.AddPart(eng, name)
    for i, eng in enumerate(engines_left):
        name = 'engine_left' + str(i + 1)
        airliner.AddPart(eng, name)

    return airliner, wires
Пример #10
0
    ScaleFactor = 44.56
    Wing = LiftingSurface(P, wingex.mySweepAngleFunctionAirliner,
                          wingex.myDihedralFunctionAirliner,
                          wingex.myTwistFunctionAirliner,
                          wingex.myChordFunctionAirliner,
                          wingex.myAirfoilFunctionAirliner,
                          SegmentNo=SegmentNo,
                          ChordFactor=ChordFactor,
                          ScaleFactor=ScaleFactor)

    Wing.Display(display)
    SpanStation = 0.3              # The engine is to be placed at 30% span
    EngineDia = 2.9
    NacelleLength = 1.95*EngineDia

    EngineSection, HChord = act.CutSect(Wing['Surface'], SpanStation)
    Chord = HChord.GetObject()
    CEP = Chord.EndPoint()
    display.DisplayShape(Chord, update=True, color='black')
    # Variables controlling the position of the engine with respect to the wing
    EngineCtrFwdOfLE = 0.98
    EngineCtrBelowLE = 0.35
    Scarf_deg = 4
    Centreloc = [CEP.X()-EngineCtrFwdOfLE*NacelleLength,
                 CEP.Y(),
                 CEP.Z()-EngineCtrBelowLE*NacelleLength]

#   Now build the engine and its pylon
    eng1 = Engine(HChord,
                  CentreLocation=Centreloc,
                  ScarfAngle=Scarf_deg,
Пример #11
0
    def _BuildPanels(self, ChordFactor, ScaleFactor):

        LESpar, TESpar, MIDSpar, StringerUp, StringerDown, PointsUp, PointsDown = self._BuildSpars(
            self.ChordFactor, self.ScaleFactor)
        PanelUp = []
        PanelDown = []

        cont = 1
        for ii in range(0, len(PointsUp) - self.NoStiffners - 1):
            if cont == self.NoStiffners:
                cont = 0
            else:
                cont = cont

                # Panel from segments
                SegH1 = GC_MakeSegment(
                    PointsUp[ii], PointsUp[ii + self.NoStiffners]).Value()
                SegH2 = GC_MakeSegment(PointsUp[ii + 1],
                                       PointsUp[ii + self.NoStiffners +
                                                1]).Value()
                SegV1 = GC_MakeSegment(PointsUp[ii], PointsUp[ii + 1]).Value()
                SegV2 = GC_MakeSegment(PointsUp[ii + self.NoStiffners],
                                       PointsUp[ii + self.NoStiffners +
                                                1]).Value()
                EdgeHUp1 = act.make_edge(SegH1)
                EdgeHUp2 = act.make_edge(SegH2)
                EdgeVUp1 = act.make_edge(SegV1)
                EdgeVUp2 = act.make_edge(SegV2)
                WirePanelUp = act.make_wire(
                    [EdgeHUp1, EdgeVUp1, EdgeHUp2, EdgeVUp2])
                PanelUpi = act.make_face(WirePanelUp)
                # In this way the pannel will be ordered in alternance between upper and lower surface
                SegH1 = GC_MakeSegment(
                    PointsDown[ii], PointsDown[ii + self.NoStiffners]).Value()
                SegH2 = GC_MakeSegment(PointsDown[ii + 1],
                                       PointsDown[ii + self.NoStiffners +
                                                  1]).Value()
                SegV1 = GC_MakeSegment(PointsDown[ii],
                                       PointsDown[ii + 1]).Value()
                SegV2 = GC_MakeSegment(PointsDown[ii + self.NoStiffners],
                                       PointsDown[ii + self.NoStiffners +
                                                  1]).Value()
                EdgeHUp1 = act.make_edge(SegH1)
                EdgeHUp2 = act.make_edge(SegH2)
                EdgeVUp1 = act.make_edge(SegV1)
                EdgeVUp2 = act.make_edge(SegV2)
                WirePanelDown = act.make_wire(
                    [EdgeHUp1, EdgeVUp1, EdgeHUp2, EdgeVUp2])
                PanelDowni = act.make_face(WirePanelDown)

                if self.ScaleFactor != 1:
                    Origin = gp_Pnt(0., 0., 0.)
                    PanelUpi = act.scale_uniformal(PanelUpi, Origin,
                                                   self.ScaleFactor)
                    PanelDowni = act.scale_uniformal(PanelDowni, Origin,
                                                     self.ScaleFactor)

                PanelUp.append(PanelUpi)
                PanelDown.append(PanelDowni)
            cont = cont + 1

        return PanelUp, PanelDown
Пример #12
0
    def _BuildRibs(self, ChordFactor, ScaleFactor):
        """Generates Ribs surface along the wingspan, given the general,
        nondimensional parameters of the object (variations of chord length,
        dihedral, etc.) and the two scaling factors.

        Parameters
        ----------
        ChordFactor - float
            Factor againt which the standard shape is scaled in the chordwise
            direction
        ScaleFactor - float
            Factor againt which the standard shape is scaled in the world
            coordinates

        Returns
        -------
        Ribs : TopoDS_Shape
            The generated Ribs surface
        """
        SectionsRibs = []
        RibsFace = []

        Step = (self.SegmentNoLoft) / (self.NoRibs - 1)
        LEPointsR = self._GenerateLeadingEdge()
        Eps = np.linspace(0, 1, self.SegmentNoLoft + 1)
        SectionsRibs = [
            self.AirfoilFunct(Eps[i], LEPointsR[i], self.ChordFunct,
                              ChordFactor, self.DihedralFunct,
                              self.TwistFunct).Curve
            for i in xrange(0, self.SegmentNoLoft + 1, Step)
        ]

        LESpar, TESpar, MIDSpar, StringerUp, StringerDown, PointsUp, PointsDown = self._BuildSpars(
            self.ChordFactor, self.ScaleFactor)

        # RIBS generated from segments
        for i in range(0, self.NoRibs):
            for ii in range(0, self.NoStiffners - 1):
                SegUp = GC_MakeSegment(
                    PointsUp[ii + i * self.NoStiffners * (Step)],
                    PointsUp[ii + i * self.NoStiffners * (Step) + 1]).Value()
                SegDown = GC_MakeSegment(
                    PointsDown[ii + i * self.NoStiffners * (Step) + 1],
                    PointsDown[ii + i * self.NoStiffners * (Step)]).Value()
                SegSide1 = GC_MakeSegment(
                    PointsDown[ii + i * self.NoStiffners * (Step)],
                    PointsUp[ii + i * self.NoStiffners * (Step)]).Value()
                SegSide2 = GC_MakeSegment(
                    PointsUp[ii + i * self.NoStiffners * (Step) + 1],
                    PointsDown[ii + i * self.NoStiffners * (Step) +
                               1]).Value()
                EdgeSegUp = act.make_edge(SegUp)
                EdgeSegDown = act.make_edge(SegDown)
                EdgeSide1 = act.make_edge(SegSide1)
                EdgeSide2 = act.make_edge(SegSide2)
                WireRib = act.make_wire(
                    [EdgeSide1, EdgeSegUp, EdgeSide2, EdgeSegDown])
                FaceRibi = act.make_face(WireRib)
                if self.ScaleFactor != 1:
                    Origin = gp_Pnt(0., 0., 0.)
                    FaceRib = act.scale_uniformal(FaceRibi, Origin,
                                                  self.ScaleFactor)
                    RibsFace.append(FaceRib)

        return SectionsRibs, RibsFace
Пример #13
0
    def _BuildSpars(self, ChordFactor, ScaleFactor):

        LE = self._GenerateLeadingEdge()

        self.NoStiffners = self.NoStiffnersLE + self.NoStiffnersTE

        SectionsProfiles = []
        SparLEFullWing = []
        SparTEFullWing = []
        SparMIDFullWing = []

        SparLEup = []
        SparLEdown = []
        SparMIDup = []
        SparMIDdown = []
        SparTEup = []
        SparTEdown = []

        planeStiffEps = []

        PStiffUpFullWing = []
        PStiffDownFullWing = []
        StringerUpFullWing = []
        StringerDownFullWing = []

        EpsS = np.linspace(0, 1, self.SegmentNoLoft + 1)
        SectionsProfiles = [
            self.AirfoilFunct(EpsS[d], LE[d], self.ChordFunct, ChordFactor,
                              self.DihedralFunct, self.TwistFunct).Curve
            for d in xrange(self.SegmentNoLoft + 1)
        ]

        # Stringers generation
        h = 0
        cont3 = 0
        PointsUp = []
        PointsDown = []
        PointsMIDup = []
        PointsMIDdown = []

        for SecR in SectionsProfiles:
            ChordLenght = ((ChordFactor * self.ChordFunct(EpsS[h])) /
                           np.cos(np.radians(self.TwistFunct(EpsS[h]))))
            LELengthX = LE[h, 0]
            LEplanePositionX = (self.PositionLESpar * ChordLenght) * np.cos(
                self.TwistFunct(EpsS[h])) + LELengthX
            TEplanePositionX = (self.PositionTESpar * ChordLenght) * np.cos(
                self.TwistFunct(EpsS[h])) + LELengthX
            MIDplanePositionX = (self.PositionMIDSpar * ChordLenght) * np.cos(
                self.TwistFunct(EpsS[h])) + LELengthX

            planeLEi = Geom_Plane(
                gp_Pln(gp_Pnt(LEplanePositionX, 0., 0.),
                       gp_Dir(gp_Vec(gp_Pnt(0., 0., 0.), gp_Pnt(1., 0., 0.)))))
            planeMIDi = Geom_Plane(
                gp_Pln(gp_Pnt(MIDplanePositionX, 0., 0.),
                       gp_Dir(gp_Vec(gp_Pnt(0., 0., 0.), gp_Pnt(1., 0., 0.)))))
            planeTEi = Geom_Plane(
                gp_Pln(gp_Pnt(TEplanePositionX, 0., 0.),
                       gp_Dir(gp_Vec(gp_Pnt(0., 0., 0.), gp_Pnt(1., 0., 0.)))))

            #            planeLEi.Rotate(gp_OY(), -np.radians(self.TwistFunct(EpsS[h])))
            #            planeMIDi.Rotate(gp_OY(), -np.radians(self.TwistFunct(EpsS[h])))
            #            planeTEi.Rotate(gp_OY(), -np.radians(self.TwistFunct(EpsS[h])))

            SegmentStiffLE = (MIDplanePositionX -
                              LEplanePositionX) / (self.NoStiffnersLE - 1)
            SegmentStiffTE = (TEplanePositionX -
                              MIDplanePositionX) / (self.NoStiffnersTE)
            NoStiffners = self.NoStiffnersLE + self.NoStiffnersTE

            PStiffUpi = []
            PStiffDowni = []
            PosStiffiEps = LEplanePositionX

            for g in xrange(NoStiffners):

                planeStiffEps = Geom_Plane(
                    gp_Pln(
                        gp_Pnt(PosStiffiEps, 0., 0.),
                        gp_Dir(gp_Vec(gp_Pnt(0., 0., 0.), gp_Pnt(1., 0.,
                                                                 0.)))))

                StiffiEps = GeomAPI_IntCS(SecR, planeStiffEps.GetHandle())
                with act.assert_isdone(StiffiEps,
                                       'failed to calculate intersection'):
                    nb_results = StiffiEps.NbPoints()
                    if nb_results == 1:
                        return StiffiEps.Point(1)
                    #print("One point intersection")
                    elif nb_results >= 1:
                        #print("More than one intersection point")
                        PStiff = []
                        for i in range(1, nb_results + 1):
                            PStiff.append(StiffiEps.Point(i))

                    else:
                        return None
                PStiffUpi.append(PStiff[0])
                PStiffDowni.append(PStiff[nb_results - 1])
                if g <= self.NoStiffnersLE - 2:
                    PosStiffiEps = PosStiffiEps + SegmentStiffLE
                else:
                    PosStiffiEps = PosStiffiEps + SegmentStiffTE

                PointsUp.append(PStiff[0])
                PointsDown.append(PStiff[nb_results - 1])

            SparLEi = GeomAPI_IntCS(SecR, planeLEi.GetHandle())
            with act.assert_isdone(SparLEi,
                                   'failed to calculate intersection'):
                nb_results = SparLEi.NbPoints()
                #print(nb_results)
                if nb_results == 1:
                    return SparLEi.Point(1)
                #print("One point intersection")
                elif nb_results >= 1:
                    #print("More than one intersection point")
                    PLE = []
                    for i in range(1, nb_results + 1):
                        PLE.append(SparLEi.Point(i))

                else:
                    return None

            SegLE = GC_MakeSegment(PLE[0], PLE[nb_results - 1]).Value()

            SparMIDi = GeomAPI_IntCS(SecR, planeMIDi.GetHandle())
            with act.assert_isdone(SparMIDi,
                                   'failed to calculate intersection'):
                nb_results = SparMIDi.NbPoints()
                #print(nb_results)
                if nb_results == 1:
                    return SparMIDi.Point(1)
                #print("One point intersection")
                elif nb_results >= 1:
                    #print("More than one intersection point")
                    PMID = []
                    for i in range(1, nb_results + 1):
                        PMID.append(SparMIDi.Point(i))

                else:
                    return None

            SegMID = GC_MakeSegment(PMID[0], PMID[nb_results - 1]).Value()
            PointsMIDup.append(PMID[0])
            PointsMIDdown.append(PMID[nb_results - 1])

            SparTEi = GeomAPI_IntCS(SecR, planeTEi.GetHandle())
            with act.assert_isdone(SparTEi,
                                   'failed to calculate intersection'):
                nb_results = SparTEi.NbPoints()
                #print(nb_results)
                if nb_results == 1:
                    return SparTEi.Point(1)
                #print("One point intersection")
                elif nb_results >= 1:
                    #print("More than one intersection point")
                    PTE = []
                    for i in range(1, nb_results + 1):
                        PTE.append(SparTEi.Point(i))

                else:
                    return None

            SegTE = GC_MakeSegment(PTE[0], PTE[nb_results - 1]).Value()

            #print(len(SparMIDdown))
            #print(len(SparMIDup))
            #print(len(SparLEup))
            #print(len(SparLEdown))
            SparLEFullWing.append(SegLE)
            SparMIDFullWing.append(SegMID)
            SparTEFullWing.append(SegTE)
            SparLEup.append(PLE[0])
            SparLEdown.append(PLE[nb_results - 1])
            SparMIDup.append(PMID[0])
            #print(PMID[nb_results-1])
            SparMIDdown.append(PMID[nb_results - 1])
            SparTEup.append(PTE[0])
            SparTEdown.append(PTE[nb_results - 1])
            PStiffUpFullWing.append(PStiffUpi)
            PStiffDownFullWing.append(PStiffDowni)
            cont3 = cont3 + 1

            h = h + 1

# Method to create spars - VIA SEGMENTS
#LE
        LoftLESparFullWing = []
        for iii in xrange(0,
                          len(PointsUp) - 2 * (self.NoStiffners - 1),
                          self.NoStiffners):
            SegUp = GC_MakeSegment(PointsUp[iii],
                                   PointsUp[iii + self.NoStiffners]).Value()
            SegDown = GC_MakeSegment(PointsDown[iii + self.NoStiffners],
                                     PointsDown[iii]).Value()
            SegSide1 = GC_MakeSegment(PointsDown[iii], PointsUp[iii]).Value()
            SegSide2 = GC_MakeSegment(PointsUp[iii + self.NoStiffners],
                                      PointsDown[iii +
                                                 self.NoStiffners]).Value()
            EdgeSegUp = act.make_edge(SegUp)
            EdgeSegDown = act.make_edge(SegDown)
            EdgeSide1 = act.make_edge(SegSide1)
            EdgeSide2 = act.make_edge(SegSide2)
            WireSparLE = act.make_wire(
                [EdgeSide1, EdgeSegUp, EdgeSide2, EdgeSegDown])
            FaceSparLEi = act.make_face(WireSparLE)

            if self.ScaleFactor != 1:
                Origin = gp_Pnt(0., 0., 0.)
                FaceSparLE = act.scale_uniformal(FaceSparLEi, Origin,
                                                 self.ScaleFactor)
                LoftLESparFullWing.append(FaceSparLE)
#MID
        LoftMIDSparFullWing = []
        for iii in xrange(0, self.SegmentNoLoft):
            SegUp = GC_MakeSegment(PointsMIDup[iii],
                                   PointsMIDup[iii + 1]).Value()
            SegDown = GC_MakeSegment(PointsMIDdown[iii + 1],
                                     PointsMIDdown[iii]).Value()
            SegSide1 = GC_MakeSegment(PointsMIDdown[iii],
                                      PointsMIDup[iii]).Value()
            SegSide2 = GC_MakeSegment(PointsMIDup[iii + 1],
                                      PointsMIDdown[iii + 1]).Value()
            EdgeSegUp = act.make_edge(SegUp)
            EdgeSegDown = act.make_edge(SegDown)
            EdgeSide1 = act.make_edge(SegSide1)
            EdgeSide2 = act.make_edge(SegSide2)
            WireSparMID = act.make_wire(
                [EdgeSide1, EdgeSegUp, EdgeSide2, EdgeSegDown])
            FaceSparMIDi = act.make_face(WireSparMID)

            if self.ScaleFactor != 1:
                Origin = gp_Pnt(0., 0., 0.)
                FaceSparMID = act.scale_uniformal(FaceSparMIDi, Origin,
                                                  self.ScaleFactor)
                LoftMIDSparFullWing.append(FaceSparMID)

#TE
        LoftTESparFullWing = []
        for iii in xrange(self.NoStiffners - 1,
                          len(PointsUp) - (self.NoStiffners),
                          self.NoStiffners):
            SegUp = GC_MakeSegment(PointsUp[iii],
                                   PointsUp[iii + self.NoStiffners]).Value()
            SegDown = GC_MakeSegment(PointsDown[iii + self.NoStiffners],
                                     PointsDown[iii]).Value()
            SegSide1 = GC_MakeSegment(PointsDown[iii], PointsUp[iii]).Value()
            SegSide2 = GC_MakeSegment(PointsUp[iii + self.NoStiffners],
                                      PointsDown[iii +
                                                 self.NoStiffners]).Value()
            EdgeSegUp = act.make_edge(SegUp)
            EdgeSegDown = act.make_edge(SegDown)
            EdgeSide1 = act.make_edge(SegSide1)
            EdgeSide2 = act.make_edge(SegSide2)
            WireSparTE = act.make_wire(
                [EdgeSide1, EdgeSegUp, EdgeSide2, EdgeSegDown])
            FaceSparTEi = act.make_face(WireSparTE)

            if self.ScaleFactor != 1:
                Origin = gp_Pnt(0., 0., 0.)
                FaceSparTE = act.scale_uniformal(FaceSparTEi, Origin,
                                                 self.ScaleFactor)
                LoftTESparFullWing.append(FaceSparTE)

        for g in range(self.NoStiffners):
            for gg in range(self.SegmentNoLoft):
                SegStringerUp = GC_MakeSegment(
                    PointsUp[gg * self.NoStiffners + g],
                    PointsUp[gg * self.NoStiffners + g +
                             self.NoStiffners]).Value()
                SegStringerDown = GC_MakeSegment(
                    PointsDown[gg * self.NoStiffners + g],
                    PointsDown[gg * self.NoStiffners + g +
                               self.NoStiffners]).Value()
                EdgeUp = act.make_edge(SegStringerUp)
                EdgeDown = act.make_edge(SegStringerDown)
                WireStringUp = act.make_wire(EdgeUp)
                WireStringDown = act.make_wire(EdgeDown)
                if self.ScaleFactor != 1:
                    Origin = gp_Pnt(0., 0., 0.)
                    StrUpFullWingi = act.scale_uniformal(
                        WireStringUp, Origin, self.ScaleFactor)
                    StrDownFullWingi = act.scale_uniformal(
                        WireStringDown, Origin, self.ScaleFactor)
                #print('hello')
            #print(self.ScaleFactor)
                StringerUpFullWing.append(StrUpFullWingi)
                StringerDownFullWing.append(StrDownFullWingi)

        return LoftLESparFullWing, LoftTESparFullWing, LoftMIDSparFullWing, StringerUpFullWing, StringerDownFullWing, PointsUp, PointsDown
Пример #14
0
"""
if __name__ == "__main__":
    import airconics
    import airconics.AirCONICStools as act
    # Initialise the display
    from OCC.Display.SimpleGui import init_display
    display, start_display, add_menu, add_function_to_menu = init_display()

    # Add NACA 4 digit airfoils to loft between:
    Af2 = airconics.primitives.Airfoil([0., 0., 0.],
                                       ChordLength=3.,
                                       Naca4Profile='2412')
    display.DisplayShape(Af2.Curve, update=True, color='GREEN')

    Af3 = airconics.primitives.Airfoil([0., 5., 0.],
                                       ChordLength=1.,
                                       Naca4Profile='0012')
    display.DisplayShape(Af3.Curve, update=True, color='GREEN')

    Af4 = airconics.primitives.Airfoil([0., 6., 0.2],
                                       ChordLength=0.2,
                                       Naca4Profile='0012')
    display.DisplayShape(Af4.Curve, update=True, color='GREEN')

    surf = act.AddSurfaceLoft([Af2, Af3, Af4])

    # Note that surf is a TOPO_DS Shape, and hence no surf.Shape is required for display
    display.DisplayShape(surf, update=True)

    start_display()
Пример #15
0
def transonic_airliner(display=None,
                       Propulsion=1,
                       EngineDia=2.9,
                       FuselageScaling=[55.902, 55.902, 55.902],
                       NoseLengthRatio=0.182,
                       TailLengthRatio=0.293,
                       WingScaleFactor=44.56,
                       WingChordFactor=1.0,
                       Topology=1,
                       SpanStation1=0.35,
                       SpanStation2=0.675,
                       EngineCtrBelowLE=0.3558,
                       EngineCtrFwdOfLE=0.9837,
                       Scarf_deg=3):
    """
    Parameters
    ----------
    Propulsion - int
        1 - twin
        2 - quad
    EngineDia - float
        Diameter of engine intake highlight
    FuselageScaling - list, length 3
        Fx, Fy, Fz scaling factors of fuselage
    NoseLengthRatio - scalar
        Proportion of forward tapering section of the fuselage 
    TailLengthRatio - scalar
        Proportion of aft tapering section of the fuselage
    WingScaleFactor - scalar
        Scale Factor of the main wing
    WingChordFactor - scalar
        Chord factor of the main wing
    Topology - int
        Topology = 2 should yield a box wing airliner - use with caution
    SpanStation - float
        Inboard engine at this span station
    SpanStation2 - float
        Outboard engine at this span station (ignored if Propulsion=1)
    EngineCtrBelowLE - float
        Engine below leading edge, normalised by the length of the nacelle -
        range: [0.35,0.5]
    EngineCtrFwdOfLE - float
        Engine forward of leading edge, normalised by the length of the nacelle
        range: [0.85,1.5]
    Scarf_deg - scalar # Engine scarf angle
    
    Returns
    -------
    airliner - 'Aircraft' class instance
        The collection of aircraft parts
    
    See also
    --------
    class Aircraft
    """

    try:
        Fus = fuselage_oml.Fuselage(NoseLengthRatio, TailLengthRatio,
                                    Scaling=FuselageScaling,
                                    NoseCoordinates=[0, 0, 0])
    except:
        print "Fuselage fitting failed - stopping."
        return None

    FuselageHeight = FuselageScaling[2]*0.105
    FuselageLength = FuselageScaling[0]
    FuselageWidth  = FuselageScaling[1]*0.106

    if Fus['OML'] is None:
        print "Failed to fit fuselage surface, stopping."
        return None

#    FSurf = rs.CopyObject(FuselageOMLSurf)

    # Position of the apex of the wing
    if FuselageHeight < 8.0:
         #787:[9.77,0,-0.307]
        WingApex = [0.1748*FuselageLength,0,-0.0523*FuselageHeight]
    else:
        WingApex = [0.1748*FuselageLength,0,-0.1*FuselageHeight] #787:[9.77,0,-0.307]


    # Set up the wing object, including the list of user-defined functions that
    # describe the spanwise variations of sweep, dihedral, etc.
    if Topology == 1:
        NSeg = 10
        Wing = liftingsurface.LiftingSurface(WingApex,
                                             mySweepAngleFunctionAirliner, 
                                             myDihedralFunctionAirliner, 
                                             myTwistFunctionAirliner, 
                                             myChordFunctionAirliner, 
                                             myAirfoilFunctionAirliner,
                                             SegmentNo=NSeg,
                                             ScaleFactor=WingScaleFactor,
                                             ChordFactor=WingChordFactor)
        RootChord = Wing.RootChord
    elif Topology == 2:
        NSeg = 101
        Wing = liftingsurface.LiftingSurface(WingApex,
                                             mySweepAngleFunctionAirliner,
                                             bw.myDihedralFunctionBoxWing,
                                             myTwistFunctionAirliner,
                                             myChordFunctionAirliner,
                                             myAirfoilFunctionAirliner, 
                                             SegmentNo=NSeg,
                                             ScaleFactor=WingScaleFactor,
                                             ChordFactor=WingChordFactor)
        RootChord = Wing.RootChord

    if Topology == 1:
    
        # Add wing to body fairing 
        WTBFXCentre = WingApex[0] + RootChord/2.0 + RootChord*0.1297 # 787: 23.8
        if FuselageHeight < 8.0:
            #Note: I made changes to this in OCC Airconics to get a better fit
            # - Paul
            WTBFZ = RootChord*0.009 #787: 0.2
            WTBFheight = 1.8*0.1212*RootChord #787:2.7
            WTBFwidth = 1.08*FuselageWidth
        else:
    
            WTBFZ = WingApex[2] + 0.005*RootChord
            WTBFheight = 0.09*RootChord 
            WTBFwidth = 1.15*FuselageWidth
    
        WTBFlength = 1.167*RootChord #787:26
        WBF_shape = act.make_ellipsoid([WTBFXCentre, 0, WTBFZ], WTBFlength,
                                        WTBFwidth, WTBFheight)
        WBF = AirconicsShape(components={'WBF': WBF_shape})

#        Trim wing inboard section
        CutCirc = act.make_circle3pt([0,WTBFwidth/4.,-45], [0,WTBFwidth/4.,45], [90,WTBFwidth/4.,0])
        CutCircDisk = act.PlanarSurf(CutCirc)
        Wing['Surface'] = act.TrimShapebyPlane(Wing['Surface'], CutCircDisk)
    elif Topology == 2:
#        Overlapping wing tips
        CutCirc = act.make_circle3pt((0,0,-45), (0,0,45), (90,0,0))
        CutCircDisk = act.PlanarSurf(CutCirc)
        Wing['Surface'] = act.TrimShapebyPlane(Wing['Surface'], CutCircDisk)


#   Engine installation (nacelle and pylon)
    NacelleLength = 1.95*EngineDia
    if Propulsion == 1:
        SpanStations = [SpanStation1]
    elif Propulsion == 2:
        SpanStations = [SpanStation1, SpanStation2]
   
    engines = []
    for i, SpanStation in enumerate(SpanStations):
        EngineSection, Chord = act.CutSect(Wing['Surface'], SpanStation)
        CEP = Chord.EndPoint()
        Centreloc = [CEP.X()-EngineCtrFwdOfLE*NacelleLength,
                    CEP.Y(), 
                    CEP.Z()-EngineCtrBelowLE*NacelleLength]
        eng =  engine.Engine(Chord,
               CentreLocation=Centreloc,
               ScarfAngle=Scarf_deg,
               HighlightRadius=EngineDia/2.0,
               MeanNacelleLength = NacelleLength)

        engines.append(eng)

#    # Script for generating and positioning the fin
#    # Position of the apex of the fin
    P = [0.6524*FuselageLength,0.003,FuselageHeight*0.384]
    #P = [36.47,0.003,2.254]55.902
    
    if Topology == 1:
        ScaleFactor = WingScaleFactor/2.032 #787:21.93
    elif Topology == 2:
        ScaleFactor = WingScaleFactor/3.5 
    
    SegmentNo = 100
    ChordFactor = 1.01#787:1.01
    Fin = liftingsurface.LiftingSurface(P, mySweepAngleFunctionFin,
                                        myDihedralFunctionFin,
                                        myTwistFunctionFin,
                                        myChordFunctionFin,
                                        myAirfoilFunctionFin,
                                        SegmentNo=SegmentNo,
                                        ChordFactor=ChordFactor,
                                        ScaleFactor=ScaleFactor)

#    Create the rotation axis centered at the apex point in the x direction
    RotAxis = gp_Ax1(gp_Pnt(*P), gp_Dir(1, 0, 0))
    
    Fin.RotateComponents(RotAxis, 90)

    if Topology == 1:
#        Tailplane
        P = [0.7692*FuselageLength,0.000,FuselageHeight*0.29]
        SegmentNo = 100
        ChordFactor = 1.01
        ScaleFactor = 0.388*WingScaleFactor #787:17.3
        TP = liftingsurface.LiftingSurface(P,
                                           mySweepAngleFunctionTP, 
                                           myDihedralFunctionTP,
                                           myTwistFunctionTP,
                                           myChordFunctionTP,
                                           myAirfoilFunctionTP,
                                           SegmentNo=SegmentNo,
                                           ChordFactor=ChordFactor,
                                           ScaleFactor=ScaleFactor)


# OCC_AirCONICS Note: Nothing below here implemented in OCC_AirCONICS - See
# Rhino version for this functionality (largely for display only)
#
#    rs.DeleteObjects([EngineSection, Chord])
#    try:
#        rs.DeleteObjects([CutCirc])
#    except:
#        pass
#
#    try:
#        rs.DeleteObjects([CutCircDisk])
#    except:
#        pass
#
#    # Windows
#    
#    # Cockpit windows:    
    CockpitWindowTop = 0.305*FuselageHeight
    
    print("Making Fuselage Windows...")
    
#    solids = Fus.CockpitWindowContours(Height=CockpitWindowTop, Depth=6)
#
##     Cut the windows out:
#    for solid in solids:
#        Fus['OML'] = act.SplitShape(Fus['OML'], solid)
#    
#    
#    print("Cockpit Windows Done.")

    

##
##    (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) = act.ObjectsExtents([Win1, Win2, Win3, Win4])
    CockpitBulkheadX = NoseLengthRatio*FuselageLength*0.9
##
##    CockpitWallPlane = rs.PlaneFromPoints([CockpitBulkheadX, -15,-15],
##    [CockpitBulkheadX,15,-15],
##    [CockpitBulkheadX,-15,15])
##    
##    CockpitWall = rs.AddPlaneSurface(CockpitWallPlane, 30, 30)
##    
##    if 'WTBF' in locals():
##        rs.TrimBrep(WTBF, CockpitWall)
##
##    rs.DeleteObject(CockpitWall)
#
##    # Window lines
    WIN = [1]
    NOWIN = [0]
##
###    # A typical window pattern (including emergency exit windows)
    WinVec = WIN + 2*NOWIN + 9*WIN + 3*NOWIN + WIN + NOWIN + 24*WIN + 2*NOWIN + WIN + NOWIN + 14*WIN + 2*NOWIN + WIN + 20*WIN + 2*NOWIN + WIN + NOWIN + 20*WIN
    wires = []
    if FuselageHeight < 8.0:
###        # Single deck
        WindowLineHeight = 0.3555*FuselageHeight
        WinX = 0.1157*FuselageLength
        WindowPitch = 0.609
        WinInd = -1
        i = 0
        while WinX < 0.75*FuselageLength:
            WinInd = WinInd + 1
            if WinVec[WinInd] == 1 and WinX > CockpitBulkheadX:
                i=i+1
                print("Generating cabin window {}".format(i))
                WinCenter = [WinX, WindowLineHeight]
                W_wire = Fus.WindowContour(WinCenter)
                wires.append(W_wire)
#                display.DisplayShape(W_wire, color='black')
#                win_port, win_stbd = Fus.MakeWindow(*WinCenter)
#                print(type(win_port), type(win_stbd))
#                
#                display.DisplayShape(win_port, color='Black')
#                display.DisplayShape(win_stbd, color='Black')
#
###                Note: Need to fix makewindow to return windows WinStbd,
##                # WinPort, 
#                Fus.MakeWindow(WinX, WindowLineHeight)
###                act.AssignMaterial(WinStbd,"Plexiglass")
###                act.AssignMaterial(WinPort,"Plexiglass")
            WinX = WinX + WindowPitch
#
#    print("Cabin windows done")



#    else:
#        # TODO: Fuselage big enough to accommodate two decks 
#        # Lower deck
#        WindowLineHeight = 0.17*FuselageHeight #0.166
#        WinX = 0.1*FuselageLength #0.112
#        WindowPitch = 0.609
#        WinInd = 0
#        while WinX < 0.757*FuselageLength:
#            WinInd = WinInd + 1
#            if WinVec[WinInd] == 1 and WinX > CockpitBulkheadX:
#                WinStbd, WinPort, FuselageOMLSurf = fuselage_oml.MakeWindow(FuselageOMLSurf, WinX, WindowLineHeight)
#                act.AssignMaterial(WinStbd,"Plexiglass")
#                act.AssignMaterial(WinPort,"Plexiglass")
#            WinX = WinX + WindowPitch
#        # Upper deck
#        WindowLineHeight = 0.49*FuselageHeight
#        WinX = 0.174*FuselageLength #0.184
#        WinInd = 0
#        while WinX < 0.757*FuselageLength:
#            WinInd = WinInd + 1
#            if WinVec[WinInd] == 1 and WinX > CockpitBulkheadX:
#                WinStbd, WinPort, FuselageOMLSurf = fuselage_oml.MakeWindow(FuselageOMLSurf, WinX, WindowLineHeight)
#                act.AssignMaterial(WinStbd,"Plexiglass")
#                act.AssignMaterial(WinPort,"Plexiglass")
#            WinX = WinX + WindowPitch
#
#
#
#
#
#    act.AssignMaterial(FuselageOMLSurf,"White_composite_external")
#    act.AssignMaterial(WingSurf,"White_composite_external")
#    try:
#        act.AssignMaterial(TPSurf,"ShinyBARedMetal")
#    except:
#        pass
#    act.AssignMaterial(FinSurf,"ShinyBARedMetal")
#    act.AssignMaterial(Win1,"Plexiglass")
#    act.AssignMaterial(Win2,"Plexiglass")
#    act.AssignMaterial(Win3,"Plexiglass")
#    act.AssignMaterial(Win4,"Plexiglass")
#
#
#    # Mirror the geometry as required
    Wing2 = Wing.MirrorComponents(plane='xz')
    try:
        # this try section allows box wing i.e. no tailplane
        TP2 = TP.MirrorComponents(plane='xz')
    except:
        pass

    engines_left = []
    for eng in engines:
        engines_left.append(eng.MirrorComponents(plane='xz'))


#    if Propulsion == 1:
#        for ObjId in EngineStbd:
#            act.MirrorObjectXZ(ObjId)
#        act.MirrorObjectXZ(PylonStbd)
#    elif Propulsion == 2:
#        raise NotImplementedError
#        for ObjId in EngineStbd1:
#            act.MirrorObjectXZ(ObjId)
#        act.MirrorObjectXZ(PylonStbd1)
#        for ObjId in EngineStbd2:
#            act.MirrorObjectXZ(ObjId)
#        act.MirrorObjectXZ(PylonStbd2)


#    Build the return assembly (could change this later based on input 'tree':
    airliner = AirconicsCollection(parts={'Wing_right': Wing,
                                          'Wing_left': Wing2,
                                          'Fuselage': Fus,
                                          'Fin': Fin,
                                          'Tailplane_right': TP,
                                          'Tailplane_left': TP2,
                                          'WBF': WBF})

    # Loop over the engines and write all components:
    for i, eng in enumerate(engines):
        name = 'engine_right' + str(i+1)
        airliner.AddPart(eng, name)
    for i, eng in enumerate(engines_left):
        name = 'engine_left' + str(i+1)
        airliner.AddPart(eng, name)

    return airliner, wires
Пример #16
0
def myDihedralFunction(Epsilon):
    """User-defined function describing the variation of dihedral as a function
    of the leading edge coordinate"""
    return 7


def myTwistFunction(Epsilon):
    """User-defined function describing the variation of twist as a function
    of the leading edge coordinate."""
    RootTwist = 0
    TipTwist = -2
    return RootTwist + Epsilon * TipTwist


myChordFunction = act.Generate_InterpFunction([1, 0.33], [0, 1])


@liftingsurface.airfoilfunct
def myAirfoilFunction(eps):
    af_root = Airfoil(SeligProfile='naca63a418')
    af_tip = Airfoil(SeligProfile='naca63a412')

    profile_dict = {
        'InterpProfile': True,
        'Epsilon': eps,
        'Af1': af_root,
        'Af2': af_tip,
        'Eps1': 0,
        'Eps2': 1
    }