From 69742f4c36243cbe2ff70dead8ec222985e67b11 Mon Sep 17 00:00:00 2001 From: ganthern <nils.ganther@stud.hs-hannover.de> Date: Sun, 18 Apr 2021 21:19:14 +0200 Subject: [PATCH] add simplify event --- CgBase/CgEnums.h | 12 ++- CgEvents/CgSimplifyEvent.cpp | 45 +++++++++--- CgEvents/CgSimplifyEvent.h | 31 +++++--- CgMath/CgGMST.h | 16 ---- CgQtViewer/CgQtGui.cpp | 125 ++++++++++++++++++++++++-------- CgQtViewer/CgQtGui.h | 12 +-- CgSceneGraph/CgSceneControl.cpp | 25 ++++--- CgSceneGraph/CgSceneControl.h | 13 ++++ 8 files changed, 192 insertions(+), 87 deletions(-) delete mode 100644 CgMath/CgGMST.h diff --git a/CgBase/CgEnums.h b/CgBase/CgEnums.h index e4a59aa..6ef90eb 100644 --- a/CgBase/CgEnums.h +++ b/CgBase/CgEnums.h @@ -10,7 +10,7 @@ -namespace Cg{ +namespace Cg { typedef enum EventType { CgMouseButtonPress = 0x00000001, @@ -33,10 +33,16 @@ namespace Cg{ // unused, may be changed to whatever CgKdTreeEvent = 0x0004000, CgShowNormalsEvent = 0x0008000, - CgEventGroup1 = 0x000f000, + CgSimplifyEvent = 0x0010000, // feel free to add whatever you like - }EventType; + } EventType; + + typedef enum ClusteringType { + CgIncrementalNumber = 0x00, + CgIncrementalDiameter = 0x01, + CgHierarchical = 0x02, + } ClusteringType; diff --git a/CgEvents/CgSimplifyEvent.cpp b/CgEvents/CgSimplifyEvent.cpp index 84e5a14..461fbda 100644 --- a/CgEvents/CgSimplifyEvent.cpp +++ b/CgEvents/CgSimplifyEvent.cpp @@ -1,30 +1,53 @@ -#include "CgShowNormalsEvent.h" +#include "CgSimplifyEvent.h" -CgBaseEvent* CgShowNormalsEvent::clone() +CgBaseEvent* CgSimplifyEvent::clone() { - return new CgShowNormalsEvent(m_type); + return new CgSimplifyEvent( + m_type, + m_do_reset, + m_max_number_of_points, + m_max_diameter_of_cluster, + m_max_variance_of_cluster, + m_clustering_type + ); } -Cg::EventType CgShowNormalsEvent::getType() +Cg::EventType CgSimplifyEvent::getType() { return m_type; } -std::ostream& operator<<(std::ostream& os,const CgShowNormalsEvent& e) +std::ostream& operator<<(std::ostream& os,const CgSimplifyEvent& e) { - os << "CgShowNormalsEvent" << " "; + os << "CgSimplifyEvent [" + << "reset: " << (e.m_do_reset ? "yes" : "no") << " | " + << "max points: " << e.m_max_number_of_points << " | " + << "max diameter: " << e.m_max_diameter_of_cluster << " | " + << "max variance: " << e.m_max_variance_of_cluster << " | " + << "clustering type: " << e.m_clustering_type << "] "; return os; } -CgShowNormalsEvent::CgShowNormalsEvent(Cg::EventType type) +CgSimplifyEvent::CgSimplifyEvent() { - m_type=type; + m_type = Cg::CgSimplifyEvent; } -CgShowNormalsEvent::CgShowNormalsEvent() -{ - m_type=Cg::CgShowNormalsEvent; +CgSimplifyEvent::CgSimplifyEvent( + Cg::EventType type, + bool do_reset, + unsigned int max_number_of_points, + float max_diameter_of_cluster, + float max_variance_of_cluster, + Cg::ClusteringType clustering_type +) { + m_type = type; + m_do_reset = do_reset; + m_max_number_of_points = max_number_of_points; + m_max_diameter_of_cluster = max_diameter_of_cluster; + m_max_variance_of_cluster = max_variance_of_cluster; + m_clustering_type = clustering_type; } diff --git a/CgEvents/CgSimplifyEvent.h b/CgEvents/CgSimplifyEvent.h index 908a808..f8d0d4f 100644 --- a/CgEvents/CgSimplifyEvent.h +++ b/CgEvents/CgSimplifyEvent.h @@ -1,26 +1,37 @@ -#ifndef CG_SHOWNORMALSEVENT -#define CG_SHOWNORMALSEVENT +#ifndef CG_SIMPLIFYEVENT +#define CG_SIMPLIFYEVENT #include "../CgBase/CgBaseEvent.h" #include "../CgBase/CgEnums.h" #include <iostream> #include <string> -class CgShowNormalsEvent : public CgBaseEvent +class CgSimplifyEvent : public CgBaseEvent { public: - CgShowNormalsEvent(); - CgShowNormalsEvent(Cg::EventType type); - ~CgShowNormalsEvent(){}; + CgSimplifyEvent(); + CgSimplifyEvent( + Cg::EventType type, + bool do_reset, + unsigned int max_number_of_points, + float max_diameter_of_cluster, + float max_variance_of_cluster, + Cg::ClusteringType clustering_type + ); + ~CgSimplifyEvent(){}; //inherited Cg::EventType getType(); CgBaseEvent* clone(); - // CgShowNormalsEvent - friend std::ostream& operator <<(std::ostream& os, const CgShowNormalsEvent& e); - + // CgSimplifyEvent + friend std::ostream& operator <<(std::ostream& os, const CgSimplifyEvent& e); private: Cg::EventType m_type; + bool m_do_reset; + unsigned int m_max_number_of_points; + float m_max_diameter_of_cluster; + float m_max_variance_of_cluster; + Cg::ClusteringType m_clustering_type; }; -#endif // CG_SHOWNORMALSEVENT \ No newline at end of file +#endif // CG_SIMPLIFYEVENT \ No newline at end of file diff --git a/CgMath/CgGMST.h b/CgMath/CgGMST.h deleted file mode 100644 index 9905ee4..0000000 --- a/CgMath/CgGMST.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifndef CGGMST_H -#define CGGMST_H - -// benchmarking utility -// takes a closure without params that returns void and runs it -// amount times, printing the duration in milliseconds to stdout afterwards -void run_timed(std::string tag, unsigned int amount, std::function<void ()> fn) { - auto t1 = std::chrono::high_resolution_clock::now(); - for(int i = 0; i < amount; i++) fn(); - auto t2 = std::chrono::high_resolution_clock::now(); - std::chrono::duration<double, std::milli> ms_double = t2 - t1; - std::cout << "average for " << tag << ": "<< ms_double.count() / double(amount) << " ms" << std::endl; -} - -#endif // CGGMST_H \ No newline at end of file diff --git a/CgQtViewer/CgQtGui.cpp b/CgQtViewer/CgQtGui.cpp index 8531aab..edea8d1 100644 --- a/CgQtViewer/CgQtGui.cpp +++ b/CgQtViewer/CgQtGui.cpp @@ -14,6 +14,7 @@ #include "../CgEvents/CgPickRayEvent.h" #include "../CgEvents/CgKdTreeEvent.h" #include "../CgEvents/CgShowNormalsEvent.h" +#include "../CgEvents/CgSimplifyEvent.h" #include "../CgEvents/CgWheelEvent.h" #include <QSlider> @@ -52,11 +53,11 @@ CgQtGui::CgQtGui(CgQtMainApplication *mw) : m_mainWindow(mw) { createKdTreeOptionPanel(kdTreeOptionsWidget); QWidget *otheropt = new QWidget; - createOptionPanelExample2(otheropt); + createSimplifyOptionPanel(otheropt); QTabWidget* m_tabs = new QTabWidget(); m_tabs->addTab(kdTreeOptionsWidget,"&k-d tree"); - m_tabs->addTab(otheropt,"&My Tab2"); + m_tabs->addTab(otheropt,"&simplify"); container->addWidget(m_tabs); m_tabs->setMaximumWidth(400); @@ -165,7 +166,8 @@ void CgQtGui::createKdTreeOptionPanel(QWidget* parent) { max_kd_depth_spinbox->setAlignment(Qt::AlignTop); max_kd_depth_spinbox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); - show_normal_colors_button = new QPushButton("show normal colors"); + // button for normal vizualization + QPushButton* show_normal_colors_button = new QPushButton("show normal colors"); connect(show_normal_colors_button, SIGNAL(clicked()), this, SLOT(slotShowNormalsButtonPressed())); tab1_control->addWidget(show_normal_colors_button); @@ -177,50 +179,115 @@ void CgQtGui::createKdTreeOptionPanel(QWidget* parent) { parent->setLayout(tab1_control); } -void CgQtGui::createOptionPanelExample2(QWidget* parent) { +void CgQtGui::createSimplifyOptionPanel(QWidget* parent) { QVBoxLayout *tab2_control = new QVBoxLayout(); QHBoxLayout *subBox = new QHBoxLayout(); - /*Example for using a button group */ - - QGroupBox* myGroupBox = new QGroupBox("Radiobutton Group Example "); - - myButtonGroup = new QButtonGroup(subBox); - myButtonGroup->setExclusive(true); - - QRadioButton* radiobutton1 = new QRadioButton( "&Option1"); - QRadioButton* radiobutton2 = new QRadioButton( "&Option2"); - QRadioButton* radiobutton3 = new QRadioButton( "&Option3"); - QRadioButton* radiobutton4 = new QRadioButton( "&Option4"); - QRadioButton* radiobutton5 = new QRadioButton( "&Option5"); - - radiobutton2->setChecked(true); - - myButtonGroup->addButton(radiobutton1,0); - myButtonGroup->addButton(radiobutton2,1); - myButtonGroup->addButton(radiobutton3,2); - myButtonGroup->addButton(radiobutton4,3); - myButtonGroup->addButton(radiobutton5,4); - + // spinbox for number of points in cluster + QLabel *max_points_label = new QLabel("max points (n):"); + tab2_control->addWidget(max_points_label); + max_points_label->setAlignment(Qt::AlignTop); + max_points_label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + + max_number_of_points_spinbox = new QSpinBox(); + tab2_control->addWidget(max_number_of_points_spinbox); + max_number_of_points_spinbox->setMinimum(1); + max_number_of_points_spinbox->setMaximum(100); + max_number_of_points_spinbox->setValue(15); + tab2_control->addWidget(max_number_of_points_spinbox); + max_number_of_points_spinbox->setAlignment(Qt::AlignTop); + max_number_of_points_spinbox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + + // spinbox for max diameter of cluster + QLabel *max_diameter_label = new QLabel("max diameter (d):"); + tab2_control->addWidget(max_diameter_label); + max_diameter_label->setAlignment(Qt::AlignTop); + max_diameter_label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + + max_diameter_of_cluster_spinbox = new QDoubleSpinBox(); + tab2_control->addWidget(max_diameter_of_cluster_spinbox); + max_diameter_of_cluster_spinbox->setMinimum(0.01); + max_diameter_of_cluster_spinbox->setMaximum(10.0); + max_diameter_of_cluster_spinbox->setValue(0.05); + max_diameter_of_cluster_spinbox->setSingleStep(0.05); + tab2_control->addWidget(max_diameter_of_cluster_spinbox); + max_diameter_of_cluster_spinbox->setAlignment(Qt::AlignTop); + max_diameter_of_cluster_spinbox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + + // spinbox for max variance of cluster + QLabel *max_variance_label = new QLabel("max variance:"); + tab2_control->addWidget(max_variance_label); + max_variance_label->setAlignment(Qt::AlignTop); + max_variance_label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + + max_variance_of_cluster_spinbox = new QDoubleSpinBox(); + tab2_control->addWidget(max_variance_of_cluster_spinbox); + max_variance_of_cluster_spinbox->setMinimum(0.01); + max_variance_of_cluster_spinbox->setMaximum(5.0); + max_variance_of_cluster_spinbox->setValue(0.05); + max_variance_of_cluster_spinbox->setSingleStep(0.05); + tab2_control->addWidget(max_variance_of_cluster_spinbox); + max_variance_of_cluster_spinbox->setAlignment(Qt::AlignTop); + max_variance_of_cluster_spinbox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + + /* select clustering type button group */ + + QGroupBox* myGroupBox = new QGroupBox("Clustering Type: "); + + clustering_type_buttongroup = new QButtonGroup(subBox); + clustering_type_buttongroup->setExclusive(true); + + QRadioButton* radiobutton1 = new QRadioButton( "Incremental w/ n"); + QRadioButton* radiobutton2 = new QRadioButton( "Incremental w/ d"); + QRadioButton* radiobutton3 = new QRadioButton( "Hierarchical"); + + radiobutton1->setChecked(true); + + clustering_type_buttongroup->addButton(radiobutton1, int(Cg::CgIncrementalNumber)); + clustering_type_buttongroup->addButton(radiobutton2, int(Cg::CgIncrementalDiameter)); + clustering_type_buttongroup->addButton(radiobutton3, int(Cg::CgHierarchical)); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(radiobutton1); vbox->addWidget(radiobutton2); vbox->addWidget(radiobutton3); - vbox->addWidget(radiobutton4); - vbox->addWidget(radiobutton5); vbox->addStretch(1); myGroupBox->setLayout(vbox); subBox->addWidget(myGroupBox); tab2_control->addLayout(subBox); - connect(myButtonGroup, SIGNAL( buttonClicked(int) ), this, SLOT( slotButtonGroupSelectionChanged() ) ); + // simplify button + QPushButton* calculate_clustering_button = new QPushButton("simplify"); + connect(calculate_clustering_button, SIGNAL(clicked()), this, SLOT(slotSimplify())); + tab2_control->addWidget(calculate_clustering_button); + + // reset button + QPushButton* reset_simplification_button = new QPushButton("reset"); + connect(reset_simplification_button, SIGNAL(clicked()), this, SLOT(slotReset())); + tab2_control->addWidget(reset_simplification_button); + parent->setLayout(tab2_control); +} +void CgQtGui::sendSimplifyEvent(bool reset) { + CgBaseEvent* e = new CgSimplifyEvent( + Cg::CgSimplifyEvent, + reset, + max_number_of_points_spinbox->value(), + max_diameter_of_cluster_spinbox->value(), + max_variance_of_cluster_spinbox->value(), + (Cg::ClusteringType) clustering_type_buttongroup->checkedId() + ); + notifyObserver(e); + m_glRenderWidget->redraw(); } -void CgQtGui::slotButtonGroupSelectionChanged() { +void CgQtGui::slotSimplify() { + sendSimplifyEvent(false); +} +void CgQtGui::slotReset() { + sendSimplifyEvent(true); } void CgQtGui::slotKdDepthSpinboxChanged() { diff --git a/CgQtViewer/CgQtGui.h b/CgQtViewer/CgQtGui.h index e5a3de5..c3a159d 100644 --- a/CgQtViewer/CgQtGui.h +++ b/CgQtViewer/CgQtGui.h @@ -52,6 +52,7 @@ class QTabWidget; class QTextEdit; class QCheckBox; class QSpinBox; +class QDoubleSpinBox; class QMenuBar; class QAction; QT_END_NAMESPACE @@ -98,16 +99,14 @@ private: void createKdTreeOptionPanel(QWidget* panel); QSpinBox* max_kd_depth_spinbox; QCheckBox* display_kd_tree_checkbox; - QPushButton* show_normal_colors_button; /* additional stuff */ void createSimplifyOptionPanel(QWidget* panel); + void sendSimplifyEvent(bool reset); QSpinBox* max_number_of_points_spinbox; - QSpinBox* max_diameter_of_cluster_spinbox; - QSpinBox* max_variance_of_cluster_spinbox; + QDoubleSpinBox* max_diameter_of_cluster_spinbox; + QDoubleSpinBox* max_variance_of_cluster_spinbox; QButtonGroup* clustering_type_buttongroup; - QPushButton* calculate_clustering_button; - QPushButton* reset_simplification_button; bool m_use_spats; bool m_show_pickray; @@ -125,7 +124,8 @@ private slots: void slotShowNormalsButtonPressed(); /* additional stuff*/ - void slotButtonGroupSelectionChanged(); + void slotSimplify(); + void slotReset(); void slotLoadMeshFile(); void slotLoadPointCloudFile(); void slotSplatting(); diff --git a/CgSceneGraph/CgSceneControl.cpp b/CgSceneGraph/CgSceneControl.cpp index 815a1cf..73d1d79 100644 --- a/CgSceneGraph/CgSceneControl.cpp +++ b/CgSceneGraph/CgSceneControl.cpp @@ -2,16 +2,6 @@ #include "CgSceneControl.h" #include "CgBase/CgEnums.h" -#include "CgEvents/CgMouseEvent.h" -#include "CgEvents/CgWheelEvent.h" -#include "CgEvents/CgKeyEvent.h" -#include "CgEvents/CgWindowResizeEvent.h" -#include "CgEvents/CgLoadMeshEvent.h" -#include "CgEvents/CgLoadPointCloudEvent.h" -#include "CgEvents/CgTrackballEvent.h" -#include "CgEvents/CgSplatEvent.h" -#include "CgEvents/CgPickRayEvent.h" -#include "CgEvents/CgKdTreeEvent.h" #include "CgBase/CgBaseRenderer.h" #include "CgPointCloud.h" #include "CgPolyLine.h" @@ -213,6 +203,10 @@ void CgSceneControl::handlePickEvent(float x, float y) { } } +void CgSceneControl::handleSimplifyEvent(CgSimplifyEvent ev) { + std::cout << ev << std::endl; +} + void CgSceneControl::handleEvent(CgBaseEvent* e) { // any kind of MouseEvents can be checked via CgEvent::CgMouseEvent a // see CgEvent enums in CgEnums.h @@ -324,8 +318,15 @@ void CgSceneControl::handleEvent(CgBaseEvent* e) { // visualize normals by coloring the points according // to their object space normals - if(e->getType() & Cg::CgShowNormalsEvent) { - if(m_pointcloud != nullptr) m_pointcloud->showNormalColors(); + if(e->getType() & Cg::CgShowNormalsEvent && m_pointcloud != nullptr) { + m_pointcloud->showNormalColors(); + m_renderer->init(m_pointcloud); + m_renderer->redraw(); + } + + if(e->getType() & Cg::CgSimplifyEvent && m_pointcloud != nullptr) { + CgSimplifyEvent* ev = (CgSimplifyEvent*) e; + handleSimplifyEvent(*ev); m_renderer->init(m_pointcloud); m_renderer->redraw(); } diff --git a/CgSceneGraph/CgSceneControl.h b/CgSceneGraph/CgSceneControl.h index 4fd2c38..f8d6bfd 100644 --- a/CgSceneGraph/CgSceneControl.h +++ b/CgSceneGraph/CgSceneControl.h @@ -10,6 +10,18 @@ #include <iostream> #include <numeric> +#include "CgEvents/CgMouseEvent.h" +#include "CgEvents/CgWheelEvent.h" +#include "CgEvents/CgKeyEvent.h" +#include "CgEvents/CgWindowResizeEvent.h" +#include "CgEvents/CgLoadMeshEvent.h" +#include "CgEvents/CgLoadPointCloudEvent.h" +#include "CgEvents/CgTrackballEvent.h" +#include "CgEvents/CgSplatEvent.h" +#include "CgEvents/CgPickRayEvent.h" +#include "CgEvents/CgKdTreeEvent.h" +#include "CgEvents/CgSimplifyEvent.h" + class CgBaseEvent; class CgBaseRenderer; class CgPointCloud; @@ -42,6 +54,7 @@ private: void calculateSingularValueDecomposition(); void createKdTreeViz(int max_depth); void handlePickEvent(float x, float y); + void handleSimplifyEvent(CgSimplifyEvent ev); // one single Disc used as Object to render the spats (in own local coordinates) CgTriangleMesh* m_disc; -- GitLab