Physics Simulation & Visualization Tool 0.1
A C++ physics simulation engine with real-time 3D visualization
Loading...
Searching...
No Matches
ThermalInspectorWidget.cpp
Go to the documentation of this file.
2
3#include <QFormLayout>
4#include <QTabWidget>
5#include <QVBoxLayout>
6
10#include "ui/ScalarWidget.h"
11
13 auto* rootLayout = new QVBoxLayout(this);
14 rootLayout->setContentsMargins(0, 0, 0, 0);
15 rootLayout->setSpacing(0);
16
17 tabs = new QTabWidget(this);
18 rootLayout->addWidget(tabs);
19
20 setLayout(rootLayout);
21 createUiComponents();
22}
23
24Physics::PhysicsBody* ThermalInspectorWidget::getBody() const {
25 if (!selectedObject) return nullptr;
26 return selectedObject->getPhysicsBody();
27}
28
29QFormLayout* ThermalInspectorWidget::createTab(const QString& title) {
30 auto* page = new QWidget(tabs);
31 auto* layout = new QFormLayout(page);
32 layout->setContentsMargins(6, 6, 6, 6);
33 layout->setSpacing(4);
34 tabs->addTab(page, title);
35 return layout;
36}
37
38void ThermalInspectorWidget::addThermalScalar(QFormLayout* target,
39 const QString& label,
40 const ThermalGetter& get,
41 const ThermalSetter& set,
42 const QString& unit,
43 const ScalarInitializer& onInit) {
44 InspectorRow row(label, this);
45 row.addScalar(
46 [this, get]() {
47 auto* body = getBody();
48 return body ? get(body->getThermalProperties(BodyLock::NOLOCK)) : 0.0;
49 },
50 [this, set](double value) {
51 if (auto* body = getBody()) {
52 auto props = body->getThermalProperties(BodyLock::NOLOCK);
53 set(props, value);
54 body->setThermalProperty(props, BodyLock::NOLOCK);
55 }
56 },
57 unit,
58 onInit
59 );
60 target->addRow(row.getLabel(), row.getEditor());
61 rows.push_back(std::move(row));
62}
63
64void ThermalInspectorWidget::createUiComponents() {
65 auto* state = createTab("State");
66 addThermalScalar(state, "Temperature",
67 [](const ThermalProperties& props) { return props.tempK; },
68 [](ThermalProperties& props, double value) { props.tempK = value; },
69 "K");
70 addThermalScalar(state, "Heat Generation",
71 [](const ThermalProperties& props) { return props.internalHeatPower; },
72 [](ThermalProperties& props, double value) { props.internalHeatPower = value; },
73 "W",
74 [](ScalarWidget* widget) {
75 widget->setRange(-1.0e30, 1.0e30);
76 widget->setDecimals(3);
77 });
78 addThermalScalar(state, "External Flux",
79 [](const ThermalProperties& props) { return props.externalHeatFlux; },
80 [](ThermalProperties& props, double value) { props.externalHeatFlux = value; },
81 "W/m2",
82 [](ScalarWidget* widget) {
83 widget->setRange(-1.0e18, 1.0e18);
84 widget->setDecimals(3);
85 });
86 addThermalScalar(state, "Entropy",
87 [](const ThermalProperties& props) { return props.entropyJPerK; },
88 [](ThermalProperties& props, double value) { props.entropyJPerK = value; },
89 "J/K",
90 [](ScalarWidget* widget) {
91 widget->setRange(-1.0e30, 1.0e30);
92 widget->setDecimals(3);
93 });
94 addThermalScalar(state, "Reference Temp",
95 [](const ThermalProperties& props) { return props.referenceTempK; },
96 [](ThermalProperties& props, double value) { props.referenceTempK = static_cast<float>(value); },
97 "K");
98
99 auto* material = createTab("Material");
100 addThermalScalar(material, "Specific Heat",
101 [](const ThermalProperties& props) { return props.specificHeat; },
102 [](ThermalProperties& props, double value) { props.specificHeat = static_cast<float>(value); },
103 "J/(kgK)");
104 addThermalScalar(material, "Specific Heat Coeff",
105 [](const ThermalProperties& props) { return props.specificHeatTempCoeff; },
106 [](ThermalProperties& props, double value) { props.specificHeatTempCoeff = static_cast<float>(value); },
107 "1/K",
108 [](ScalarWidget* widget) {
109 widget->setRange(-1.0e3, 1.0e3);
110 widget->setDecimals(8);
111 });
112 addThermalScalar(material, "Thermal Mass",
113 [](const ThermalProperties& props) { return props.thermalMassFraction; },
114 [](ThermalProperties& props, double value) { props.thermalMassFraction = static_cast<float>(value); });
115 addThermalScalar(material, "Density",
116 [](const ThermalProperties& props) { return props.density; },
117 [](ThermalProperties& props, double value) { props.density = static_cast<float>(value); },
118 "kg/m3",
119 [](ScalarWidget* widget) {
120 widget->setRange(0.0, 1.0e12);
121 widget->setDecimals(3);
122 });
123 addThermalScalar(material, "Expansion Coeff",
124 [](const ThermalProperties& props) { return props.linearExpansionCoeff; },
125 [](ThermalProperties& props, double value) { props.linearExpansionCoeff = static_cast<float>(value); },
126 "1/K",
127 [](ScalarWidget* widget) {
128 widget->setRange(-1.0e3, 1.0e3);
129 widget->setDecimals(8);
130 });
131
132 auto* radiation = createTab("Radiation");
133 addThermalScalar(radiation, "Emissivity",
134 [](const ThermalProperties& props) { return props.emissivity; },
135 [](ThermalProperties& props, double value) { props.emissivity = static_cast<float>(value); });
136 addThermalScalar(radiation, "Emissivity Coeff",
137 [](const ThermalProperties& props) { return props.emissivityTempCoeff; },
138 [](ThermalProperties& props, double value) { props.emissivityTempCoeff = static_cast<float>(value); },
139 "1/K",
140 [](ScalarWidget* widget) {
141 widget->setRange(-1.0e3, 1.0e3);
142 widget->setDecimals(8);
143 });
144 addThermalScalar(radiation, "Absorptivity",
145 [](const ThermalProperties& props) { return props.absorptivity; },
146 [](ThermalProperties& props, double value) { props.absorptivity = static_cast<float>(value); });
147 addThermalScalar(radiation, "Absorptivity Coeff",
148 [](const ThermalProperties& props) { return props.absorptivityTempCoeff; },
149 [](ThermalProperties& props, double value) { props.absorptivityTempCoeff = static_cast<float>(value); },
150 "1/K",
151 [](ScalarWidget* widget) {
152 widget->setRange(-1.0e3, 1.0e3);
153 widget->setDecimals(8);
154 });
155
156 auto* transfer = createTab("Transfer");
157 addThermalScalar(transfer, "Convection",
158 [](const ThermalProperties& props) { return props.heatTransferCoeff; },
159 [](ThermalProperties& props, double value) { props.heatTransferCoeff = static_cast<float>(value); },
160 "W/(m2K)");
161 addThermalScalar(transfer, "Conductivity",
162 [](const ThermalProperties& props) { return props.conductivity; },
163 [](ThermalProperties& props, double value) { props.conductivity = static_cast<float>(value); },
164 "W/(mK)");
165 addThermalScalar(transfer, "Conductivity Coeff",
166 [](const ThermalProperties& props) { return props.conductivityTempCoeff; },
167 [](ThermalProperties& props, double value) { props.conductivityTempCoeff = static_cast<float>(value); },
168 "1/K",
169 [](ScalarWidget* widget) {
170 widget->setRange(-1.0e3, 1.0e3);
171 widget->setDecimals(8);
172 });
173
174 auto* phase = createTab("Phase");
175 addThermalScalar(phase, "Melting Point",
176 [](const ThermalProperties& props) { return props.meltingPoint; },
177 [](ThermalProperties& props, double value) { props.meltingPoint = static_cast<float>(value); },
178 "K");
179 addThermalScalar(phase, "Latent Fusion",
180 [](const ThermalProperties& props) { return props.latentHeatFusion; },
181 [](ThermalProperties& props, double value) { props.latentHeatFusion = static_cast<float>(value); },
182 "J/kg",
183 [](ScalarWidget* widget) {
184 widget->setRange(0.0, 1.0e12);
185 widget->setDecimals(3);
186 });
187 addThermalScalar(phase, "Fusion",
188 [](const ThermalProperties& props) { return props.fusionProgress; },
189 [](ThermalProperties& props, double value) { props.fusionProgress = static_cast<float>(value); },
190 "",
191 [](ScalarWidget* widget) {
192 widget->setRange(0.0, 1.0);
193 widget->setDecimals(4);
194 });
195 addThermalScalar(phase, "Boiling Point",
196 [](const ThermalProperties& props) { return props.boilingPoint; },
197 [](ThermalProperties& props, double value) { props.boilingPoint = static_cast<float>(value); },
198 "K");
199 addThermalScalar(phase, "Latent Vaporization",
200 [](const ThermalProperties& props) { return props.latentHeatVaporization; },
201 [](ThermalProperties& props, double value) { props.latentHeatVaporization = static_cast<float>(value); },
202 "J/kg",
203 [](ScalarWidget* widget) {
204 widget->setRange(0.0, 1.0e12);
205 widget->setDecimals(3);
206 });
207 addThermalScalar(phase, "Vaporization",
208 [](const ThermalProperties& props) { return props.vaporizationProgress; },
209 [](ThermalProperties& props, double value) { props.vaporizationProgress = static_cast<float>(value); },
210 "",
211 [](ScalarWidget* widget) {
212 widget->setRange(0.0, 1.0);
213 widget->setDecimals(4);
214 });
215}
216
218 selectedObject = object;
219
220 if (getBody()) {
221 this->setVisible(true);
222 this->setEnabled(true);
223 refresh();
224 } else {
225 this->setVisible(false);
226 }
227}
228
230 selectedObject = nullptr;
231 this->setVisible(false);
232}
233
235 if (!getBody()) {
236 this->setVisible(false);
237 return;
238 }
239
240 for (auto& row : rows) {
241 row.refresh();
242 }
243}
Abstract base class for inspector panel sections.
Physics::PhysicsBody * getPhysicsBody() const
Definition SceneObject.h:39
void unload() override
Unloads the current object and clears section state.
void load(SceneObject *object) override
Loads and binds this section to a scene object.
void refresh() override
Updates UI widgets from the current object's state.
ThermalInspectorWidget(QWidget *parent=nullptr)