CMS 3D CMS Logo

VisG4Navigator.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "VisGeant4/VisG4Volumes/interface/VisG4Navigator.h"
00004 #include "VisGeant4/VisG4Volumes/interface/VisG4VolumeTwig.h"
00005 #include <classlib/utils/DebugAids.h>
00006 #include <G4VPhysicalVolume.hh>
00007 #include <G4LogicalVolume.hh>
00008 #include <algorithm>
00009 #include <set>
00010 
00011 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00012 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00013 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00014 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00015 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00016 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00017 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00018 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00019 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00020 
00021 void
00022 VisG4Navigator::build (int levels, G4VPhysicalVolume *from, IgTwig *to)
00023 {
00024     // Check that the volume is valid (world) volume, in particular
00025     // that it isn't replicated.  (FIXME: can we allow this without to
00026     // being a VisG4VolumeTwig?)
00027     ASSERT (from);
00028     ASSERT (from->GetLogicalVolume ());
00029     // ASSERT (! from->IsReplicated ());
00030     ASSERT (levels > 0);
00031 
00032     // Check that to is valid and empty
00033     ASSERT (to);
00034     ASSERT (! to->children ());
00035 
00036     // Add this one and descend
00037     build (levels, from, new VisG4VolumeTwig (to, from));
00038 }
00039 
00040 void
00041 VisG4Navigator::build (int levels,
00042                       G4VPhysicalVolume *from,
00043                       VisG4VolumeTwig *twig)
00044 {
00045     ASSERT (from);
00046     ASSERT (from->GetLogicalVolume ());
00047     ASSERT (twig);
00048     ASSERT (! twig->children ());
00049 
00050     if (! levels)
00051         return;
00052 
00053     G4LogicalVolume             *mother = from->GetLogicalVolume ();
00054     std::set<G4LogicalVolume *> seen;
00055 
00056     for (int i = 0; i < mother->GetNoDaughters (); ++i)
00057     {
00058         G4VPhysicalVolume *daughter = mother->GetDaughter (i);
00059         G4LogicalVolume   *logdaughter = daughter->GetLogicalVolume ();
00060 
00061         // Process this physical volume.  We do not deal with replicas
00062         // here, they get mapped into this twig when the scene graph
00063         // is rendered.  However we do deal with logical vs. physical
00064         // mapping here, creating children in the mode required.
00065         if (twig->logical () && ! seen.insert (logdaughter).second)
00066             continue;
00067 
00068         VisG4VolumeTwig *t = new VisG4VolumeTwig (twig, daughter);
00069         t->logical (twig->logical ());
00070         build (levels-1, daughter, t);
00071     }
00072 }
00073 
00076 unsigned
00077 VisG4Navigator::findLogical (G4VPhysicalVolume *volume, unsigned index)
00078 {
00079     ASSERT (volume);
00080     ASSERT (volume->GetLogicalVolume ());
00081     ASSERT (int(index) < volume->GetLogicalVolume ()->GetNoDaughters ());
00082 
00083     G4LogicalVolume *mother = volume->GetLogicalVolume ();
00084     G4LogicalVolume *desired = mother->GetDaughter (index)->GetLogicalVolume ();
00085 
00086     // Compute the logical index of the first node that matches
00087     // `desired'.  Avoid dynamic memory allocation, this code is
00088     // getting hit all the time.  The static array is ugly, but it
00089     // speeds things up considerably.  We know the array tends to be
00090     // small, so searching it is fast.
00091 
00092     ASSERT (desired);
00093     static std::vector<G4LogicalVolume *> seen;
00094 
00095     seen.clear ();
00096     seen.reserve (index);
00097     for (int i = 0; i < mother->GetNoDaughters (); ++i)
00098     {
00099         // Get the child
00100         G4VPhysicalVolume *daughter = mother->GetDaughter (i);
00101         G4LogicalVolume   *logdaughter = daughter->GetLogicalVolume ();
00102 
00103         // Remember this volume; if we've already seen it, skip;
00104         // otherwise add it to the vector.
00105         if (std::find (seen.begin (), seen.end (), logdaughter) == seen.end ())
00106         {
00107             if (logdaughter == desired)
00108                 return seen.size ();
00109 
00110             seen.push_back (logdaughter);
00111         }
00112     }
00113 
00114     ASSERT (false);
00115     return 0;
00116 }

Generated on Tue Jun 9 17:50:07 2009 for CMSSW by  doxygen 1.5.4