diff --git a/CMakeLists.txt b/CMakeLists.txt index 97e3af70b7655ff86ad5a50f53a1c79b6776560e..67588097ac52b7e97e121c8b8de075c4fc8fb7aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,5 +27,9 @@ if(OPENVOLUMEMESH_FOUND) endif() endif() +find_package(CXX11) +if(CXX11_FLAG_DETECTED) + add_definitions (-DENABLE_PROPVIS_HISTOGRAMS) +endif() openflipper_plugin (INSTALLDATA Icons DIRS OpenMesh OpenVolumeMesh Widgets DEPS OpenMesh OpenVolumeMesh) diff --git a/OpenMesh/OMPropertyVisualizer.hh b/OpenMesh/OMPropertyVisualizer.hh index a76e6fd35fafbf70a42267c0b50fd8be0ed98690..d7b02ffe1b4bee3a1afa3b41fdc4b90ab17e9270 100644 --- a/OpenMesh/OMPropertyVisualizer.hh +++ b/OpenMesh/OMPropertyVisualizer.hh @@ -140,6 +140,11 @@ protected: template <typename InnerType > QString getPropertyText_(unsigned int index); +#ifdef ENABLE_PROPVIS_HISTOGRAMS + template<typename Type> + void showHistogram(ACG::QtWidgets::QtHistogramWidget *histogramWidget); +#endif + private: template<typename PropHandleT> class CopyProperty @@ -157,7 +162,6 @@ private: const PropHandleT &p1, &p2; MeshT*& mesh; }; - }; diff --git a/OpenMesh/OMPropertyVisualizerDouble.hh b/OpenMesh/OMPropertyVisualizerDouble.hh index e0f9830a4643fe3dbd624979da5bf00c450fad8e..95cac28dc8389cf0f9780c706c20bf34011c04e5 100644 --- a/OpenMesh/OMPropertyVisualizerDouble.hh +++ b/OpenMesh/OMPropertyVisualizerDouble.hh @@ -84,6 +84,8 @@ protected: virtual void setEdgePropertyFromText(unsigned int index, QString text); virtual void setHalfedgePropertyFromText(unsigned int index, QString text); virtual void setVertexPropertyFromText(unsigned int index, QString text); + + ACG::IColorCoder *buildColorCoder() override; }; diff --git a/OpenMesh/OMPropertyVisualizerDoubleT.cc b/OpenMesh/OMPropertyVisualizerDoubleT.cc index bccc77e839ea4f3d1a0d37f62a0f6ad9722d0c93..e0c325ba3608dcef87b5d1ac78687c249a900874 100644 --- a/OpenMesh/OMPropertyVisualizerDoubleT.cc +++ b/OpenMesh/OMPropertyVisualizerDoubleT.cc @@ -60,6 +60,10 @@ OMPropertyVisualizerDouble<MeshT>::OMPropertyVisualizerDouble(MeshT* _mesh, Prop DoubleWidget* w = new DoubleWidget(); w->paramDouble->setTitle(QString("Double Parameters of ").append(PropertyVisualizer::propertyInfo.propName().c_str())); PropertyVisualizer::widget = w; +#ifdef ENABLE_PROPVIS_HISTOGRAMS + this->connect(w->computeHistogramButton, &QPushButton::clicked, + [this, w](){this->template showHistogram<double>(w->histogram);}); +#endif } template <typename MeshT> @@ -449,6 +453,13 @@ void OMPropertyVisualizerDouble<MeshT>::setVertexPropertyFromText(unsigned int i mesh->property(prop, vh) = this->strToDouble(text); } +template<typename MeshT> +ACG::IColorCoder *OMPropertyVisualizerDouble<MeshT>::buildColorCoder() +{ + DoubleWidget* doubleWidget = static_cast<DoubleWidget*>(PropertyVisualizer::widget); + return doubleWidget->buildColorCoder(); +} + template<typename MeshT> void OMPropertyVisualizerDouble<MeshT>::removeProperty() diff --git a/OpenMesh/OMPropertyVisualizerT.cc b/OpenMesh/OMPropertyVisualizerT.cc index e7d49f4a988ef49a4d83c0af3282c78fc1097367..8deda8be81fa312356d077a4ec09dbfa27ea3706 100644 --- a/OpenMesh/OMPropertyVisualizerT.cc +++ b/OpenMesh/OMPropertyVisualizerT.cc @@ -423,3 +423,59 @@ void OMPropertyVisualizer<MeshT>::setVertexPropertyFromText(unsigned int index, { emit log(LOGERR, "Setting vertex property not implemented"); } + + +#ifdef ENABLE_PROPVIS_HISTOGRAMS + +template<typename MeshT> +template<typename Type> +void OMPropertyVisualizer<MeshT>::showHistogram(ACG::QtWidgets::QtHistogramWidget *histogramWidget) { + using PV = OMPropertyVisualizer<MeshT>; + const std::string &prop_name = PV::propertyInfo.propName(); + + // ugly repetition ahead. In C++14, we could use a generic lambda, + // in C++11 the cleanest solution would be to add another templated member function - not worth it. + switch (PropertyVisualizer::propertyInfo.entityType()) { + case PropertyInfo::EF_FACE: + { + OpenMesh::FPropHandleT<Type> prop_handle; + if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break; + PropertyVisualizer::template showHistogramT<Type>( + histogramWidget, + PV::mesh->property(prop_handle).data_vector()); + break; + } + case PropertyInfo::EF_EDGE: + { + OpenMesh::EPropHandleT<Type> prop_handle; + if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break; + PropertyVisualizer::template showHistogramT<Type>( + histogramWidget, + PV::mesh->property(prop_handle).data_vector()); + break; + } + case PropertyInfo::EF_HALFEDGE: + { + OpenMesh::HPropHandleT<Type> prop_handle; + if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break; + PropertyVisualizer::template showHistogramT<Type>( + histogramWidget, + PV::mesh->property(prop_handle).data_vector()); + break; + } + case PropertyInfo::EF_VERTEX: + { + OpenMesh::VPropHandleT<Type> prop_handle; + if (!PV::mesh->get_property_handle(prop_handle, prop_name)) break; + PropertyVisualizer::template showHistogramT<Type>( + histogramWidget, + PV::mesh->property(prop_handle).data_vector()); + break; + } + default: + assert(false); + } +} +#endif + + diff --git a/OpenVolumeMesh/OVMPropertyVisualizer.hh b/OpenVolumeMesh/OVMPropertyVisualizer.hh index 2794e2a94dde31c748db66d8aa08c1870c4b4c44..93f0b87531104090ef82784a768627888efe197f 100644 --- a/OpenVolumeMesh/OVMPropertyVisualizer.hh +++ b/OpenVolumeMesh/OVMPropertyVisualizer.hh @@ -60,6 +60,8 @@ #include <ObjectTypes/VolumeMeshObject/VolumeMeshDrawModesContainer.hh> +#include <ACG/QtWidgets/QtHistogramWidget.hh> + #include <iostream> template <typename MeshT> @@ -97,6 +99,12 @@ public: /// Returns the ID of the closest primitive. unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint); +#ifdef ENABLE_PROPVIS_HISTOGRAMS +protected slots: + template <typename Type> + void showHistogram(ACG::QtWidgets::QtHistogramWidget *histogramWidget); +#endif + protected: MeshT* mesh; @@ -240,3 +248,4 @@ void Classname::visualizeVertexProp(bool _setDrawMode)\ #endif /* OVM_PROPERTY_VISUALIZER_HH */ #endif /* ENABLE_OPENVOLUMEMESH_SUPPORT */ + diff --git a/OpenVolumeMesh/OVMPropertyVisualizerDouble.hh b/OpenVolumeMesh/OVMPropertyVisualizerDouble.hh index 865e2291f914d88cfc74a971db980e9576d18659..397e7a37411abe9bc8db2ac11ce04bbbd4974b62 100644 --- a/OpenVolumeMesh/OVMPropertyVisualizerDouble.hh +++ b/OpenVolumeMesh/OVMPropertyVisualizerDouble.hh @@ -89,6 +89,8 @@ protected: virtual void setEdgePropertyFromText(unsigned int index, QString text); virtual void setHalfedgePropertyFromText(unsigned int index, QString text); virtual void setVertexPropertyFromText(unsigned int index, QString text); + + ACG::IColorCoder *buildColorCoder() override; }; #if defined(INCLUDE_TEMPLATES) && !defined(OVM_PROPERTY_VISUALIZER_DOUBLE_CC) diff --git a/OpenVolumeMesh/OVMPropertyVisualizerDoubleT.cc b/OpenVolumeMesh/OVMPropertyVisualizerDoubleT.cc index 293483da68ef3972e2b3c4e194871f4230ce82b1..e0085178eb1da768a658f2b1ba17bfae29de6f93 100644 --- a/OpenVolumeMesh/OVMPropertyVisualizerDoubleT.cc +++ b/OpenVolumeMesh/OVMPropertyVisualizerDoubleT.cc @@ -57,6 +57,8 @@ #include <ACG/Utils/LinearTwoColorCoder.hh> #include <ACG/Utils/ColorConversion.hh> +#include <QObject> + template <typename MeshT> OVMPropertyVisualizerDouble<MeshT>::OVMPropertyVisualizerDouble(MeshT* _mesh, int objectID, PropertyInfo _propertyInfo) : OVMPropertyVisualizer<MeshT>(_mesh, objectID, _propertyInfo) @@ -65,6 +67,11 @@ OVMPropertyVisualizerDouble<MeshT>::OVMPropertyVisualizerDouble(MeshT* _mesh, in DoubleWidget* w = new DoubleWidget(); w->paramDouble->setTitle(QString("Double Parameters of ").append(PropertyVisualizer::propertyInfo.propName().c_str())); PropertyVisualizer::widget = w; +#ifdef ENABLE_PROPVIS_HISTOGRAMS + this->connect(w->computeHistogramButton, &QPushButton::clicked, + [this, w](){this->template showHistogram<double>(w->histogram);}); +#endif + } template <typename MeshT> @@ -261,4 +268,11 @@ void OVMPropertyVisualizerDouble<MeshT>::setVertexPropertyFromText(unsigned int prop[vh] = this->strToDouble(text); } +template <typename MeshT> +ACG::IColorCoder *OVMPropertyVisualizerDouble<MeshT>::buildColorCoder() +{ + DoubleWidget* doubleWidget = static_cast<DoubleWidget*>(PropertyVisualizer::widget); + return doubleWidget->buildColorCoder(); +} + #endif /* ENABLE_OPENVOLUMEMESH_SUPPORT */ diff --git a/OpenVolumeMesh/OVMPropertyVisualizerInteger.hh b/OpenVolumeMesh/OVMPropertyVisualizerInteger.hh index 22b9fc372efab6a5c1efb9d5c3e5dc17d39d214a..3032d1c40067b1c14bd77eb432a89dbd42d593aa 100644 --- a/OpenVolumeMesh/OVMPropertyVisualizerInteger.hh +++ b/OpenVolumeMesh/OVMPropertyVisualizerInteger.hh @@ -88,6 +88,8 @@ protected: virtual void setHalfedgePropertyFromText(unsigned int index, QString text); virtual void setVertexPropertyFromText(unsigned int index, QString text); + ACG::IColorCoder *buildColorCoder() override; + T mNumericLimitMax; T mNumericLimitMin; diff --git a/OpenVolumeMesh/OVMPropertyVisualizerIntegerT.cc b/OpenVolumeMesh/OVMPropertyVisualizerIntegerT.cc index 63bbf3928a163e1afe3f7d0d6099586d32364c7c..1cc6d8d90709133119756b8b7d3f88acf889c204 100644 --- a/OpenVolumeMesh/OVMPropertyVisualizerIntegerT.cc +++ b/OpenVolumeMesh/OVMPropertyVisualizerIntegerT.cc @@ -265,4 +265,11 @@ void OVMPropertyVisualizerInteger<MeshT, T>::setVertexPropertyFromText(unsigned prop[vh] = this->strToInt(text); } +template <typename MeshT, typename T> +ACG::IColorCoder *OVMPropertyVisualizerInteger<MeshT, T>::buildColorCoder() +{ + IntegerWidget* integerWidget = static_cast<IntegerWidget*>(PropertyVisualizer::widget); + return integerWidget->buildColorCoder(); +} + #endif /* ENABLE_OPENVOLUMEMESH_SUPPORT */ diff --git a/OpenVolumeMesh/OVMPropertyVisualizerT.cc b/OpenVolumeMesh/OVMPropertyVisualizerT.cc index b28bf231183f5332feecefa9e38ab8b30a740cb3..069015b915f047da9cf04bc1001a09fbddd15220 100644 --- a/OpenVolumeMesh/OVMPropertyVisualizerT.cc +++ b/OpenVolumeMesh/OVMPropertyVisualizerT.cc @@ -63,6 +63,8 @@ #include "OVMPropertyVisualizer.hh" +#include <ACG/Utils/Histogram.hh> + template <typename MeshT> template <typename InnerType> QString OVMPropertyVisualizer<MeshT>::getPropertyText_(unsigned int index) @@ -407,4 +409,49 @@ void OVMPropertyVisualizer<MeshT>::setVertexPropertyFromText(unsigned int /*inde emit log(LOGERR, "Setting VertexProp not implemented for this property type"); } +#ifdef ENABLE_PROPVIS_HISTOGRAMS + +template<typename MeshT> +template<typename Type> +void OVMPropertyVisualizer<MeshT>::showHistogram(ACG::QtWidgets::QtHistogramWidget *histogramWidget) { + using PV = OVMPropertyVisualizer<MeshT>; + const std::string &prop_name = PV::propertyInfo.propName(); + + switch (PropertyVisualizer::propertyInfo.entityType()) { + case PropertyInfo::EF_CELL: + this->showHistogramT<Type>( + histogramWidget, + PV::mesh->template request_cell_property<Type>(prop_name)); + break; + case PropertyInfo::EF_FACE: + this->showHistogramT<Type>( + histogramWidget, + PV::mesh->template request_face_property<Type>(prop_name)); + break; + case PropertyInfo::EF_HALFFACE: + this->showHistogramT<Type>( + histogramWidget, + PV::mesh->template request_halfface_property<Type>(prop_name)); + break; + case PropertyInfo::EF_EDGE: + this->showHistogramT<Type>( + histogramWidget, + PV::mesh->template request_edge_property<Type>(prop_name)); + break; + case PropertyInfo::EF_HALFEDGE: + this->showHistogramT<Type>( + histogramWidget, + PV::mesh->template request_halfedge_property<Type>(prop_name)); + break; + case PropertyInfo::EF_VERTEX: + this->showHistogramT<Type>( + histogramWidget, + PV::mesh->template request_vertex_property<Type>(prop_name)); + break; + case PropertyInfo::EF_ANY: + assert(false); + } +} +#endif + #endif /* ENABLE_OPENVOLUMEMESH_SUPPORT */ diff --git a/PropertyVisualizer.cc b/PropertyVisualizer.cc index 140cf773477f39babf10975cdb55bfc4a3dbe480..87391bb0eb45c8407c484bd63809f9c37d64a322 100644 --- a/PropertyVisualizer.cc +++ b/PropertyVisualizer.cc @@ -155,3 +155,8 @@ OpenMesh::Vec2f PropertyVisualizer::strToVec2f (QString str) QStringList strList = s.split(QObject::tr(", ")); return OpenMesh::Vec2f(strList[0].toFloat(),strList[1].toFloat()); } + +ACG::IColorCoder *PropertyVisualizer::buildColorCoder() +{ + throw std::runtime_error("Requested color coder on a Propvis that does not implement it"); +} diff --git a/PropertyVisualizer.hh b/PropertyVisualizer.hh index 6fa4e543e5beec138d0f2d87f98fecabafae75f4..589be0f7f3caadbacf2fc447a08ba791ac38d439 100644 --- a/PropertyVisualizer.hh +++ b/PropertyVisualizer.hh @@ -54,6 +54,8 @@ #include <OpenFlipper/BasePlugin/BaseInterface.hh> #include <OpenFlipper/BasePlugin/LoggingInterface.hh> +#include <ACG/QtWidgets/QtHistogramWidget.hh> +#include <ACG/Utils/IColorCoder.hh> #include "OpenMesh/Core/Geometry/VectorT.hh" @@ -178,12 +180,31 @@ public: protected: + virtual ACG::IColorCoder *buildColorCoder(); +#ifdef ENABLE_PROPVIS_HISTOGRAMS + template<typename PropType, typename Iterable> + void showHistogramT(ACG::QtWidgets::QtHistogramWidget *widget, + Iterable data); +#endif PropertyInfo propertyInfo; public: QWidget* widget; - }; +#ifdef ENABLE_PROPVIS_HISTOGRAMS +template<typename PropType, typename Iterable> +void PropertyVisualizer::showHistogramT( + ACG::QtWidgets::QtHistogramWidget *widget, + Iterable data) +{ + const size_t max_bins = 50; // TODO: expose in GUI? + widget->setMinimumHeight(300); + widget->setColorCoder(buildColorCoder()); + ACG::Histogram *hist = new ACG::HistogramT<PropType>(data.begin(), data.end(), max_bins); + widget->setHistogram(hist); +} +#endif + #endif /* PROPERTY_VISUALIZER_HH */ diff --git a/Widgets/DoubleWidget.ui b/Widgets/DoubleWidget.ui index dd880a3fd4e2ee1173df0c7a1bc0b8d2baf67d10..888bdb8c266e0638c7708e53b0eb6c8293f21036 100644 --- a/Widgets/DoubleWidget.ui +++ b/Widgets/DoubleWidget.ui @@ -6,29 +6,14 @@ <rect> <x>0</x> <y>0</y> - <width>404</width> - <height>172</height> + <width>453</width> + <height>291</height> </rect> </property> <property name="windowTitle"> <string>Property Visualization</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QGroupBox" name="paramDouble"> <property name="title"> @@ -152,6 +137,35 @@ </layout> </widget> </item> + <item> + <widget class="QGroupBox" name="histogramGroupbox"> + <property name="title"> + <string>Histogram</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="computeHistogramButton"> + <property name="text"> + <string>Compute Histogram</string> + </property> + </widget> + </item> + <item> + <widget class="ACG::QtWidgets::QtHistogramWidget" name="histogram" native="true"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + </layout> + </widget> + </item> </layout> </widget> <customwidgets> @@ -160,6 +174,12 @@ <extends>QPushButton</extends> <header>ACG/QtWidgets/QtColorChooserButton.hh</header> </customwidget> + <customwidget> + <class>ACG::QtWidgets::QtHistogramWidget</class> + <extends>QWidget</extends> + <header>ACG/QtWidgets/QtHistogramWidget.hh</header> + <container>1</container> + </customwidget> </customwidgets> <tabstops> <tabstop>doubleFixedRange</tabstop>