27#include <Inventor/nodes/SoSwitch.h>
28#include <Inventor/nodes/SoSeparator.h>
29#include <Inventor/actions/SoGetBoundingBoxAction.h>
31#include <Inventor/SbLinear.h>
32#include <Inventor/SbViewportRegion.h>
80 assert(
m_d->subsysflag2sep.find(flag)==
m_d->subsysflag2sep.end());
81 assert(
m_d->subsysflag_2_iphi2sephelper.find(flag)==
m_d->subsysflag_2_iphi2sephelper.end());
82 m_d->subsysflag_2_iphi2sephelper[flag] = std::map<int,VP1ExtraSepLayerHelper*>();
83 m_d->subsysflag2sep[flag] = subsystemsep;
85 assert(
m_d->subsysflag2labelsep.find(flag)==
m_d->subsysflag2labelsep.end());
86 assert(
m_d->subsysflag_2_iphi2labelsephelper.find(flag)==
m_d->subsysflag_2_iphi2labelsephelper.end());
87 m_d->subsysflag_2_iphi2labelsephelper[flag] = std::map<int,VP1ExtraSepLayerHelper*>();
88 m_d->subsysflag2labelsep[flag] = subsystemsep;
95 assert(
m_d->subsysflag2sep.find(flag)!=
m_d->subsysflag2sep.end());
96 assert(
m_d->subsysflag_2_iphi2sephelper.find(flag)!=
m_d->subsysflag_2_iphi2sephelper.end());
98 if (
m_d->subsysflag_2_iphi2sephelper[flag].find(iphi)!=
m_d->subsysflag_2_iphi2sephelper[flag].end()) {
99 return m_d->subsysflag_2_iphi2sephelper[flag][iphi];
102 SoSwitch * sw =
new SoSwitch;
103 sw->whichChild = (iphi>=0 ?
m_d->phisectionwidget->virtualSectorEnabled(iphi,
NPHISECTORS):!
m_d->phisectionwidget->allSectorsOff()) ? SO_SWITCH_ALL : SO_SWITCH_NONE;
105 m_d->iphi2switches[iphi].insert(sw);
107 SoSeparator * sep =
new SoSeparator;
110 m_d->subsysflag_2_iphi2sephelper[flag][iphi] = sephelper;
113 m_d->subsysflag2sep[flag]->addChild(sw);
121 assert(
m_d->subsysflag2labelsep.find(flag)!=
m_d->subsysflag2labelsep.end());
122 assert(
m_d->subsysflag_2_iphi2labelsephelper.find(flag)!=
m_d->subsysflag_2_iphi2labelsephelper.end());
124 if (
m_d->subsysflag_2_iphi2labelsephelper[flag].find(iphi)!=
m_d->subsysflag_2_iphi2labelsephelper[flag].end()) {
125 return m_d->subsysflag_2_iphi2labelsephelper[flag][iphi];
128 SoSwitch * sw =
new SoSwitch;
129 sw->whichChild = (iphi>=0 ?
m_d->phisectionwidget->virtualSectorEnabled(iphi,
NPHISECTORS):!
m_d->phisectionwidget->allSectorsOff()) ? SO_SWITCH_ALL : SO_SWITCH_NONE;
131 m_d->iphi2Labelswitches[iphi].insert(sw);
133 SoSeparator * sep =
new SoSeparator;
136 m_d->subsysflag_2_iphi2labelsephelper[flag][iphi] = sephelper;
139 m_d->subsysflag2labelsep[flag]->addChild(sw);
155 assert(sw->getNumChildren()==2);
157 assert(sw->getChild(1)->getTypeId()==SoSeparator::getClassTypeId());
159 SoNode* shape =
static_cast<SoShape*
>(sw->getChild(0));
160 SoSeparator* sep =
static_cast<SoSeparator*
>(sw->getChild(1));
163 if (sw->whichChild.getValue() != 0)
167 if (shape->getTypeId()==SoTubs::getClassTypeId()) {
168 m_d->volaroundZ_tubs[sw] = std::pair<SoTubs*,SoSeparator*>(
static_cast<SoTubs*
>(shape),sep);
169 }
else if (shape->getTypeId()==SoPcons::getClassTypeId()) {
170 m_d->volaroundZ_pcons[sw] = std::pair<SoPcons*,SoSeparator*>(
static_cast<SoPcons*
>(shape),sep);
171 }
else if (shape->getTypeId()==SoCons::getClassTypeId()) {
172 m_d->volaroundZ_cons[sw] = std::pair<SoCons*,SoSeparator*>(
static_cast<SoCons*
>(shape),sep);
174 assert(shape->getTypeId()==SoLAr::getClassTypeId());
175 m_d->volaroundZ_lar[sw] = std::pair<SoLAr*,SoSeparator*>(
static_cast<SoLAr*
>(shape),sep);
179 SbVec3f unitz (0.0f, 0.0f, 1.0f);
182 SbVec3f translation; SbRotation rotation; SbVec3f scaleFactor; SbRotation scaleOrientation;
183 transf.getTransform (translation, rotation, scaleFactor, scaleOrientation);
185 rotation.multVec(unitz,transfunitz);
188 transfunitz.getValue(
x,
y,
z);
190 bool rotaroundy = (
z<0&&std::fabs(
x)*10<std::fabs(
z));
193 SbVec3f unitx (1.0f, 0.0f, 0.0f);
195 rotation.multVec(unitx,transfunitx);
196 transfunitx.getValue(
x,
y,
z);
198 m_d->volaroundZ_switch2transfinfo[sw] = std::pair<double,bool>(phirot,rotaroundy);
201 if (
m_d->subsysflag_2_volAroundZSepHelper.find(flag)!=
m_d->subsysflag_2_volAroundZSepHelper.end())
202 return m_d->subsysflag_2_volAroundZSepHelper[flag];
204 SoSeparator * subsyssep_volaroundZ =
new SoSeparator;
205 assert(
m_d->subsysflag2sep.find(flag)!=
m_d->subsysflag2sep.end());
206 m_d->subsysflag2sep[flag]->addChild(subsyssep_volaroundZ);
208 subsyssep_volaroundZ->ref();
210 m_d->subsysflag_2_volAroundZSepHelper[flag] = sephelper;
223 SbViewportRegion dummyvp;
224 SoGetBoundingBoxAction
a(dummyvp);
226 SbXfBox3f xfbox =
a.getXfBoundingBox();
227 xfbox.transform(transform);
228 SbBox3f box = xfbox.project();
229 shape->unrefNoDelete();
232 float minx, miny, minz, maxx, maxy, maxz;
233 box.getBounds(minx, miny, minz, maxx, maxy, maxz);
235 box.getCenter().getValue(
x,
y,
z);
236 if (std::abs(
x*20.0)<std::abs(std::min(minx,maxx))&&std::abs(
y*20.0)<std::abs(std::min(miny,maxy))) {
238 if (shape->getTypeId()==SoTubs::getClassTypeId()
239 ||shape->getTypeId()==SoPcons::getClassTypeId()
240 ||shape->getTypeId()==SoCons::getClassTypeId()
241 ||shape->getTypeId()==SoLAr::getClassTypeId()) {
249 std::string Typenametest = shape->getTypeId().getName().getString();
250 m_d->system->message(
"WARNING: Unknown volume type (boolean?) for volume around Z-axis (type "
251 +QString(Typenametest.c_str())+
"). Phi-sector cuts won't work for this!");
263 : QObject(parent),
m_d(new
Imp)
265 m_d->phisectionwidget = psw;
267 m_d->nactivelargechanges = 0;
268 m_d->currentlyEnabledPhiSectors = QVector<bool>(
NPHISECTORS,
false);
269 QList<int> l; l << 4 << 6 << 9 << 12 << 18 <<
NPHISECTORS;
281 std::map<VP1GeoFlags::SubSystemFlag,std::map<int,VP1ExtraSepLayerHelper*> >
::iterator it, itE =
m_d->subsysflag_2_iphi2sephelper.end();
282 for (it =
m_d->subsysflag_2_iphi2sephelper.begin();it!=itE;++it) {
283 std::map<int,VP1ExtraSepLayerHelper*>::iterator it2(it->second.begin()),it2E(it->second.end());
284 for (;it2!=it2E;++it2) {
285 SoSeparator * sep = it2->second->topSeparator();
286 delete (it2->second);
291 std::map<VP1GeoFlags::SubSystemFlag,std::map<int,VP1ExtraSepLayerHelper*> >
::iterator it4, itE4 =
m_d->subsysflag_2_iphi2labelsephelper.end();
292 for (it4 =
m_d->subsysflag_2_iphi2labelsephelper.begin();it4!=itE4;++it4) {
293 std::map<int,VP1ExtraSepLayerHelper*>::iterator it5(it4->second.begin()),it5E(it4->second.end());
294 for (;it5!=it5E;++it5) {
295 SoSeparator * sep = it5->second->topSeparator();
296 delete (it5->second);
300 std::map<VP1GeoFlags::SubSystemFlag,VP1ExtraSepLayerHelper*>::iterator it3,it3E =
m_d->subsysflag_2_volAroundZSepHelper.end();
301 for (it3 =
m_d->subsysflag_2_volAroundZSepHelper.begin();it3!=it3E;++it3) {
302 SoSeparator * sep = it3->second->topSeparator();
303 delete (it3->second);
312 QVector<bool> v =
m_d->phisectionwidget->virtualSectorsEnabled(
NPHISECTORS);
313 if (
m_d->currentlyEnabledPhiSectors == v)
315 QList<int> changedPhiSectors;
317 if (
m_d->currentlyEnabledPhiSectors[iphi]!=v[iphi])
318 changedPhiSectors << iphi;
319 m_d->currentlyEnabledPhiSectors = v;
320 for (
int iphi : changedPhiSectors)
326 bool turnedon =
m_d->currentlyEnabledPhiSectors.at(iphi);
327 if (
m_d->iphi2switches.find(iphi)!=
m_d->iphi2switches.end()) {
328 std::set<SoSwitch*>::iterator it, itE =
m_d->iphi2switches[iphi].end();
329 for (it =
m_d->iphi2switches[iphi].begin();it!=itE;++it) {
330 if ((*it)->whichChild.getValue() != (turnedon?SO_SWITCH_ALL:SO_SWITCH_NONE))
331 (*it)->whichChild = (turnedon?SO_SWITCH_ALL:SO_SWITCH_NONE);
335 if (
m_d->iphi2Labelswitches.find(iphi)!=
m_d->iphi2Labelswitches.end()) {
336 std::set<SoSwitch*>::iterator it, itE =
m_d->iphi2Labelswitches[iphi].end();
337 for (it =
m_d->iphi2Labelswitches[iphi].begin();it!=itE;++it) {
338 if ((*it)->whichChild.getValue() != (turnedon?SO_SWITCH_ALL:SO_SWITCH_NONE))
339 (*it)->whichChild = (turnedon?SO_SWITCH_ALL:SO_SWITCH_NONE);
345 bool alloff =
m_d->phisectionwidget->allSectorsOff();
346 std::map<int,std::set<SoSwitch*> >
::iterator it_zax_switches =
m_d->iphi2switches.find(-1);
347 if (it_zax_switches!=
m_d->iphi2switches.end()) {
348 std::set<SoSwitch*>::iterator it, itE = it_zax_switches->second.end();
349 for (it = it_zax_switches->second.begin();it!=itE;++it) {
350 if ((*it)->whichChild.getValue() != (alloff?SO_SWITCH_NONE:SO_SWITCH_ALL))
351 (*it)->whichChild = (alloff?SO_SWITCH_NONE:SO_SWITCH_ALL);
360 phistart = tubs->
pSPhi.getValue();
361 phispan = tubs->
pDPhi.getValue();
367 dest->pRMin.setValue(source->pRMin.getValue());
368 dest->pRMax.setValue(source->pRMax.getValue());
369 dest->pDz.setValue(source->pDz.getValue());
370 dest->pSPhi.setValue(phistart);
371 dest->pDPhi.setValue(phispan);
372 dest->drawEdgeLines.setValue(source->drawEdgeLines.getValue());
378 phistart = pcons->
fSPhi.getValue();
379 phispan = pcons->
fDPhi.getValue();
385 dest->fRmin = source->fRmin;
386 dest->fRmax = source->fRmax;
387 dest->fDz = source->fDz;
388 dest->fSPhi.setValue(phistart);
389 dest->fDPhi.setValue(phispan);
390 dest->drawEdgeLines.setValue(source->drawEdgeLines.getValue());
396 phistart = cons->
fSPhi.getValue();
397 phispan = cons->
fDPhi.getValue();
403 dest->fRmin1.setValue(source->fRmin1.getValue());
404 dest->fRmin2.setValue(source->fRmin2.getValue());
405 dest->fRmax1.setValue(source->fRmax1.getValue());
406 dest->fRmax2.setValue(source->fRmax2.getValue());
407 dest->fDz.setValue(source->fDz.getValue());
408 dest->fSPhi.setValue(phistart);
409 dest->fDPhi.setValue(phispan);
415 phistart = lar->
fSPhi.getValue();
416 phispan = lar->
fDPhi.getValue();
422 dest->fRmin = source->fRmin;
423 dest->fRmax = source->fRmax;
424 dest->fDz = source->fDz;
425 dest->fSPhi.setValue(phistart);
426 dest->fDPhi.setValue(phispan);
434 typename std::map<SoSwitch*,std::pair<T*,SoSeparator*> >
::iterator it, itE = volaroundZ.end();
435 for (it = volaroundZ.begin();it!=itE;++it) {
437 if (it->first->whichChild.getValue() != SO_SWITCH_NONE)
438 it->first->whichChild = SO_SWITCH_NONE;
440 if (it->first->whichChild.getValue() != 0)
441 it->first->whichChild = 0;
444 SbBool save = it->first->enableNotify(
false);
445 SoSeparator * sep = it->second.second;
446 sep->removeAllChildren();
450 system->message(
"updateRepresentationsOfVolsAroundZAxis_Specific ERROR: Inconsistent maps");
453 double phirot = it_transfinfo->second.first;
454 bool rotaroundy = it_transfinfo->second.second;
459 QList<VP1Interval> ranges =
phisectionwidget->enabledPhiRanges( sphi, sphi+dphi );
461 int n = ranges.count();
462 for (
int i = 0; i< n; ++i) {
464 double deltaphi = ranges.at(i).length();
465 double startphi = rotaroundy ? - ranges.at(i).upper() - 2*
M_PI + phirot : ranges.at(i).lower()-phirot;
466 while (startphi<0) startphi += 2*
M_PI;
467 while (startphi+deltaphi>2*
M_PI) startphi -= 2*
M_PI;
469 sep->addChild(shape);
472 it->first->whichChild = 1;
473 it->first->enableNotify(save);
485 m_d->updateRepresentationsOfVolsAroundZAxis_Specific<
SoTubs>(
m_d->volaroundZ_tubs);
486 m_d->updateRepresentationsOfVolsAroundZAxis_Specific<
SoPcons>(
m_d->volaroundZ_pcons);
487 m_d->updateRepresentationsOfVolsAroundZAxis_Specific<
SoCons>(
m_d->volaroundZ_cons);
488 m_d->updateRepresentationsOfVolsAroundZAxis_Specific<
SoLAr>(
m_d->volaroundZ_lar);
494 if (++(
m_d->nactivelargechanges)==1) {
496 std::map<VP1GeoFlags::SubSystemFlag,std::map<int,VP1ExtraSepLayerHelper*> >
::iterator it, itE =
m_d->subsysflag_2_iphi2sephelper.end();
497 for (it =
m_d->subsysflag_2_iphi2sephelper.begin();it!=itE;++it) {
498 std::map<int,VP1ExtraSepLayerHelper*>::iterator it2(it->second.begin()),it2E(it->second.end());
499 for (;it2!=it2E;++it2)
500 it2->second->largeChangesBegin();
502 std::map<VP1GeoFlags::SubSystemFlag,VP1ExtraSepLayerHelper*>::iterator it3,it3E =
m_d->subsysflag_2_volAroundZSepHelper.end();
503 for (it3 =
m_d->subsysflag_2_volAroundZSepHelper.begin();it3!=it3E;++it3)
504 it3->second->largeChangesBegin();
512 if (--(
m_d->nactivelargechanges)==0) {
514 std::map<VP1GeoFlags::SubSystemFlag,std::map<int,VP1ExtraSepLayerHelper*> >
::iterator it, itE =
m_d->subsysflag_2_iphi2sephelper.end();
515 for (it =
m_d->subsysflag_2_iphi2sephelper.begin();it!=itE;++it) {
516 std::map<int,VP1ExtraSepLayerHelper*>::iterator it2(it->second.begin()),it2E(it->second.end());
517 for (;it2!=it2E;++it2)
518 it2->second->largeChangesEnd();
520 std::map<VP1GeoFlags::SubSystemFlag,VP1ExtraSepLayerHelper*>::iterator it3,it3E =
m_d->subsysflag_2_volAroundZSepHelper.end();
521 for (it3 =
m_d->subsysflag_2_volAroundZSepHelper.begin();it3!=it3E;++it3)
522 it3->second->largeChangesEnd();
std::map< VP1GeoFlags::SubSystemFlag, std::map< int, VP1ExtraSepLayerHelper * > > subsysflag_2_iphi2labelsephelper
std::map< VP1GeoFlags::SubSystemFlag, std::map< int, VP1ExtraSepLayerHelper * > > subsysflag_2_iphi2sephelper
std::map< VP1GeoFlags::SubSystemFlag, SoSeparator * > subsysflag2sep
std::map< int, std::set< SoSwitch * > > iphi2Labelswitches
std::map< VP1GeoFlags::SubSystemFlag, VP1ExtraSepLayerHelper * > subsysflag_2_volAroundZSepHelper
std::map< SoSwitch *, std::pair< SoCons *, SoSeparator * > > volaroundZ_cons
PhiSectionWidget * phisectionwidget
void copyShapeFieldsAndOverridePhiRange(const SoTubs *source, SoTubs *dest, double phistart, double phispan)
std::map< SoSwitch *, std::pair< SoPcons *, SoSeparator * > > volaroundZ_pcons
std::map< SoSwitch *, std::pair< double, bool > > volaroundZ_switch2transfinfo
std::map< SoSwitch *, std::pair< SoLAr *, SoSeparator * > > volaroundZ_lar
std::map< VP1GeoFlags::SubSystemFlag, SoSeparator * > subsysflag2labelsep
void getPhiExtentOfShape(const SoTubs *tubs, double &phistart, double &phispan)
void updateRepresentationsOfVolsAroundZAxis_Specific(std::map< SoSwitch *, std::pair< T *, SoSeparator * > > &volaroundZ)
std::map< int, std::set< SoSwitch * > > iphi2switches
std::map< SoSwitch *, std::pair< SoTubs *, SoSeparator * > > volaroundZ_tubs
QVector< bool > currentlyEnabledPhiSectors
int getVolumeType(const SbMatrix &transform, SoNode *shape) const
PhiSectorManager(PhiSectionWidget *, IVP1System *, QObject *parent=0)
VP1ExtraSepLayerHelper * registerVolumeAroundZAxis(VP1GeoFlags::SubSystemFlag flag, SoSwitch *sw, const SbMatrix &tranformation)
void updateEnabledPhiSections(int)
virtual ~PhiSectorManager()
VP1ExtraSepLayerHelper * getSepHelperForNode(VP1GeoFlags::SubSystemFlag flag, int iphi)
void registerSubSystemSeparator(VP1GeoFlags::SubSystemFlag flag, SoSeparator *subsystemsep)
void enabledPhiSectorsChanged()
VP1ExtraSepLayerHelper * getLabelSepHelperForNode(VP1GeoFlags::SubSystemFlag flag, int iphi)
Addition to handle label separators, in exactly the same way as getSepHelperForNode(....
void updateRepresentationsOfVolsAroundZAxis()
SoCons - Inventor version of the G4Cons Geant Geometry entity.
SoSFFloat fDPhi
Delta-angle, in radians.
SoSFFloat fSPhi
Starting angle, in radians.
SoLAr - Inventor version of the G4Cons Geant Geometry entity.
SoSFFloat fSPhi
Starting angle, in radians.
SoSFFloat fDPhi
Delta-angle, in radians.
SoPcons - Inventor version of the G4Cons Geant Geometry entity.
SoSFFloat fDPhi
Delta-angle, in radians.
SoSFFloat fSPhi
Starting angle, in radians.
SoTubs - Inventor version of the G4Tubs Geant Geometry entity.
SoSFFloat pDPhi
Delta-angle, in radians.
SoSFFloat pSPhi
Starting angle, in radians.
static double phiFromXY(const double &x, const double &y)
static void messageVerbose(const QString &)
static void message(const QString &, IVP1System *sys=0)