diff --git a/GeoModelVisualization/VP1Base/VP1Base/IVP13DStandardChannelWidget.h b/GeoModelVisualization/VP1Base/VP1Base/IVP13DStandardChannelWidget.h index d65b4b713bfb689e9d5b1fca9fc4ea47cb7044b7..22c51305c1e699ae70cc455b1df58d48488ece3f 100644 --- a/GeoModelVisualization/VP1Base/VP1Base/IVP13DStandardChannelWidget.h +++ b/GeoModelVisualization/VP1Base/VP1Base/IVP13DStandardChannelWidget.h @@ -16,6 +16,9 @@ #define IVP13DSTANDARDCHANNELWIDGET_H #include "VP1Base/IVP13DChannelWidget.h" + + +// FWD declarations class IVP13DSystem; class IVP13DSystemSimple; class QResizeEvent; @@ -74,6 +77,7 @@ private slots: void toggleSystemActive(); void updateSnapshotDim(); void setImageFromPresets(); + void updateTransparencyType(unsigned type); protected slots: void showControlsForSystem(); diff --git a/GeoModelVisualization/VP1Base/VP1Base/VP1Msg.h b/GeoModelVisualization/VP1Base/VP1Base/VP1Msg.h index 0f72e1ada0a3e5707448cc6fc099a1c179e19f3c..81ba888e176edd30eb5728a3551f9b496bae9456 100644 --- a/GeoModelVisualization/VP1Base/VP1Base/VP1Msg.h +++ b/GeoModelVisualization/VP1Base/VP1Base/VP1Msg.h @@ -30,6 +30,8 @@ class VP1Msg : public VP1String { public: static bool verbose() { return m_verbose; } // Returns true if env var VP1_VERBOSE_OUTPUT=1 static bool debug() { return m_debug; } // Returns true if env var VP1_DEBUG_OUTPUT=1 + static bool debug2() { return m_debug_2; } // Returns true if env var VP1_DEBUG_2_OUTPUT=1 + static bool debug3() { return m_debug_3; } // Returns true if env var VP1_DEBUG_3_OUTPUT=1 #if defined BUILDVP1LIGHT static void enableMsg(const QString&, const QString&); @@ -39,6 +41,8 @@ public: static void message(const QString&, IVP1System*sys = 0);//Non-zero sys pointer to get message in GUI static void messageDebug(const QString&); + static void messageDebug2(const QString&); + static void messageDebug3(const QString&); static void messageWarning(const QString&); static void messageVerbose(const QString&);//This outputs only if verbose() is true. static void messageWarningRed( const QString& str ); @@ -54,6 +58,8 @@ public: static const char* prefix_msg() { return "VP1MESSAGE";} static const char* prefix_debug() { return "VP1MSG_DEBUG";} + static const char* prefix_debug2() { return "VP1MSG_DEBUG_2";} + static const char* prefix_debug3() { return "VP1MSG_DEBUG_3";} static const char* prefix_warning() { return "VP1MSG_WARNING";} static const char* prefix_verbose() { return "VP1MSG_VERBOSE";} @@ -62,6 +68,8 @@ private: ~VP1Msg(){} static bool m_verbose; static bool m_debug; + static bool m_debug_2; + static bool m_debug_3; }; #endif diff --git a/GeoModelVisualization/VP1Base/src/IVP13DStandardChannelWidget.cxx b/GeoModelVisualization/VP1Base/src/IVP13DStandardChannelWidget.cxx index 24b262f2f1353b8d2bfa33f33ed1da051e999fcb..bc968161ba228ed4ee8886808f374ecf068f177b 100644 --- a/GeoModelVisualization/VP1Base/src/IVP13DStandardChannelWidget.cxx +++ b/GeoModelVisualization/VP1Base/src/IVP13DStandardChannelWidget.cxx @@ -30,6 +30,7 @@ #include <Inventor/actions/SoBoxHighlightRenderAction.h> #include <Inventor/nodes/SoPerspectiveCamera.h> #include <Inventor/SoOffscreenRenderer.h> +#include <Inventor/actions/SoGLRenderAction.h> #include <QSplitter> #include <QVBoxLayout> @@ -252,12 +253,22 @@ void IVP13DStandardChannelWidget::create() { m_d->viewer->setTransparencyType( SoGLRenderAction::BLEND ); // this looks better for geometry volumes //Setup camera info: - foreach(IVP13DSystem*sys,m_d->systemsAllowedCameraList) + foreach(IVP13DSystem*sys,m_d->systemsAllowedCameraList) { sys->registerViewer(m_d->viewer); + connect(sys,SIGNAL(updateTransparencyType(unsigned)), this,SLOT(updateTransparencyType(unsigned))); + } snapshotgroupbox->hide(); } + +//___________________________________________________________________________ +void IVP13DStandardChannelWidget::updateTransparencyType(unsigned type) +{ + //if( VP1Msg::debug()) + //std::cout << "Changing global transparency type to: " << type << std::endl; + m_d->viewer->setTransparencyType( VP1QtInventorUtils::intToTransparencyType(type) ); +} //___________________________________________________________________________ void IVP13DStandardChannelWidget::Imp::setupSplitter(QWidget * rightwidget) { diff --git a/GeoModelVisualization/VP1Base/src/VP1Msg.cxx b/GeoModelVisualization/VP1Base/src/VP1Msg.cxx index 4afb2e5ddd4b7cd8c6f6ae7602e6b5aa4e5eccfb..59629a742d93f34c3999f58023d90d58381c6d08 100644 --- a/GeoModelVisualization/VP1Base/src/VP1Msg.cxx +++ b/GeoModelVisualization/VP1Base/src/VP1Msg.cxx @@ -20,6 +20,8 @@ #ifndef BUILDVP1LIGHT //TODO: Merge the two mechanisms, specifically for VP1 bool VP1Msg::m_verbose = VP1QtUtils::environmentVariableIsOn("VP1_VERBOSE_OUTPUT"); bool VP1Msg::m_debug = VP1QtUtils::environmentVariableIsOn("VP1_DEBUG_OUTPUT"); + bool VP1Msg::m_debug_2 = VP1QtUtils::environmentVariableIsOn("VP1_DEBUG_2_OUTPUT"); + bool VP1Msg::m_debug_3 = VP1QtUtils::environmentVariableIsOn("VP1_DEBUG_3_OUTPUT"); #endif #ifdef BUILDVP1LIGHT bool VP1Msg::m_verbose = VP1QtUtils::expertSettingIsSet("general", "ExpertSettings/VP1_VERBOSE_OUTPUT"); @@ -38,12 +40,31 @@ void VP1Msg::message( const QString& str, IVP1System*sys ) //____________________________________________________________________ void VP1Msg::messageDebug( const QString& str ) { - if (!debug()){ + if ( ! (debug() or debug2() or debug3()) ){ return; } std::cout << "DBG!!!" << prefix_debug() << ": "<< str.toStdString()<<std::endl; } +//____________________________________________________________________ +void VP1Msg::messageDebug2( const QString& str ) +{ + if ( ! (debug2() or debug3()) ){ + return; + } + std::cout << prefix_debug2() << ": "<< str.toStdString()<<std::endl; +} + +//____________________________________________________________________ +void VP1Msg::messageDebug3( const QString& str ) +{ + if (!debug3()){ + return; + } + std::cout << prefix_debug3() << ": "<< str.toStdString()<<std::endl; +} + + //____________________________________________________________________ void VP1Msg::messageWarning( const QString& str ) { diff --git a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h index 7133772b3475d518dba4f1fa3a583eb15ad1e668..4fc0a1e7827e48d8072182a7f7706be7455492fe 100644 --- a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h +++ b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h @@ -1,17 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ //////////////////////////////////////////////////////////////// -// // -// Header file for class GeoSysController // -// // -// Description: Controller for the geometry system. // -// // -// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) // -// Initial version: October 2008 // -// // +// +// Header file for class GeoSysController +// +// Description: Controller for the geometry system. +// +// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) +// Initial version: October 2008 +// +// Major updates: +// +// - Riccardo Maria BIANCHI (riccardo.maria.bianchi@cern.ch) +// Jul 2021: Added support to filter volumes based on names +// //////////////////////////////////////////////////////////////// #ifndef GEOSYSCONTROLLER_H @@ -75,6 +80,9 @@ public: //Settings with change signals: float transparency() const; + void setTransparency(float value) const; + bool isTranspLocked() const; + bool showVolumeOutLines() const; int labels() const; QList<int> labelPosOffset() ; //!< Offset in x,y,z @@ -90,10 +98,10 @@ signals: //Signals without state: void resetSubSystems(VP1GeoFlags::SubSystemFlag); - void autoExpandByVolumeOrMaterialName(bool,QString);//volname: (false,namestr), matname: (true,namestr) + void autoExpandByVolumeOrMaterialName(bool, QString); //volname: (false,namestr), matname: (true,namestr) void volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE);//Might not be used atm. void volumeResetRequested(VolumeHandle*); - + void signalFilterVolumes(QString, bool, int, bool, bool, bool); void saveMaterialsToFile(QString,bool);//(filename,onlyChangedMaterials) void loadMaterialsFromFile(QString);//filename void displayLocalAxesChanged(int); @@ -112,7 +120,6 @@ private slots: void saveMaterialsRequested(); void loadMaterialsRequested(); void emit_autoExpandByVolumeOrMaterialName(); - // void emit_actionOnAllNonStandardVolumes(); // not used anymore? }; #endif diff --git a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h index 9d100b53915eefc30113cc25887cc3f640f4d23b..e33dda7102b53f93f496c4e0e7c259023a26db82 100644 --- a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h +++ b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h @@ -6,26 +6,35 @@ #define VP1GEOMETRYSYSTEM_H ///////////////////////////////////////////////////////////////////////// -// // -// Header file for class VP1GeometrySystem // -// // -// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> // -// // -// Derived from V-atlas geometry system by Joe Boudreau. // -// Origins of initial version dates back to ~1996, initial VP1 // -// version by TK (May 2007) and almost entirely rewritten Oct 2007 // -// // +// +// Header file for class VP1GeometrySystem +// +// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> +// +// Derived from V-atlas geometry system by Joe Boudreau. +// Origins of initial version dates back to ~1996, initial VP1 +// version by TK (May 2007) and almost entirely rewritten Oct 2007 +// +// - Jul 2021, Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> +// * Added the 'filter volumes' tool +// * Added signal/slot to update transparency type in the 3D window +// ///////////////////////////////////////////////////////////////////////// #include "VP1Base/IVP13DSystemSimple.h" #include "VP1GeometrySystems/VP1GeoFlags.h" #include "VP1GeometrySystems/VolumeHandle.h"//fixme + #include "GeoModelKernel/GeoPhysVol.h" + #include <set> #include <map> #include <QStack> #include <QString> + + + class VP1GeometrySystem : public IVP13DSystemSimple { Q_OBJECT @@ -52,6 +61,9 @@ public: QByteArray saveState(); void restoreFromState(QByteArray); +signals: + void updateTransparencyType(unsigned type); + public slots: void setCurvedSurfaceRealism(int);//Accepts values in the range 0..100. @@ -60,10 +72,14 @@ protected slots: void updateTransparency(); void resetSubSystems(VP1GeoFlags::SubSystemFlags); - void autoExpandByVolumeOrMaterialName(bool,QString);//volname: (false,namestr), matname: (true,namestr) + void autoExpandByVolumeOrMaterialName(bool, QString);//volname: (false,namestr), matname: (true,namestr) + + void volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE); + void volumeResetRequested(VolumeHandle*); - // void volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE); // not used anymore? - // void volumeResetRequested(VolumeHandle*); // not used anymore? + void actionOnAllNonStandardVolumes(bool);//true: zap, false: expand. + void actionOnAllVolumes(bool zap, bool standardVolumes = true);//true: zap, false: expand; true: standardVolumes + void filterVolumes(QString targetname, bool bymatname, int maxDepth, bool stopAtFirst, bool visitChildren, bool reset); void setShowVolumeOutLines(bool); diff --git a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VolumeHandle.h b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VolumeHandle.h index 10c32872f0ed27fcffdaedce396fa3b2ed091267..082bb56b25041a356eeed17e40194048e22b3813 100644 --- a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VolumeHandle.h +++ b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VolumeHandle.h @@ -76,6 +76,7 @@ public: bool isEther() const; void expandMothersRecursivelyToNonEther();//expands the tree down to volumes that are either not ether or without children + bool isInitialisedAndHasNonStandardShape() const;//True if the 3D shape of this volume can not be represented by standard VRML nodes. SoSeparator * nodeSoSeparator() const;//Returns pointer to 3D representation of volume (null if not built yet). void ensureBuildNodeSep(); diff --git a/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx b/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx index 5917f02d1c4b257066a6121d3b8655c915541579..d804ce7badbe33e266e8a4d44de51d887d031ab4 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx @@ -1,15 +1,23 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ //////////////////////////////////////////////////////////////// -// // -// Implementation of class GeoSysController // -// // -// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) // -// Initial version: October 2008 // -// // +// +// Implementation of class GeoSysController +// +// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) +// Initial version: October 2008 +// +// Major updates: +// +// - Riccardo Maria BIANCHI (riccardo.maria.bianchi@cern.ch) +// 2019 +// +// - Riccardo Maria BIANCHI (riccardo.maria.bianchi@cern.ch) +// Jul 2021: Added support to filter volumes based on names +// //////////////////////////////////////////////////////////////// #define VP1IMPVARNAME m_d @@ -47,7 +55,6 @@ public: std::map<VP1GeoFlags::SubSystemFlag,QCheckBox*> subSysCheckBoxMap; float last_transparency; bool last_showVolumeOutLines; - // VP1GeoFlags::MuonChamberAdaptionStyleFlags last_muonChamberAdaptionStyle; int last_labels; //!< needed for POSSIBLECHANGE_IMP macro. QList<int> last_labelPosOffset; //!< needed for POSSIBLECHANGE_IMP macro. SoPickStyle * pickStyle; @@ -56,8 +63,6 @@ public: QString lastSaveMaterialsFile; QString lastLoadMaterialsFile; - -// std::map<QString, QList<QCheckBox*> > labelProvidingSystems; //!< First is name of system, second is list of types of information provided (system stores actual information) }; @@ -77,7 +82,7 @@ GeoSysController::GeoSysController(IVP1System * sys) // m_d->ui_disp.widget_drawOptions->setLineWidthsDisabled(); m_d->ui_disp.widget_drawOptions->setPointSizesDisabled(); // m_d->ui_disp.widget_drawOptions->setBaseLightingDisabled(); - m_d->ui_disp.widget_drawOptions->setComplexity(0.6); + m_d->ui_disp.widget_drawOptions->setComplexity(1.0); // default 'curved surface accuracy' value m_d->pickStyle = new SoPickStyle; m_d->pickStyle->ref(); @@ -119,15 +124,16 @@ GeoSysController::GeoSysController(IVP1System * sys) connect(m_d->ui_misc.lineEdit_expand_vols_volname,SIGNAL(returnPressed()),this,SLOT(emit_autoExpandByVolumeOrMaterialName())); connect(m_d->ui_misc.pushButton_expand_vols_volname,SIGNAL(clicked()),this,SLOT(emit_autoExpandByVolumeOrMaterialName())); + // filter volumes + connect(m_d->ui_misc.lineEdit_filter_logvolname,SIGNAL(returnPressed()),this,SLOT(emit_autoExpandByVolumeOrMaterialName())); + connect(m_d->ui_misc.pushButton_filter_logvolname,SIGNAL(clicked()),this,SLOT(emit_autoExpandByVolumeOrMaterialName())); + connect(m_d->ui_misc.pushButton_filter_reset,SIGNAL(clicked()),this,SLOT(emit_autoExpandByVolumeOrMaterialName())); + + connect(m_d->ui_int.checkBox_localAxes, SIGNAL(stateChanged(int)), this, SIGNAL(displayLocalAxesChanged(int))); connect(m_d->ui_int.slider_AxesScale, SIGNAL(valueChanged(int)), this, SIGNAL(axesScaleChanged(int))); - setLastSelectedVolume(0); - - - - } //____________________________________________________________________ @@ -334,6 +340,20 @@ float GeoSysController::transparency() const return (v>=100?1.0:(v<=0?0.0:v/100.0)); } +//____________________________________________________________________ +void GeoSysController::setTransparency(float value) const +{ + assert( 0. <= value && value <= 100.); + m_d->ui_disp.spinBox_transp->setValue(value); + return; +} + +//____________________________________________________________________ +bool GeoSysController::isTranspLocked() const +{ + return m_d->ui_misc.lockTransp->isChecked(); +} + //____________________________________________________________________ bool GeoSysController::showVolumeOutLines() const { @@ -344,14 +364,63 @@ bool GeoSysController::showVolumeOutLines() const //____________________________________________________________________ void GeoSysController::emit_autoExpandByVolumeOrMaterialName() { - bool volname(sender()==m_d->ui_misc.pushButton_expand_vols_volname - ||sender()==m_d->ui_misc.lineEdit_expand_vols_volname); - QString name(volname?m_d->ui_misc.lineEdit_expand_vols_volname->text() - :m_d->ui_misc.lineEdit_expand_vols_matname->text()); - if (name.isEmpty()) - return; - messageVerbose("emitting autoExpandByVolumeOrMaterialName("+str(!volname)+", "+name+")"); - emit autoExpandByVolumeOrMaterialName(!volname,name); + // if we filter on visible objects, then... + if (sender()==m_d->ui_misc.pushButton_expand_vols_volname + || sender()==m_d->ui_misc.lineEdit_expand_vols_volname) + { + // check if a name is set in the 'volume' field + bool volname(sender()==m_d->ui_misc.pushButton_expand_vols_volname + ||sender()==m_d->ui_misc.lineEdit_expand_vols_volname); + + // get volume's or material's name + QString name(volname ? m_d->ui_misc.lineEdit_expand_vols_volname->text() + : m_d->ui_misc.lineEdit_expand_vols_matname->text()); + + // return if name is empty + if (name.isEmpty()) { + return; + } + + // emit the signal + messageVerbose("emitting autoExpandByVolumeOrMaterialName("+str(!volname)+", "+name+")"); + emit autoExpandByVolumeOrMaterialName(!volname,name); + } + // if we use the 'filter volumes' feature, then... + else if (sender()==m_d->ui_misc.pushButton_filter_logvolname + || sender()==m_d->ui_misc.lineEdit_filter_logvolname + || sender()==m_d->ui_misc.pushButton_filter_reset) + { + // handle as "filter" if was sent by the 'filter volume' field or 'Apply' button... + bool filter(sender()==m_d->ui_misc.pushButton_filter_logvolname + || sender()==m_d->ui_misc.lineEdit_filter_logvolname); + + // handle as "reset the view" if sent by the 'reset filters' button... + bool resetView(sender()==m_d->ui_misc.pushButton_filter_reset); + + // get additional options + int maxDepth(m_d->ui_misc.spinBox_maxDepth->value()==-1 ? 9999 : m_d->ui_misc.spinBox_maxDepth->value()); + bool stopAtFirst(m_d->ui_misc.radioButton_StopAtFirst->isChecked() ? true : false ); + bool visitChildren(m_d->ui_misc.radioButton_DoNotVisitChildren->isChecked() ? false : true); + + bool bymatname = false; // TODO: set this in the UI! + QString nameRegEx(m_d->ui_misc.lineEdit_filter_logvolname->text()); + + // return if name is empty + if (nameRegEx.isEmpty()) { + return; + } + + // clear regex if we are resetting the filters + if (resetView) { + m_d->ui_misc.radioButton_StopAtFirst->setChecked(true); + m_d->ui_misc.radioButton_DoNotVisitChildren->setChecked(true); + m_d->ui_misc.lineEdit_filter_logvolname->clear(); + } + + messageDebug("emitting signalFilterVolumes("+nameRegEx + ", " + str(bymatname) + ", " + str(maxDepth) + ", " + str(stopAtFirst)+ ", " + str(visitChildren) + ", " + str(resetView)+")"); + emit signalFilterVolumes(nameRegEx, bymatname, maxDepth, stopAtFirst, visitChildren, resetView); + } + return; } //____________________________________________________________________ diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx index 22d13f1607b1ba850dea45c5b4237502fcf59e55..3e97ae23600afe0426ec99427236e4f6ce62a528 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx @@ -1,22 +1,25 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ ///////////////////////////////////////////////////////////////////////// -// // -// Implementation of class VP1GeometrySystem // -// // -// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> // -// // -// Derived from V-atlas geometry system by Joe Boudreau. // -// Origins of initial version dates back to ~1996, initial VP1 // -// version by TK (May 2007) and almost entirely rewritten Oct 2007. // -// Major refactoring october 2008. // -// // -// Updates: // -// - Aug 2019, Riccardo Maria Bianchi @ CERN // -// - Aug 2020, Riccardo Maria Bianchi @ CERN // -// // +// +// Implementation of class VP1GeometrySystem +// +// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> +// +// Derived from V-atlas geometry system by Joe Boudreau. +// Origins of initial version dates back to ~1996, initial VP1 +// version by TK (May 2007) and almost entirely rewritten Oct 2007. +// Major refactoring october 2008. +// +// Updates: +// - Aug 2019, Riccardo Maria Bianchi @ CERN +// - Aug 2020, Riccardo Maria Bianchi @ CERN +// - Jul 2021, Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> +// * Added the 'filter volumes' tool +// * Added signal/slot to update transparency type in the 3D window +// ///////////////////////////////////////////////////////////////////////// // local includes @@ -198,7 +201,10 @@ public: static void catchKbdState(void *userData, SoEventCallback *CB); const SoKeyboardEvent *kbEvent; + void changeStateOfVisibleNonStandardVolumesRecursively(VolumeHandle*,VP1GeoFlags::VOLSTATE); + void changeStateOfAllVolumesRecursively(VolumeHandle*,VP1GeoFlags::VOLSTATE); void expandVisibleVolumesRecursively(VolumeHandle*,const QRegExp&,bool bymatname); + bool filterVolumesRec(VolumeHandle* vol, QRegExp selregexp, bool bymatname, bool stopAtFirst, bool visitChildren, bool resetView, bool &zapAll, bool &matchFound, unsigned &nFound, int maxIter = 1, unsigned int iter = 0); SoSeparator* m_textSep;//!< Separator used to hold all visible labels. @@ -295,7 +301,15 @@ QWidget * VP1GeometrySystem::buildController() connect(m_d->controller,SIGNAL(loadMaterialsFromFile(QString)),this,SLOT(loadMaterialsFromFile(QString))); connect(m_d->controller,SIGNAL(transparencyChanged(float)),this,SLOT(updateTransparency())); + + connect (m_d->controller,SIGNAL(volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE)), this,SLOT(volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE))); + connect (m_d->controller,SIGNAL(volumeResetRequested(VolumeHandle*)), this,SLOT(volumeResetRequested(VolumeHandle*))); + + + connect(m_d->controller,SIGNAL(actionOnAllNonStandardVolumes(bool)),this,SLOT(actionOnAllNonStandardVolumes(bool))); connect(m_d->controller,SIGNAL(autoExpandByVolumeOrMaterialName(bool,QString)),this,SLOT(autoExpandByVolumeOrMaterialName(bool,QString))); + connect(m_d->controller,SIGNAL(signalFilterVolumes(QString, bool, int, bool, bool, bool)),this,SLOT(filterVolumes(QString, bool, int, bool, bool, bool))); + connect(m_d->controller->requestOutputButton(), SIGNAL(clicked()), this, SLOT(saveTrees())); connect(m_d->controller,SIGNAL(displayLocalAxesChanged(int)), this, SLOT(toggleLocalAxes(int))); connect(m_d->controller,SIGNAL(axesScaleChanged(int)), this, SLOT(setAxesScale(int))); @@ -418,7 +432,6 @@ void VP1GeometrySystem::buildPermanentSceneGraph(StoreGateSvc*/*detstore*/, SoSe subsys->soswitch->whichChild = SO_SWITCH_ALL; //Enable in tree browser: m_d->volumetreemodel->enableSubSystem(subsys->flag); - // new ModelTest(m_d->volumetreemodel, m_d->treeView_volumebrowser); } if (!m_d->restoredTopvolstates.isEmpty()) { m_d->applyTopVolStates(m_d->restoredTopvolstates,false); @@ -498,7 +511,6 @@ GeoPhysVol* VP1GeometrySystem::Imp::createTheWorld(GeoPhysVol* world) const GeoMaterial* worldMat = new GeoMaterial("std::Air", densityOfAir); const GeoBox* worldBox = new GeoBox(2000*SYSTEM_OF_UNITS::cm, 2000*SYSTEM_OF_UNITS::cm, 2500*SYSTEM_OF_UNITS::cm); const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, worldMat); - // GeoPhysVol* worldPhys = new GeoPhysVol(worldLog); world = new GeoPhysVol(worldLog); } return world; @@ -612,17 +624,16 @@ GeoPhysVol* VP1GeometrySystem::Imp::getGeometryFromLocalDB() } } -// } // end if m_existingGeoInput - return world; - } +//_____________________________________________________________________________________ void VP1GeometrySystem::toggleLocalAxes(int i) { if (i==0) m_d->axesSwitch->whichChild=SO_SWITCH_NONE; else m_d->axesSwitch->whichChild=SO_SWITCH_ALL; } +//_____________________________________________________________________________________ void VP1GeometrySystem::setAxesScale(int i) { double x=(i-50)/25.0; double scale = pow(10,x); @@ -657,7 +668,6 @@ void VP1GeometrySystem::checkboxChanged() sw->enableNotify(save); //Enable in tree browser: m_d->volumetreemodel->enableSubSystem(subsys->flag); - // new ModelTest(m_d->volumetreemodel, m_d->treeView_volumebrowser); if (save) sw->touch(); } else { @@ -1031,7 +1041,7 @@ void VP1GeometrySystem::Imp::buildSystem(SubSystemInfo* si) VP1Msg::messageDebug("-- toptree vol: " + QString(it->volname.c_str()) ); // Get the material name from the top volume and search for it - // in the lsit of "default" materials for the sub-detectors: + // in the list of "default" materials for the sub-detectors: QString topMaterialName = QString::fromStdString(it->pV->getLogVol()->getMaterial()->getName()); VP1Msg::messageDebug("topMaterial: " + topMaterialName); SoMaterial* topMaterial = detVisAttributes->get(it->volname); @@ -1043,8 +1053,13 @@ void VP1GeometrySystem::Imp::buildSystem(SubSystemInfo* si) } VolumeHandleSharedData* volhandle_subsysdata = new VolumeHandleSharedData(controller, - si->flag, &sonodesep2volhandle, it->pV, phisectormanager, - topMaterial, matVisAttributes, volVisAttributes, + si->flag, + &sonodesep2volhandle, + it->pV, + phisectormanager, + topMaterial, + matVisAttributes, + volVisAttributes, controller->zappedVolumeListModel(), controller->volumeTreeBrowser(), m_textSep); @@ -1069,7 +1084,6 @@ void VP1GeometrySystem::Imp::buildSystem(SubSystemInfo* si) //Perform auto expansion of all ether volumes (needed for muon dead material): VolumeHandle::VolumeHandleListItr it, itE(si->vollist.end()); - // int idx=0; // for debug for (it = si->vollist.begin(); it!=itE; ++it){ (*it)->expandMothersRecursivelyToNonEther(); } @@ -1282,10 +1296,12 @@ void VP1GeometrySystem::autoExpandByVolumeOrMaterialName(bool bymatname,QString return; } - messageVerbose("Auto expansions of visible volumes requested. Target all volumes with " + messageVerbose("Auto expansions of **visible** volumes requested. Target all volumes with " +str(bymatname?"material name":"name")+" matching "+targetname); - QRegExp selregexp(targetname,Qt::CaseSensitive,QRegExp::Wildcard); + //QRegExp selregexp(targetname,Qt::CaseSensitive,QRegExp::Wildcard); + QRegExp selregexp(targetname, Qt::CaseSensitive, QRegExp::RegExp); + VP1Msg::messageDebug("RegExp pattern: " + selregexp.pattern() ); std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; m_d->volumetreemodel->getRootHandles(roothandles); @@ -1294,49 +1310,95 @@ void VP1GeometrySystem::autoExpandByVolumeOrMaterialName(bool bymatname,QString bool save = m_d->sceneroot->enableNotify(false); m_d->phisectormanager->largeChangesBegin(); - deselectAll(); + if (roothandles.size() == 0) { + VP1Msg::messageWarningRed("No root nodes selected! Please select at least a root node before trying to apply filters. Ideally, you should turn on only the root node containing the volumes you are interested in; e.g., turn on the 'Endcap MDT' root node, if you are looking for an EIL chamber."); + } else { + bool save = m_d->sceneroot->enableNotify(false); + m_d->phisectormanager->largeChangesBegin(); - for (unsigned i = 0; i<roothandles.size();++i) { - it = roothandles.at(i).first; - itE = roothandles.at(i).second; - for(;it!=itE;++it) - m_d->expandVisibleVolumesRecursively(*it,selregexp,bymatname); - } + deselectAll(); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); + for (unsigned i = 0; i<roothandles.size();++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + bool matchFound = false; + + for(;it!=itE;++it) { + VolumeHandle* vol = *it; + VP1Msg::messageDebug("Looking inside the root node [name: " + vol->getName() + ", material: " + QString::fromStdString(vol->geoMaterial()->getName()) + "]" ); + m_d->expandVisibleVolumesRecursively(vol, selregexp, bymatname); + } + } + + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); + } } } //_____________________________________________________________________________________ void VP1GeometrySystem::Imp::expandVisibleVolumesRecursively(VolumeHandle* handle,const QRegExp& selregexp,bool bymatname) { - if (handle->state()==VP1GeoFlags::ZAPPED) + //if (handle->state()==VP1GeoFlags::ZAPPED) + // return; + VP1Msg::messageDebug("VP1GeometrySystem::Imp::expandVisibleVolumesRecursively()"); + if (handle->state()==VP1GeoFlags::ZAPPED) { + VP1Msg::messageDebug(handle->getName() +" is ZAPPED. Returning..."); return; + } + if (handle->state()==VP1GeoFlags::CONTRACTED) { + VP1Msg::messageDebug(handle->getName() +" is CONTRACTED. Going on..."); //See if we match (and have children) - if so, update state. if (handle->nChildren()>0 - && selregexp.exactMatch(bymatname?QString(handle->geoMaterial()->getName().c_str()):handle->getName())) { + && selregexp.exactMatch(bymatname?QString(handle->geoMaterial()->getName().c_str()):handle->getName())) + { + VP1Msg::messageDebug(handle->getName() +" has >0 children: OK! Setting it to 'EXPANDED'."); handle->setState(VP1GeoFlags::EXPANDED); } + VP1Msg::messageDebug(handle->getName() +" - Now returning..."); return; } + //Must be expanded: Let us call on any (initialised) children instead. - if (handle->nChildren()==0||!handle->childrenAreInitialised()) + if (handle->nChildren()==0||!handle->childrenAreInitialised()) { + VP1Msg::messageDebug(handle->getName() +" has NO children or they are not initialized. Returning..."); return; + } + + //TODO: does the code comes here ever??? Check! + VP1Msg::messageDebug(handle->getName() +" - Now looping over children..."); VolumeHandle::VolumeHandleListItr it(handle->childrenBegin()), itE(handle->childrenEnd()); - for(;it!=itE;++it) + for(;it!=itE;++it) { expandVisibleVolumesRecursively(*it,selregexp,bymatname); + } } +//_____________________________________________________________________________________ +void VP1GeometrySystem::volumeStateChangeRequested(VolumeHandle*vh,VP1GeoFlags::VOLSTATE state) +{ + //might not use this slot presently... + if (!vh) + return; + deselectAll(); + vh->setState(state); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); +} - - +//_____________________________________________________________________________________ +void VP1GeometrySystem::volumeResetRequested(VolumeHandle*vh) +{ + if (!vh) + return; + deselectAll(); + vh->reset(); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); +} //_____________________________________________________________________________________ @@ -1447,7 +1509,7 @@ void VP1GeometrySystem::loadMaterialsFromFile(QString filename) - +//_____________________________________________________________________________________ void VP1GeometrySystem::saveTrees() { #ifdef __APPLE__ char buffer[1024]; @@ -1496,6 +1558,7 @@ void VP1GeometrySystem::saveTrees() { world->unref(); } +//_____________________________________________________________________________________ GeoPhysVol *VP1GeometrySystem::newWorld() const { const double gr = SYSTEM_OF_UNITS::gram; const double mole = SYSTEM_OF_UNITS::mole; @@ -1520,3 +1583,277 @@ GeoPhysVol *VP1GeometrySystem::newWorld() const { GeoPhysVol* world = new GeoPhysVol(worldLog); return world; } + + +//_____________________________________________________________________________________ +void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, int maxDepth = 1, bool stopAtFirst = true, bool visitChildren = false, bool resetView = false) +{ + + // initialize the regular expression + QRegExp selregexp(targetname, Qt::CaseSensitive, QRegExp::RegExp); + // VP1Msg::messageDebug("RegExp pattern: " + selregexp.pattern() ); + + QStringList ll; + ll << "VP1GeometrySystem::filterVolumes" << "RegExp pattern:" << selregexp.pattern() + << "- maxDepth:" << QString::number(maxDepth) + << "- stopAtFirst:" << QString::number(stopAtFirst) + << "- visitChildren:" << QString::number(visitChildren) + << "- resetView:" << QString::number(resetView); + VP1Msg::messageDebug(ll.join(" ")); + + + // get root handles list + std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; + m_d->volumetreemodel->getRootHandles(roothandles); + VolumeHandle::VolumeHandleListItr it, itE; + + bool save = m_d->sceneroot->enableNotify(false); + m_d->phisectormanager->largeChangesBegin(); + deselectAll(); + + bool zapAll = false; // TODO: do we need that? + bool matchFound = false; + unsigned nFound = 0; + + // loop over root handles + for (unsigned i = 0; i<roothandles.size();++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + + // loop over root volumes + for(;it!=itE;++it) { + + VolumeHandle* handle = (*it); + + VP1Msg::messageDebug("Looking at the root node [name: " + handle->getName() + ", mat: " + QString::fromStdString(handle->geoMaterial()->getName()) + "]" ); + m_d->filterVolumesRec(handle, selregexp, bymatname, stopAtFirst, visitChildren, resetView, zapAll, matchFound, nFound, maxDepth); + VP1Msg::messageDebug("matchFound: " + QString::number(matchFound)); + + if (resetView) { + VP1Msg::messageDebug("'expanding' and 'contracting' the root volume..."); + // in the call to 'filterVolumesRec' above, when resetting the view, + // we have 'contracted' the root volume and all the children we had 'zapped' before. + // So, now we need to open ('expand'), and then close ('contract') the root volume again, + // in order to get rid of the manually-contracted volumes. + handle->setState(VP1GeoFlags::EXPANDED); + handle->setState(VP1GeoFlags::CONTRACTED); + } + + } // end loop over root volumes + } // loop over root handles + + // give feedback to the user + message("[filter volumes] # of matching volumes: " + QString::number(nFound)); + + //if user chose to visit children of matching volumes, + //then we change transparency type to 'Sorted Object Blend', usually better to visualize nested volumes + if (visitChildren && (nFound>0) ) { + message( QString("[filter volumes] NOTE: to show both matching mother and matching daughter volumes, ") + + QString("transparency has been set to 50% and transparency type has been changed to 'Sorted Object Blend', ") + + QString("which is usually better to visualize nested geometry volumes. ") + + QString("You can disable this auto-setting by checking the 'lock'.") ); + if ( ! m_d->controller->isTranspLocked()) { + m_d->controller->setTransparency(50); + emit updateTransparencyType( VP1QtInventorUtils::transparencyTypeToInt(SoGLRenderAction::SORTED_OBJECT_BLEND) ); + } + } + + + VP1Msg::messageDebug("largeChangesEnding..."); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); + } + +} +//_____________________________________________________________________________________ +bool VP1GeometrySystem::Imp::filterVolumesRec(VolumeHandle* handle, QRegExp selregexp, bool bymatname, bool stopAtFirst, bool visitChildren, bool resetView, bool &zapAll, bool &matchFound, unsigned &nFound, int maxIter, unsigned int iter) +{ + if (!zapAll) { + VP1Msg::messageDebug2("iteration: " + QString::number(iter) + ", maxIter: " + QString::number(maxIter)); + VP1Msg::messageDebug2("looking into volume: " + handle->getName()); + } + + // zap the current volume by default... + handle->setState(VP1GeoFlags::ZAPPED); + + VP1Msg::messageDebug2("filtering: " + handle->getName() ); + + if ( !zapAll ) { + if ( !resetView ) { + //... then unzap the volume if it matches the filter regex + if (selregexp.exactMatch( bymatname ? QString(handle->geoMaterial()->getName().c_str()) : handle->getName()) ) + { + matchFound = true; + ++nFound; + VP1Msg::messageDebug(handle->getName() +" - **MATCH!** - 'Contracting' it (-->make it visible)..."); + handle->setState(VP1GeoFlags::CONTRACTED); // match, make the matching volume visible + // if a matching volume was found and 'stop at first' option was choosen, then stop here + //VP1Msg::messageDebug2("matchFound: " + QString::number(matchFound) + " - stopAtFirst: " + QString::number(stopAtFirst)); + + if (stopAtFirst && matchFound) { + VP1Msg::messageDebug("\tYou chose to show only the first matching volume, so we stop here - exiting from the inner children loop..."); + //return matchFound; + zapAll = true; + } + } else { + VP1Msg::messageDebug2("not matching --> zapping it"); + handle->setState(VP1GeoFlags::ZAPPED); // no match, open the volume to show its children + } + } + if (resetView) { + if(handle->state()!=VP1GeoFlags::CONTRACTED) { + VP1Msg::messageDebug2("resetView --> contracting it"); + handle->setState(VP1GeoFlags::CONTRACTED); // open the volume to show its children + } + } + } // end if !zapAll + + + // check iterations, a.k.a., the 'maxDepth', i.e., the number of layers of daughter volumes visited + if( maxIter != -1 && iter == maxIter) { + VP1Msg::messageDebug("maxIter [" + QString::number(iter) + "] reached, returning from the recursive method and go to the next upper volume..."); + return matchFound; + } + // increment the iteration number + iter++; + + // if no match yet, + // or if user asked to visit children of matching volumes too, + // then loop over children + if ( !matchFound || (matchFound && visitChildren) ) { + if (!zapAll) { + VP1Msg::messageDebug2("No match, or you chose to inspect all child volumes, so we look into the children..."); + } + if (handle->nChildren()>0) { + // get children list + handle->initialiseChildren(); + VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()),itChlE(handle->childrenEnd()); + for (;itChl!=itChlE;++itChl) { + + VolumeHandle* child = (*itChl); + + // filter children volumes recursively + filterVolumesRec(child, selregexp, bymatname, stopAtFirst, visitChildren, resetView, zapAll, matchFound, nFound, maxIter, iter); + if (stopAtFirst && matchFound) { + //return matchFound; + zapAll = true; + } + } // end loop over children + + if (resetView) { + // in the call to 'filterVolumesRec' above, when resetting the view, + // we have 'contracted' the root volume and all the children we had 'zapped' before. + // So, now we need to open ('expand'), and then close ('contract') the root volume again, + // in order to get rid of the manually-contracted volumes. + handle->setState(VP1GeoFlags::EXPANDED); + handle->setState(VP1GeoFlags::CONTRACTED); + } + } + } + + return matchFound; +} + + + + + + + + + + + +// ========================= + +//////// +// Methods which come from VP1 and have been rplaced by other methods, +// but they are useful for later use, +// when we try to act on all volumes +//////// + +// Not used at the moment, but useful +//_____________________________________________________________________________________ +void VP1GeometrySystem::Imp::changeStateOfAllVolumesRecursively(VolumeHandle*handle,VP1GeoFlags::VOLSTATE target) +{ + handle->initialiseChildren(); + handle->setState(target); + VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()),itChlE(handle->childrenEnd()); + + // loop over second level children + for (;itChl!=itChlE;++itChl) { + changeStateOfAllVolumesRecursively(*itChl, target); + } +} + + +// Not used at the moment, but useful +//_____________________________________________________________________________________ +void VP1GeometrySystem::Imp::changeStateOfVisibleNonStandardVolumesRecursively(VolumeHandle*handle,VP1GeoFlags::VOLSTATE target) +{ + assert(target!=VP1GeoFlags::CONTRACTED); + if (handle->isAttached()) { + //The volume is visible, so ignore daughters + if (handle->isInitialisedAndHasNonStandardShape()) { + if (target!=VP1GeoFlags::EXPANDED||handle->nChildren()>0) + handle->setState(target); + } + return; + } else if (handle->state()==VP1GeoFlags::ZAPPED) + return; + //Must be expanded: Let us call on any (initialised) children instead. + if (handle->nChildren()==0||!handle->childrenAreInitialised()) + return; + VolumeHandle::VolumeHandleListItr it(handle->childrenBegin()), itE(handle->childrenEnd()); + for(;it!=itE;++it) + changeStateOfVisibleNonStandardVolumesRecursively(*it, target); +} + +// Not used at the moment, but useful +//_____________________________________________________________________________________ +void VP1GeometrySystem::actionOnAllNonStandardVolumes(bool zap) +{ + actionOnAllVolumes(zap, false); +} + +// Not used at the moment, but useful +//_____________________________________________________________________________________ +void VP1GeometrySystem::actionOnAllVolumes(bool zap, bool standardVolumes /* default: true*/) +{ + //VP1GeoFlags::VOLSTATE target = zap ? VP1GeoFlags::ZAPPED : VP1GeoFlags::EXPANDED; + VP1GeoFlags::VOLSTATE target = zap ? VP1GeoFlags::ZAPPED : VP1GeoFlags::CONTRACTED; + messageVerbose("Action on volumes with non-standard VRML representations. Target state is "+VP1GeoFlags::toString(target)); + + std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; + m_d->volumetreemodel->getRootHandles(roothandles); + VolumeHandle::VolumeHandleListItr it, itE; + + bool save = m_d->sceneroot->enableNotify(false); + m_d->phisectormanager->largeChangesBegin(); + + deselectAll(); + + for (unsigned i = 0; i<roothandles.size();++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + for(;it!=itE;++it) { + if (standardVolumes) { + m_d->changeStateOfAllVolumesRecursively(*it, target); + } else { + m_d->changeStateOfVisibleNonStandardVolumesRecursively(*it, target); + } + } + } + + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); + } +} + + diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx index e6001ea5d937288589267b490481b0f57a0c9e41..d40b20423f1811b54863f60bdcc89b6f6a995183 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx @@ -73,6 +73,7 @@ public: static VolState getChildStates(const VolumeHandle*theclass ); static void applyChildStates(const VolState&,VolumeHandle*theclass); + static bool hasNonStandardShapeChildren(const SoGroup*g); }; @@ -181,7 +182,7 @@ bool VolumeHandle::hasName(const std::string& n) const //____________________________________________________________________ SoMaterial * VolumeHandle::material() { - VP1Msg::messageDebug("VolumeHandle::material() - LogVol name: " + QString::fromStdString(m_d->pV->getLogVol()->getName())); + VP1Msg::messageDebug2("VolumeHandle::material() - LogVol name: " + QString::fromStdString(m_d->pV->getLogVol()->getName())); // if it's not the first time here and // the material has been assigned already, then return that if (m_d->material) @@ -238,7 +239,7 @@ SoSeparator * VolumeHandle::nodeSoSeparator() const //____________________________________________________________________ void VolumeHandle::ensureBuildNodeSep() { - VP1Msg::messageDebug("VolumeHandle::ensureBuildNodeSep()"); + VP1Msg::messageDebug3("VolumeHandle::ensureBuildNodeSep()"); if (m_d->nodesep && m_d->label_sep) return; @@ -344,15 +345,15 @@ void VolumeHandle::ensureBuildNodeSep() //____________________________________________________________________ void VolumeHandle::Imp::attach(VolumeHandle*vh) { - VP1Msg::messageDebug("VolumeHandle::Imp::attach() - name: " + vh->getName()); + VP1Msg::messageDebug3("VolumeHandle::Imp::attach() - name: " + vh->getName()); if (!isattached) { vh->ensureBuildNodeSep(); if (attachsepHelper) { - VP1Msg::messageDebug("adding node..."); + VP1Msg::messageDebug3("adding node..."); attachsepHelper->addNodeUnderMaterial(nodesep,vh->material()); } if (attachlabelSepHelper) { - VP1Msg::messageDebug("adding label..."); + VP1Msg::messageDebug3("adding label..."); attachlabelSepHelper->addNode(label_sep); } isattached=true; @@ -682,6 +683,35 @@ void VolumeHandle::Imp::applyChildStates(const VolState& vs,VolumeHandle*theclas } +//____________________________________________________________________ +bool VolumeHandle::Imp::hasNonStandardShapeChildren(const SoGroup*g) +{ + const int n(g->getNumChildren()); + for (int i=0; i < n; ++i) { + const SoNode*c = g->getChild(i); + if (c->getTypeId().isDerivedFrom(SoShape::getClassTypeId())) { + if (c->getTypeId().isDerivedFrom(SoPcons::getClassTypeId()) + ||c->getTypeId().isDerivedFrom(SoPolyhedron::getClassTypeId()) + ||c->getTypeId().isDerivedFrom(SoTransparency::getClassTypeId())) + return true; + } else if (c->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) { + if (hasNonStandardShapeChildren(static_cast<const SoGroup*>(c))) + return true; + } + } + return false; +} + +//____________________________________________________________________ +bool VolumeHandle::isInitialisedAndHasNonStandardShape() const +{ + VP1HEPVisUtils::initAllCustomClasses(); + return m_d->nodesep ? Imp::hasNonStandardShapeChildren(m_d->nodesep) : false; +} + + + + //____________________________________________________________________ bool VolumeHandle::isPositiveZ() const { diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VolumeTreeModel.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VolumeTreeModel.cxx index addc936508f3f5a20074b70bb6bb534d5f6476d8..64a6f3e10b36e0241eae099518b6b388ddff6454 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VolumeTreeModel.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VolumeTreeModel.cxx @@ -337,11 +337,17 @@ QVariant VolumeTreeModel::data(const QModelIndex& index, int role) const else return QColor::fromRgbF( 0.5, 0.5, 0.5 ); } + //DisplayRole: - if (volumeHandle->nChildren()>1) - return volumeHandle->getName() + " (" + QString::fromStdString(volumeHandle->geoMaterial()->getName()) + ") [" + QString::number(volumeHandle->nChildren())+"]"; + + QString volState = "e"; + if(volumeHandle->state()==VP1GeoFlags::CONTRACTED) volState = "c"; + else if(volumeHandle->state()==VP1GeoFlags::ZAPPED) volState = "z"; + + if (volumeHandle->nChildren()>0) + return volumeHandle->getName() + " (" + QString::fromStdString(volumeHandle->geoMaterial()->getName()) + ") [" + QString::number(volumeHandle->nChildren())+"] ("+ volState + ")" ; else - return volumeHandle->getName() + " (" + QString::fromStdString(volumeHandle->geoMaterial()->getName()) + ")"; + return volumeHandle->getName() + " (" + QString::fromStdString(volumeHandle->geoMaterial()->getName()) + ") ("+ volState + ")" ; } if (role==Qt::TextColorRole) diff --git a/GeoModelVisualization/VP1GeometrySystems/src/settings_misc_form.ui b/GeoModelVisualization/VP1GeometrySystems/src/settings_misc_form.ui index da0b4cd0d52287e59120c693ebfc03a5030ac8cd..76bb969dc337fd788dbfdfa09a33c062227e9b85 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/settings_misc_form.ui +++ b/GeoModelVisualization/VP1GeometrySystems/src/settings_misc_form.ui @@ -6,20 +6,50 @@ <rect> <x>0</x> <y>0</y> - <width>370</width> - <height>425</height> + <width>387</width> + <height>701</height> </rect> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Ignored"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>701</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>387</width> + <height>701</height> + </size> + </property> <property name="windowTitle"> - <string>Form</string> + <string>Mis. settings</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QGroupBox" name="groupBox"> + <layout class="QGridLayout" name="gridLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> + <item row="0" column="0"> + <widget class="QGroupBox" name="actionsGroupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="title"> <string>Actions on visible volumes</string> </property> <layout class="QGridLayout" name="_5"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> <property name="leftMargin"> <number>4</number> </property> @@ -98,29 +128,260 @@ p, li { white-space: pre-wrap; } </layout> </widget> </item> - <item> - <layout class="QHBoxLayout" name="_10"> - <item> - <spacer> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_close"> - <property name="text"> - <string>&Close</string> - </property> - </widget> - </item> - </layout> + <item row="1" column="0"> + <widget class="QGroupBox" name="filtersGroupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Filter volumes</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QLabel" name="label_filter_logVolName"> + <property name="text"> + <string>LogVol's name:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_filter_logvolname"> + <property name="toolTip"> + <string>Filter geometry volumes based on the name of the GeoLogVol node. You can use regular expressions and wildcards (*).</string> + </property> + <property name="placeholderText"> + <string>ex: Inner.* [regexp]</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_filter_logvolname"> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_maxDepth"> + <property name="toolTip"> + <string>The maximum number of daughter volumes visited. Note: default is '1'; '0' means 'only root/top volumes'; '-1' means 'MAX', but can be VERY slow depending on the geometry complexity.</string> + </property> + <property name="statusTip"> + <string>The maximum number of daughter volumes visited. Note: default is '1'; '0' means 'only root/top volumes'; '-1' means 'MAX', but can be VERY slow depending on the geometry complexity.</string> + </property> + <property name="whatsThis"> + <string>The maximum number of daughter volumes visited. Note: default is '1'; '0' means 'only root/top volumes'; '-1' means 'MAX', but can be VERY slow depending on the geometry complexity.</string> + </property> + <property name="text"> + <string>max. depth</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_maxDepth"> + <property name="toolTip"> + <string>The maximum number of daughter volumes visited. Note: default is '1'; '0' means 'only root/top volumes'; '-1' means 'MAX', but can be VERY slow depending on the geometry complexity.</string> + </property> + <property name="statusTip"> + <string>The maximum number of daughter volumes visited. Note: default is '1'; '0' means 'only root/top volumes'; '-1' means 'MAX', but can be VERY slow depending on the geometry complexity.</string> + </property> + <property name="whatsThis"> + <string>The maximum number of daughter volumes visited. Note: default is '1'; '0' means 'only root/top volumes'; '-1' means 'MAX', but can be VERY slow depending on the geometry complexity.</string> + </property> + <property name="minimum"> + <number>-1</number> + </property> + <property name="maximum"> + <number>99</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>[0: top volumes; -1: All (slower)]</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>How many matching volumes should I show?</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QRadioButton" name="radioButton_StopAtFirst"> + <property name="toolTip"> + <string>Default. Stop after a first match has been found. Useful for a quick check.</string> + </property> + <property name="text"> + <string>Show the first match</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioButton_LoopOverAll"> + <property name="toolTip"> + <string>Look for all volumes matching the filter string. ATTENTION, it can take a lof of time.</string> + </property> + <property name="text"> + <string>Show all (slower)</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_4"> + <property name="title"> + <string>Do you want to visit children of matching volumes?</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="1"> + <widget class="QRadioButton" name="radioButton_VisitAllChildren"> + <property name="toolTip"> + <string>When a volume matches the filter, do visit all its child volumes as well. It can be slow.</string> + </property> + <property name="statusTip"> + <string>When a volume matches the filter, do visit all its child volumes as well. It can be slow.</string> + </property> + <property name="whatsThis"> + <string>When a volume matches the filter, do visit all its child volumes as well. It can be slow.</string> + </property> + <property name="accessibleDescription"> + <string>When a volume matches the filter, do visit all its child volumes as well. It can be slow.</string> + </property> + <property name="text"> + <string>Visit All Children</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QRadioButton" name="radioButton_DoNotVisitChildren"> + <property name="toolTip"> + <string>Default. When a volume matches the filter, do not visit its child volumes.</string> + </property> + <property name="text"> + <string>Do Not Visit Children</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="lockTransp"> + <property name="toolTip"> + <string>When enabling 'Visit All Children', if there are matching daughter to be shown inside a matching mother volume, then the transparency will be automatically set to 50% and set to a given type, to ease the visualization of nested volumes. You can disable this by checking this.</string> + </property> + <property name="statusTip"> + <string>When enabling 'Visit All Children', if there are matching daughter to be shown inside a matching mother volume, then the transparency will be automatically set to 50% and set to a given type, to ease the visualization of nested volumes. You can disable this by checking this.</string> + </property> + <property name="whatsThis"> + <string>When enabling 'Visit All Children', if there are matching daughter to be shown inside a matching mother volume, then the transparency will be automatically set to 50% and set to a given type, to ease the visualization of nested volumes. You can disable this by checking this.</string> + </property> + <property name="accessibleDescription"> + <string>When enabling 'Visit All Children', if there are matching daughter to be shown inside a matching mother volume, then the transparency will be automatically set to 50% and set to a given type. You can disable this by checking this.</string> + </property> + <property name="text"> + <string>[lock transparency]</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>(slower)</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_filter_reset"> + <property name="toolTip"> + <string>Visualize all volumes by removing all filters.</string> + </property> + <property name="text"> + <string>Reset filters</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="bottomLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_close"> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </item> + </layout> + </widget> </item> </layout> </widget>