From c0cd2fab1ad95045e4b3d142c077a07e1642d1c7 Mon Sep 17 00:00:00 2001 From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> Date: Wed, 28 Jul 2021 19:13:27 +0200 Subject: [PATCH] Speed up the filter volumes, fix the reset, add options. --- .../VP1Base/IVP13DStandardChannelWidget.h | 4 + .../src/IVP13DStandardChannelWidget.cxx | 13 +- .../VP1GeometrySystems/GeoSysController.h | 5 +- .../VP1GeometrySystems/VP1GeometrySystem.h | 11 +- .../src/GeoSysController.cxx | 29 +- .../src/VP1GeometrySystem.cxx | 277 ++++++++++-------- .../VP1GeometrySystems/src/VolumeHandle.cxx | 8 +- .../src/VolumeTreeModel.cxx | 12 +- .../src/settings_misc_form.ui | 203 ++++++++++--- 9 files changed, 389 insertions(+), 173 deletions(-) diff --git a/GeoModelVisualization/VP1Base/VP1Base/IVP13DStandardChannelWidget.h b/GeoModelVisualization/VP1Base/VP1Base/IVP13DStandardChannelWidget.h index d65b4b713..22c51305c 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/src/IVP13DStandardChannelWidget.cxx b/GeoModelVisualization/VP1Base/src/IVP13DStandardChannelWidget.cxx index 24b262f2f..bc968161b 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/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h index 764fd6cb6..88dfb470f 100644 --- a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h +++ b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/GeoSysController.h @@ -80,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 @@ -99,7 +102,7 @@ signals: //void autoExpandByVolumeOrMaterialName(bool, QString, bool, bool stopAtFirst=true, bool doNotVisitChildren=false); //volname: (false,namestr), matname: (true,namestr), filter (true/false) void volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE);//Might not be used atm. void volumeResetRequested(VolumeHandle*); - void signalFilterVolumes(QString, bool, bool, bool, bool); + void signalFilterVolumes(QString, bool, int, bool, bool, bool); void saveMaterialsToFile(QString,bool);//(filename,onlyChangedMaterials) void loadMaterialsFromFile(QString);//filename void displayLocalAxesChanged(int); diff --git a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h index fcb8fd45c..f79192644 100644 --- a/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h +++ b/GeoModelVisualization/VP1GeometrySystems/VP1GeometrySystems/VP1GeometrySystem.h @@ -21,11 +21,17 @@ #include "VP1GeometrySystems/VP1GeoFlags.h" #include "VP1GeometrySystems/VolumeHandle.h"//fixme #include "GeoModelKernel/GeoPhysVol.h" +//#include <Inventor/actions/SoGLRenderAction.h> #include <set> #include <map> #include <QStack> #include <QString> +// FWD declarations +//class SoGLRenderAction; + + + class VP1GeometrySystem : public IVP13DSystemSimple { Q_OBJECT @@ -52,6 +58,9 @@ public: QByteArray saveState(); void restoreFromState(QByteArray); +signals: + void updateTransparencyType(unsigned type); + public slots: void setCurvedSurfaceRealism(int);//Accepts values in the range 0..100. @@ -68,7 +77,7 @@ protected slots: 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, bool stopAtFirst, bool visitChildren, bool reset); + void filterVolumes(QString targetname, bool bymatname, int maxDepth, bool stopAtFirst, bool visitChildren, bool reset); void setShowVolumeOutLines(bool); diff --git a/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx b/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx index 5be138d2d..dbddcd0a7 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/GeoSysController.cxx @@ -136,6 +136,11 @@ GeoSysController::GeoSysController(IVP1System * sys) 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))); + // TODO: shrink the widgets' layout to make the whole form smaller + // started, but vonly those settings below are not enough... + //m_d->ui_misc.bottomLayout->layout()->setSizeConstraint(QLayout::SetFixedSize); + //m_d->ui_misc.actionsGroupBox->layout()->setSizeConstraint(QLayout::SetFixedSize); + //m_d->ui_misc.filtersGroupBox->layout()->setSizeConstraint(QLayout::SetFixedSize); setLastSelectedVolume(0); @@ -280,6 +285,11 @@ PhiSectionWidget * GeoSysController::phiSectionWidget() const return m_d->ui_disp.phisectionwidget; } +////____________________________________________________________________ +//QTextBrowser* GeoSysController::getFiltersTextOut() const { + //return m_d->ui_misc.textOut; +//} + //____________________________________________________________________ ZappedVolumeListModel * GeoSysController::zappedVolumeListModel() const { @@ -348,6 +358,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 { @@ -433,6 +457,7 @@ void GeoSysController::emit_autoExpandByVolumeOrMaterialName() 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); @@ -451,8 +476,8 @@ void GeoSysController::emit_autoExpandByVolumeOrMaterialName() m_d->ui_misc.lineEdit_filter_logvolname->clear(); } - messageDebug("emitting signalFilterVolumes("+nameRegEx + ", " + str(bymatname) + ", " + str(stopAtFirst)+ ", " + str(visitChildren) + ", " + str(resetView)+")"); - emit signalFilterVolumes(nameRegEx, bymatname, stopAtFirst, visitChildren, resetView); + 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 64176f745..5bd4f4b29 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx @@ -202,7 +202,7 @@ public: void changeStateOfAllVolumesRecursively(VolumeHandle*,VP1GeoFlags::VOLSTATE); void expandVisibleVolumesRecursively(VolumeHandle*,const QRegExp&,bool bymatname); //bool filterVolumesRecursively(VolumeHandle*, const QRegExp&, bool bymatname, bool stopAtFirst, bool doNotVisitChildren); - bool filterVolumesRec(VolumeHandle* vol, QRegExp selregexp, bool bymatname, bool stopAtFirst, bool visitChildren, bool resetView, bool zapAll, unsigned int iter = 0); + 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. @@ -307,7 +307,7 @@ QWidget * VP1GeometrySystem::buildController() connect(m_d->controller,SIGNAL(actionOnAllNonStandardVolumes(bool)),this,SLOT(actionOnAllNonStandardVolumes(bool))); //connect(m_d->controller,SIGNAL(autoExpandByVolumeOrMaterialName(bool,QString, bool, bool, bool)),this,SLOT(autoExpandByVolumeOrMaterialName(bool,QString, bool, bool, bool))); connect(m_d->controller,SIGNAL(autoExpandByVolumeOrMaterialName(bool,QString)),this,SLOT(autoExpandByVolumeOrMaterialName(bool,QString))); - connect(m_d->controller,SIGNAL(signalFilterVolumes(QString, bool, bool, bool, bool)),this,SLOT(filterVolumes(QString, bool, bool, bool, bool))); + 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))); @@ -1330,7 +1330,7 @@ void VP1GeometrySystem::autoExpandByVolumeOrMaterialName(bool bymatname,QString for(;it!=itE;++it) { VolumeHandle* vol = *it; - VP1Msg::messageDebug("Looking inside root node - name: " + vol->getName() + " - mat: " + QString::fromStdString(vol->geoMaterial()->getName()) ); + VP1Msg::messageDebug("Looking inside the root node [name: " + vol->getName() + ", material: " + QString::fromStdString(vol->geoMaterial()->getName()) + "]" ); m_d->expandVisibleVolumesRecursively(vol, selregexp, bymatname); } } @@ -1558,7 +1558,7 @@ void VP1GeometrySystem::loadMaterialsFromFile(QString filename) - +//_____________________________________________________________________________________ void VP1GeometrySystem::saveTrees() { #ifdef __APPLE__ char buffer[1024]; @@ -1607,6 +1607,7 @@ void VP1GeometrySystem::saveTrees() { world->unref(); } +//_____________________________________________________________________________________ GeoPhysVol *VP1GeometrySystem::newWorld() const { const double gr = SYSTEM_OF_UNITS::gram; const double mole = SYSTEM_OF_UNITS::mole; @@ -1634,81 +1635,36 @@ GeoPhysVol *VP1GeometrySystem::newWorld() const { //_____________________________________________________________________________________ -void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, bool stopAtFirst = true, bool visitChildren = false, bool resetView = false) +void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, int maxDepth = 1, bool stopAtFirst = true, bool visitChildren = false, bool resetView = false) { - bool matchFound = false; 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(" ")); - if (resetView) { - VP1Msg::messageDebug("reset the view..."); - actionOnAllVolumes(false); // we 'contract' all the volumes - foreach (Imp::SubSystemInfo * si, m_d->subsysInfoList) { - std::cout << "Resetting the system: " << si << " : " << si->systemName << std::endl; - - /* - std::vector<SubSystemInfo::TreetopInfo>::const_iterator it, itE = si->treetopinfo.end(); - for (it=si->treetopinfo.begin(); it!=itE; ++it) - { - VP1Msg::messageDebug("-- toptree vol: " + QString(it->volname.c_str()) ); - } - */ - } - - //return; - } else { - // first pass: clean the view by zapping all volumes recursively - VP1Msg::messageDebug("first pass: clean the view, zap all volumes"); - actionOnAllVolumes(true); // we 'zap' the volumes - } - - /* - // We loop over all volumes to: - // - reset the view, by expanding all volumes, and return - // - prepare the view to show the filtered volumes, by zapping all volumes - bool save = m_d->sceneroot->enableNotify(false); - m_d->phisectormanager->largeChangesBegin(); - deselectAll(); - // get handles - for (unsigned i = 0; i<roothandles.size();++i) { - it = roothandles.at(i).first; - itE = roothandles.at(i).second; - - // loop over root handles - for(;it!=itE;++it) { - - VolumeHandle* handle = (*it); - - VP1Msg::messageDebug("Looking inside root node - name: " + handle->getName() + " - mat: " + QString::fromStdString(handle->geoMaterial()->getName()) ); - - if (resetView) { - VP1Msg::messageDebug("reset the view..."); - m_d->filterVolumesRec(handle, selregexp, bymatname, false, false, true, false); - return; - } else { - // first pass: clean the view by zapping all volumes recursively - VP1Msg::messageDebug("first pass: clean the view, zap all volumes"); - m_d->filterVolumesRec(handle, selregexp, bymatname, false, false, false, true); - } - } // end loop over root handles - } // loop over root handles list - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); - } - */ - - VP1Msg::messageDebug("second pass: filter matching volumes and make them visible"); + //if (resetView) { + //VP1Msg::messageDebug("reset the view..."); + //actionOnAllVolumes(false); // we 'contract' all the volumes + //foreach (Imp::SubSystemInfo * si, m_d->subsysInfoList) { + //VP1Msg::messageDebug2( "Resetting the system: " + QString::fromStdString(si->systemName)); + //} + + ////return; + //} else { + //// first pass: clean the view by zapping all volumes recursively + //VP1Msg::messageDebug("first pass: clean the view, zap all volumes"); + //actionOnAllVolumes(true); // we 'zap' the volumes + //} + + + //VP1Msg::messageDebug("filter matching volumes and make them visible"); // get root handles list std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; @@ -1718,45 +1674,72 @@ void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, bool s bool save = m_d->sceneroot->enableNotify(false); m_d->phisectormanager->largeChangesBegin(); deselectAll(); - // get handles + + 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 handles + // loop over root volumes for(;it!=itE;++it) { VolumeHandle* handle = (*it); // unsigned int iter = 0 - if (resetView) { + //if (resetView) { // 'contract' (i.e., make visible) the root volumes // RMB -- Note: I have not found any other way of correctly resetting to the initial view, - // if not 'contracting' all volumes in the call to actionOnAllVolumes(contracted) above, + // if not 'contracting' all volumes in the call to actionOnAllVolumes(contracted) above in this same method, // and then expanding / contracting the root volumes excplicitly, here... // This way, it works, after the reset I have the top root volumes contracted and all subvolumes ready to be shown when opening the root volumes, // but I'm wondering if there is another more elegant way to achieve that... :-/ - handle->setState(VP1GeoFlags::EXPANDED); // TODO: is this call needed, now that we have actionOnAll(CONTRACTED) above??? - handle->setState(VP1GeoFlags::CONTRACTED); // TODO: is this call needed, now that we have actionOnAll(CONTRACTED) above??? - } - // filter volumes - else { - // second pass: filter volumes recursively, to make the matching volumes visible - VP1Msg::messageDebug("Looking inside root node - name: " + handle->getName() + " - mat: " + QString::fromStdString(handle->geoMaterial()->getName()) ); - matchFound = m_d->filterVolumesRec(handle, selregexp, bymatname, stopAtFirst, visitChildren, resetView, false); - VP1Msg::messageDebug("second pass - matchFound: " + QString::number(matchFound)); - if (stopAtFirst && matchFound) { - break; - } + //handle->setState(VP1GeoFlags::EXPANDED); + //handle->setState(VP1GeoFlags::CONTRACTED); + //} + // filter volumes. If maxDepth==0, then we only loop over root volumes + //else { + // second pass: filter volumes recursively, to make the matching volumes visible + 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 (stopAtFirst && matchFound) { + //break; + //} + 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); + } + //} + + } // end loop over root volumes + + //if (stopAtFirst && matchFound) { + //break; + //} + } // loop over root handles + + // give feedback to the user + //m_d->controller->ui_misc.textOut->setText("# of matching volumes: " + QString::number(nFound)); + message("[filter volumes] # of matching volumes: " + QString::number(nFound)); + if (visitChildren && (nFound>0) ) { + //if user chose to visit children of matching volumes, + //then we change transoparency type to '' + message("[filter volumes] NOTE: to show both matching mother and matching daughter volumes, transparency has been set to 50% and transparency type has been changed to 'Sorted Object Blend', which is usually better to visualize nested geometry volumes. 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) ); } + } - } // end loop over root handles - - if (stopAtFirst && matchFound) { - break; - } - } // loop over root handles list m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); m_d->phisectormanager->largeChangesEnd(); @@ -1767,25 +1750,26 @@ void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, bool s } //_____________________________________________________________________________________ -bool VP1GeometrySystem::Imp::filterVolumesRec(VolumeHandle* handle, QRegExp selregexp, bool bymatname, bool stopAtFirst, bool visitChildren, bool resetView, bool zapAll, unsigned int iter) +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("\titeration: " + QString::number(iter) + " - looking into volume: " + handle->getName()); - - iter++; + if (!zapAll) { + VP1Msg::messageDebug2("iteration: " + QString::number(iter) + ", maxIter: " + QString::number(maxIter)); + VP1Msg::messageDebug2("looking into volume: " + handle->getName()); + } + // if 'reset' is true, // then we want to unzap all volumes to reset to a standard view - bool unzap( resetView ? true : false ); + //bool unzap( resetView ? true : false ); // if 'zapAll' is true, then we want to 'clean' the view // by zapping all volumes, usually before performing // some other operations // In this case, we set other options to false too - unzap = zapAll ? false : true; - stopAtFirst = zapAll ? false : stopAtFirst; + //unzap = zapAll ? false : true; + //stopAtFirst = zapAll ? false : stopAtFirst; - bool matchFound = false; + //bool matchFound = false; // zap the current volume by default... handle->setState(VP1GeoFlags::ZAPPED); @@ -1795,57 +1779,98 @@ bool VP1GeometrySystem::Imp::filterVolumesRec(VolumeHandle* handle, QRegExp selr 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()) ) { - VP1Msg::messageDebug(handle->getName() +" - **MATCH!** - 'Contracting' it (-->make it visible)..."); + 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; - } else { + //return matchFound; + zapAll = true; + } + /* + else { VP1Msg::messageDebug("\tYou chose to show all volumes matching the regular expression, so we search for others..."); - // if 'visitChildren' is TRUE, then we don't return; we go on to visit the children + //if 'visitChildren' is TRUE, then we don't return; we go on to visit the children if ( !visitChildren) { return matchFound; } } + */ } else { - VP1Msg::messageDebug2("not matching --> expanding it"); - handle->setState(VP1GeoFlags::EXPANDED); // no match, open the volume to show its children + //VP1Msg::messageDebug2("not matching --> expanding it"); + //handle->setState(VP1GeoFlags::EXPANDED); // no match, open the volume to show its children + VP1Msg::messageDebug2("not matching --> zapping it"); + handle->setState(VP1GeoFlags::ZAPPED); // no match, open the volume to show its children } } // we now expand the unmatching volume, unless the 'visitChildren' is set to TRUE: // in that case, if the volume matched, we have 'contracted' it but we haven't returned, // and we want to go on visiting the children - if (unzap && (!visitChildren)) { - VP1Msg::messageDebug2("unzap/!visitChildren --> expanding it"); - handle->setState(VP1GeoFlags::EXPANDED); // open the volume to show its children + //if (unzap && (!visitChildren)) { + //VP1Msg::messageDebug2("unzap/!visitChildren --> expanding it"); + //handle->setState(VP1GeoFlags::EXPANDED); // 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 - if (handle->nChildren()>0) { - // get children list - handle->initialiseChildren(); - VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()),itChlE(handle->childrenEnd()); - // if no match yet, then loop over children - if ( !matchFound || visitChildren ) { + // 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++; + + + // TODO: I should see if it will be faster to use EXPAND on layers: + // i.e., EXPAND the root, then ZAP all daughter in the first pass, then search and CONTRACT the matching volume. + // Then go on the other layers, depending on the maxDepth set by the user. That should result in a faster search. + + // 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..."); + 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); + } } - for (;itChl!=itChlE;++itChl) { - - VolumeHandle* child = (*itChl); - - // filter children volumes recursively - matchFound = filterVolumesRec(child, selregexp, bymatname, stopAtFirst, visitChildren, resetView, zapAll, iter); - if (stopAtFirst && matchFound) { - return matchFound; - } - } // end loop over children - } } return matchFound; diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx index b5a340ad9..3f439f123 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandle.cxx @@ -239,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; @@ -345,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; diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VolumeTreeModel.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VolumeTreeModel.cxx index addc93650..64a6f3e10 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 1169511e8..2838c5cef 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/settings_misc_form.ui +++ b/GeoModelVisualization/VP1GeometrySystems/src/settings_misc_form.ui @@ -10,16 +10,46 @@ <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,12 +128,21 @@ p, li { white-space: pre-wrap; } </layout> </widget> </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> + <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> @@ -132,6 +171,61 @@ p, li { white-space: pre-wrap; } </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> + <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"> @@ -169,8 +263,27 @@ p, li { white-space: pre-wrap; } <property name="title"> <string>Do you want to visit children of matching volumes?</string> </property> - <layout class="QHBoxLayout" name="horizontalLayout_9"> - <item> + <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> @@ -183,13 +296,22 @@ p, li { white-space: pre-wrap; } </property> </widget> </item> - <item> - <widget class="QRadioButton" name="radioButton_VisitAllChildren"> + <item row="1" column="1"> + <widget class="QCheckBox" name="lockTransp"> <property name="toolTip"> - <string>When a volume matches the filter, do visit all its child volumes as well. NOT RECOMMENDED. It is lengthy and it breaks the "Expand to children" functionality. Use it only if you know what you are doing.</string> + <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>Visit All Children</string> + <string>[lock transparency]</string> </property> </widget> </item> @@ -209,29 +331,40 @@ 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="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> -- GitLab