RCAIDE-GUI 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- common_widgets/__init__.py +6 -0
- common_widgets/animated_toggle.py +141 -0
- common_widgets/color.py +17 -0
- common_widgets/data_entry_widget.py +337 -0
- common_widgets/image_widget.py +21 -0
- common_widgets/unit_picker_widget.py +48 -0
- main.py +168 -0
- rcaide_gui-1.0.0.dist-info/METADATA +96 -0
- rcaide_gui-1.0.0.dist-info/RECORD +170 -0
- rcaide_gui-1.0.0.dist-info/WHEEL +5 -0
- rcaide_gui-1.0.0.dist-info/entry_points.txt +2 -0
- rcaide_gui-1.0.0.dist-info/top_level.txt +5 -0
- rcaide_io.py +818 -0
- tabs/__init__.py +10 -0
- tabs/aircraft_configs/__init__.py +3 -0
- tabs/aircraft_configs/aircraft_configs.py +301 -0
- tabs/analysis/__init__.py +4 -0
- tabs/analysis/analysis.py +92 -0
- tabs/analysis/widgets/__init__.py +13 -0
- tabs/analysis/widgets/aeroacoustics_widget.py +158 -0
- tabs/analysis/widgets/aerodynamics_widget.py +108 -0
- tabs/analysis/widgets/analysis_data_widget.py +29 -0
- tabs/analysis/widgets/atmosphere_widget.py +49 -0
- tabs/analysis/widgets/costs_widget.py +35 -0
- tabs/analysis/widgets/energy_widget.py +32 -0
- tabs/analysis/widgets/geometry_widget.py +55 -0
- tabs/analysis/widgets/planets_widget.py +34 -0
- tabs/analysis/widgets/propulsion_widget.py +53 -0
- tabs/analysis/widgets/stability_widget.py +34 -0
- tabs/analysis/widgets/weights_widget.py +94 -0
- tabs/geometry/__init__.py +6 -0
- tabs/geometry/aircraft_configs.py +232 -0
- tabs/geometry/frames/__init__.py +15 -0
- tabs/geometry/frames/booms/__init__.py +5 -0
- tabs/geometry/frames/booms/boom_frame.py +238 -0
- tabs/geometry/frames/cargo_bays/__init__.py +5 -0
- tabs/geometry/frames/cargo_bays/cargo_bay_frame.py +159 -0
- tabs/geometry/frames/default_frame.py +23 -0
- tabs/geometry/frames/energy_network/__init__.py +2 -0
- tabs/geometry/frames/energy_network/turbofan_network/__init__.py +3 -0
- tabs/geometry/frames/energy_network/turbofan_network/frames/__init__.py +1 -0
- tabs/geometry/frames/energy_network/turbofan_network/widgets/__init__.py +1 -0
- tabs/geometry/frames/fuselages/__init__.py +5 -0
- tabs/geometry/frames/fuselages/fuselage_frame.py +294 -0
- tabs/geometry/frames/geometry_frame.py +91 -0
- tabs/geometry/frames/landing_gears/__init__.py +5 -0
- tabs/geometry/frames/landing_gears/landing_gear_frame.py +189 -0
- tabs/geometry/frames/nacelles/__init__.py +1 -0
- tabs/geometry/frames/powertrain/__init__.py +6 -0
- tabs/geometry/frames/powertrain/converters/__init__.py +5 -0
- tabs/geometry/frames/powertrain/converters/converter_frame.py +137 -0
- tabs/geometry/frames/powertrain/distributors/__init__.py +5 -0
- tabs/geometry/frames/powertrain/distributors/distributor_frame.py +143 -0
- tabs/geometry/frames/powertrain/nacelles/__init__.py +5 -0
- tabs/geometry/frames/powertrain/nacelles/nacelle_frame.py +283 -0
- tabs/geometry/frames/powertrain/powertrain_frame.py +259 -0
- tabs/geometry/frames/powertrain/propulsors/__init__.py +5 -0
- tabs/geometry/frames/powertrain/propulsors/propulsor_frame.py +146 -0
- tabs/geometry/frames/powertrain/sources/__init__.py +6 -0
- tabs/geometry/frames/powertrain/sources/energy_source_frame.py +147 -0
- tabs/geometry/frames/vehicle_frame.py +171 -0
- tabs/geometry/frames/wings/__init__.py +5 -0
- tabs/geometry/frames/wings/wings_frame.py +457 -0
- tabs/geometry/geometry.py +513 -0
- tabs/geometry/widgets/__init__.py +12 -0
- tabs/geometry/widgets/booms/__init__.py +6 -0
- tabs/geometry/widgets/booms/boom_section_widget.py +109 -0
- tabs/geometry/widgets/cargo_bays/__init__.py +1 -0
- tabs/geometry/widgets/fuselages/__init__.py +8 -0
- tabs/geometry/widgets/fuselages/cabin_class_widget.py +188 -0
- tabs/geometry/widgets/fuselages/cabin_widget.py +217 -0
- tabs/geometry/widgets/fuselages/fuselage_section_widget.py +190 -0
- tabs/geometry/widgets/geometry_data_widget.py +25 -0
- tabs/geometry/widgets/landing_gears/__init__.py +6 -0
- tabs/geometry/widgets/nacelles/__init__.py +1 -0
- tabs/geometry/widgets/powertrain/__init__.py +9 -0
- tabs/geometry/widgets/powertrain/converters/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/converters/turboelectric_generator_widget.py +74 -0
- tabs/geometry/widgets/powertrain/distributors/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/distributors/fuel_line_widget.py +81 -0
- tabs/geometry/widgets/powertrain/modulators/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/modulators/esc_widget.py +58 -0
- tabs/geometry/widgets/powertrain/nacelles/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/nacelles/nacelle_section_widget.py +115 -0
- tabs/geometry/widgets/powertrain/powertrain_connector_widget.py +136 -0
- tabs/geometry/widgets/powertrain/powertrain_widget.py +206 -0
- tabs/geometry/widgets/powertrain/propulsors/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/propulsors/turbofan_widget.py +462 -0
- tabs/geometry/widgets/powertrain/sources/__init__.py +6 -0
- tabs/geometry/widgets/powertrain/sources/fuel_tank_widget.py +103 -0
- tabs/geometry/widgets/powertrain/sources/source_selector_widget.py +35 -0
- tabs/geometry/widgets/wings/__init__.py +7 -0
- tabs/geometry/widgets/wings/wing_cs_widget.py +198 -0
- tabs/geometry/widgets/wings/wing_section_widget.py +298 -0
- tabs/home/__init__.py +3 -0
- tabs/home/home.py +585 -0
- tabs/mission/__init__.py +4 -0
- tabs/mission/mission.py +1124 -0
- tabs/mission/widgets/__init__.py +3 -0
- tabs/mission/widgets/flight_controls_widget.py +186 -0
- tabs/mission/widgets/mission_analysis_widget.py +166 -0
- tabs/mission/widgets/mission_segment_helper.py +358 -0
- tabs/mission/widgets/mission_segment_widget.py +358 -0
- tabs/solve/__init__.py +4 -0
- tabs/solve/plots/__init__.py +12 -0
- tabs/solve/plots/aeroacoustics/__init__.py +6 -0
- tabs/solve/plots/aeroacoustics/plot_2D_noise_contour.py +184 -0
- tabs/solve/plots/aeroacoustics/plot_3D_noise_contour.py +219 -0
- tabs/solve/plots/aeroacoustics/plot_noise_certification_contour.py +115 -0
- tabs/solve/plots/aeroacoustics/plot_noise_level.py +118 -0
- tabs/solve/plots/aerodynamics/__init__.py +10 -0
- tabs/solve/plots/aerodynamics/plot_aerodynamic_coefficients.py +156 -0
- tabs/solve/plots/aerodynamics/plot_aerodynamic_forces.py +155 -0
- tabs/solve/plots/aerodynamics/plot_aircraft_aerodynamics.py +136 -0
- tabs/solve/plots/aerodynamics/plot_drag_components.py +157 -0
- tabs/solve/plots/aerodynamics/plot_lift_distribution.py +107 -0
- tabs/solve/plots/aerodynamics/plot_rotor_conditions.py +255 -0
- tabs/solve/plots/aerodynamics/plot_rotor_disc_performance.py +144 -0
- tabs/solve/plots/aerodynamics/plot_rotor_performance.py +124 -0
- tabs/solve/plots/common/__init__.py +4 -0
- tabs/solve/plots/common/plot_style.py +71 -0
- tabs/solve/plots/common/set_axes.py +55 -0
- tabs/solve/plots/create_plot_widgets.py +34 -0
- tabs/solve/plots/emissions/__init__.py +3 -0
- tabs/solve/plots/emissions/plot_emissions.py +167 -0
- tabs/solve/plots/energy/__init__.py +12 -0
- tabs/solve/plots/energy/plot_altitude_sfc_weight.py +134 -0
- tabs/solve/plots/energy/plot_battery_cell_conditions.py +154 -0
- tabs/solve/plots/energy/plot_battery_degradation.py +157 -0
- tabs/solve/plots/energy/plot_battery_module_C_rates.py +139 -0
- tabs/solve/plots/energy/plot_battery_module_conditions.py +157 -0
- tabs/solve/plots/energy/plot_battery_pack_conditions.py +164 -0
- tabs/solve/plots/energy/plot_battery_ragone_diagram.py +97 -0
- tabs/solve/plots/energy/plot_battery_temperature.py +136 -0
- tabs/solve/plots/energy/plot_electric_propulsor_efficiencies.py +136 -0
- tabs/solve/plots/energy/plot_propulsor_throttles.py +119 -0
- tabs/solve/plots/mission/__init__.py +5 -0
- tabs/solve/plots/mission/plot_aircraft_velocities.py +145 -0
- tabs/solve/plots/mission/plot_flight_conditions.py +236 -0
- tabs/solve/plots/mission/plot_flight_trajectory.py +172 -0
- tabs/solve/plots/stability/__init__.py +5 -0
- tabs/solve/plots/stability/plot_flight_forces_and_moments.py +163 -0
- tabs/solve/plots/stability/plot_lateral_stability.py +151 -0
- tabs/solve/plots/stability/plot_longitudinal_stability.py +173 -0
- tabs/solve/plots/thermal_management/__init__.py +7 -0
- tabs/solve/plots/thermal_management/plot_air_cooled_conditions.py +152 -0
- tabs/solve/plots/thermal_management/plot_cross_flow_heat_exchanger_conditions.py +185 -0
- tabs/solve/plots/thermal_management/plot_reservoir_conditions.py +141 -0
- tabs/solve/plots/thermal_management/plot_thermal_management_performance.py +105 -0
- tabs/solve/plots/thermal_management/plot_wavy_channel_conditions.py +161 -0
- tabs/solve/plots/weights/__init__.py +4 -0
- tabs/solve/plots/weights/plot_load_diagram.py +163 -0
- tabs/solve/plots/weights/plot_weight_breakdown.py +164 -0
- tabs/solve/solve.py +1498 -0
- tabs/style_sheet.py +114 -0
- tabs/tab_widget.py +14 -0
- tabs/visualize_geometry/__init__.py +4 -0
- tabs/visualize_geometry/core_3d_viewer.py +253 -0
- tabs/visualize_geometry/features/__init__.py +10 -0
- tabs/visualize_geometry/features/axes_gizmo.py +173 -0
- tabs/visualize_geometry/features/background.py +161 -0
- tabs/visualize_geometry/features/blueprint.py +685 -0
- tabs/visualize_geometry/features/camera.py +364 -0
- tabs/visualize_geometry/features/drag_aircraft.py +219 -0
- tabs/visualize_geometry/features/grid.py +194 -0
- tabs/visualize_geometry/features/measurement.py +367 -0
- tabs/visualize_geometry/features/screenshot.py +91 -0
- tabs/visualize_geometry/geometry_helper_functions.py +3 -0
- tabs/visualize_geometry/visualize_geometry.py +731 -0
- utilities.py +257 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/fuselages/cabin_class_widget.py
|
|
2
|
+
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
# ------------------------------------------------------------------------------
|
|
5
|
+
# Imports
|
|
6
|
+
# ------------------------------------------------------------------------------
|
|
7
|
+
import RCAIDE
|
|
8
|
+
import math
|
|
9
|
+
from PyQt6.QtWidgets import (QHBoxLayout, QLabel,
|
|
10
|
+
QLineEdit, QPushButton, QSizePolicy, QSpacerItem,
|
|
11
|
+
QVBoxLayout, QWidget, QFrame, QComboBox)
|
|
12
|
+
|
|
13
|
+
from utilities import Units
|
|
14
|
+
from common_widgets import DataEntryWidget
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CabinClassWidget(QWidget):
|
|
18
|
+
# Visible fields; preserve everything else.
|
|
19
|
+
visible_data_keys = {
|
|
20
|
+
"class_type",
|
|
21
|
+
"Number of Passengers",
|
|
22
|
+
"Number of Seats Abreast",
|
|
23
|
+
"Number of Rows",
|
|
24
|
+
"Number of Seats",
|
|
25
|
+
"Seat Width",
|
|
26
|
+
"Seat Arm Rest Width",
|
|
27
|
+
"Seat Length",
|
|
28
|
+
"Seat Pitch",
|
|
29
|
+
"Aisle Width",
|
|
30
|
+
"number_of_passengers",
|
|
31
|
+
"number_of_seats_abrest",
|
|
32
|
+
"number_of_seats_abreast",
|
|
33
|
+
"number_of_rows",
|
|
34
|
+
"number_of_seats",
|
|
35
|
+
"seat_width",
|
|
36
|
+
"seat_arm_rest_width",
|
|
37
|
+
"seat_length",
|
|
38
|
+
"seat_pitch",
|
|
39
|
+
"aisle_width",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def __init__(self, index, on_delete, section_data=None):
|
|
43
|
+
# Initializing the CabinClassWidget
|
|
44
|
+
super().__init__()
|
|
45
|
+
self.index = index
|
|
46
|
+
self.on_delete = on_delete
|
|
47
|
+
self.data_entry_widget: DataEntryWidget | None = None
|
|
48
|
+
self.header_layout = QHBoxLayout()
|
|
49
|
+
# Hidden fields restored on save.
|
|
50
|
+
self.preserved_data = {}
|
|
51
|
+
self.init_ui(section_data)
|
|
52
|
+
|
|
53
|
+
# noinspection DuplicatedCode
|
|
54
|
+
def init_ui(self, section_data):
|
|
55
|
+
main_layout = QVBoxLayout()
|
|
56
|
+
# add spacing, buttons and drop down to header layout
|
|
57
|
+
spacer_left = QSpacerItem(80, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
58
|
+
self.header_layout.addItem(spacer_left)
|
|
59
|
+
self.header_layout.addWidget(QLabel("Class Type: "))
|
|
60
|
+
self.class_type_combo = QComboBox()
|
|
61
|
+
#list of types of "classes" for cabins
|
|
62
|
+
self.class_type_combo.addItems(["Economy", "Business", "First"])
|
|
63
|
+
self.header_layout.addWidget(self.class_type_combo)
|
|
64
|
+
self.header_layout.addItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum))
|
|
65
|
+
#adding delete button
|
|
66
|
+
delete_btn = QPushButton("Delete Class")
|
|
67
|
+
delete_btn.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
68
|
+
delete_btn.clicked.connect(self.delete_clicked)
|
|
69
|
+
self.header_layout.addWidget(delete_btn)
|
|
70
|
+
main_layout.addLayout(self.header_layout)
|
|
71
|
+
|
|
72
|
+
# List of data labels
|
|
73
|
+
self.data_units_labels = [
|
|
74
|
+
("Number of Passengers", Units.Count),
|
|
75
|
+
("Number of Seats Abreast", Units.Count),
|
|
76
|
+
("Number of Rows", Units.Count),
|
|
77
|
+
("Number of Seats", Units.Count),
|
|
78
|
+
("Seat Width", Units.Length),
|
|
79
|
+
("Seat Arm Rest Width", Units.Length),
|
|
80
|
+
("Seat Length", Units.Length),
|
|
81
|
+
("Seat Pitch", Units.Length),
|
|
82
|
+
("Aisle Width", Units.Length)
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
self.data_entry_widget = DataEntryWidget(self.data_units_labels)
|
|
86
|
+
|
|
87
|
+
#adding data entry widget (labels) to main layout
|
|
88
|
+
main_layout.addWidget(self.data_entry_widget)
|
|
89
|
+
|
|
90
|
+
# Add horizontal bar
|
|
91
|
+
line_bar = QFrame()
|
|
92
|
+
line_bar.setFrameShape(QFrame.Shape.HLine)
|
|
93
|
+
line_bar.setFrameShadow(QFrame.Shadow.Sunken)
|
|
94
|
+
main_layout.addWidget(line_bar)
|
|
95
|
+
#loading data if provided
|
|
96
|
+
if section_data:
|
|
97
|
+
self.load_data_values(section_data)
|
|
98
|
+
|
|
99
|
+
self.setLayout(main_layout)
|
|
100
|
+
|
|
101
|
+
def create_rcaide_structure(self, data):
|
|
102
|
+
#creating the correct class type based on user selection
|
|
103
|
+
class_type = data.get("class_type", self.class_type_combo.currentText())
|
|
104
|
+
if class_type == "Economy":
|
|
105
|
+
classtype = RCAIDE.Library.Components.Fuselages.Cabins.Classes.Economy()
|
|
106
|
+
elif class_type == "Business":
|
|
107
|
+
classtype = RCAIDE.Library.Components.Fuselages.Cabins.Classes.Business()
|
|
108
|
+
elif class_type == "First":
|
|
109
|
+
classtype = RCAIDE.Library.Components.Fuselages.Cabins.Classes.First()
|
|
110
|
+
else:
|
|
111
|
+
classtype = RCAIDE.Library.Components.Fuselages.Cabins.Classes.Economy()
|
|
112
|
+
#economy is default
|
|
113
|
+
|
|
114
|
+
#setting all values from data entry to the rcaide structure
|
|
115
|
+
classtype.number_of_passengers = int(data["Number of Passengers"][0])
|
|
116
|
+
seats_abreast = int(data["Number of Seats Abreast"][0])
|
|
117
|
+
number_of_rows = int(data["Number of Rows"][0])
|
|
118
|
+
number_of_seats = int(data["Number of Seats"][0])
|
|
119
|
+
# Infer missing seat/row counts for LOPA.
|
|
120
|
+
if number_of_seats <= 0 and seats_abreast > 0 and number_of_rows > 0:
|
|
121
|
+
number_of_seats = seats_abreast * number_of_rows
|
|
122
|
+
if number_of_rows <= 0 and seats_abreast > 0 and number_of_seats > 0:
|
|
123
|
+
number_of_rows = math.ceil(number_of_seats / seats_abreast)
|
|
124
|
+
if seats_abreast > 0 and number_of_seats > seats_abreast * number_of_rows:
|
|
125
|
+
number_of_rows = math.ceil(number_of_seats / seats_abreast)
|
|
126
|
+
# RCAIDE/LOPA reads `abrest`; keep both spellings.
|
|
127
|
+
classtype.number_of_seats_abrest = seats_abreast
|
|
128
|
+
classtype.number_of_seats_abreast = seats_abreast
|
|
129
|
+
classtype.number_of_rows = number_of_rows
|
|
130
|
+
classtype.number_of_seats = number_of_seats
|
|
131
|
+
classtype.seat_width = data["Seat Width"][0]
|
|
132
|
+
classtype.seat_arm_rest_width = data["Seat Arm Rest Width"][0]
|
|
133
|
+
classtype.seat_length = data["Seat Length"][0]
|
|
134
|
+
classtype.seat_pitch = data["Seat Pitch"][0]
|
|
135
|
+
classtype.aisle_width = data["Aisle Width"][0]
|
|
136
|
+
|
|
137
|
+
# Restore hidden RCAIDE fields.
|
|
138
|
+
for key, value in data.items():
|
|
139
|
+
if key not in self.visible_data_keys:
|
|
140
|
+
setattr(classtype, key, self._unwrap_value(value))
|
|
141
|
+
|
|
142
|
+
return classtype
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def _unwrap_value(value):
|
|
146
|
+
if (
|
|
147
|
+
isinstance(value, list)
|
|
148
|
+
and len(value) == 2
|
|
149
|
+
and isinstance(value[1], int)
|
|
150
|
+
and not isinstance(value[1], bool)
|
|
151
|
+
):
|
|
152
|
+
return value[0]
|
|
153
|
+
return value
|
|
154
|
+
|
|
155
|
+
def get_data_values(self):
|
|
156
|
+
#getting data from data entry widget
|
|
157
|
+
data = self.data_entry_widget.get_values()
|
|
158
|
+
data_si = self.data_entry_widget.get_values_si()
|
|
159
|
+
selected_type = self.class_type_combo.currentText()
|
|
160
|
+
#setting class type in data
|
|
161
|
+
data_si["class_type"] = selected_type
|
|
162
|
+
data["class_type"] = selected_type
|
|
163
|
+
# Preserve hidden fields in both data forms.
|
|
164
|
+
data.update(self.preserved_data)
|
|
165
|
+
data_si.update(self.preserved_data)
|
|
166
|
+
classtype = self.create_rcaide_structure(data_si)
|
|
167
|
+
data["Number of Rows"] = [classtype.number_of_rows, 0]
|
|
168
|
+
data["Number of Seats"] = [classtype.number_of_seats, 0]
|
|
169
|
+
data_si["Number of Rows"] = [classtype.number_of_rows, 0]
|
|
170
|
+
data_si["Number of Seats"] = [classtype.number_of_seats, 0]
|
|
171
|
+
return data, classtype
|
|
172
|
+
|
|
173
|
+
def load_data_values(self, section_data):
|
|
174
|
+
#loading data into data entry widget and setting class type
|
|
175
|
+
# Save hidden fields for round-trip.
|
|
176
|
+
self.preserved_data = {
|
|
177
|
+
key: value
|
|
178
|
+
for key, value in section_data.items()
|
|
179
|
+
if key not in self.visible_data_keys
|
|
180
|
+
}
|
|
181
|
+
self.data_entry_widget.load_data(section_data)
|
|
182
|
+
if "class_type" in section_data:
|
|
183
|
+
self.class_type_combo.setCurrentText(section_data["class_type"])
|
|
184
|
+
|
|
185
|
+
def delete_clicked(self):
|
|
186
|
+
#calling on_delete callback when delete button is pressed
|
|
187
|
+
if self.on_delete:
|
|
188
|
+
self.on_delete(self.index)
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/fuselages/cabin_widget.py
|
|
2
|
+
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
# ------------------------------------------------------------------------------
|
|
5
|
+
# Imports
|
|
6
|
+
# ------------------------------------------------------------------------------
|
|
7
|
+
import RCAIDE
|
|
8
|
+
from PyQt6.QtWidgets import (QHBoxLayout, QLabel,
|
|
9
|
+
QLineEdit, QPushButton, QSizePolicy, QSpacerItem,
|
|
10
|
+
QVBoxLayout, QWidget, QFrame)
|
|
11
|
+
|
|
12
|
+
from utilities import Units, clear_layout
|
|
13
|
+
from common_widgets import DataEntryWidget
|
|
14
|
+
from tabs.geometry.widgets.fuselages.cabin_class_widget import CabinClassWidget
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CabinWidget(QWidget):
|
|
18
|
+
# Visible fields; preserve everything else.
|
|
19
|
+
visible_data_keys = {
|
|
20
|
+
"Cabin Name",
|
|
21
|
+
"cabin_type",
|
|
22
|
+
"Number of Passengers",
|
|
23
|
+
"Number of Seats",
|
|
24
|
+
"Type A Door Length",
|
|
25
|
+
"Galley Lavatory Length",
|
|
26
|
+
"Emergency Exit Seat Pitch",
|
|
27
|
+
"Length",
|
|
28
|
+
"Width",
|
|
29
|
+
"Height",
|
|
30
|
+
"Wide Body",
|
|
31
|
+
"classes",
|
|
32
|
+
"tag",
|
|
33
|
+
"number_of_passengers",
|
|
34
|
+
"number_of_seats",
|
|
35
|
+
"type_a_door_length",
|
|
36
|
+
"galley_lavatory_length",
|
|
37
|
+
"emergency_exit_seat_pitch",
|
|
38
|
+
"length",
|
|
39
|
+
"width",
|
|
40
|
+
"height",
|
|
41
|
+
"wide_body",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def __init__(self, index, on_delete, section_data=None, cabin_type="Regular"):
|
|
45
|
+
super(CabinWidget, self).__init__()
|
|
46
|
+
self.index = index
|
|
47
|
+
self.on_delete = on_delete
|
|
48
|
+
self.cabin_type = cabin_type
|
|
49
|
+
self.data_entry_widget: DataEntryWidget | None = None
|
|
50
|
+
self.name_layout = QHBoxLayout()
|
|
51
|
+
self.classes_layout = QVBoxLayout()
|
|
52
|
+
# Hidden fields restored on save.
|
|
53
|
+
self.preserved_data = {}
|
|
54
|
+
self.init_ui(section_data)
|
|
55
|
+
|
|
56
|
+
# noinspection DuplicatedCode
|
|
57
|
+
def init_ui(self, section_data):
|
|
58
|
+
main_layout = QVBoxLayout()
|
|
59
|
+
type_label = QLabel(f"<b>Type: {self.cabin_type} Cabin</b>")
|
|
60
|
+
main_layout.addWidget(type_label)
|
|
61
|
+
# add spacing
|
|
62
|
+
spacer_left = QSpacerItem(80, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
63
|
+
spacer_right = QSpacerItem(300, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
64
|
+
self.name_layout.addItem(spacer_left)
|
|
65
|
+
self.name_layout.addWidget(QLabel("Cabin Name: "))
|
|
66
|
+
self.name_layout.addWidget(QLineEdit(self))
|
|
67
|
+
self.name_layout.addItem(spacer_right)
|
|
68
|
+
|
|
69
|
+
main_layout.addLayout(self.name_layout)
|
|
70
|
+
|
|
71
|
+
# List of data labels
|
|
72
|
+
data_units_labels = [
|
|
73
|
+
("Number of Passengers", Units.Count),
|
|
74
|
+
("Number of Seats", Units.Count),
|
|
75
|
+
("Type A Door Length", Units.Length),
|
|
76
|
+
("Galley Lavatory Length", Units.Length),
|
|
77
|
+
("Emergency Exit Seat Pitch", Units.Length),
|
|
78
|
+
("Length", Units.Length),
|
|
79
|
+
("Width", Units.Length),
|
|
80
|
+
("Height", Units.Length),
|
|
81
|
+
("Wide Body", Units.Boolean)
|
|
82
|
+
#potentially add the "filled seats arrangement" option later
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
self.data_entry_widget = DataEntryWidget(data_units_labels)
|
|
86
|
+
main_layout.addWidget(self.data_entry_widget)
|
|
87
|
+
|
|
88
|
+
main_layout.addWidget(QLabel("<b>Cabin Classes</b>"))
|
|
89
|
+
add_class_button = QPushButton("Add Cabin Class")
|
|
90
|
+
add_class_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
91
|
+
add_class_button.clicked.connect(self.add_cabin_class)
|
|
92
|
+
main_layout.addWidget(add_class_button)
|
|
93
|
+
main_layout.addLayout(self.classes_layout)
|
|
94
|
+
|
|
95
|
+
# Add horizontal bar
|
|
96
|
+
line_bar = QFrame()
|
|
97
|
+
line_bar.setFrameShape(QFrame.Shape.HLine)
|
|
98
|
+
line_bar.setFrameShadow(QFrame.Shadow.Sunken)
|
|
99
|
+
main_layout.addWidget(line_bar)
|
|
100
|
+
|
|
101
|
+
delete_button = QPushButton("Delete Cabin", self)
|
|
102
|
+
delete_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
103
|
+
delete_button.clicked.connect(self.delete_button_pressed)
|
|
104
|
+
# center delete button
|
|
105
|
+
delete_button_layout = QHBoxLayout()
|
|
106
|
+
delete_button_layout.addItem(QSpacerItem(50, 5, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum))
|
|
107
|
+
delete_button_layout.addWidget(delete_button)
|
|
108
|
+
delete_button_layout.addItem(QSpacerItem(50, 5, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum))
|
|
109
|
+
main_layout.addLayout(delete_button_layout)
|
|
110
|
+
|
|
111
|
+
self.setLayout(main_layout)
|
|
112
|
+
|
|
113
|
+
if section_data:
|
|
114
|
+
self.load_data_values(section_data)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def add_cabin_class(self):
|
|
119
|
+
widget = CabinClassWidget(self.classes_layout.count(), self.delete_cabin_class)
|
|
120
|
+
self.classes_layout.addWidget(widget)
|
|
121
|
+
|
|
122
|
+
def delete_cabin_class(self, index):
|
|
123
|
+
item = self.classes_layout.itemAt(index)
|
|
124
|
+
if item:
|
|
125
|
+
widget = item.widget()
|
|
126
|
+
if widget:
|
|
127
|
+
widget.deleteLater()
|
|
128
|
+
self.classes_layout.removeWidget(widget)
|
|
129
|
+
self.classes_layout.update()
|
|
130
|
+
for i in range(self.classes_layout.count()):
|
|
131
|
+
item = self.classes_layout.itemAt(i)
|
|
132
|
+
if item and item.widget():
|
|
133
|
+
item.widget().index = i
|
|
134
|
+
|
|
135
|
+
def create_rcaide_structure(self, data):
|
|
136
|
+
if self.cabin_type == "Side":
|
|
137
|
+
cabin = RCAIDE.Library.Components.Fuselages.Cabins.Side_Cabin()
|
|
138
|
+
|
|
139
|
+
else:
|
|
140
|
+
cabin = RCAIDE.Library.Components.Fuselages.Cabins.Cabin()
|
|
141
|
+
|
|
142
|
+
cabin.tag = data["Cabin Name"]
|
|
143
|
+
cabin.number_of_passengers = int(data["Number of Passengers"][0])
|
|
144
|
+
cabin.number_of_seats = int(data["Number of Seats"][0])
|
|
145
|
+
cabin.type_a_door_length = data["Type A Door Length"][0]
|
|
146
|
+
cabin.galley_lavatory_length = data["Galley Lavatory Length"][0]
|
|
147
|
+
cabin.emergency_exit_seat_pitch = data["Emergency Exit Seat Pitch"][0]
|
|
148
|
+
cabin.length = data["Length"][0]
|
|
149
|
+
cabin.width = data["Width"][0]
|
|
150
|
+
cabin.height = data["Height"][0]
|
|
151
|
+
cabin.wide_body = data["Wide Body"][0]
|
|
152
|
+
|
|
153
|
+
# Restore hidden RCAIDE fields.
|
|
154
|
+
for key, value in data.items():
|
|
155
|
+
if key not in self.visible_data_keys:
|
|
156
|
+
setattr(cabin, key, self._unwrap_value(value))
|
|
157
|
+
|
|
158
|
+
return cabin
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
def _unwrap_value(value):
|
|
162
|
+
if (
|
|
163
|
+
isinstance(value, list)
|
|
164
|
+
and len(value) == 2
|
|
165
|
+
and isinstance(value[1], int)
|
|
166
|
+
and not isinstance(value[1], bool)
|
|
167
|
+
):
|
|
168
|
+
return value[0]
|
|
169
|
+
return value
|
|
170
|
+
|
|
171
|
+
def get_data_values(self):
|
|
172
|
+
data = self.data_entry_widget.get_values()
|
|
173
|
+
data_si = self.data_entry_widget.get_values_si()
|
|
174
|
+
data["Cabin Name"] = self.name_layout.itemAt(2).widget().text()
|
|
175
|
+
data["cabin_type"] = self.cabin_type
|
|
176
|
+
data_si["Cabin Name"] = self.name_layout.itemAt(2).widget().text()
|
|
177
|
+
data_si["cabin_type"] = self.cabin_type
|
|
178
|
+
# Preserve hidden fields in both data forms.
|
|
179
|
+
data.update(self.preserved_data)
|
|
180
|
+
data_si.update(self.preserved_data)
|
|
181
|
+
cabin_object = self.create_rcaide_structure(data_si)
|
|
182
|
+
|
|
183
|
+
data["classes"] = []
|
|
184
|
+
for i in range(self.classes_layout.count()):
|
|
185
|
+
item = self.classes_layout.itemAt(i)
|
|
186
|
+
if item and item.widget():
|
|
187
|
+
class_widget = item.widget()
|
|
188
|
+
class_data, class_object = class_widget.get_data_values()
|
|
189
|
+
data["classes"].append(class_data)
|
|
190
|
+
if hasattr(cabin_object, "append_cabin_class"):
|
|
191
|
+
cabin_object.append_cabin_class(class_object)
|
|
192
|
+
else:
|
|
193
|
+
cabin_object.classes.append(class_object)
|
|
194
|
+
|
|
195
|
+
return data, cabin_object
|
|
196
|
+
|
|
197
|
+
def load_data_values(self, section_data):
|
|
198
|
+
# Save hidden fields for round-trip.
|
|
199
|
+
self.preserved_data = {
|
|
200
|
+
key: value
|
|
201
|
+
for key, value in section_data.items()
|
|
202
|
+
if key not in self.visible_data_keys
|
|
203
|
+
}
|
|
204
|
+
self.data_entry_widget.load_data(section_data)
|
|
205
|
+
self.name_layout.itemAt(2).widget().setText(section_data["Cabin Name"])
|
|
206
|
+
if "cabin_type" in section_data:
|
|
207
|
+
self.cabin_type = section_data["cabin_type"]
|
|
208
|
+
self.layout().itemAt(0).widget().setText(f"<b>Type: {self.cabin_type} Cabin</b>")
|
|
209
|
+
clear_layout(self.classes_layout)
|
|
210
|
+
if "classes" in section_data:
|
|
211
|
+
for class_data in section_data["classes"]:
|
|
212
|
+
class_widget = CabinClassWidget(self.classes_layout.count(), self.delete_cabin_class, class_data)
|
|
213
|
+
self.classes_layout.addWidget(class_widget)
|
|
214
|
+
|
|
215
|
+
def delete_button_pressed(self):
|
|
216
|
+
if self.on_delete:
|
|
217
|
+
self.on_delete(self.index)
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/fuselages/fuselage_section_widget.py
|
|
2
|
+
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
# ------------------------------------------------------------------------------
|
|
5
|
+
# Imports
|
|
6
|
+
# ------------------------------------------------------------------------------
|
|
7
|
+
# RCAIDE imports
|
|
8
|
+
import RCAIDE
|
|
9
|
+
|
|
10
|
+
# RCAIDE GUI imports
|
|
11
|
+
from utilities import Units
|
|
12
|
+
from common_widgets import DataEntryWidget
|
|
13
|
+
|
|
14
|
+
# PyQT imports
|
|
15
|
+
from PyQt6.QtWidgets import QHBoxLayout, QLabel,QLineEdit, QPushButton, QSizePolicy, QSpacerItem,QVBoxLayout, QWidget, QFrame, QComboBox
|
|
16
|
+
from PyQt6.QtCore import Qt
|
|
17
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
18
|
+
# Fuselage Segment Widget
|
|
19
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
20
|
+
class FuselageSectionWidget(QWidget):
|
|
21
|
+
def __init__(self, index, on_delete, section_data=None):
|
|
22
|
+
super(FuselageSectionWidget, self).__init__()
|
|
23
|
+
|
|
24
|
+
# self.data_fields = {}
|
|
25
|
+
self.coordinate_filename = ""
|
|
26
|
+
self.index = index
|
|
27
|
+
self.on_delete = on_delete
|
|
28
|
+
self.data_entry_widget: DataEntryWidget | None = None
|
|
29
|
+
|
|
30
|
+
self.name_layout = QHBoxLayout()
|
|
31
|
+
self.init_ui(section_data)
|
|
32
|
+
|
|
33
|
+
# noinspection DuplicatedCode
|
|
34
|
+
def init_ui(self, section_data):
|
|
35
|
+
main_layout = QVBoxLayout()
|
|
36
|
+
# add spacing
|
|
37
|
+
spacer_left = QSpacerItem(80, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
38
|
+
spacer_right = QSpacerItem(300, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
39
|
+
self.name_layout.addItem(spacer_left)
|
|
40
|
+
self.name_layout.addWidget(QLabel("Segment Name: "))
|
|
41
|
+
self.segment_name_input = QLineEdit(self)
|
|
42
|
+
self.segment_name_input.setFixedWidth(200)
|
|
43
|
+
self.name_layout.addWidget(self.segment_name_input)
|
|
44
|
+
self.name_layout.addItem(spacer_right)
|
|
45
|
+
|
|
46
|
+
## Energy Network
|
|
47
|
+
segment_label = QLabel("Segment Type:")
|
|
48
|
+
segment_label.setFixedWidth(100) # Adjust width of label
|
|
49
|
+
self.name_layout.addWidget(segment_label)
|
|
50
|
+
self.fuselage_segment_combo = QComboBox()
|
|
51
|
+
self.fuselage_segment_combo.addItems(["Circle Segment", "Ellipse Segment", "Rounded Rectangle Segment", "Super Ellipse Segment" , "Segment"])
|
|
52
|
+
self.fuselage_segment_combo.setFixedWidth(400) # Fix width of combo box
|
|
53
|
+
self.name_layout.addWidget(self.fuselage_segment_combo, alignment=Qt.AlignmentFlag.AlignLeft)
|
|
54
|
+
# Connect signal
|
|
55
|
+
# self.fuselage_segment_combo.currentIndexChanged.connect(self.display_selected_segment)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
main_layout.addLayout(self.name_layout)
|
|
59
|
+
|
|
60
|
+
# List of data labels
|
|
61
|
+
data_units_labels = [
|
|
62
|
+
("Percent X Location", Units.Unitless),
|
|
63
|
+
("Percent Z Location", Units.Unitless),
|
|
64
|
+
("Height", Units.Length),
|
|
65
|
+
("Width", Units.Length),
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
self.data_entry_widget = DataEntryWidget(data_units_labels)
|
|
69
|
+
delete_button = QPushButton("Delete Segment", self)
|
|
70
|
+
delete_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
71
|
+
# delete_button.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
|
72
|
+
# delete_button.setFixedWidth(150)
|
|
73
|
+
delete_button.clicked.connect(self.delete_button_pressed)
|
|
74
|
+
# center delete button
|
|
75
|
+
delete_button_layout = QHBoxLayout()
|
|
76
|
+
delete_button_layout.addItem(QSpacerItem(50, 5, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum))
|
|
77
|
+
delete_button_layout.addWidget(delete_button)
|
|
78
|
+
delete_button_layout.addItem(QSpacerItem(50, 5, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum))
|
|
79
|
+
|
|
80
|
+
main_layout.addWidget(self.data_entry_widget)
|
|
81
|
+
main_layout.addLayout(delete_button_layout)
|
|
82
|
+
|
|
83
|
+
# Add horizontal bar
|
|
84
|
+
line_bar = QFrame()
|
|
85
|
+
line_bar.setFrameShape(QFrame.Shape.HLine)
|
|
86
|
+
line_bar.setFrameShadow(QFrame.Shadow.Sunken)
|
|
87
|
+
main_layout.addWidget(line_bar)
|
|
88
|
+
|
|
89
|
+
self.setLayout(main_layout)
|
|
90
|
+
|
|
91
|
+
if section_data:
|
|
92
|
+
self.load_data_values(section_data)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def create_rcaide_structure(self, data):
|
|
97
|
+
|
|
98
|
+
selected_segment = self.fuselage_segment_combo.currentText()
|
|
99
|
+
segment = None
|
|
100
|
+
|
|
101
|
+
#if selected_segment == "Ellipse Segment":
|
|
102
|
+
#item = self.powertrain_layout.itemAt(0)
|
|
103
|
+
#assert item is not None
|
|
104
|
+
#widget = item.widget()
|
|
105
|
+
#assert widget is not None and isinstance(widget, PowertrainWidget)
|
|
106
|
+
#_, lines, propulsors,converters = widget.get_data_values()
|
|
107
|
+
|
|
108
|
+
if selected_segment == "Circle Segment":
|
|
109
|
+
segment = RCAIDE.Library.Components.Fuselages.Segments.Circle_Segment()
|
|
110
|
+
segment.percent_x_location = data["Percent X Location"][0]
|
|
111
|
+
segment.percent_z_location = data["Percent Z Location"][0]
|
|
112
|
+
segment.height = data["Height"][0]
|
|
113
|
+
segment.width = data["Width"][0]
|
|
114
|
+
segment.tag = data["Segment Name"]
|
|
115
|
+
elif selected_segment == "Ellipse Segment":
|
|
116
|
+
segment = RCAIDE.Library.Components.Fuselages.Segments.Ellipse_Segment()
|
|
117
|
+
segment.percent_x_location = data["Percent X Location"][0]
|
|
118
|
+
segment.percent_z_location = data["Percent Z Location"][0]
|
|
119
|
+
segment.height = data["Height"][0]
|
|
120
|
+
segment.width = data["Width"][0]
|
|
121
|
+
segment.tag = data["Segment Name"]
|
|
122
|
+
elif selected_segment == "Rounded Rectangle Segment":
|
|
123
|
+
segment = RCAIDE.Library.Components.Fuselages.Segments.Rounded_Rectangle_Segment()
|
|
124
|
+
segment.percent_x_location = data["Percent X Location"][0]
|
|
125
|
+
segment.percent_z_location = data["Percent Z Location"][0]
|
|
126
|
+
segment.height = data["Height"][0]
|
|
127
|
+
segment.width = data["Width"][0]
|
|
128
|
+
segment.tag = data["Segment Name"]
|
|
129
|
+
elif selected_segment == "Super Ellipse Segment":
|
|
130
|
+
segment = RCAIDE.Library.Components.Fuselages.Segments.Super_Ellipse_Segment()
|
|
131
|
+
segment.percent_x_location = data["Percent X Location"][0]
|
|
132
|
+
segment.percent_z_location = data["Percent Z Location"][0]
|
|
133
|
+
segment.height = data["Height"][0]
|
|
134
|
+
segment.width = data["Width"][0]
|
|
135
|
+
segment.tag = data["Segment Name"]
|
|
136
|
+
elif selected_segment == "Segment":
|
|
137
|
+
segment = RCAIDE.Library.Components.Fuselages.Segments.Segment()
|
|
138
|
+
segment.percent_x_location = data["Percent X Location"][0]
|
|
139
|
+
segment.percent_z_location = data["Percent Z Location"][0]
|
|
140
|
+
segment.height = data["Height"][0]
|
|
141
|
+
segment.width = data["Width"][0]
|
|
142
|
+
segment.tag = data["Segment Name"]
|
|
143
|
+
else:
|
|
144
|
+
segment = None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
return segment
|
|
148
|
+
|
|
149
|
+
def get_data_values(self):
|
|
150
|
+
data = self.data_entry_widget.get_values()
|
|
151
|
+
data_si = self.data_entry_widget.get_values_si()
|
|
152
|
+
data["Segment Name"] = self.name_layout.itemAt(2).widget().text()
|
|
153
|
+
data_si["Segment Name"] = self.name_layout.itemAt(2).widget().text()
|
|
154
|
+
selected_type = self.fuselage_segment_combo.currentText()
|
|
155
|
+
data["segment_type"] = selected_type
|
|
156
|
+
data_si["segment_type"] = selected_type
|
|
157
|
+
segment = self.create_rcaide_structure(data_si)
|
|
158
|
+
return data, segment
|
|
159
|
+
|
|
160
|
+
def load_data_values(self, section_data):
|
|
161
|
+
self.data_entry_widget.load_data(section_data)
|
|
162
|
+
self.name_layout.itemAt(2).widget().setText(section_data["Segment Name"])
|
|
163
|
+
|
|
164
|
+
if "segment_type" in section_data:
|
|
165
|
+
index = self.fuselage_segment_combo.findText(section_data["segment_type"])
|
|
166
|
+
if index>=0:
|
|
167
|
+
self.fuselage_segment_combo.setCurrentIndex(index)
|
|
168
|
+
|
|
169
|
+
def delete_button_pressed(self):
|
|
170
|
+
if self.on_delete is None:
|
|
171
|
+
print("on_delete is None")
|
|
172
|
+
return
|
|
173
|
+
|
|
174
|
+
self.on_delete(self.index)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def display_selected_segment(self, index):
|
|
178
|
+
selected_fuselage_segmemt = self.fuselage_segment_combo.currentText()
|
|
179
|
+
# Clear the layout first
|
|
180
|
+
clear_layout(self.powertrain_layout)
|
|
181
|
+
|
|
182
|
+
if selected_fuselage_segmemt == "Fuel":
|
|
183
|
+
self.main_powertrain_widget = PowertrainWidget()
|
|
184
|
+
self.powertrain_layout.addWidget(self.main_powertrain_widget)
|
|
185
|
+
elif selected_fuselage_segmemt == "None Selected":
|
|
186
|
+
# Do nothing or add blank widget
|
|
187
|
+
pass
|
|
188
|
+
else:
|
|
189
|
+
# Handle other energy network options here
|
|
190
|
+
pass
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/geometry_data_widget.py
|
|
2
|
+
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
# ------------------------------------------------------------------------------
|
|
5
|
+
# Imports
|
|
6
|
+
# ------------------------------------------------------------------------------
|
|
7
|
+
from PyQt6.QtWidgets import QWidget
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GeometryDataWidget(QWidget):
|
|
11
|
+
def __init__(self):
|
|
12
|
+
super(GeometryDataWidget, self).__init__()
|
|
13
|
+
|
|
14
|
+
def create_rcaide_structure(self, data):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
# Should return the data array AND the RCAIDE structure for the widget
|
|
18
|
+
def get_data_values(self):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
def load_data_values(self, data):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
def delete_button_pressed(self):
|
|
25
|
+
pass
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/fuselages/__init__.py
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
3
|
+
# IMPORT
|
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/nacelles/__init__.py
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/powertrain/__init__.py
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
3
|
+
# IMPORT
|
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
from tabs.geometry.frames.powertrain.converters import *
|
|
7
|
+
from tabs.geometry.frames.powertrain.sources import *
|
|
8
|
+
from tabs.geometry.frames.powertrain.propulsors import *
|
|
9
|
+
from tabs.geometry.frames.powertrain.distributors import *
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/widgets/powertrain/converters/__init__.py
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
3
|
+
# IMPORT
|
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
from tabs.geometry.widgets.powertrain.converters.turboelectric_generator_widget import TurboelectricGeneratorWidget
|