SPH
ParticleProbe.cpp
Go to the documentation of this file.
4 
6 
7 inline std::string toName(const std::string& s) {
8  return capitalize(replaceAll(s, "_", " "));
9 }
10 
11 inline std::string toKey(const std::string& s) {
12  return split(s, '.').back();
13 }
14 
15 void ParticleProbe::onMenu(wxCommandEvent& UNUSED(evt)) {
16  if (!particle) {
17  return;
18  }
19 
20  if (!wxTheClipboard->Open()) {
21  return;
22  }
23  wxTheClipboard->Clear();
24 
25  for (Particle::QuantityData data : particle->getQuantities()) {
26  std::stringstream ss;
27  if (data.id == QuantityId::POSITION) {
28  if (!data.dt.empty()) {
29  ss << data.dt;
30  wxTheClipboard->SetData(new wxTextDataObject(ss.str()));
31  }
32  continue;
33  }
34  if (!data.value.empty()) {
35  std::stringstream ss;
36  ss << data.value;
37  wxTheClipboard->SetData(new wxTextDataObject(ss.str()));
38  }
39  }
40 
41  wxTheClipboard->Flush();
42  wxTheClipboard->Close();
43 }
44 
45 void ParticleProbe::onPaint(wxPaintEvent& UNUSED(evt)) {
46  wxPaintDC dc(this);
47  wxSize canvasSize = dc.GetSize();
48 
49  // draw background
50  Rgba backgroundColor = Rgba(this->GetParent()->GetBackgroundColour());
51  wxBrush brush;
52  brush.SetColour(wxColour(backgroundColor.darken(0.3f)));
53  dc.SetBrush(brush);
54  dc.DrawRectangle(wxPoint(0, 0), canvasSize);
55 
56  if (!particle) {
57  return;
58  }
59 
60  // draw colored square
61  brush.SetColour(wxColour(color));
62  dc.SetBrush(brush);
63  wxPoint offset(config.leftSkip, config.topSkip);
64  dc.DrawRectangle(offset, wxSize(15, 15));
65 
66  // particle index
67  const bool isLightTheme = backgroundColor.intensity() > 0.5_f;
68  if (isLightTheme) {
69  dc.SetTextForeground(wxColour(Rgba(0.2f, 0.2f, 0.2f)));
70  } else {
71  dc.SetTextForeground(wxColour(Rgba(0.8f, 0.8f, 0.8f)));
72  }
73  dc.DrawText("Particle " + std::to_string(particle->getIndex()), wxPoint(24, 4));
74 
75  // particle position
76  const Vector position = particle->getValue(QuantityId::POSITION);
78  dc, L"x = " + toPrintableString(position[X]), offset + wxSize(0, 1 * config.lineSkip));
80  dc, L"y = " + toPrintableString(position[Y]), offset + wxSize(0, 2 * config.lineSkip));
82  dc, L"z = " + toPrintableString(position[Z]), offset + wxSize(0, 3 * config.lineSkip));
83 
84  Dynamic velocityValue = particle->getDt(QuantityId::POSITION);
85  Dynamic accelerationValue = particle->getD2t(QuantityId::POSITION);
86  if (velocityValue) {
87  const Vector velocity = velocityValue;
88  const Size x = canvasSize.x / 2;
90  dc, L"v_x = " + toPrintableString(velocity[X]), offset + wxSize(x, 1 * config.lineSkip));
92  dc, L"v_y = " + toPrintableString(velocity[Y]), offset + wxSize(x, 2 * config.lineSkip));
94  dc, L"v_z = " + toPrintableString(velocity[Z]), offset + wxSize(x, 3 * config.lineSkip));
95  } else if (accelerationValue) {
96  const Vector acceleration = accelerationValue;
97  const Size x = canvasSize.x / 2;
99  dc, L"dv_x = " + toPrintableString(acceleration[X]), offset + wxSize(x, 1 * config.lineSkip));
101  dc, L"dv_y = " + toPrintableString(acceleration[Y]), offset + wxSize(x, 2 * config.lineSkip));
103  dc, L"dv_z = " + toPrintableString(acceleration[Z]), offset + wxSize(x, 3 * config.lineSkip));
104  }
105 
106  offset.y += 4 * config.lineSkip;
107 
108  // print other particle data
109  for (Particle::QuantityData data : particle->getQuantities()) {
110  if (data.id == QuantityId::POSITION) {
111  // skip position info, already printed
112  continue;
113  }
114 
117 
118  SPH_ASSERT(!data.value.empty());
119  const DynamicId id = data.value.getType();
120  const std::wstring label = getMetadata(data.id).label;
121  switch (id) {
122  case DynamicId::FLOAT:
125  drawTextWithSubscripts(dc, label + L" = " + toPrintableString(data.value.get<Float>()), offset);
126  offset.y += config.lineSkip;
127  break;
128  case DynamicId::SIZE:
129  drawTextWithSubscripts(dc, label + L" = " + std::to_wstring(data.value.get<Size>()), offset);
130  offset.y += config.lineSkip;
131  break;
132  case DynamicId::VECTOR: {
133  const Vector vector = data.value;
134  this->printVector(dc, vector, label, offset);
135  offset.y += 3 * config.lineSkip;
136  break;
137  }
139  const TracelessTensor tensor = data.value;
140  this->printTensor(dc, tensor, label, offset);
141  offset.y += 6 * config.lineSkip;
142  break;
143  }
145  const SymmetricTensor tensor = data.value;
146  this->printTensor(dc, tensor, label, offset);
147  offset.y += 6 * config.lineSkip;
148  break;
149  }
150 
151  default:
152  // don't throw, but don't print anything
153  break;
154  }
155  }
156 
157  for (const Particle::ParamData& data : particle->getParameters()) {
158  std::string label = BodySettings::getEntryName(data.id).value();
159  const DynamicId id = data.value.getType();
160  switch (id) {
161  case DynamicId::STRING:
162  drawTextWithSubscripts(dc, toKey(label) + " = " + toName(data.value.get<std::string>()), offset);
163  offset.y += config.lineSkip;
164  break;
165  default:
166  break;
167  }
168  }
169 }
170 
171 void ParticleProbe::printVector(wxDC& dc,
172  const Vector& v,
173  const std::wstring& label,
174  const wxPoint offset) const {
176  dc, label + L"_x = " + toPrintableString(v[X]), offset + wxSize(0, 0 * config.lineSkip));
178  dc, label + L"_y = " + toPrintableString(v[Y]), offset + wxSize(0, 1 * config.lineSkip));
180  dc, label + L"_z = " + toPrintableString(v[Z]), offset + wxSize(0, 2 * config.lineSkip));
181 }
182 
183 template <typename Type>
184 void ParticleProbe::printTensor(wxDC& dc,
185  const Type& tensor,
186  const std::wstring& label,
187  const wxPoint offset) const {
188  const Size x = dc.GetSize().x / 2;
190  dc, label + L"_xx = " + toPrintableString(tensor(X, X)), offset + wxSize(0, 0 * config.lineSkip));
192  dc, label + L"_yy = " + toPrintableString(tensor(Y, Y)), offset + wxSize(0, 1 * config.lineSkip));
194  dc, label + L"_zz = " + toPrintableString(tensor(Z, Z)), offset + wxSize(0, 2 * config.lineSkip));
196  dc, label + L"_xy = " + toPrintableString(tensor(X, Y)), offset + wxSize(x, 0 * config.lineSkip));
198  dc, label + L"_xz = " + toPrintableString(tensor(X, Z)), offset + wxSize(x, 1 * config.lineSkip));
200  dc, label + L"_yz = " + toPrintableString(tensor(Y, Z)), offset + wxSize(x, 2 * config.lineSkip));
201 }
202 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
DynamicId
Enum representing a value type stored in a Value object.
Definition: Dynamic.h:18
@ SYMMETRIC_TENSOR
@ TRACELESS_TENSOR
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
std::string toKey(const std::string &s)
NAMESPACE_SPH_BEGIN std::string toName(const std::string &s)
Frame showing information about selected particle.
QuantityMetadata getMetadata(const QuantityId key)
Returns the quantity information using quantity ID.
Definition: QuantityIds.cpp:27
Quantity identifiers.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
std::string replaceAll(const std::string &source, const std::string &old, const std::string &s)
Replaces all occurences of string with a new string.
Array< std::string > split(const std::string &s, const char delimiter)
Splits a string into an array of string using given delimiter.
std::string capitalize(const std::string &input)
Capitalizes first letters of all words in the string, except for words like 'and',...
void drawTextWithSubscripts(wxDC &dc, const std::wstring &text, const wxPoint point)
Definition: Utils.cpp:86
std::wstring toPrintableString(const Float value, const Size precision, const Float decimalThreshold)
Converts the value to a printable string.
Definition: Utils.cpp:121
@ Y
Definition: Vector.h:23
@ X
Definition: Vector.h:22
@ Z
Definition: Vector.h:24
INLINE T & back() noexcept
Definition: Array.h:176
Convenient object for storing a single value of different types.
Definition: Dynamic.h:35
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
Definition: Color.h:8
float intensity() const
Returns the average intensity of the color.
Definition: Color.h:115
Rgba darken(const float amount) const
Returns a color darker by given factor.
Definition: Color.h:137
static Optional< std::string > getEntryName(const BodySettingsId idx)
Returns the human-readable name of the entry with given index.
Definition: Settings.h:357
Symmetric tensor of 2nd order.
Symmetric traceless 2nd order tensor.
Vector position(const Float a, const Float e, const Float u)
Computes the position on the elliptic trajectory.
Definition: TwoBody.cpp:82
Vector velocity(const Float a, const Float e, const Float u, const Float n)
Computes the velocity vector on the elliptic trajectory.
Definition: TwoBody.cpp:86
Stored info about a material parameter.
Definition: Particle.h:187
Stored info about a quantity.
Definition: Particle.h:125
std::wstring label
Short designation of the quantity (i.e. 'rho', 's', ...).
Definition: QuantityIds.h:256