diff --git a/CMakeLists.txt b/CMakeLists.txt index bbecc47..357ef33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,15 +9,14 @@ project( SamplinSafari DESCRIPTION "A research tool to visualize and interactively inspect high-dimensional (quasi) Monte Carlo samplers." - # VERSION ${VERSION} - LANGUAGES C CXX) - -set(SAMPLINSAFARI_VERSION "${GIT_DESCRIBE}") + VERSION 1.1.0 + LANGUAGES C CXX + ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(SAMPLINSAFARI_VERSION "${SAMPLINSAFARI_VERSION} (64 bit)") + set(APP_BITS_VERSION "64 bit") elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(SAMPLINSAFARI_VERSION "${SAMPLINSAFARI_VERSION} (32 bit)") + set(APP_BITS_VERSION "32 bit") endif() include(sanitizers) @@ -145,10 +144,12 @@ endif() cpmaddpackage( NAME hello_imgui GITHUB_REPOSITORY wkjarosz/hello_imgui - GIT_TAG "c5121ed50314596c575ec613df93b73b39711292" + GIT_TAG "873fec179d5ccc090f166f9cddc5caeca92dfa14" OPTIONS "HELLOIMGUI_WITH_GLFW ON" - "HELLOIMGUI_WITH_TEST_ENGINE OFF") + "HELLOIMGUI_WITH_TEST_ENGINE OFF" + # "HELLOIMGUI_MACOS_NO_BUNDLE ON" + ) # ============================================================================ @@ -220,52 +221,37 @@ set_target_properties(samplerlib PROPERTIES CXX_STANDARD 17) # Now build the Samplin' Safari viewer app +string(TIMESTAMP YEAR "%Y") -# Resource file (icons etc.) -set(EXTRA_SOURCE "") -if (APPLE) - set(EXTRA_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.icns") -# elseif(WIN32) - # set(EXTRA_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.rc") -endif() - +set(output_name "Samplin Safari") set(HELLO_IMGUI_BUNDLE_IDENTIFIER_URL_PART "com.im.SamplinSafari") set(HELLO_IMGUI_BUNDLE_IDENTIFIER_NAME_PART ${app_name}) -set(HELLO_IMGUI_ICON_DISPLAY_NAME "Samplin' Safari") -set(HELLO_IMGUI_BUNDLE_NAME "Samplin' Safari") -set(HELLO_IMGUI_BUNDLE_COPYRIGHT "© Wojciech Jarosz") -set(HELLO_IMGUI_BUNDLE_EXECUTABLE ${app_name}) -set(HELLO_IMGUI_BUNDLE_VERSION ${SAMPLINSAFARI_VERSION}) +set(HELLO_IMGUI_ICON_DISPLAY_NAME ${output_name}) +set(HELLO_IMGUI_BUNDLE_NAME ${output_name}) +set(HELLO_IMGUI_BUNDLE_COPYRIGHT "© Wojciech Jarosz, ${YEAR}") +set(HELLO_IMGUI_BUNDLE_EXECUTABLE ${output_name}) +set(HELLO_IMGUI_BUNDLE_VERSION ${APP_BITS_VERSION}) +set(HELLO_IMGUI_BUNDLE_SHORT_VERSION ${PROJECT_VERSION}) set(HELLO_IMGUI_BUNDLE_ICON_FILE icon.icns) hello_imgui_add_app(SamplinSafari gui/SampleViewer.cpp gui/shader.cpp gui/gui_app.cpp - ${EXTRA_SOURCE}) + ) set_target_properties(SamplinSafari PROPERTIES - OUTPUT_NAME "SamplinSafari" - CXX_STANDARD 17) + OUTPUT_NAME ${output_name} + CXX_STANDARD 17 + ) target_link_libraries( SamplinSafari PRIVATE samplerlib linalg fmt::fmt - portable_file_dialogs) - -if (APPLE) - # Build an application bundle on OSX - set_target_properties(SamplinSafari PROPERTIES - MACOSX_BUNDLE TRUE - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/MacOSXBundleInfo.plist.in) - set_source_files_properties(resources/icon.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") -else() - # Insulate from a few types of ABI changes by statically linking against libgcc and libstdc++ - set_target_properties(SamplinSafari PROPERTIES LINK_FLAGS "-static-libgcc") -endif() - + portable_file_dialogs + ) if (UNIX AND NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG) add_custom_command(TARGET SamplinSafari POST_BUILD COMMAND strip $) diff --git a/gui/SampleViewer.cpp b/gui/SampleViewer.cpp index c239b3b..188149e 100644 --- a/gui/SampleViewer.cpp +++ b/gui/SampleViewer.cpp @@ -7,9 +7,6 @@ #include "SampleViewer.h" -#include - -namespace fs = std::filesystem; using namespace linalg::ostream_overloads; using std::cerr; @@ -198,29 +195,37 @@ SampleViewer::SampleViewer() : GUIApp() // Dockable windows // the parameter editor - HelloImGui::DockableWindow winEditor; - winEditor.label = "Editor"; - winEditor.dockSpaceName = "EditorDock"; - winEditor.canBeClosed = true; - winEditor.callBeginEnd = false; - winEditor.GuiFunction = [this] { draw_editor(); }; - - // A Log window named "Logs" will be placed in "MiscSpace". It uses the HelloImGui logger gui - HelloImGui::DockableWindow logsWindow; - logsWindow.label = "Logs"; - logsWindow.dockSpaceName = "MiscSpace"; - logsWindow.GuiFunction = [] { HelloImGui::LogGui(); }; - - m_params.dockingParams.dockableWindows = {winEditor, logsWindow}; + HelloImGui::DockableWindow editorWindow; + editorWindow.label = "Sample parameters"; + editorWindow.dockSpaceName = "EditorSpace"; + editorWindow.canBeClosed = false; + editorWindow.GuiFunction = [this] { draw_editor(); }; + + // A console window named "Console" will be placed in "ConsoleSpace". It uses the HelloImGui logger gui + HelloImGui::DockableWindow consoleWindow; + consoleWindow.label = "Console"; + consoleWindow.dockSpaceName = "ConsoleSpace"; + consoleWindow.isVisible = false; + consoleWindow.rememberIsVisible = true; + consoleWindow.GuiFunction = [] { HelloImGui::LogGui(); }; + + m_params.dockingParams.dockableWindows = {editorWindow, consoleWindow}; // Docking Splits { - HelloImGui::DockingSplit split; - split.initialDock = "MainDockSpace"; - split.newDock = "EditorDock"; - split.direction = ImGuiDir_Right; - split.ratio = 0.25f; - m_params.dockingParams.dockingSplits = {split}; + HelloImGui::DockingSplit splitEditorMain; + splitEditorMain.initialDock = "MainDockSpace"; + splitEditorMain.newDock = "EditorSpace"; + splitEditorMain.direction = ImGuiDir_Left; + splitEditorMain.ratio = 0.2f; + + HelloImGui::DockingSplit splitMainConsole; + splitMainConsole.initialDock = "MainDockSpace"; + splitMainConsole.newDock = "ConsoleSpace"; + splitMainConsole.direction = ImGuiDir_Down; + splitMainConsole.ratio = 0.25f; + + m_params.dockingParams.dockingSplits = {splitEditorMain, splitMainConsole}; } m_params.callbacks.LoadAdditionalFonts = []() @@ -291,8 +296,6 @@ int2 SampleViewer::get_draw_range() const void SampleViewer::draw_gui() { - HelloImGui::Log(HelloImGui::LogLevel::Info, "Current working directory: %s.", fs::current_path().c_str()); - m_viewport_pos_GL = m_viewport_pos = {0, 0}; m_viewport_size = m_fbsize; if (auto id = m_params.dockingParams.dockSpaceIdFromName("MainDockSpace")) @@ -338,7 +341,7 @@ void SampleViewer::draw_gui() else { for (int i = 0; i < 3; ++i) - draw_text(m_viewport_pos + m_viewport_size - int2(200, (2 - i) * 14 + 20), m_time_strings[i], + draw_text(m_viewport_pos + m_viewport_size - int2(20, (2 - i) * 14 + 20), m_time_strings[i], float4(1.0f, 1.0f, 1.0f, 0.75f), 16, 0); int2 range = get_draw_range(); @@ -373,291 +376,284 @@ void SampleViewer::draw_editor() return; } - ImGui::Begin("Sample parameters"); - { - // ========================================================= - ImGui::SeparatorText("Point set"); - // ========================================================= + // ========================================================= + ImGui::SeparatorText("Point set"); + // ========================================================= - if (ImGui::BeginCombo("##", m_samplers[m_sampler]->name().c_str())) + if (ImGui::BeginCombo("##", m_samplers[m_sampler]->name().c_str())) + { + for (int n = 0; n < NUM_POINT_TYPES; n++) { - for (int n = 0; n < NUM_POINT_TYPES; n++) + Sampler *sampler = m_samplers[n]; + const bool is_selected = (m_sampler == n); + if (ImGui::Selectable(sampler->name().c_str(), is_selected)) { - Sampler *sampler = m_samplers[n]; - const bool is_selected = (m_sampler == n); - if (ImGui::Selectable(sampler->name().c_str(), is_selected)) - { - m_sampler = n; - sampler->setJitter(m_jitter * 0.01f); - sampler->setRandomized(m_randomize); - update_GPU_points(); - update_GPU_grids(); - HelloImGui::Log(HelloImGui::LogLevel::Debug, "Switching to sampler %d: %s.", m_sampler, - sampler->name().c_str()); - } - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); + m_sampler = n; + sampler->setJitter(m_jitter * 0.01f); + sampler->setRandomized(m_randomize); + update_GPU_points(); + update_GPU_grids(); + HelloImGui::Log(HelloImGui::LogLevel::Debug, "Switching to sampler %d: %s.", m_sampler, + sampler->name().c_str()); } - ImGui::EndCombo(); - } - ImGui::SetItemTooltip("Key: Up/Down"); - if (accept_keys && !ImGui::IsKeyDown(ImGuiMod_Shift) && - (ImGui::IsKeyPressed(ImGuiKey_UpArrow) || ImGui::IsKeyPressed(ImGuiKey_DownArrow))) - { - int delta = ImGui::IsKeyPressed(ImGuiKey_DownArrow) ? 1 : -1; - m_sampler = mod(m_sampler + delta, (int)NUM_POINT_TYPES); - Sampler *sampler = m_samplers[m_sampler]; - sampler->setJitter(m_jitter * 0.01f); - sampler->setRandomized(m_randomize); - update_GPU_points(); - update_GPU_grids(); - } - if (ImGui::SliderInt("Num points", &m_target_point_count, 1, 1 << 17, "%d", - ImGuiSliderFlags_Logarithmic | ImGuiSliderFlags_AlwaysClamp)) - { - HelloImGui::Log(HelloImGui::LogLevel::Debug, "Setting target point count to %d.", m_target_point_count); - update_GPU_points(); - update_GPU_grids(); - HelloImGui::Log(HelloImGui::LogLevel::Debug, "Regenerated %d points.", m_point_count); - } - // now that the user has finished editing, sync the GUI value - if (ImGui::IsItemDeactivatedAfterEdit()) - m_target_point_count = m_point_count; - ImGui::SetItemTooltip("Key: Left/Right"); - if (accept_keys && (ImGui::IsKeyPressed(ImGuiKey_LeftArrow) || ImGui::IsKeyPressed(ImGuiKey_RightArrow))) - { - m_target_point_count = - std::max(1u, ImGui::IsKeyPressed(ImGuiKey_RightArrow) ? roundUpPow2(m_target_point_count + 1) - : roundDownPow2(m_target_point_count - 1)); - update_GPU_points(); - update_GPU_grids(); + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); } + ImGui::EndCombo(); + } + ImGui::SetItemTooltip("Key: Up/Down"); + if (accept_keys && !ImGui::IsKeyDown(ImGuiMod_Shift) && + (ImGui::IsKeyPressed(ImGuiKey_UpArrow) || ImGui::IsKeyPressed(ImGuiKey_DownArrow))) + { + int delta = ImGui::IsKeyPressed(ImGuiKey_DownArrow) ? 1 : -1; + m_sampler = mod(m_sampler + delta, (int)NUM_POINT_TYPES); + Sampler *sampler = m_samplers[m_sampler]; + sampler->setJitter(m_jitter * 0.01f); + sampler->setRandomized(m_randomize); + update_GPU_points(); + update_GPU_grids(); + } - if (ImGui::SliderInt("Dimensions", &m_num_dimensions, 2, 10, "%d", ImGuiSliderFlags_AlwaysClamp)) - { - update_GPU_points(); - update_GPU_grids(); - } - ImGui::SetItemTooltip("Key: D/d"); - if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_D)) + if (ImGui::SliderInt("Num points", &m_target_point_count, 1, 1 << 17, "%d", + ImGuiSliderFlags_Logarithmic | ImGuiSliderFlags_AlwaysClamp)) + { + HelloImGui::Log(HelloImGui::LogLevel::Debug, "Setting target point count to %d.", m_target_point_count); + update_GPU_points(); + update_GPU_grids(); + HelloImGui::Log(HelloImGui::LogLevel::Debug, "Regenerated %d points.", m_point_count); + } + // now that the user has finished editing, sync the GUI value + if (ImGui::IsItemDeactivatedAfterEdit()) + m_target_point_count = m_point_count; + ImGui::SetItemTooltip("Key: Left/Right"); + if (accept_keys && (ImGui::IsKeyPressed(ImGuiKey_LeftArrow) || ImGui::IsKeyPressed(ImGuiKey_RightArrow))) + { + m_target_point_count = + std::max(1u, ImGui::IsKeyPressed(ImGuiKey_RightArrow) ? roundUpPow2(m_target_point_count + 1) + : roundDownPow2(m_target_point_count - 1)); + update_GPU_points(); + update_GPU_grids(); + } + + if (ImGui::SliderInt("Dimensions", &m_num_dimensions, 2, 10, "%d", ImGuiSliderFlags_AlwaysClamp)) + { + update_GPU_points(); + update_GPU_grids(); + } + ImGui::SetItemTooltip("Key: D/d"); + if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_D)) + { + m_num_dimensions = std::clamp(m_num_dimensions + (ImGui::IsKeyDown(ImGuiMod_Shift) ? 1 : -1), 2, 10); + update_GPU_points(); + update_GPU_grids(); + } + + if (ImGui::Checkbox("Randomize", &m_randomize)) + update_GPU_points(); + ImGui::SetItemTooltip("Key: R/r"); + if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_R)) + { + if (ImGui::IsKeyDown(ImGuiMod_Shift)) { - m_num_dimensions = std::clamp(m_num_dimensions + (ImGui::IsKeyDown(ImGuiMod_Shift) ? 1 : -1), 2, 10); - update_GPU_points(); - update_GPU_grids(); + m_randomize = true; + m_samplers[m_sampler]->setRandomized(true); } + else + m_randomize = !m_randomize; + update_GPU_points(); + } - if (ImGui::Checkbox("Randomize", &m_randomize)) - update_GPU_points(); - ImGui::SetItemTooltip("Key: R/r"); - if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_R)) + if (ImGui::SliderFloat("Jitter", &m_jitter, 0.f, 100.f, "%3.1f%%")) + { + m_samplers[m_sampler]->setJitter(m_jitter * 0.01f); + update_GPU_points(); + update_GPU_grids(); + } + + // add optional widgets for OA samplers + if (OrthogonalArray *oa = dynamic_cast(m_samplers[m_sampler])) + { + // Controls for the strengths of the OA + auto change_strength = [oa, this](int strength) { - if (ImGui::IsKeyDown(ImGuiMod_Shift)) + if ((unsigned)strength != oa->strength()) { - m_randomize = true; - m_samplers[m_sampler]->setRandomized(true); + oa->setStrength(strength); + update_GPU_points(); + update_GPU_grids(); } - else - m_randomize = !m_randomize; - update_GPU_points(); - } - - if (ImGui::SliderFloat("Jitter", &m_jitter, 0.f, 100.f, "%3.1f%%")) + }; + int strength = oa->strength(); + if (ImGui::InputInt("Strength", &strength, 1)) + change_strength(std::max(2, strength)); + ImGui::SetItemTooltip("Key: T/t"); + if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_T)) + change_strength(std::max(2, strength + (ImGui::IsKeyDown(ImGuiMod_Shift) ? 1 : -1))); + + // Controls for the offset type of the OA + auto offset_names = oa->offsetTypeNames(); + auto change_offset_type = [oa, this](int offset) { - m_samplers[m_sampler]->setJitter(m_jitter * 0.01f); + oa->setOffsetType(offset); + m_jitter = oa->jitter(); update_GPU_points(); update_GPU_grids(); - } - - // add optional widgets for OA samplers - if (OrthogonalArray *oa = dynamic_cast(m_samplers[m_sampler])) + }; + if (ImGui::BeginCombo("Offset type", offset_names[oa->offsetType()].c_str())) { - // Controls for the strengths of the OA - auto change_strength = [oa, this](int strength) - { - if ((unsigned)strength != oa->strength()) - { - oa->setStrength(strength); - update_GPU_points(); - update_GPU_grids(); - } - }; - int strength = oa->strength(); - if (ImGui::InputInt("Strength", &strength, 1)) - change_strength(std::max(2, strength)); - ImGui::SetItemTooltip("Key: T/t"); - if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_T)) - change_strength(std::max(2, strength + (ImGui::IsKeyDown(ImGuiMod_Shift) ? 1 : -1))); - - // Controls for the offset type of the OA - auto offset_names = oa->offsetTypeNames(); - auto change_offset_type = [oa, this](int offset) + for (unsigned n = 0; n < offset_names.size(); n++) { - oa->setOffsetType(offset); - m_jitter = oa->jitter(); - update_GPU_points(); - update_GPU_grids(); - }; - if (ImGui::BeginCombo("Offset type", offset_names[oa->offsetType()].c_str())) - { - for (unsigned n = 0; n < offset_names.size(); n++) - { - const bool is_selected = (oa->offsetType() == n); - if (ImGui::Selectable(offset_names[n].c_str(), is_selected)) - change_offset_type(n); + const bool is_selected = (oa->offsetType() == n); + if (ImGui::Selectable(offset_names[n].c_str(), is_selected)) + change_offset_type(n); - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); } - ImGui::SetItemTooltip("Key: Shift+Up/Down"); - if (accept_keys && ImGui::IsKeyDown(ImGuiMod_Shift) && - (ImGui::IsKeyPressed(ImGuiKey_UpArrow) || ImGui::IsKeyPressed(ImGuiKey_DownArrow))) - change_offset_type(mod((int)oa->offsetType() + (ImGui::IsKeyPressed(ImGuiKey_DownArrow) ? 1 : -1), - (int)NUM_OFFSET_TYPES)); + ImGui::EndCombo(); } + ImGui::SetItemTooltip("Key: Shift+Up/Down"); + if (accept_keys && ImGui::IsKeyDown(ImGuiMod_Shift) && + (ImGui::IsKeyPressed(ImGuiKey_UpArrow) || ImGui::IsKeyPressed(ImGuiKey_DownArrow))) + change_offset_type( + mod((int)oa->offsetType() + (ImGui::IsKeyPressed(ImGuiKey_DownArrow) ? 1 : -1), (int)NUM_OFFSET_TYPES)); + } - // ========================================================= - ImGui::SeparatorText("Camera/view"); - // ========================================================= - - // ImGui::RadioButton("XY", &m_view, 0); - // ImGui::SameLine(); - // ImGui::RadioButton("YZ", &m_view, 1); - // ImGui::SameLine(); - // ImGui::RadioButton("XZ", &m_view, 2); - // ImGui::SameLine(); - // ImGui::RadioButton("XYZ", &m_view, 3); - // ImGui::SameLine(); - // ImGui::RadioButton("2D", &m_view, 4); - - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, - ImVec2{ImGui::GetStyle().ItemSpacing.y, ImGui::GetStyle().ItemSpacing.y}); + // ========================================================= + ImGui::SeparatorText("Camera/view"); + // ========================================================= - const char *items[] = {"XY", "YZ", "XZ", "XYZ", "2D"}; - bool is_selected; + // ImGui::RadioButton("XY", &m_view, 0); + // ImGui::SameLine(); + // ImGui::RadioButton("YZ", &m_view, 1); + // ImGui::SameLine(); + // ImGui::RadioButton("XZ", &m_view, 2); + // ImGui::SameLine(); + // ImGui::RadioButton("XYZ", &m_view, 3); + // ImGui::SameLine(); + // ImGui::RadioButton("2D", &m_view, 4); - for (int i = 0; i < IM_ARRAYSIZE(items); ++i) - { - if (i > CAMERA_XY) - ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, + ImVec2{ImGui::GetStyle().ItemSpacing.y, ImGui::GetStyle().ItemSpacing.y}); - is_selected = m_view == i; - if (is_selected) - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); + const char *items[] = {"XY", "YZ", "XZ", "XYZ", "2D"}; + bool is_selected; - if (ImGui::Button(items[i], float2{40.f, 0.f})) - { - set_view((CameraType)i); - } - ImGui::SetItemTooltip("Key: %d", (i + 1) % IM_ARRAYSIZE(items)); - ImGui::PopStyleColor(is_selected); - } + for (int i = 0; i < IM_ARRAYSIZE(items); ++i) + { + if (i > CAMERA_XY) + ImGui::SameLine(); - ImGui::PopStyleVar(); + is_selected = m_view == i; + if (is_selected) + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); - if (accept_keys) + if (ImGui::Button(items[i], float2{40.f, 0.f})) { - if (ImGui::IsKeyPressed(ImGuiKey_1)) - set_view(CAMERA_XY); - else if (ImGui::IsKeyPressed(ImGuiKey_2)) - set_view(CAMERA_YZ); - else if (ImGui::IsKeyPressed(ImGuiKey_3)) - set_view(CAMERA_XZ); - else if (ImGui::IsKeyPressed(ImGuiKey_4)) - set_view(CAMERA_CURRENT); - else if (ImGui::IsKeyPressed(ImGuiKey_0)) - set_view(CAMERA_2D); + set_view((CameraType)i); } + ImGui::SetItemTooltip("Key: %d", (i + 1) % IM_ARRAYSIZE(items)); + ImGui::PopStyleColor(is_selected); + } - // ========================================================= - ImGui::SeparatorText("Display options"); - // ========================================================= + ImGui::PopStyleVar(); - bool pushed = m_scale_radius_with_points; - if (pushed) - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); + if (accept_keys) + { + if (ImGui::IsKeyPressed(ImGuiKey_1)) + set_view(CAMERA_XY); + else if (ImGui::IsKeyPressed(ImGuiKey_2)) + set_view(CAMERA_YZ); + else if (ImGui::IsKeyPressed(ImGuiKey_3)) + set_view(CAMERA_XZ); + else if (ImGui::IsKeyPressed(ImGuiKey_4)) + set_view(CAMERA_CURRENT); + else if (ImGui::IsKeyPressed(ImGuiKey_0)) + set_view(CAMERA_2D); + } - ImGui::SliderFloat("Radius", &m_radius, 0.f, 1.f, ""); - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_COMPRESS)) - m_scale_radius_with_points = !m_scale_radius_with_points; - ImGui::SetItemTooltip("Scale radius with number of points"); - if (pushed) - ImGui::PopStyleColor(); - - ImGui::Checkbox("1D projections", &m_show_1d_projections); - ImGui::SetItemTooltip("Key: p"); - if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_P)) - m_show_1d_projections = !m_show_1d_projections; - - ImGui::Checkbox("Point indices", &m_show_point_nums); - ImGui::Checkbox("Point coords", &m_show_point_coords); - - ImGui::Checkbox("Coarse grid", &m_show_coarse_grid); - ImGui::SetItemTooltip("Key: g"); - ImGui::Checkbox("Fine grid", &m_show_fine_grid); - ImGui::SetItemTooltip("Key: G"); - if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_G)) - { - if (ImGui::IsKeyDown(ImGuiMod_Shift)) - m_show_fine_grid = !m_show_fine_grid; - else - m_show_coarse_grid = !m_show_coarse_grid; - update_GPU_grids(); - } + // ========================================================= + ImGui::SeparatorText("Display options"); + // ========================================================= + + bool pushed = m_scale_radius_with_points; + if (pushed) + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); + + ImGui::SliderFloat("Radius", &m_radius, 0.f, 1.f, ""); + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_COMPRESS)) + m_scale_radius_with_points = !m_scale_radius_with_points; + ImGui::SetItemTooltip("Scale radius with number of points"); + if (pushed) + ImGui::PopStyleColor(); + + ImGui::Checkbox("1D projections", &m_show_1d_projections); + ImGui::SetItemTooltip("Key: p"); + if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_P)) + m_show_1d_projections = !m_show_1d_projections; + + ImGui::Checkbox("Point indices", &m_show_point_nums); + ImGui::Checkbox("Point coords", &m_show_point_coords); + + ImGui::Checkbox("Coarse grid", &m_show_coarse_grid); + ImGui::SetItemTooltip("Key: g"); + ImGui::Checkbox("Fine grid", &m_show_fine_grid); + ImGui::SetItemTooltip("Key: G"); + if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_G)) + { + if (ImGui::IsKeyDown(ImGuiMod_Shift)) + m_show_fine_grid = !m_show_fine_grid; + else + m_show_coarse_grid = !m_show_coarse_grid; + update_GPU_grids(); + } - ImGui::Checkbox("Bounding box", &m_show_bbox); - ImGui::SetItemTooltip("Key: b"); - if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_B)) - { - m_show_bbox = !m_show_bbox; - update_GPU_grids(); - } + ImGui::Checkbox("Bounding box", &m_show_bbox); + ImGui::SetItemTooltip("Key: b"); + if (accept_keys && ImGui::IsKeyPressed(ImGuiKey_B)) + { + m_show_bbox = !m_show_bbox; + update_GPU_grids(); + } - // ========================================================= - ImGui::SeparatorText("Dimension mapping"); - // ========================================================= + // ========================================================= + ImGui::SeparatorText("Dimension mapping"); + // ========================================================= - if (ImGui::SliderInt3("XYZ", &m_dimension[0], 0, m_num_dimensions - 1, "%d", ImGuiSliderFlags_AlwaysClamp)) - update_GPU_points(false); + if (ImGui::SliderInt3("XYZ", &m_dimension[0], 0, m_num_dimensions - 1, "%d", ImGuiSliderFlags_AlwaysClamp)) + update_GPU_points(false); - // ========================================================= - ImGui::SeparatorText("Visible subset"); - // ========================================================= + // ========================================================= + ImGui::SeparatorText("Visible subset"); + // ========================================================= - if (ImGui::Checkbox("Subset by point index", &m_subset_by_index)) - update_GPU_points(false); - if (m_subset_by_index) - { - m_subset_by_coord = false; - ImGui::SliderInt("First point", &m_first_draw_point, 0, m_point_count - 1, "%d", - ImGuiSliderFlags_AlwaysClamp); - ImGui::SliderInt("Num subset points", &m_point_draw_count, 0, m_point_count - m_first_draw_point, "%d", - ImGuiSliderFlags_AlwaysClamp); - } + if (ImGui::Checkbox("Subset by point index", &m_subset_by_index)) + update_GPU_points(false); + if (m_subset_by_index) + { + m_subset_by_coord = false; + ImGui::SliderInt("First point", &m_first_draw_point, 0, m_point_count - 1, "%d", ImGuiSliderFlags_AlwaysClamp); + ImGui::SliderInt("Num subset points", &m_point_draw_count, 0, m_point_count - m_first_draw_point, "%d", + ImGuiSliderFlags_AlwaysClamp); + } - if (ImGui::Checkbox("Subset by coordinates", &m_subset_by_coord)) + if (ImGui::Checkbox("Subset by coordinates", &m_subset_by_coord)) + update_GPU_points(false); + if (m_subset_by_coord) + { + m_subset_by_index = false; + if (ImGui::SliderInt("Subset axis", &m_subset_axis, 0, m_num_dimensions - 1, "%d", + ImGuiSliderFlags_AlwaysClamp)) + update_GPU_points(false); + if (ImGui::SliderInt("Num levels", &m_num_subset_levels, 1, m_point_count, "%d", ImGuiSliderFlags_AlwaysClamp)) + update_GPU_points(false); + if (ImGui::SliderInt("Level", &m_subset_level, 0, m_num_subset_levels - 1, "%d", ImGuiSliderFlags_AlwaysClamp)) update_GPU_points(false); - if (m_subset_by_coord) - { - m_subset_by_index = false; - if (ImGui::SliderInt("Subset axis", &m_subset_axis, 0, m_num_dimensions - 1, "%d", - ImGuiSliderFlags_AlwaysClamp)) - update_GPU_points(false); - if (ImGui::SliderInt("Num levels", &m_num_subset_levels, 1, m_point_count, "%d", - ImGuiSliderFlags_AlwaysClamp)) - update_GPU_points(false); - if (ImGui::SliderInt("Level", &m_subset_level, 0, m_num_subset_levels - 1, "%d", - ImGuiSliderFlags_AlwaysClamp)) - update_GPU_points(false); - } } - ImGui::End(); } void SampleViewer::initialize_GL() diff --git a/gui/SampleViewer.h b/gui/SampleViewer.h index e8daca2..8344f3f 100644 --- a/gui/SampleViewer.h +++ b/gui/SampleViewer.h @@ -164,7 +164,7 @@ class SampleViewer : public GUIApp bool m_randomize = false; float m_jitter = 80.f; float m_radius = 0.5f; - bool m_scale_radius_with_points = false; + bool m_scale_radius_with_points = true; bool m_show_1d_projections = false, m_show_point_nums = false, m_show_point_coords = false, m_show_coarse_grid = false, m_show_fine_grid = false, m_show_bbox = false; diff --git a/macos/Info.plist b/macos/Info.plist new file mode 100644 index 0000000..82a5d22 --- /dev/null +++ b/macos/Info.plist @@ -0,0 +1,29 @@ + + + + + CFBundleIdentifier + ${HELLO_IMGUI_BUNDLE_IDENTIFIER} + + CFBundleName + ${HELLO_IMGUI_BUNDLE_NAME} + + CFBundleDisplayName + ${HELLO_IMGUI_ICON_DISPLAY_NAME} + + CFBundleExecutable + ${HELLO_IMGUI_BUNDLE_EXECUTABLE} + + CFBundleShortVersionString + ${HELLO_IMGUI_BUNDLE_SHORT_VERSION} + + CFBundleVersion + ${HELLO_IMGUI_BUNDLE_VERSION} + + NSHumanReadableCopyright + ${HELLO_IMGUI_BUNDLE_COPYRIGHT} + + CFBundleIconFile + ${HELLO_IMGUI_BUNDLE_ICON_FILE} + + diff --git a/macos/icon.icns b/macos/icon.icns new file mode 100644 index 0000000..fd6b553 Binary files /dev/null and b/macos/icon.icns differ diff --git a/resources/MacOSXBundleInfo.plist.in b/resources/MacOSXBundleInfo.plist.in deleted file mode 100644 index c330af7..0000000 --- a/resources/MacOSXBundleInfo.plist.in +++ /dev/null @@ -1,252 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - True - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - EXR - exr - - CFBundleTypeIconFile - Document-EXR - CFBundleTypeMIMETypes - - image/exr - - CFBundleTypeOSTypes - - exr - EXR - - CFBundleTypeRole - Viewer - LSItemContentTypes - - com.ilm.openexr-image - - - - CFBundleTypeExtensions - - bmp - BMP - - CFBundleTypeIconFile - Document-BMP - CFBundleTypeMIMETypes - - image/bmp - image/x-bmp - image/x-windows-bmp - image/ms-bmp - image/x-ms-bmp - application/bmp - - CFBundleTypeOSTypes - - BMP - BMPf - - CFBundleTypeRole - Viewer - LSItemContentTypes - - com.microsoft.bmp - - - - CFBundleTypeExtensions - - gif - GIF - - CFBundleTypeIconFile - Document-GIF - CFBundleTypeMIMETypes - - image/gif - - CFBundleTypeOSTypes - - GIFf - - CFBundleTypeRole - Viewer - LSItemContentTypes - - com.compuserve.gif - - - - CFBundleTypeExtensions - - jpg - JPG - jpeg - JPEG - jpe - JPE - thm - THM - - CFBundleTypeIconFile - Document-JPG - CFBundleTypeMIMETypes - - image/jpeg - image/jpg - image/pjpeg - - CFBundleTypeOSTypes - - JPEG - ???? - - CFBundleTypeRole - Viewer - LSItemContentTypes - - public.jpeg - - - - CFBundleTypeExtensions - - pic - PIC - hdr - HDR - - CFBundleTypeIconFile - Document-PIC - CFBundleTypeRole - Viewer - LSItemContentTypes - - public.radiance - - - - CFBundleTypeExtensions - - pfm - PFM - pnm - PNM - - CFBundleTypeIconFile - Document-PFM - CFBundleTypeRole - Viewer - LSItemContentTypes - - public.pfm - - - - CFBundleTypeExtensions - - png - PNG - - CFBundleTypeIconFile - Document-PNG - CFBundleTypeMIMETypes - - image/png - application/png - application/x-png - - CFBundleTypeOSTypes - - PNGf - - CFBundleTypeRole - Viewer - LSItemContentTypes - - public.png - - - - CFBundleTypeExtensions - - tga - TGA - - CFBundleTypeIconFile - Document-TGA - CFBundleTypeOSTypes - - TPIC - - CFBundleTypeRole - Viewer - LSItemContentTypes - - com.truevision.tga-image - - - - CFBundleTypeExtensions - - psd - PSD - - CFBundleTypeIconFile - Document-PSD - CFBundleTypeMIMETypes - - image/photoshop - image/x-photoshop - image/psd - application/photoshop - application/psd - - CFBundleTypeOSTypes - - 8BPS - - CFBundleTypeRole - Viewer - LSItemContentTypes - - com.adobe.photoshop-image - - - - NSSupportsAutomaticGraphicsSwitching - - -