15 #define _CRT_SECURE_NO_DEPRECATE
16 #define _CRT_SECURE_NO_WARNINGS
17 #pragma warning(disable : 4067)
18 #pragma warning(disable : 4333)
19 #pragma warning(disable : 4312)
23 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
24 #pragma GCC diagnostic ignored "-Wformat-security"
27 #if defined(__clang__)
28 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
29 #pragma GCC diagnostic ignored "-Wformat-security"
35 inline T
pw(T val, T power)
37 return copysign(1.0, val) * pow(abs(val), power);
40 namespace cmap = tinycolormap;
45 static_cast<std::underlying_type_t<GIM_Flags>
>(lhs) |
46 static_cast<std::underlying_type_t<GIM_Flags>
>(rhs));
52 static_cast<std::underlying_type_t<GIM_Flags>
>(lhs) &
53 static_cast<std::underlying_type_t<GIM_Flags>
>(rhs));
59 return static_cast<bool>(flags & flag);
72 for (
int y = 0; y < ny; y++)
74 for (
int x = 0; x < nx; x++)
86 int last_yt = (last_idr / nx);
89 set_min_max(last_idr);
90 for (
int y = (std::max)(0, this->last_y - render_update_offset); y < (std::min)(last_yt + render_update_offset, ny); y++)
92 for (
int x = 0; x < nx; x++)
98 this->last_y = last_yt;
99 this->last_idr = last_idr;
106 int idr = idy * nx + idx;
107 float val =
pw((data->at(idr) - data_min) / data_range, power);
117 int idr = idy * nx + idx;
120 float mag = (abs(data->at(idr)) - data_min) / data_range;
121 float ang = arg(data->at(idr));
122 ang = (ang / M_PI + 1) / 2;
123 mag =
pw(mag, power);
138 return abs((*data)[idr]);
141 template <
typename T>
144 for (
int idr = this->last_idr; idr < last_idr; idr++)
146 float val = get_val(idr);
150 data_range = data_max - data_min;
151 b_trigger_update =
true;
156 data_range = data_max - data_min;
157 b_trigger_update =
true;
162 template <
typename T>
165 for (
int idr = 0; idr < nxy; idr++)
167 float val = get_val(idr);
171 data_range = data_max - data_min;
172 b_trigger_update =
true;
177 data_range = data_max - data_min;
178 b_trigger_update =
true;
183 template <
typename T>
189 this->tex_id = tex_id;
190 this->pb_open = visible;
191 this->auto_render = auto_render;
192 this->data_cmap = data_cmap;
201 this->render_update_offset = 0;
202 this->b_trigger_update =
false;
203 saveFileDialog = ImGui::FileBrowser(ImGuiFileBrowserFlags_EnterNewFilename | ImGuiFileBrowserFlags_CreateNewDir);
204 saveFileDialog.SetTitle(
"Save " + title +
" image as .png");
205 saveDataDialog = ImGui::FileBrowser(ImGuiFileBrowserFlags_EnterNewFilename | ImGuiFileBrowserFlags_CreateNewDir);
206 saveDataDialog.SetTitle(
"Save " + title +
"-data as numpy array (.npy)");
208 uv_min = ImVec2(0.0f, 0.0f);
209 uv_max = ImVec2(1.0f, 1.0f);
210 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
211 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
212 sdl_srf = SDL_CreateRGBSurface(0, this->nx, this->ny, 32, 0, 0, 0, 0);
215 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
217 this->b_data_set =
false;
220 template <
typename T>
224 set_nx_ny(width, height);
233 template <
typename T>
241 data_range = FLT_MAX;
244 template <
typename T>
249 this->nxy = height * width;
251 data_fft.resize(nxy);
252 data_fft_f.resize(nxy);
253 data_val.resize(nxy);
257 sdl_srf = SDL_CreateRGBSurface(0, this->nx, this->ny, 32, 0, 0, 0, 0);
260 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
264 template <
typename T>
267 this->render_update_offset = render_update_offset;
268 render_window(b_redraw, last_y, b_trigger_update);
271 template <
typename T>
276 data_range = FLT_MAX;
283 FFT2D::r2c(*data, data_val);
284 fft2d.fft(data_val, data_fft);
285 FFT2D::c2abs(data_fft, data_fft_f);
292 fft2d.fft(*data, data_fft);
293 FFT2D::c2abs(data_fft, data_fft_f);
298 template <
typename T>
301 int n_im = (fr_count) / nxy;
311 fr_count -= (n_im * nxy);
321 val = data->at(y * nx + x);
322 ImGui::BeginTooltip();
323 ImGui::Text(
"XY: %i, %i", x, y);
324 ImGui::Text(
"Value: %.2f", val);
325 ImGui::Text(
"Zoom: %.2f", zoom);
332 std::complex<float> val = 0.0;
334 val = data->at(y * nx + x);
335 ImGui::BeginTooltip();
336 ImGui::Text(
"XY: %i, %i", x, y);
337 ImGui::Text(
"Angle: %.2f", arg(val));
338 ImGui::Text(
"Magnitude: %.2f", abs(val));
339 ImGui::Text(
"Zoom: %.2f", zoom);
344 template <
typename T>
347 ImGui::SetNextWindowSize(ImVec2{256, 256}, ImGuiCond_FirstUseEver);
348 bool t_open = ImGui::Begin(title.c_str(), pb_open, ImGuiWindowFlags_NoScrollbar);
351 bool fr_switch = detect_frame_switch(fr_count);
352 b_trigger_update = b_trigger_update || b_trigger_ext || fr_switch;
353 if (b_trigger_update)
361 if (ImGui::Button(
"Save Image as..."))
363 saveFileDialog.Open();
365 saveFileDialog.Display();
366 if (saveFileDialog.HasSelected())
368 std::string img_file = saveFileDialog.GetSelected().string();
369 saveFileDialog.ClearSelected();
377 if (ImGui::Button(
"Save Data as..."))
379 saveDataDialog.Open();
381 saveDataDialog.Display();
382 if (saveDataDialog.HasSelected())
384 std::string com_file = saveDataDialog.GetSelected().string();
385 saveDataDialog.ClearSelected();
393 bool fft_button_press = ImGui::Button(
"Compute FFT");
394 if (fft_button_press)
396 *fft_window->pb_open =
true;
398 if (fft_button_press || (*fft_window->pb_open && b_trigger_update))
403 fft_window->set_data(nx, ny, &data_fft_f);
404 fft_window->b_trigger_update =
true;
408 std::cout <<
"FFT was not performed, because no data was found in " + this->title +
"!" << std::endl;
416 ImGui::SetNextItemWidth(64);
417 if (ImGui::DragFloat(
"Power", &power, 0.05f, 0.05f, 2.0f,
"%.2f"))
421 render_image((fr_count == 0) ? nxy : fr_count);
422 b_trigger_update =
true;
429 ImGui::SetNextItemWidth(-1);
430 if (ImGui::Combo(
"Colormap", &data_cmap, cmaps, IM_ARRAYSIZE(cmaps)))
434 render_image((fr_count == 0) ? nxy : fr_count);
435 b_trigger_update =
true;
439 if (b_redraw && auto_render && fr_count > 0)
440 render_image(fr_count);
442 ImGui::SetNextWindowBgAlpha(0.0f);
443 ImGui::BeginChildFrame(ImGui::GetID(
"ImageFrame"), ImVec2(0.0f, 0.0f), ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
444 ImVec2 vAvail = ImGui::GetContentRegionAvail();
445 float scale = (std::min)(vAvail.x / sdl_srf->w, vAvail.y / sdl_srf->h);
446 float tex_h = sdl_srf->h * scale;
447 float tex_w = sdl_srf->w * scale;
448 float tex_h_z = tex_h * zoom;
449 float tex_w_z = tex_w * zoom;
450 if (b_redraw || b_trigger_update)
452 glBindTexture(GL_TEXTURE_2D, (*tex_id));
453 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, sdl_srf->w, sdl_srf->h, 0,
454 GL_BGRA, GL_UNSIGNED_BYTE, sdl_srf->pixels);
456 ImVec2 pos = ImGui::GetCursorScreenPos();
457 ImGui::Image((ImTextureID)(*tex_id), ImVec2(tex_w_z, tex_h_z), uv_min, uv_max, tint_col, border_col);
458 if (ImGui::IsItemHovered())
462 float dz = (float)io.MouseWheel;
463 ImVec2 xy = ImGui::GetMousePos();
466 float rel_x = xy.x - pos.x - ImGui::GetScrollX();
467 float rel_y = xy.y - pos.y - ImGui::GetScrollY();
471 if ((std::abs(dz) > 0.0f) || ImGui::IsMouseClicked(ImGuiMouseButton_Left))
475 start_xs = ImGui::GetScrollX();
476 start_ys = ImGui::GetScrollY();
480 if (ImGui::IsMouseDown(ImGuiMouseButton_Left))
482 ImGui::SetScrollX(start_xs - (rel_x - start_x));
483 ImGui::SetScrollY(start_ys - (rel_y - start_y));
487 if (std::abs(dz) > 0.0f)
490 float zoom2 = zoom + dz * 0.1;
491 zoom2 = (std::max)(1.0f, zoom2);
493 float dx = ((xy.x - pos.x) / tex_w_z) * tex_w * (zoom2 - zoom);
494 float dy = ((xy.y - pos.y) / tex_h_z) * tex_h * (zoom2 - zoom);
496 ImGui::SetScrollX(start_xs + dx);
497 ImGui::SetScrollY(start_ys + dy);
503 if (ImGui::IsMouseDown(ImGuiMouseButton_Right))
505 float scale_fct = scale * zoom;
506 int x = (int)std::floor((xy.x - pos.x) / scale_fct);
507 int y = (int)std::floor((xy.y - pos.y) / scale_fct);
508 value_tooltip(x, y, zoom);
510 if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
513 ImGui::SetScrollX(0.0f);
514 ImGui::SetScrollY(0.0f);
517 ImGui::EndChildFrame();
520 b_trigger_update =
false;
void save_numpy(std::string *path, int nx, int ny, std::vector< T > *data)
void save_image(std::string *path, SDL_Surface *sdl_srf)
GIM_Flags operator|(GIM_Flags lhs, GIM_Flags rhs)
GIM_Flags operator&(GIM_Flags lhs, GIM_Flags rhs)
ImGuiImageWindow(const std::string &title, GLuint *tex_id, bool auto_render, int data_cmap, GIM_Flags flags=GIM_Flags::None, bool *visible=nullptr)
void set_nx_ny(int width, int height)
void set_data(int width, int height, std::vector< T > *data)
void render_window(bool b_redraw, int last_y, int render_update_offset, bool b_trigger_update)
void draw_pixel(SDL_Surface *surface, int x, int y, float val, int col_map)