ATLAS Offline Software
Loading...
Searching...
No Matches
VolumeHandle.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
11
13#include "VP1Base/VP1Msg.h"
14// #include "VP1Base/VP1QtInventorUtils.h"
20
21#include "GeoModelKernel/GeoVolumeCursor.h"
22#include "GeoModelKernel/GeoShapeShift.h"
23#include "GeoModelKernel/GeoTube.h"
24#include "GeoModelKernel/GeoTubs.h"
25
26#include <Inventor/nodes/SoSeparator.h>
27#include <Inventor/nodes/SoTransform.h>
28#include <Inventor/nodes/SoSwitch.h>
29#include <Inventor/nodes/SoShape.h>
30#include <Inventor/nodes/SoMaterial.h>
31#include <Inventor/nodes/SoText2.h>
32#include <Inventor/nodes/SoTranslation.h>
33
34#include <QHash>
35#include <QBuffer>
36#include <QByteArray>
37#include <QPair>
38#include <QSet>
39#include <QMap>
40#include <QDataStream>
41
42// Suppress warning from Coin4 headers.
43#if __GNUC__ >= 10
44# pragma GCC diagnostic ignored "-Wdeprecated-copy"
45#endif
46
47//____________________________________________________________________
49public:
50 Imp(VolumeHandleSharedData * the_cd, const GeoPVConstLink& the_pV, const SbMatrix& the_ac)
51 : commondata(the_cd), pV(the_pV),accumTrans(the_ac),attachsepHelper(0),attachlabelSepHelper(0),nodesep(0), material(0), label_sep(0), labels(0), isattached(false) {}
52
54 GeoPVConstLink pV;
55 const SbMatrix accumTrans;//FIXME: Use pointer - and free once children are created AND nodesep has been build. Or just construct on the fly!
56
59
60 SoSeparator * nodesep;
61 SoMaterial * material;
62 SoSeparator* label_sep;
63 int labels;
64 QList<int> labelsPosOffsets;
65
67 void attach(VolumeHandle*vh);
68 void detach();
69
70 class VolState {
71 public:
72 int nZappedChildren() const { return m_zappedChildren.count(); }
73 int nExpandedChildren() const { return m_expandedChildren.count(); }
74 QMap<quint32,VolState> m_expandedChildren;
75 QSet<quint32> m_zappedChildren;
76 };
77
78 static VolState getChildStates(const VolumeHandle*theclass );
79 static void applyChildStates(const VolState&,VolumeHandle*theclass);
80 static bool hasNonStandardShapeChildren(const SoGroup*g);
81
82};
83
84
85QDataStream & operator<< ( QDataStream & out, const VolumeHandle::Imp::VolState & vs ) {
86 out << vs.m_expandedChildren;
87 out << vs.m_zappedChildren;
88 return out;
89}
90QDataStream & operator>> ( QDataStream & in, VolumeHandle::Imp::VolState & vs ) {
91 in >> vs.m_expandedChildren;
92 in >> vs.m_zappedChildren;
93 return in;
94}
95
96//____________________________________________________________________
97VolumeHandle::VolumeHandle(VolumeHandleSharedData * cd,VolumeHandle * parent, const GeoPVConstLink& pV, int childNumber, const MuonChamberState& mcs, const SbMatrix& accumTrans)
98 : m_d(new Imp(cd,pV,accumTrans)), m_childNumber(childNumber), m_nchildren(childNumber>=0?pV->getNChildVols():0), m_muonChamberState(mcs), m_parent(parent),
99 m_state(VP1GeoFlags::CONTRACTED)
100{
101 // std::cout<<"VolumeHandle ctor for "<<this<<" with parent="<<parent<<" and GeoPVConstLink @"<<&pV<<std::endl;
102 //commondata might be 0 in the special case where VolumeHandle is
103 //used as a base class for other reasons inside
104 //VolumeTreeModel. Just make sure we dont crash in that case.
105 if (cd) {
106 cd->ref();
108 m_d->attach(this);
109 }
110}
111
112//____________________________________________________________________
114{
115 if (m_d->commondata) {
117 m_d->commondata->removeZappedVolumesFromGui(this);
119 VolumeHandleListItr it, itE = m_children.end();
120 for (it = m_children.begin(); it!=itE; ++it)
121 delete *it;
122 m_children.clear();
123 }
124 if (m_d->material)
125 m_d->material->unref();
126 if (m_d->nodesep)
127 m_d->nodesep->unref();
128 if (m_d->label_sep)
129 m_d->label_sep->unref();
130 m_d->commondata->unref();
131 }
132 delete m_d;
133}
134
135//____________________________________________________________________
137{
139 return;
140
141 assert(m_nchildren);
142
143 //Loop over children:
144 m_children.reserve(m_nchildren);
145 unsigned ichild(0);
146 GeoVolumeCursor av(m_d->pV);
147 while (!av.atEnd()) {
148
149 //Add transformation between parent and child to find the complete transformation of the child:
150 SbMatrix matr;
152 matr.multRight(m_d->accumTrans);
153 m_children.push_back(new VolumeHandle(m_d->commondata,this,av.getVolume(),ichild++,(isInMuonChamber()?MUONCHAMBERCHILD:NONMUONCHAMBER),matr));
154 //std::cout << "initialised: " << av.getName() << " - " << m_children.back()->getName().toStdString() << " - " << m_children.back() << std::endl;
155 av.next();
156 }
157
158 assert(ichild==m_nchildren&&m_children.size()==m_nchildren);
159
160}
161
162//____________________________________________________________________
163GeoPVConstLink VolumeHandle::geoPVConstLink() const
164{
165 return m_d->pV;
166}
167
168//____________________________________________________________________
170{
171 return m_d->pV->getLogVol()->getName().c_str();
172}
173
174//____________________________________________________________________
176{
177 return m_d->pV->getLogVol()->getName();
178}
179
180//____________________________________________________________________
181bool VolumeHandle::hasName(const std::string& n) const
182{
183 return m_d->pV->getLogVol()->getName() == n;
184}
185
186//____________________________________________________________________
188{
189 if (m_d->material)
190 return m_d->material;
191
192 //First see if the "databases" of volumes/material know about this volume:
193
194 SoMaterial * mat = m_d->commondata->volVisAttributes()->get(m_d->pV->getLogVol()->getName());
195 if (mat) {
196 m_d->material = mat;
197 m_d->material->ref();
198 return m_d->material;
199 }
200 mat = m_d->commondata->matVisAttributes()->get(m_d->pV->getLogVol()->getMaterial()->getName());
201 if (mat) {
202 m_d->material = mat;
203 m_d->material->ref();
204 return m_d->material;
205 }
206
207 //Apparently not. We now have two ways of finding a material: We can
208 //take a system dependent fallback material, or we can take the
209 //material of the parent.
210
211 mat = m_d->commondata->fallBackTopLevelMaterial();
212 if (mat) {
213 m_d->material = mat;
214 m_d->material->ref();
215 return m_d->material;
216 }
217
218 if (m_parent) {
219 m_d->material = m_parent->material();
220 assert(m_d->material);
221 m_d->material->ref();
222 return m_d->material;
223 }
224
225 m_d->material = m_d->commondata->matVisAttributes()->get("DEFAULT");
226 assert(m_d->material);
227 m_d->material->ref();
228 return m_d->material;
229}
230
231//____________________________________________________________________
232SoSeparator * VolumeHandle::nodeSoSeparator() const
233{
234 return m_d->nodesep;
235}
236
237//____________________________________________________________________
239{
240 VP1Msg::messageDebug("VolumeHandle::ensureBuildNodeSep()");
241 if (m_d->nodesep && m_d->label_sep)
242 return;
243
244 m_d->label_sep = new SoSeparator;
245 m_d->label_sep->ref();
246
247 m_d->nodesep = new SoSeparator;//FIXME: rendercaching??
248 // m_d->nodesep->renderCaching.setValue(SoSeparator::ON);
249 // m_d->nodesep->boundingBoxCaching.setValue(SoSeparator::ON);
250 m_d->nodesep->ref();//Since we are keeping it around irrespective of whether it is attached or not.
251
252 //Transform:
253 m_d->nodesep->addChild(VP1LinAlgUtils::toSoTransform(m_d->accumTrans));
254
255 //VP1Msg::messageDebug("calling toShapeNode()...");
256 SoNode * shape = m_d->commondata->toShapeNode(m_d->pV);//NB: Ignore contained transformation of GeoShapeShifts.
257 if (!shape) {
258 m_d->nodesep->removeAllChildren();
259 std::cout << "Geomsys/VolumeHandle Error: Null shape!!!"<<std::endl;
260 return;
261 }
262
263 //What phi sector do we belong in?
264 int iphi = m_d->commondata->phiSectorManager()->getVolumeType(m_d->accumTrans, shape);
265
266 if (iphi >= -1 ) {
267 //VP1Msg::messageDebug("Cylinders [iphi >= -1]...");
268 //Substitute shapes that are essentially cylinders with such. This
269 //can be done safely since this tube won't need
270 //phi-slicing and is done to gain render performance.
271 if ( m_d->pV->getLogVol()->getShape()->typeID()==GeoTube::getClassTypeID() )
272 {
273 //VP1Msg::messageDebug("GeoTube...");
274 const GeoTube * geotube = static_cast<const GeoTube*>(m_d->pV->getLogVol()->getShape());
275 if (geotube->getRMin()==0.0)
276 shape = m_d->commondata->getSoCylinderOrientedLikeGeoTube(geotube->getRMax(),geotube->getZHalfLength());
277 }
278 else if ( m_d->pV->getLogVol()->getShape()->typeID()==GeoTubs::getClassTypeID() )
279 {
280 //VP1Msg::messageDebug("GeoTubs...");
281 const GeoTubs * geotubs = static_cast<const GeoTubs*>(m_d->pV->getLogVol()->getShape());
282 if (geotubs->getRMin()==0.0 && geotubs->getDPhi() >= 2*M_PI-1.0e-6)
283 shape = m_d->commondata->getSoCylinderOrientedLikeGeoTube(geotubs->getRMax(),geotubs->getZHalfLength());
284 }
285 }
286
287 //In the case of a GeoShapeShift we add its contained transformation here:
288 //Fixme: Remember to use this extra transformation for phisector cuts also!
289 if (m_d->pV->getLogVol()->getShape()->typeID()==GeoShapeShift::getClassTypeID())
290 m_d->nodesep->addChild(VP1LinAlgUtils::toSoTransform(Amg::EigenTransformToCLHEP(dynamic_cast<const GeoShapeShift*>(m_d->pV->getLogVol()->getShape())->getX())));
291
292 //Add shape child(ren) and get the separator (helper) where we attach the nodesep when volume is visible:
293 if (iphi >= -1) {
294 m_d->nodesep->addChild(shape);
295 m_d->attachsepHelper = m_d->commondata->phiSectorManager()->getSepHelperForNode(m_d->commondata->subSystemFlag(), iphi);
296 m_d->attachlabelSepHelper = m_d->commondata->phiSectorManager()->getLabelSepHelperForNode(m_d->commondata->subSystemFlag(), iphi);
297 } else {
298 SoSwitch * sw = new SoSwitch;
299 sw->addChild(shape);
300 SoSeparator * sep_slicedvols = new SoSeparator;
301 sw->addChild(sep_slicedvols);
302 sw->whichChild = 0;
303 m_d->nodesep->addChild(sw);
304 m_d->attachsepHelper = m_d->commondata->phiSectorManager()->registerVolumeAroundZAxis( m_d->commondata->subSystemFlag(), sw, m_d->accumTrans );
305 //FIXME - what about labels?
306 }
307
308 //Register shape to volume handle connection (for user interactions):
309 //NB: "shape" might be shared between several volumes, so we use the separator above for the actual link!
310 //(this must be done last as it also sets outline defaults)
311 m_d->commondata->registerNodeSepForVolumeHandle(m_d->nodesep,this);
312
313 //VP1Msg::messageDebug("VolumeHandle::ensureBuildNodeSep() - DONE.");
314}
315
316//____________________________________________________________________
318{
319 VP1Msg::messageDebug("VolumeHandle::Imp::attach() - name: " + vh->getName());
320 if (!isattached) {
321 vh->ensureBuildNodeSep();
322 if (attachsepHelper) {
323 VP1Msg::messageDebug("adding node...");
324 attachsepHelper->addNodeUnderMaterial(nodesep,vh->material());
325 }
327 VP1Msg::messageDebug("adding label...");
329 }
330 isattached=true;
331 commondata->volumeBrowser()->scheduleUpdateOfAllNonHiddenIndices();//Browser need to change e.g. colour for this volume
332 }
333 //VP1Msg::messageDebug("attach: DONE.");
334}
335
336//____________________________________________________________________
338{
339 if (isattached) {
340 if (attachsepHelper)
341 attachsepHelper->removeNodeUnderMaterial(nodesep,material);
343 attachlabelSepHelper->removeNode(label_sep);
344 isattached=false;
345 commondata->volumeBrowser()->scheduleUpdateOfAllNonHiddenIndices();//Browser need to change e.g. colour for this volume
346 }
347}
348
349//____________________________________________________________________
351{
352 if (m_state==state)
353 return;
354
355 //Mark muon chamber as dirty.
356 if (isInMuonChamber()) {
358 if (tp->m_muonChamberState == MUONCHAMBER)
359 tp->m_muonChamberState = MUONCHAMBER_DIRTY;
360 }
361
362 //Update state flag and presence in GUI lists:
364 m_state = state;
365 if (oldstate==VP1GeoFlags::ZAPPED)
366 m_d->commondata->removeZappedVolumesFromGui(this);
367 else if (state==VP1GeoFlags::ZAPPED)
368 m_d->commondata->addZappedVolumeToGui(this);
369
370 //Only thing left is visibility updates (i.e. attachment to 3D scenegraph).
371
373 //No visibility updates necessary
374 assert(!m_d->isattached);
375 return;
376 }
377
378 //We might need visibility updates. Which ones depend on the
379 //particular change of state:
380
382 // VP1GeoFlags::EXPANDED/VP1GeoFlags::ZAPPED -> VP1GeoFlags::CONTRACTED: Show this and hide all children.
383 m_d->attach(this);
385 } else if (state==VP1GeoFlags::EXPANDED) {
386 // VP1GeoFlags::CONTRACTED -> VP1GeoFlags::EXPANDED: Hide this. Allow children to be shown.
387 // VP1GeoFlags::ZAPPED -> VP1GeoFlags::EXPANDED: Allow children to be shown.
388 if (oldstate==VP1GeoFlags::CONTRACTED)
389 m_d->detach();
391 } else {
392 assert(state==VP1GeoFlags::ZAPPED);
393 // VP1GeoFlags::CONTRACTED -> VP1GeoFlags::ZAPPED: Hide this.
394 // VP1GeoFlags::EXPANDED -> VP1GeoFlags::ZAPPED: Hide all children.
395 if (oldstate==VP1GeoFlags::CONTRACTED)
396 m_d->detach();
397 else
399 }
400}
401
402//____________________________________________________________________
404{
406 return;//Fine to abort since children starts in contracted state
407 //if initialised at a later time.
408 VolumeHandleListItr childItrE = m_children.end();
409 for (VolumeHandleListItr childItr = m_children.begin(); childItr!=childItrE; ++childItr) {
410 (*childItr)->setState(VP1GeoFlags::CONTRACTED);
411 (*childItr)->contractDaughtersRecursively();
412 }
413}
414
415//____________________________________________________________________
417{
418 return m_parent ? ( m_parent->state()==VP1GeoFlags::EXPANDED ? m_parent->haveParentsNotExpanded() : true ) : false;
419}
420
421//____________________________________________________________________
423
424 if (!m_nchildren)
425 return;
428
429 VolumeHandleListItr childItrE = m_children.end();
430 for (VolumeHandleListItr childItr = m_children.begin(); childItr!=childItrE; ++childItr) {
431 if ((*childItr)->state()==VP1GeoFlags::CONTRACTED)
432 (*childItr)->m_d->attach(*childItr);
433 else if ((*childItr)->state()==VP1GeoFlags::EXPANDED)
434 (*childItr)->attachAllContractedChildren();
435 }
436}
437
438//____________________________________________________________________
440 if (!m_nchildren)
441 return;
443 return;//Since children not initialised won't have been attached!
444
445 VolumeHandleListItr childItrE = m_children.end();
446 for (VolumeHandleListItr childItr = m_children.begin(); childItr!=childItrE; ++childItr) {
447 if ((*childItr)->state()==VP1GeoFlags::CONTRACTED)
448 (*childItr)->m_d->detach();
449 else if ((*childItr)->state()==VP1GeoFlags::EXPANDED)
450 (*childItr)->detachAllContractedChildren();
451 }
452}
453
454//____________________________________________________________________
456{
457 GeoPVConstLink parent_pV;
458 if (m_parent) {
459 parent_pV = m_parent->geoPVConstLink();
460 } else {
461 parent_pV = m_d->commondata->geoPVConstLinkOfTreeTopsMother();
462 if (parent_pV==m_d->pV) {
463 //To follow historical behaviour, we always assume that
464 //tree-tops (in the GeoModel sense) have a copy number of 0.
465 return 0;
466 }
467 }
468 GeoVolumeCursor av(parent_pV);
469 int i(0);//We need to check the childNumber since volumes in a replica have same volume link
470 while (!av.atEnd()) {
471 if (m_childNumber==i&&m_d->pV==av.getVolume()) {
472 std::optional<int> Qint = av.getId();
473 return Qint ? *Qint : -1;//-1 for "Invalid"
474 }
475 av.next();
476 ++i;
477 }
478 return -2;//error
479}
480
481//____________________________________________________________________
482quint32 VolumeHandle::hashID() const
483{
484 // return qHash( QPair<QString,quint32>(getName(),copyNumber()));//NOT UNIQUE!!
485 return qHash( QPair<QString,quint32>(getName(),childNumber()));
486}
487
488//____________________________________________________________________
490 return m_d->accumTrans;
491}
492
493//____________________________________________________________________
495 if (!m_parent)
496 return m_d->accumTrans;
497 return m_parent->getGlobalTransformToVolume().inverse().multRight(m_d->accumTrans);
498}
499
500//____________________________________________________________________
502{
503 return m_d->isattached;
504}
505
506//____________________________________________________________________
507const GeoMaterial * VolumeHandle::geoMaterial() const {
508 return geoPVConstLink()->getLogVol()->getMaterial();
509}
510
511//____________________________________________________________________
513{
514 return !isMuonChamber() && QString(geoMaterial()->getName().c_str()).endsWith("Ether");
515}
516
517//____________________________________________________________________
519 //std::cout<<"VolumeHandle::expandMothersRecursivelyToNonEther() for "<<this->getNameStdString() << " [" <<this<< "]" << " - n. children: " << nChildren() << std::endl;
520
521 if (!nChildren()||!isEther()) {
522 //VP1Msg::messageDebug("====> no children or not 'Ether' material. Skipping & returning.");
523 return;
524 }
525
528 VolumeHandleListItr childItrE = m_children.end();
529 for (VolumeHandleListItr childItr = m_children.begin(); childItr!=childItrE; ++childItr) {
530 //std::cout << "\t-->expanding child " << (*childItr)->getNameStdString() << " - " << (*childItr) << std::endl ;
531 (*childItr)->expandMothersRecursivelyToNonEther();
532 }
534 //std::cout<<"VolumeHandle::expandMothersRecursivelyToNonEther() for "<<this->getNameStdString() << " [" <<this<< "]" <<" DONE.\n\n"<<std::endl;
535
536}
537
538//____________________________________________________________________
540{
541 QByteArray ba;
542 QBuffer buffer(&ba);
543 buffer.open(QIODevice::WriteOnly);
544
545 QDataStream out(&buffer);
546 out << (qint32)0;//version
548 out << Imp::getChildStates(this);
549
550 buffer.close();
551 return ba;
552
553}
554
555//____________________________________________________________________
557{
558 QBuffer buffer(&ba);
559 buffer.open(QIODevice::ReadOnly);
560 QDataStream state(&buffer);
561 qint32 version;
562 state >> version;
563 if (version!=0)
564 return;//We ignore wrong versions silently here.
565 qint32 st;
566 state >> st;
568 if (st == 2)
569 newstate = VP1GeoFlags::ZAPPED;
570 else if (st == 1)
571 newstate = VP1GeoFlags::EXPANDED;
572
573 Imp::VolState vs;
574 state >> vs;
575 buffer.close();
576
577 if (newstate==VP1GeoFlags::EXPANDED) {
579 m_d->applyChildStates(vs,this);
580 }
581 setState(newstate);
582}
583
584//____________________________________________________________________
586{
587 return m_d->commondata->subSystemFlag();
588}
589
590//____________________________________________________________________
592{
593 VolState vs;
594 if (theclass->m_state!=VP1GeoFlags::EXPANDED||theclass->m_nchildren==0||!theclass->childrenAreInitialised())
595 return vs;
596
597 VolumeHandleListConstItr it, itE = theclass->m_children.end();
598 for (it = theclass->m_children.begin(); it!=itE; ++it) {
599 if ((*it)->state()==VP1GeoFlags::ZAPPED)
600 vs.m_zappedChildren.insert((*it)->hashID());
601 else if ((*it)->state()==VP1GeoFlags::EXPANDED)
602 vs.m_expandedChildren.insert((*it)->hashID(),(*it)->m_d->getChildStates(*it));
603 }
604 return vs;
605}
606
607//____________________________________________________________________
609{
610 bool hasExpandedChildren = !vs.m_expandedChildren.isEmpty();
611 bool hasZappedChildren = !vs.m_zappedChildren.isEmpty();
612 if (!hasExpandedChildren&&!hasZappedChildren)
613 return;
614
615 QMap<quint32,VolState>::const_iterator expItr, expItrEnd = vs.m_expandedChildren.end();
616 QSet<quint32>::const_iterator zapItr, zapItrEnd = vs.m_zappedChildren.end();
617
618 theclass->initialiseChildren();
619 VolumeHandleListConstItr it, itE = theclass->m_children.end();
620 for (it = theclass->m_children.begin(); it!=itE; ++it) {
621 quint32 id = (*it)->hashID();
622 zapItr = vs.m_zappedChildren.find(id);
623 if (zapItr!=zapItrEnd) {
624 (*it)->setState(VP1GeoFlags::ZAPPED);
625 continue;
626 }
627 expItr = vs.m_expandedChildren.find(id);
628 if (expItr!=expItrEnd) {
629 (*it)->setState(VP1GeoFlags::ZAPPED);
630 applyChildStates(expItr.value(),*it);
631 (*it)->setState(VP1GeoFlags::EXPANDED);
632 }
633 }
634}
635
636//____________________________________________________________________
638{
639 const int n(g->getNumChildren());
640 for (int i=0; i < n; ++i) {
641 const SoNode*c = g->getChild(i);
642 if (c->getTypeId().isDerivedFrom(SoShape::getClassTypeId())) {
643 if (c->getTypeId().isDerivedFrom(SoPcons::getClassTypeId())
644 ||c->getTypeId().isDerivedFrom(SoPolyhedron::getClassTypeId())
645 ||c->getTypeId().isDerivedFrom(SoTransparency::getClassTypeId()))
646 return true;
647 } else if (c->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) {
648 if (hasNonStandardShapeChildren(static_cast<const SoGroup*>(c)))
649 return true;
650 }
651 }
652 return false;
653}
654
655//____________________________________________________________________
661
662//____________________________________________________________________
664{
665 SbVec3f dir;
666 m_d->accumTrans.multDirMatrix(SbVec3f(0,0,1),dir);
667 float x,y,z;
668 dir.getValue(x,y,z);
669 return z>0;
670}
671
673 int labels = m_d->commondata->controller()->labels();
674 QList<int> offsets = m_d->commondata->controller()->labelPosOffset();
675
676 m_d->attachlabelSepHelper->largeChangesBegin();
677
678 if ( m_d->labels != labels || m_d->labelsPosOffsets != offsets){
679 m_d->labels = labels;
680 m_d->labelsPosOffsets = offsets;
681 m_d->label_sep->removeAllChildren ();
682
683 SoText2 *labelText = new SoText2;
684 labelText->ref();
685 QStringList text;
686 if (labels&0x1){
687 QString name = getDescriptiveName();
688 text << name;
689 }
690
691 // only one label selected - must be better way to do this!
692 bool singleLabel = (labels&0x2 && !(labels&0x4) && !(labels&0x8))
693 || (labels&0x4 && !(labels&0x2) && !(labels&0x8))
694 || (labels&0x8 && !(labels&0x2) && !(labels&0x4));
695 if (isInMuonChamber() && labels&0xE){
696 for (unsigned int i=0; i<3 ;++i){
697 // Check to see which label we use.
698 unsigned int mask=1<<(i+1);
699 if (!(labels&mask)) continue; // bits 1,2,3 are used for labels
700
701 QString output;
702 if ( singleLabel ) {
703 output+="t0=";
704 } else {
705 if (i==0) output+="Moore t0=";
706 if (i==1) output+="Mboy t0=";
707 if (i==2) output+="<unknown>=";
708 }
709 output += muonChamberT0(i);
710 text << output;
711 }
712 }
713
714 unsigned int row=0;
715 for(const QString& str : text){
716 QByteArray array = str.toLatin1();
717 labelText->string.set1Value(row++,array.data());
718 }
719
720 SoTransform *labelTranslate = VP1LinAlgUtils::toSoTransform(m_d->accumTrans);
721 assert(labelTranslate!=0);
722 float offScale=10.0;
723 float labx,laby,labz;
724 labelTranslate->translation.getValue().getValue(labx,laby,labz);
725// std::cout <<getNameStdString()<<" offsets (x,y,z)=("<<offsets[0]<<","<<offsets[1]<<","<<offsets[2]<<")"<<std::endl;
726
727 labelTranslate->translation.setValue(labx+(offsets[0]*offScale),laby+(offsets[1]*offScale),labz+(offsets[2]*offScale));
728
729 m_d->label_sep->addChild(labelTranslate);
730 m_d->label_sep->addChild(labelText);
731 }
732
733 m_d->attachlabelSepHelper->largeChangesEnd();
734}
735
#define M_PI
#define y
#define x
#define z
QDataStream & operator<<(QDataStream &out, const VolumeHandle::Imp::VolState &vs)
QDataStream & operator>>(QDataStream &in, VolumeHandle::Imp::VolState &vs)
static void initAllCustomClasses()
static SoTransform * toSoTransform(const HepGeom::Transform3D &, SoTransform *t=0)
static void transformToMatrix(SoTransform *xf, SbMatrix &result)
static void messageDebug(const QString &)
Definition VP1Msg.cxx:39
QSet< quint32 > m_zappedChildren
QMap< quint32, VolState > m_expandedChildren
const SbMatrix accumTrans
static void applyChildStates(const VolState &, VolumeHandle *theclass)
void attach(VolumeHandle *vh)
GeoPVConstLink pV
static bool hasNonStandardShapeChildren(const SoGroup *g)
VP1ExtraSepLayerHelper * attachlabelSepHelper
VolumeHandleSharedData * commondata
SoSeparator * label_sep
SoMaterial * material
VP1ExtraSepLayerHelper * attachsepHelper
static VolState getChildStates(const VolumeHandle *theclass)
SoSeparator * nodesep
QList< int > labelsPosOffsets
Imp(VolumeHandleSharedData *the_cd, const GeoPVConstLink &the_pV, const SbMatrix &the_ac)
void setState(const VP1GeoFlags::VOLSTATE &state)
bool hasName(const std::string &) const
VolumeHandle(VolumeHandleSharedData *, VolumeHandle *parent, const GeoPVConstLink &, int childNumber, const MuonChamberState &mcs=NONMUONCHAMBER, const SbMatrix &accumTrans=SbMatrix())
bool isMuonChamber() const
bool childrenAreInitialised() const
virtual ~VolumeHandle()
VolumeHandleList::const_iterator VolumeHandleListConstItr
bool isPositiveZ() const
const SbMatrix & getGlobalTransformToVolume() const
std::string getNameStdString() const
void attachAllContractedChildren()
VP1GeoFlags::VOLSTATE state() const
const GeoMaterial * geoMaterial() const
void initialiseChildren()
QString getName() const
void ensureBuildNodeSep()
MuonChamberState m_muonChamberState
void applyPersistifiableState(QByteArray)
SbMatrix getLocalTransformToVolume() const
SoMaterial * material()
virtual QString muonChamberT0(unsigned int=0) const
VolumeHandle * topLevelParent()
bool isEther() const
void contractDaughtersRecursively()
VP1GeoFlags::VOLSTATE m_state
bool isAttached() const
SoSeparator * nodeSoSeparator() const
GeoPVConstLink geoPVConstLink() const
bool haveParentsNotExpanded() const
bool isInitialisedAndHasNonStandardShape() const
int copyNumber() const
void detachAllContractedChildren()
bool isInMuonChamber() const
VolumeHandle * m_parent
virtual QString getDescriptiveName() const
VolumeHandleList m_children
void expandMothersRecursivelyToNonEther()
VolumeHandleList::iterator VolumeHandleListItr
const unsigned m_nchildren
const int m_childNumber
VP1GeoFlags::SubSystemFlag subsystem() const
quint32 hashID() const
VolumeHandle * parent()
int childNumber() const
QByteArray getPersistifiableState() const
unsigned nChildren() const
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.