diff --git a/Navigator/src/Navigator/Application.cpp b/Navigator/src/Navigator/Application.cpp index 6bffa8a..94b5acc 100644 --- a/Navigator/src/Navigator/Application.cpp +++ b/Navigator/src/Navigator/Application.cpp @@ -3,6 +3,9 @@ #include "Renderer/RenderCommand.h" #include "Editor/EditorLayer.h" +//temp +#include "CutMap.h" + namespace Navigator { Application* Application::s_instance = nullptr; @@ -18,6 +21,10 @@ namespace Navigator { PushLayer(new EditorLayer(&m_histMap)); m_histMap.AddHistogram("myHisto", "joseph", 100, 0, 10); + + CutMap::GetInstance().AddCut("joe_cut","joseph",0.0, 7.0); + + m_histMap.AddCutToHistogramDraw("joe_cut", "myHisto"); m_imgui_layer = new ImGuiLayer(); PushOverlay(m_imgui_layer); diff --git a/Navigator/src/Navigator/CutMap.cpp b/Navigator/src/Navigator/CutMap.cpp index e4cb9c8..ef6a0d4 100644 --- a/Navigator/src/Navigator/CutMap.cpp +++ b/Navigator/src/Navigator/CutMap.cpp @@ -1,5 +1,4 @@ #include "CutMap.h" -#include "imgui.h" #include "implot.h" namespace Navigator { @@ -33,10 +32,85 @@ namespace Navigator { Cut2D::~Cut2D() {} /* - + Even-odd point in polygon algorithm (see Wikipedia) + Walk around the sides of the polygon and check intersection with each of the sides. + Cast a ray from the point to infinity in any direction and check the number of intersections. + If odd number of intersections, point is inside. Even, point is outside. + Edge cases of point is a vertex or on a side considered. */ bool Cut2D::IsInside(double x, double y) const { - return false; + bool result = false; + size_t j = m_points.size() -1; + double slope; + for(size_t i=0; i y) != (m_points[j].y > y)) + { + slope = (x - m_points[i].x)*(m_points[j].y - m_points[i].y) - (m_points[j].x - m_points[i].x)*(y - m_points[i].y); + if(slope == 0.0) + return true; + else if ((slope < 0.0) != (m_points[j].y < m_points[i].y)) + result = !result; + } + j=i; + } + return result; } -} \ No newline at end of file + + //Only in ImPlot/ImGui context!!!! + /* + Again, more complicated. Want to draw the polygon that makes up the 2D-cut. To perform this, + first need to convert plot coordinates into global window coords (pixels). Then tell ImGui to add + a polyline to the draw list, make it red and closed. For this to work, this must be called within the + BeignPlot()/EndPlot() combo for which it was created (why histos own the draw commands). + */ + void Cut2D::Draw() const + { + std::vector draw_points; + draw_points.reserve(m_points.size()); + auto draw_list = ImGui::GetWindowDrawList(); + + for(auto& point : m_points) + draw_points.push_back(ImPlot::PlotToPixels(point.x, point.y)); + + draw_list->AddPolyline(draw_points.data(), static_cast(draw_points.size()), ImGui::ColorConvertFloat4ToU32(colorVec), ImDrawFlags_Closed, 0.1); + } + + /* CutMap */ + CutMap* CutMap::s_instance = new CutMap(); //Guarantee existance for duration of program. + + CutMap::CutMap() {} + + CutMap::~CutMap() {} + + void CutMap::DrawCut(const std::string& name) + { + std::lock_guard lock(m_cutMutex); + auto iter = m_map.find(name); + if(iter != m_map.end()) + iter->second->Draw(); + } + + bool CutMap::IsInsideCut(const std::string& name, double xval, double yval) + { + std::lock_guard lock(m_cutMutex); + bool result = false; + auto iter = m_map.find(name); + if(iter != m_map.end()) + result = iter->second->IsInside(xval, yval); + return result; + } + + std::vector CutMap::GetListOfCutParams() + { + std::lock_guard lock(m_cutMutex); + std::vector list; + list.reserve(m_map.size()); + for(auto& entry : m_map) + list.push_back(entry.second->GetCutParams()); + return list; + } +} diff --git a/Navigator/src/Navigator/CutMap.h b/Navigator/src/Navigator/CutMap.h index 53765aa..28af13f 100644 --- a/Navigator/src/Navigator/CutMap.h +++ b/Navigator/src/Navigator/CutMap.h @@ -2,6 +2,7 @@ #define CUT_MAP_H #include "NavCore.h" +#include "imgui.h" #include namespace Navigator { @@ -42,7 +43,7 @@ namespace Navigator { inline const std::string& GetName() const { return m_params.name; } inline const std::string& GetXParameter() const { return m_params.x_par; } inline const std::string& GetYParameter() const { return m_params.y_par; } - inline const CutParams& GetCutParams() const { return m_params }; + inline const CutParams& GetCutParams() const { return m_params; } protected: CutParams m_params; }; @@ -73,6 +74,7 @@ namespace Navigator { private: std::vector m_points; + const ImVec4 colorVec = {1.0, 0.0, 0.0, 0.5}; }; class NAV_API CutMap @@ -96,7 +98,7 @@ namespace Navigator { void DrawCut(const std::string& name); bool IsInsideCut(const std::string& name, double xval, double yval = 0); - std::vector GetListOfCutParams() const; + std::vector GetListOfCutParams(); private: std::unordered_map> m_map; @@ -106,4 +108,4 @@ namespace Navigator { }; } -#endif \ No newline at end of file +#endif diff --git a/Navigator/src/Navigator/Editor/EditorLayer.cpp b/Navigator/src/Navigator/Editor/EditorLayer.cpp index d0bcc69..e74f0a8 100644 --- a/Navigator/src/Navigator/Editor/EditorLayer.cpp +++ b/Navigator/src/Navigator/Editor/EditorLayer.cpp @@ -37,6 +37,11 @@ namespace Navigator { m_spectrumPanel.UpdateActiveList(m_histoList); } + void EditorLayer::UpdateCutLists() + { + m_cutList = CutMap::GetInstance().GetListOfCutParams(); + } + void EditorLayer::OnImGuiRender() { // We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into, @@ -139,6 +144,7 @@ namespace Navigator { UpdateHistogramLists(); + UpdateCutLists(); m_spectrumPanel.OnImGuiRender(); if (ImGui::Begin("Spectra")) @@ -154,7 +160,33 @@ namespace Navigator { ImGui::BulletText("Y Parameter: %s", params.y_par.c_str()); ImGui::BulletText("Y Bins: %d Y Min: %f Y Max: %f", params.nbins_y, params.min_y, params.max_y); } - + if(params.cutsDrawnUpon.size() != 0 && ImGui::TreeNode("Cuts Drawn")) + { + for(auto& cut : params.cutsDrawnUpon) + ImGui::BulletText("%s", cut.c_str()); + ImGui::TreePop(); + } + if(params.cutsAppliedTo.size() != 0 && ImGui::TreeNode("Cuts Applied")) + { + for(auto& cut : params.cutsAppliedTo) + ImGui::BulletText("%s", cut.c_str()); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + } + ImGui::End(); + } + + if(ImGui::Begin("Cuts")) + { + for(auto& params : m_cutList) + { + if(ImGui::TreeNode(params.name.c_str())) + { + ImGui::BulletText("X Parameter: %s", params.x_par.c_str()); + if(params.y_par != "None") + ImGui::BulletText("Y Parameter: %s", params.y_par.c_str()); ImGui::TreePop(); } } diff --git a/Navigator/src/Navigator/Editor/EditorLayer.h b/Navigator/src/Navigator/Editor/EditorLayer.h index a40478e..7ee8ffc 100644 --- a/Navigator/src/Navigator/Editor/EditorLayer.h +++ b/Navigator/src/Navigator/Editor/EditorLayer.h @@ -5,6 +5,7 @@ #include "Navigator/Events/Event.h" #include "Navigator/Events/PhysicsEvent.h" #include "Navigator/HistogramMap.h" +#include "Navigator/CutMap.h" #include "SpectrumPanel.h" #include "FileDialog.h" @@ -25,9 +26,11 @@ namespace Navigator { private: void UpdateHistogramLists(); + void UpdateCutLists(); bool OnPhysicsParamEvent(PhysicsParamEvent& event); HistogramMap* m_histMap; //Not owned by the EditorLayer!! std::vector m_histoList; + std::vector m_cutList; std::vector m_paramList; SpectrumPanel m_spectrumPanel; FileDialog m_fileDialog; diff --git a/Navigator/src/Navigator/Histogram.cpp b/Navigator/src/Navigator/Histogram.cpp index ecaeb96..153d16b 100644 --- a/Navigator/src/Navigator/Histogram.cpp +++ b/Navigator/src/Navigator/Histogram.cpp @@ -1,4 +1,5 @@ #include "Histogram.h" +#include "CutMap.h" #include "implot.h" /* @@ -52,6 +53,8 @@ namespace Navigator { return; int bin = int((x - m_params.min_x)/(m_binWidth)); + + auto& cutmap = CutMap::GetInstance(); m_binCounts[bin] += 1.0; } @@ -61,6 +64,9 @@ namespace Navigator { { ImPlot::SetupAxes(m_params.x_par.c_str(), "Counts",0, ImPlotAxisFlags_LockMin); ImPlot::PlotBars(m_params.name.c_str(), &m_binCenters.data()[0], &m_binCounts.data()[0], m_params.nbins_x, m_binWidth); + auto& cutmap = CutMap::GetInstance(); + for(auto& cut : m_params.cutsDrawnUpon) + cutmap.DrawCut(cut); } void Histogram1D::ClearData() @@ -130,6 +136,9 @@ namespace Navigator { ImPlot::SetupAxes(m_params.x_par.c_str(), m_params.y_par.c_str(), 0, 0); ImPlot::PlotHeatmap(m_params.name.c_str(), &m_binCounts.data()[0], m_params.nbins_y, m_params.nbins_x, 0, m_maxBinContent, NULL, ImPlotPoint(m_params.min_x, m_params.min_y), ImPlotPoint(m_params.max_x, m_params.max_y)); + auto& cutmap = CutMap::GetInstance(); + for(auto& cut : m_params.cutsDrawnUpon) + cutmap.DrawCut(cut); } void Histogram2D::ClearData() @@ -138,4 +147,4 @@ namespace Navigator { m_binCounts[i] = 0; m_maxBinContent = 0; } -} \ No newline at end of file +} diff --git a/Navigator/src/Navigator/Histogram.h b/Navigator/src/Navigator/Histogram.h index f869606..7c11157 100644 --- a/Navigator/src/Navigator/Histogram.h +++ b/Navigator/src/Navigator/Histogram.h @@ -14,6 +14,8 @@ namespace Navigator { std::string name; std::string x_par; std::string y_par; + std::vector cutsDrawnUpon; + std::vector cutsAppliedTo; int nbins_x = 0; double min_x = 0; double max_x = 0; @@ -44,6 +46,8 @@ namespace Navigator { inline const std::string& GetXParam() const { return m_params.x_par; }; inline const std::string& GetYParam() const { return m_params.y_par; }; inline const std::string& GetName() const { return m_params.name; } + inline void AddCutToBeDrawn(const std::string& name) { m_params.cutsDrawnUpon.push_back(name); } + inline void AddCutToBeApplied(const std::string& name) { m_params.cutsAppliedTo.push_back(name); } protected: HistogramParameters m_params; @@ -94,4 +98,4 @@ namespace Navigator { } -#endif \ No newline at end of file +#endif diff --git a/Navigator/src/Navigator/HistogramMap.cpp b/Navigator/src/Navigator/HistogramMap.cpp index 3ef308f..19bdd86 100644 --- a/Navigator/src/Navigator/HistogramMap.cpp +++ b/Navigator/src/Navigator/HistogramMap.cpp @@ -10,6 +10,22 @@ namespace Navigator { { } + void HistogramMap::AddCutToHistogramDraw(const std::string &cutname, const std::string &histoname) + { + std::lock_guard lock(m_histMutex); + auto iter = m_map.find(histoname); + if(iter != m_map.end()) + iter->second->AddCutToBeDrawn(cutname); + } + + void HistogramMap::AddCutToHistogramApplied(const std::string &cutname, const std::string &histoname) + { + std::lock_guard lock(m_histMutex); + auto iter = m_map.find(histoname); + if(iter != m_map.end()) + iter->second->AddCutToBeApplied(cutname); + } + void HistogramMap::UpdateHistograms() { std::lock_guard guard(m_histMutex); @@ -73,4 +89,4 @@ namespace Navigator { if (iter != m_map.end()) iter->second->Draw(); } -} \ No newline at end of file +} diff --git a/Navigator/src/Navigator/HistogramMap.h b/Navigator/src/Navigator/HistogramMap.h index 5bbdddc..260f8b6 100644 --- a/Navigator/src/Navigator/HistogramMap.h +++ b/Navigator/src/Navigator/HistogramMap.h @@ -28,6 +28,8 @@ namespace Navigator { m_map[name].reset(new Histogram2D(name, paramx, paramy, bins_x, min_x, max_x, bins_y, min_y, max_y)); } + void AddCutToHistogramDraw(const std::string& cutname, const std::string& histoname); + void AddCutToHistogramApplied(const std::string& cutname, const std::string& histoname); void UpdateHistograms(); void DrawHistograms(); @@ -46,4 +48,4 @@ namespace Navigator { } -#endif \ No newline at end of file +#endif