def _BuildFuselageOML(NoseLengthRatio, TailLengthRatio, CylindricalMidSection, SimplificationReqd): MaxFittingAttempts = 6 FittingAttempts = -1 NetworkSrfSettings = [ [35, 20, 15, 5, 20], [35, 30, 15, 5, 20], [35, 20, 15, 2, 20], [30, 30, 15, 2, 20], [30, 20, 15, 2, 20], [25, 20, 15, 2, 20], [20, 20, 15, 2, 20], [15, 20, 15, 2, 20]] StarboardCurve, PortCurve, FSVUCurve, FSVLCurve, FSVMeanCurve, NoseEndX, TailStartX, EndX = _FuselageLongitudinalGuideCurves(NoseLengthRatio, TailLengthRatio) while FittingAttempts <= MaxFittingAttempts: FittingAttempts = FittingAttempts + 1 # Construct array of cross section definition frames SX0 = 0 Step01 = NetworkSrfSettings[FittingAttempts][0] SX1 = 0.04*NoseEndX Step12 = NetworkSrfSettings[FittingAttempts][1] SX2 = SX1 + 0.25*NoseEndX Step23 = NetworkSrfSettings[FittingAttempts][2] SX3 = NoseEndX Step34 = NetworkSrfSettings[FittingAttempts][3] SX4 = TailStartX Step45 = NetworkSrfSettings[FittingAttempts][4] SX5 = EndX print "Attempting network surface fit with network density setup ", NetworkSrfSettings[FittingAttempts][:] Stations01 = act.pwfrange(SX0,SX1,max([Step01,2])) Stations12 = act.pwfrange(SX1,SX2,max([Step12,2])) Stations23 = act.pwfrange(SX2,SX3,max([Step23,2])) Stations34 = act.pwfrange(SX3,SX4,max([Step34,2])) Stations45 = act.pwfrange(SX4,SX5,max([Step45,2])) StationRange = Stations01[:-1] + Stations12[:-1] + Stations23[:-1] + Stations34[:-1] + Stations45 C = [] FirstTime = True for XStation in StationRange: P = rs.PlaneFromPoints((XStation,0,0),(XStation,1,0),(XStation,0,1)) IP1 = rs.PlaneCurveIntersection(P,StarboardCurve) IP2 = rs.PlaneCurveIntersection(P,FSVUCurve) IP3 = rs.PlaneCurveIntersection(P,PortCurve) IP4 = rs.PlaneCurveIntersection(P,FSVLCurve) IPcentre = rs.PlaneCurveIntersection(P,FSVMeanCurve) IPoint1 = rs.AddPoint(IP1[0][1]) IPoint2 = rs.AddPoint(IP2[0][1]) IPoint3 = rs.AddPoint(IP3[0][1]) IPoint4 = rs.AddPoint(IP4[0][1]) IPointCentre = rs.AddPoint(IPcentre[0][1]) PseudoDiameter = abs(IP4[0][1].Z-IP2[0][1].Z) if CylindricalMidSection and NoseEndX < XStation < TailStartX: # Ensure that the parallel section of the fuselage is cylindrical # if CylindricalMidSection is True print "Enforcing circularity in the central section..." if FirstTime: PseudoRadius = PseudoDiameter/2 FirstTime = False Pc = rs.PointCoordinates(IPointCentre) P1 = P2 = P3 = Pc P1 = rs.PointAdd(P1,(0,PseudoRadius,0)) P2 = rs.PointAdd(P2,(0,0,PseudoRadius)) P3 = rs.PointAdd(P3,(0,-PseudoRadius,0)) c = rs.AddCircle3Pt(P1, P2, P3) else: c = rs.AddInterpCurve([IPoint1,IPoint2,IPoint3,IPoint4,IPoint1],knotstyle=3) # Once CSec is implemented in Rhino Python, this could be replaced rs.DeleteObjects([IPoint1,IPoint2,IPoint3,IPoint4,IPointCentre]) list.append(C,c) # Fit fuselage external surface CurveNet = [] for c in C[1:]: list.append(CurveNet,c) list.append(CurveNet, FSVUCurve) list.append(CurveNet, PortCurve) list.append(CurveNet, FSVLCurve) list.append(CurveNet, StarboardCurve) FuselageOMLSurf = rs.AddNetworkSrf(CurveNet) rs.DeleteObjects(C) if not(FuselageOMLSurf==None): print "Network surface fit succesful on attempt ", FittingAttempts+1 FittingAttempts = MaxFittingAttempts+1 # Force an exit from 'while' # If all attempts at fitting a network surface failed, we attempt a Sweep2 if FuselageOMLSurf==None: print "Failed to fit network surface to the external shape of the fuselage" print "Attempting alternative fitting method, quality likely to be low..." try: FuselageOMLSurf = rs.AddSweep2([FSVUCurve,FSVLCurve],C[:]) except: FuselageOMLSurf = False SimplificationReqd = True # Enforce simplification if not(FuselageOMLSurf): print "Alternative fitting method failed too. Out of ideas." if FuselageOMLSurf and SimplificationReqd: rs.UnselectAllObjects() rs.SelectObject(FuselageOMLSurf) ToleranceStr = str(0.0005*EndX) print "Smoothing..." rs.Command("FitSrf " + ToleranceStr) rs.UnselectAllObjects() # Compute the stern point coordinates of the fuselage Pu = rs.CurveEndPoint(FSVUCurve) Pl = rs.CurveEndPoint(FSVLCurve) SternPoint = [Pu.X, Pu.Y, 0.5*(Pu.Z+Pl.Z)] rs.DeleteObjects([FSVUCurve,FSVLCurve,PortCurve,StarboardCurve,FSVMeanCurve]) return FuselageOMLSurf, SternPoint
def _BuildFuselageOML(NoseLengthRatio, TailLengthRatio, CylindricalMidSection, SimplificationReqd): MaxFittingAttempts = 6 FittingAttempts = -1 NetworkSrfSettings = [[35, 20, 15, 5, 20], [35, 30, 15, 5, 20], [35, 20, 15, 2, 20], [30, 30, 15, 2, 20], [30, 20, 15, 2, 20], [25, 20, 15, 2, 20], [20, 20, 15, 2, 20], [15, 20, 15, 2, 20]] StarboardCurve, PortCurve, FSVUCurve, FSVLCurve, FSVMeanCurve, NoseEndX, TailStartX, EndX = _FuselageLongitudinalGuideCurves( NoseLengthRatio, TailLengthRatio) while FittingAttempts <= MaxFittingAttempts: FittingAttempts = FittingAttempts + 1 # Construct array of cross section definition frames SX0 = 0 Step01 = NetworkSrfSettings[FittingAttempts][0] SX1 = 0.04 * NoseEndX Step12 = NetworkSrfSettings[FittingAttempts][1] SX2 = SX1 + 0.25 * NoseEndX Step23 = NetworkSrfSettings[FittingAttempts][2] SX3 = NoseEndX Step34 = NetworkSrfSettings[FittingAttempts][3] SX4 = TailStartX Step45 = NetworkSrfSettings[FittingAttempts][4] SX5 = EndX print "Attempting network surface fit with network density setup ", NetworkSrfSettings[ FittingAttempts][:] Stations01 = act.pwfrange(SX0, SX1, max([Step01, 2])) Stations12 = act.pwfrange(SX1, SX2, max([Step12, 2])) Stations23 = act.pwfrange(SX2, SX3, max([Step23, 2])) Stations34 = act.pwfrange(SX3, SX4, max([Step34, 2])) Stations45 = act.pwfrange(SX4, SX5, max([Step45, 2])) StationRange = Stations01[: -1] + Stations12[: -1] + Stations23[: -1] + Stations34[: -1] + Stations45 C = [] FirstTime = True for XStation in StationRange: P = rs.PlaneFromPoints((XStation, 0, 0), (XStation, 1, 0), (XStation, 0, 1)) IP1 = rs.PlaneCurveIntersection(P, StarboardCurve) IP2 = rs.PlaneCurveIntersection(P, FSVUCurve) IP3 = rs.PlaneCurveIntersection(P, PortCurve) IP4 = rs.PlaneCurveIntersection(P, FSVLCurve) IPcentre = rs.PlaneCurveIntersection(P, FSVMeanCurve) IPoint1 = rs.AddPoint(IP1[0][1]) IPoint2 = rs.AddPoint(IP2[0][1]) IPoint3 = rs.AddPoint(IP3[0][1]) IPoint4 = rs.AddPoint(IP4[0][1]) IPointCentre = rs.AddPoint(IPcentre[0][1]) PseudoDiameter = abs(IP4[0][1].Z - IP2[0][1].Z) if CylindricalMidSection and NoseEndX < XStation < TailStartX: # Ensure that the parallel section of the fuselage is cylindrical # if CylindricalMidSection is True print "Enforcing circularity in the central section..." if FirstTime: PseudoRadius = PseudoDiameter / 2 FirstTime = False Pc = rs.PointCoordinates(IPointCentre) P1 = P2 = P3 = Pc P1 = rs.PointAdd(P1, (0, PseudoRadius, 0)) P2 = rs.PointAdd(P2, (0, 0, PseudoRadius)) P3 = rs.PointAdd(P3, (0, -PseudoRadius, 0)) c = rs.AddCircle3Pt(P1, P2, P3) else: c = rs.AddInterpCurve( [IPoint1, IPoint2, IPoint3, IPoint4, IPoint1], knotstyle=3) # Once CSec is implemented in Rhino Python, this could be replaced rs.DeleteObjects( [IPoint1, IPoint2, IPoint3, IPoint4, IPointCentre]) list.append(C, c) # Fit fuselage external surface CurveNet = [] for c in C[1:]: list.append(CurveNet, c) list.append(CurveNet, FSVUCurve) list.append(CurveNet, PortCurve) list.append(CurveNet, FSVLCurve) list.append(CurveNet, StarboardCurve) FuselageOMLSurf = rs.AddNetworkSrf(CurveNet) rs.DeleteObjects(C) if not (FuselageOMLSurf == None): print "Network surface fit succesful on attempt ", FittingAttempts + 1 FittingAttempts = MaxFittingAttempts + 1 # Force an exit from 'while' # If all attempts at fitting a network surface failed, we attempt a Sweep2 if FuselageOMLSurf == None: print "Failed to fit network surface to the external shape of the fuselage" print "Attempting alternative fitting method, quality likely to be low..." try: FuselageOMLSurf = rs.AddSweep2([FSVUCurve, FSVLCurve], C[:]) except: FuselageOMLSurf = False SimplificationReqd = True # Enforce simplification if not (FuselageOMLSurf): print "Alternative fitting method failed too. Out of ideas." if FuselageOMLSurf and SimplificationReqd: rs.UnselectAllObjects() rs.SelectObject(FuselageOMLSurf) ToleranceStr = str(0.0005 * EndX) print "Smoothing..." rs.Command("FitSrf " + ToleranceStr) rs.UnselectAllObjects() # Compute the stern point coordinates of the fuselage Pu = rs.CurveEndPoint(FSVUCurve) Pl = rs.CurveEndPoint(FSVLCurve) SternPoint = [Pu.X, Pu.Y, 0.5 * (Pu.Z + Pl.Z)] rs.DeleteObjects( [FSVUCurve, FSVLCurve, PortCurve, StarboardCurve, FSVMeanCurve]) return FuselageOMLSurf, SternPoint