CMS 3D CMS Logo

VisG4TwigOps.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "VisGeant4/VisG4Volumes/interface/VisG4TwigOps.h"
00004 #include "VisGeant4/VisG4Volumes/interface/VisG4VolumeTwig.h"
00005 #include "Iguana/Studio/interface/IgTwigOps.h"
00006 #include "Iguana/Studio/interface/IgQtObjectMenu.h"
00007 #include "Iguana/Studio/interface/IgQtObjectMenuMessage.h"
00008 #include "VisGeant4/VisG4Core/interface/VisG4VisTransform3D.h"
00009 #include "VisGeant4/VisG4Volumes/interface/VisG4VolumePicker.h"
00010 #include "VisGeant4/VisG4Volumes/interface/VisG4Details.h"
00011 #include "VisGeant4/VisG4Volumes/interface/VisG4Filter.h"
00012 #include "VisGeant4/VisG4Volumes/interface/VisG4FilterTable.h"
00013 #include "Iguana/Controls/interface/IgMatEdMainWidget.h"
00014 #include "Iguana/Controls/src/IgMatEdMainMenu.h"
00015 
00016 #include "Iguana/Framework/interface/IgRepSet.h"
00017 #include <classlib/utils/DebugAids.h>
00018 
00019 #include <qapplication.h>
00020 #include <qpushbutton.h>
00021 #include <qlistbox.h>
00022 #include <qdialog.h>
00023 #include <qlayout.h>
00024 #include <qlabel.h>
00025 #include <qcolordialog.h>
00026 #include <qinputdialog.h>
00027 #include <qcombobox.h>
00028 #include <qmenubar.h>
00029 #include <qmessagebox.h>
00030 #include <qstring.h>
00031 #include <qprogressdialog.h>
00032 #include <qvbox.h>
00033 
00034 #include <G4VPhysicalVolume.hh>
00035 #include <G4LogicalVolume.hh>
00036 #include <G4VisAttributes.hh>
00037 #include <G4Material.hh>
00038 #include <G4VSolid.hh>
00039 #include <G4VPVParameterisation.hh>
00040 #include <G4VoxelLimits.hh>
00041 #include <G4AffineTransform.hh>
00042 #include <Randomize.hh>
00043 
00044 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00045 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00046 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00047 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00048 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00049 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00050 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00051 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00052 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00053 
00054 void
00055 VisG4TwigOps::menuAction (IgQtObjectMenuMessage message)
00056 {
00057     static const IgQtObjectMenu::ItemDef defs [] = {
00058         { -1, MENU_LOGICAL, "Logical Children",
00059           SLOT (actionLogical (int)), MENU_LOGICAL },
00060         { -1, MENU_GET_MASS, "Get Mass",
00061           SLOT (actionGetMass (int)), MENU_GET_MASS },
00062 
00063         { -1, MENU_SHOW_CATEGORY, "Show By Category", 0, -1 },
00064         { MENU_SHOW_CATEGORY, CAT_SENSITIVE,    "Sensitive",
00065           SLOT (actionShowCategory (int)), CAT_SENSITIVE },
00066         { MENU_SHOW_CATEGORY, CAT_INSENSITIVE,  "Any Insensitive",
00067           SLOT (actionShowCategory (int)), CAT_INSENSITIVE },
00068         { MENU_SHOW_CATEGORY, CAT_FILTER,       "User Defined Filter",
00069           SLOT (actionApplyFilter (int)), CAT_FILTER },
00070 #if 0
00071         { MENU_SHOW_CATEGORY, CAT_BEAMPIPE,        "Beampipe",
00072           SLOT(actionShowCategory(int)), CAT_BEAMPIPE },
00073         { MENU_SHOW_CATEGORY, CAT_CABLE,           "Cables",
00074           SLOT(actionShowCategory(int)), CAT_CABLE },
00075         { MENU_SHOW_CATEGORY, CAT_COOLING,         "Cooling",
00076           SLOT(actionShowCategory(int)), CAT_COOLING },
00077         { MENU_SHOW_CATEGORY, CAT_MAGNET,          "Magnet",
00078           SLOT(actionShowCategory(int)), CAT_MAGNET },
00079         { MENU_SHOW_CATEGORY, CAT_SUPPORT,         "Support",
00080           SLOT(actionShowCategory(int)), CAT_SUPPORT },
00081         { MENU_SHOW_CATEGORY, CAT_SENSITIVE_CONT,  "Sensitive Container",
00082           SLOT(actionShowCategory(int)), CAT_SENSITIVE_CONT },
00083 #endif
00084 
00085         { -1, MENU_SHOW_MATERIAL, "Show By Material...",
00086           SLOT(actionShowMaterial(int)), MENU_SHOW_MATERIAL },
00087 
00088         { -1, MENU_HIDE_CATEGORY, "Hide By Category", 0, -1 },
00089         { MENU_HIDE_CATEGORY, CAT_SENSITIVE,       "Sensitive",
00090           SLOT(actionHideCategory(int)), CAT_SENSITIVE },
00091         { MENU_HIDE_CATEGORY, CAT_INSENSITIVE,     "Any Insensitive",
00092           SLOT(actionHideCategory(int)), CAT_INSENSITIVE },
00093 #if 0
00094         { MENU_HIDE_CATEGORY, CAT_BEAMPIPE,        "Beampipe",
00095           SLOT(actionHideCategory(int)), CAT_BEAMPIPE },
00096         { MENU_HIDE_CATEGORY, CAT_CABLE,           "Cables",
00097           SLOT(actionHideCategory(int)), CAT_CABLE },
00098         { MENU_HIDE_CATEGORY, CAT_COOLING,         "Cooling",
00099           SLOT(actionHideCategory(int)), CAT_COOLING },
00100         { MENU_HIDE_CATEGORY, CAT_MAGNET,          "Magnet",
00101           SLOT(actionHideCategory(int)), CAT_MAGNET },
00102         { MENU_HIDE_CATEGORY, CAT_SUPPORT,         "Support",
00103           SLOT(actionHideCategory(int)), CAT_SUPPORT },
00104         { MENU_HIDE_CATEGORY, CAT_SENSITIVE_CONT,  "Sensitive Container",
00105           SLOT(actionHideCategory(int)), CAT_SENSITIVE_CONT },
00106 #endif
00107 
00108         { -1, MENU_HIDE_MATERIAL, "Hide By Material...",
00109           SLOT(actionShowMaterial(int)), MENU_HIDE_MATERIAL },
00110 
00111         { -1, MENU_RENDER_SEP, 0, 0, -1 },
00112         { -1, MENU_APPEARANCE, "Appearance...",
00113           SLOT(actionAppearance(int)), MENU_APPEARANCE },               
00114         { -1, MENU_RENDER,  "Render", 0, -1 },
00115         { MENU_RENDER, MENU_RENDER_AS_IS, "As Is",
00116           SLOT(actionRender(int)), MENU_RENDER_AS_IS },
00117         { MENU_RENDER, MENU_RENDER_SOLID, "Solid",
00118           SLOT(actionRender(int)), MENU_RENDER_SOLID },
00119         { MENU_RENDER, MENU_RENDER_WIREFRAME, "Wireframe",
00120           SLOT(actionRender(int)), MENU_RENDER_WIREFRAME },
00121         { -1, MENU_RENDER_ALL,  "Render All", 0, -1 },
00122         { MENU_RENDER_ALL, MENU_RENDER_SOLID, "Solid",
00123           SLOT(actionRenderAll(int)), MENU_RENDER_SOLID },
00124         { MENU_RENDER_ALL, MENU_RENDER_WIREFRAME, "Wireframe",
00125           SLOT(actionRenderAll(int)), MENU_RENDER_WIREFRAME },
00126 #if 0
00127         { -1, MENU_COLOUR, "Set Colour...",
00128           SLOT(actionColour(int)), MENU_COLOUR },
00129         { -1, MENU_TRANSPARENCY, "Set Transparency...",
00130           SLOT(actionTransparency(int)), MENU_TRANSPARENCY },
00131 #endif
00132     };
00133     static const int ndefs = sizeof (defs)/sizeof (defs[0]);
00134 
00135     m_menu = message.menu ();
00136     if (! (m_twig = dynamic_cast<VisG4VolumeTwig *> (message.object ())))
00137         m_menu->removeFromDefs (defs, ndefs);
00138     else
00139     {
00140         m_menu->insertFromDefs (this, defs, ndefs);
00141         menuUpdate ();
00142     }
00143 }
00144 
00145 void
00146 VisG4TwigOps::menuUpdate (void)
00147 {
00148     ASSERT (m_menu);
00149     // Update menu items to reflec the state of this twig.
00150     m_menu->changeItem (MENU_LOGICAL, m_twig->logical ()
00151                         ? "Physical Children" : "Logical Children");
00152     m_menu->setItemEnabled (MENU_GET_MASS, m_twig->logical ());
00153 
00154     const G4VisAttributes *attrs = m_twig->volume ()
00155                                    ->GetLogicalVolume ()
00156                                    ->GetVisAttributes ();
00157     ASSERT (attrs);
00158 
00159     bool                isset = attrs->IsForceDrawingStyle ();
00160     bool                solid = (attrs->GetForcedDrawingStyle ()
00161                                  == G4VisAttributes::solid);
00162     IgQtObjectMenu      *submenu = m_menu->subMenu (MENU_RENDER);
00163     submenu->setItemChecked (MENU_RENDER_AS_IS, !isset);
00164     submenu->setItemChecked (MENU_RENDER_SOLID, isset && solid);
00165     submenu->setItemChecked (MENU_RENDER_WIREFRAME, isset && !solid);
00166 }
00167 
00169 void
00170 VisG4TwigOps::actionLogical (int /* id */)
00171 {
00172     ASSERT (m_twig);
00173     QApplication::setOverrideCursor (Qt::waitCursor);
00174     m_twig->logical (! m_twig->logical ());
00175     IgRepSet::invalidate (m_twig, IgTwig::SELF_MASK | IgTwig::STRUCTURE_MASK);
00176     QApplication::restoreOverrideCursor ();
00177 }
00178 
00180 void
00181 VisG4TwigOps::actionGetMass (int /* id */)
00182 {
00183     ASSERT (m_twig);
00184     QApplication::setOverrideCursor (Qt::waitCursor);
00185     // doGetMass (id, m_twig);
00186     
00187     double mass = VisG4TwigOps::getMass (m_twig->volume ()->GetLogicalVolume (), m_twig->volume ()->GetLogicalVolume ()->GetMaterial ()) / kg;
00188 
00189     QApplication::restoreOverrideCursor ();    
00190    
00191 //     double mass = twig->volume ()->GetLogicalVolume ()->GetMass (false, twig->volume ()->GetLogicalVolume ()
00192 //                        ->GetMaterial ());
00193 
00194     QString text = QString ("Mass = %1 Kg")
00195                    .arg (mass, 0, 'g', 3);
00196     QMessageBox::information ((QWidget *) 0, "Logical Volume Mass", text);
00197 
00198 }
00199 
00201 void
00202 VisG4TwigOps::actionShowCategory (int id)
00203 {
00204     QApplication::setOverrideCursor (Qt::waitCursor);
00205     // Enable upwards if in show (FIXME: Reuse IgTwigOps)
00206     IgTwig *update = m_twig;
00207     for (IgTwig *t = m_twig->parent (); t; update = t, t = t->parent ())
00208         t->selfTraverse (true);
00209 
00210     doShowCategory (true, id, m_twig);
00211     IgRepSet::invalidate (update, IgTwig::FLAGS_MASK | IgTwig::STRUCTURE_MASK);
00212     QApplication::restoreOverrideCursor ();
00213 }
00214 
00215 void
00216 VisG4TwigOps::actionHideCategory (int id)
00217 {
00218     QApplication::setOverrideCursor (Qt::waitCursor);
00219     doShowCategory (false, id, m_twig);
00220     QApplication::restoreOverrideCursor ();
00221 }
00222 
00223 void
00224 VisG4TwigOps::doGetMass (int /* id */, VisG4VolumeTwig *twig)
00225 {
00226     ASSERT (twig);
00227 
00228     double mass = VisG4TwigOps::getMass (twig->volume ()->GetLogicalVolume (), twig->volume ()->GetLogicalVolume ()->GetMaterial ()) / kg;
00229     
00230 //     double mass = twig->volume ()->GetLogicalVolume ()->GetMass (false, twig->volume ()->GetLogicalVolume ()
00231 //                        ->GetMaterial ());
00232 
00233     QString text = QString ("Mass = %1")
00234                    .arg (mass);
00235     QMessageBox::information ((QWidget *) 0, "Logical Volume Mass", text);
00236 }
00237 
00238 //
00239 // FIXME: Temporary function to calculate mass - 
00240 // to be replaced with native G4 GetMass function 
00241 // when we'll move to 7.0.
00242 //
00243 double
00244 VisG4TwigOps::getMass (G4LogicalVolume *vol, G4Material *material)
00245 {
00246     G4LogicalVolume *logVol = vol;
00247     G4Material *logMaterial = material;
00248     if (!logMaterial)
00249     {
00250         QMessageBox::warning ((QWidget *) 0, "Logical Volume Mass: InvalidSetup", "No material associated to the logical volume!");
00251         return 0;
00252     }
00253     
00254     G4VSolid *logSolid = logVol->GetSolid ();
00255     if (!logSolid)
00256     {
00257         QMessageBox::warning ((QWidget *) 0, "Logical Volume Mass: InvalidSetup", "No solid associated to the logical volume!");
00258         return 0;
00259     }
00260     
00261     G4double globalDensity = logMaterial->GetDensity ();
00262     G4double mass = estimateCubicVolume (logSolid) * globalDensity;
00263 
00264     // For each daughter in the tree, subtract the mass occupied
00265     // and add the real daughter's one computed recursively
00266 
00267     int nDaughters = logVol->GetNoDaughters ();
00268 
00269     QProgressDialog progress( "Calculating mass...", "Abort", nDaughters,
00270                               0, "progress", TRUE );
00271     
00272     for (int it = 0; it < nDaughters; it++)
00273     {
00274         progress.setProgress (it);
00275         qApp->processEvents ();
00276 
00277         if (progress.wasCanceled ())
00278             break;
00279 
00280         G4VPhysicalVolume *physDaughter = logVol->GetDaughter (it);
00281         G4LogicalVolume *logDaughter = physDaughter->GetLogicalVolume ();
00282         G4double subMass = 0.0;
00283         G4VSolid* daughterSolid = 0;
00284         G4Material* daughterMaterial = 0;
00285         
00286         // Compute the mass to subtract and to add for each daughter
00287         // considering its multiplicity (i.e. replicated or not) and
00288         // eventually its parameterisation (by solid and/or by material)
00289         //
00290         for (G4int i = 0; i < physDaughter->GetMultiplicity (); i++)
00291         {
00292             G4VPVParameterisation *physParam = physDaughter->GetParameterisation ();
00293             if (physParam)
00294             {
00295                 daughterSolid = physParam->ComputeSolid (i, physDaughter);
00296                 daughterSolid->ComputeDimensions (physParam, i, physDaughter);
00297                 daughterMaterial = physParam->ComputeMaterial (i, physDaughter);
00298             }
00299             else
00300             {
00301                 daughterSolid = logDaughter->GetSolid ();
00302                 daughterMaterial = logDaughter->GetMaterial();
00303             }
00304             subMass = estimateCubicVolume (daughterSolid) * globalDensity;
00305 
00306             // Subtract the daughter's portion for the mass and add the real
00307             // daughter's mass computed recursively
00308             //
00309             mass = mass - subMass + getMass (logDaughter, daughterMaterial);
00310         }
00311     }
00312     progress.setProgress (nDaughters);
00313     return mass;
00314 }
00315 
00316 //
00317 // FIXME: Temporary function to calculate mass - 
00318 // to be replaced with native G4 GetMass function 
00319 // when we'll move to 7.0.
00320 //
00321 double
00322 VisG4TwigOps::estimateCubicVolume (G4VSolid *solid)
00323 {
00324     G4int nStat = 1000000;
00325     G4double epsilon = 0.001;
00326     G4VSolid *solidVol = solid;
00327     
00328     G4int iInside=0;
00329     G4double px,py,pz,minX,maxX,minY,maxY,minZ,maxZ,volume;
00330     G4bool yesno;
00331     G4ThreeVector p;
00332     EInside in;
00333     
00334     // values needed for CalculateExtent signature
00335 
00336     G4VoxelLimits limit;                // Unlimited
00337     G4AffineTransform origin;
00338 
00339     // min max extents of pSolid along X,Y,Z
00340 
00341     yesno = solidVol->CalculateExtent(kXAxis,limit,origin,minX,maxX);
00342     yesno = solidVol->CalculateExtent(kYAxis,limit,origin,minY,maxY);
00343     yesno = solidVol->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
00344     
00345     // limits
00346 
00347     if(nStat < 100)    nStat   = 100;
00348     if(epsilon > 0.01) epsilon = 0.01;
00349 
00350     for(G4int i = 0; i < nStat; i++ )
00351     {
00352         px = minX+(maxX-minX)*G4UniformRand();
00353         py = minY+(maxY-minY)*G4UniformRand();
00354         pz = minZ+(maxZ-minZ)*G4UniformRand();
00355         p  = G4ThreeVector(px,py,pz);
00356         in = solidVol->Inside(p);
00357         if(in != kOutside) iInside++;    
00358     }
00359     volume = (maxX-minX)*(maxY-minY)*(maxZ-minZ)*iInside/nStat;
00360     return volume;
00361 }
00362 
00363 void
00364 VisG4TwigOps::doShowCategory (bool show, int id, VisG4VolumeTwig *twig)
00365 {
00366     ASSERT (twig);
00367 
00368     // Set twig visibility
00369     bool matches = false;
00370     switch (id)
00371     {
00372     case CAT_SENSITIVE:
00373         matches = (twig->volume ()->GetLogicalVolume ()
00374                    ->GetSensitiveDetector () != 0);
00375         break;
00376 
00377     case CAT_INSENSITIVE:
00378         matches = (twig->volume ()->GetLogicalVolume ()
00379                    ->GetSensitiveDetector () == 0);
00380         break;
00381 
00382     case CAT_BEAMPIPE:
00383     case CAT_CABLE:
00384     case CAT_COOLING:
00385     case CAT_MAGNET:
00386     case CAT_SUPPORT:
00387     case CAT_SENSITIVE_CONT:
00388     default:
00389         ASSERT (false);
00390     }
00391 
00392     // Update twig itself
00393     if (matches)
00394         twig->selfVisible (show);
00395     twig->selfTraverse (true);
00396     twig->expand ();
00397 
00398     // Update children
00399     for (unsigned i = twig->children (); i; --i)
00400     {
00401         IgTwig *child = twig->child (i-1);
00402         ASSERT (dynamic_cast<VisG4VolumeTwig *> (child));
00403         doShowCategory (show, id, static_cast<VisG4VolumeTwig *> (child));
00404     }
00405 }
00406 
00408 void
00409 VisG4TwigOps::actionShowMaterial (int id)
00410 {
00411     // Pop up the material selector.  First populate the list with
00412     // known materials, select the ones we've selected in the past,
00413     // and then get the selection response from the user.
00414     QDialog     *matdiag = new QDialog (0, "Materials", true);
00415     QVBoxLayout *layout = new QVBoxLayout (matdiag, 11, 6);
00416     QLabel      *title = new QLabel (matdiag);
00417     QListBox    *materials = new QListBox (matdiag);
00418     QHBoxLayout *buttons = new QHBoxLayout (0, 0, 6);
00419     QPushButton *ok = new QPushButton (matdiag);
00420     QPushButton *cancel = new QPushButton (matdiag);
00421     
00422     matdiag->resize (300, 300);
00423     matdiag->setCaption ("Materials");
00424 
00425     title->setText ("Please select materials to show");
00426     ok->setText ("OK");
00427     cancel->setText ("Cancel");
00428     layout->addWidget (title);
00429 
00430     materials->setSelectionMode (QListBox::Extended);
00431     layout->addWidget (materials);
00432 
00433     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00434     buttons->addWidget (ok);
00435     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00436     buttons->addWidget (cancel);
00437     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00438     layout->addLayout (buttons);
00439 
00440     connect (ok, SIGNAL(clicked()), matdiag, SLOT(accept()));
00441     connect (cancel, SIGNAL(clicked()), matdiag, SLOT(reject()));
00442 
00443     // FIXME: Include only materials available in this subtree?
00444     // FIXME: This should be one integrated twig control centre that
00445     // follows current selection, and provides a widget stack to show
00446     // various selection criteria like by material, category, level,
00447     // etc.  (as well as other twig operations)
00448     ASSERT (G4Material::GetMaterialTable ());
00449     const G4MaterialTable *mt = G4Material::GetMaterialTable ();
00450     for (G4MaterialTable::const_iterator i = mt->begin(); i != mt->end(); ++i)
00451     {
00452         materials->insertItem ((*i)->GetName ().c_str ());
00453         materials->setSelected (materials->count ()-1,
00454                                 m_selected.count ((*i)->GetName ()));
00455     }
00456     materials->sort ();
00457 
00458     if (matdiag->exec () != QDialog::Accepted)
00459         return;
00460 
00461     for (unsigned i = 0; i < materials->count (); ++i)
00462     {
00463         std::string name ((const char *) materials->text (i).utf8 ());
00464         if (materials->isSelected (i))
00465             m_selected.insert (name);
00466         else
00467             m_selected.erase (name);
00468     }
00469 
00470     // FIXME: Enable upwards?  Does this material cut apply from here
00471     // downwards or is it a global operation for the whole scene graph
00472     // at render time?  If the latter, it belongs to a top-level menu
00473     // and not here.  For now make it work like the others.
00474     QApplication::setOverrideCursor (Qt::waitCursor);
00475     bool        show = id == MENU_SHOW_MATERIAL;
00476     IgTwig      *update = m_twig;
00477     for (IgTwig *t = m_twig->parent(); show && t; update = t, t = t->parent())
00478         t->selfTraverse (true);
00479 
00480     // Update nested twigs to match this material cut
00481     doShowMaterial (show, m_twig);
00482 
00483     // FIXME: menu needs to be updated!
00484     IgRepSet::invalidate (update, IgTwig::FLAGS_MASK | IgTwig::STRUCTURE_MASK);
00485     QApplication::restoreOverrideCursor ();
00486 }
00487 
00488 void
00489 VisG4TwigOps::doShowMaterial (bool show, VisG4VolumeTwig *twig)
00490 {
00491     ASSERT (twig);
00492 
00493     // Set twig visibility
00494     if (m_selected.count (twig->volume ()->GetLogicalVolume ()
00495                           ->GetMaterial ()->GetName ()))
00496         twig->selfVisible (show);
00497     twig->expand ();
00498     twig->selfTraverse (true);
00499 
00500     unsigned inum = twig->children ();
00501     QProgressDialog progress( "Show Material...", "Abort", inum,
00502                               0, "progress", true);
00503 
00504     // Update children
00505     for (unsigned i = inum; i; --i)
00506     {
00507         progress.setProgress (i);
00508         qApp->processEvents ();
00509 
00510         if (progress.wasCanceled ())
00511             break;
00512 
00513         IgTwig *child = twig->child (i-1);
00514         ASSERT (dynamic_cast<VisG4VolumeTwig *> (child));
00515         doShowMaterial (show, static_cast<VisG4VolumeTwig *> (child));
00516     }
00517     progress.setProgress (inum);
00518 }
00519 
00521 void
00522 VisG4TwigOps::actionRender (int id)
00523 { 
00524     ASSERT (m_changed.empty ()); 
00525     doRender (id, m_twig, false); 
00526     m_changed.clear (); 
00527 }
00528 
00529 void
00530 VisG4TwigOps::actionRenderAll (int id)
00531 {
00532     // Update twig and all its children.  Don't expand the tree.
00533     QApplication::setOverrideCursor (Qt::waitCursor);
00534     ASSERT (m_changed.empty ());
00535     doRender (id, m_twig, true);
00536     m_changed.clear ();
00537     QApplication::restoreOverrideCursor ();
00538 }
00539 
00540 void
00541 VisG4TwigOps::doRender (int id, VisG4VolumeTwig *twig, bool recurse)
00542 {
00543     // VisG4GeometryTwig guarantees that every logical volume has vis
00544     // attrs and that they are unique.  (FIXME: If this volume is in
00545     // physical mode, the attrs are still shared by many twigs and we
00546     // have to be careful about notifying they all have changed, or
00547     // rather, make sure each gets separate visualisation settings.)
00548 
00549     bool                changed = false;
00550     G4VisAttributes     *attrs = const_cast<G4VisAttributes *>
00551                                  (twig->volume ()
00552                                   ->GetLogicalVolume ()
00553                                   ->GetVisAttributes ());
00554     ASSERT (attrs);
00555     switch (id)
00556     {
00557     case MENU_RENDER_AS_IS:
00558         // Retain current force style, but turn force off
00559         changed = attrs->IsForceDrawingStyle ();
00560         if (attrs->GetForcedDrawingStyle () == G4VisAttributes::solid)
00561             attrs->SetForceSolid (false);
00562         else
00563             attrs->SetForceWireframe (false);
00564         break;
00565 
00566     case MENU_RENDER_SOLID:
00567         changed = (! attrs->IsForceDrawingStyle ()
00568                    || (attrs->GetForcedDrawingStyle ()
00569                        != G4VisAttributes::solid));
00570         attrs->SetForceSolid (true);
00571         break;
00572 
00573     case MENU_RENDER_WIREFRAME:
00574         changed = (! attrs->IsForceDrawingStyle ()
00575                    || (attrs->GetForcedDrawingStyle ()
00576                        != G4VisAttributes::wireframe));
00577         attrs->SetForceWireframe (true);
00578         break;
00579 
00580     default:
00581         ASSERT (false);
00582         break;
00583     }
00584 
00585     if (changed || m_changed.count (attrs))
00586     {
00587         IgRepSet::invalidate (twig, IgTwig::SELF_MASK);
00588         m_changed.insert (attrs);
00589     }
00590 
00591     for (unsigned i = twig->children (); recurse && i; --i)
00592     {
00593         IgTwig *child = twig->child (i-1);
00594         ASSERT (dynamic_cast<VisG4VolumeTwig *> (child));
00595         doRender (id, static_cast<VisG4VolumeTwig *> (child), true);
00596     }
00597 }
00598 
00599 void
00600 VisG4TwigOps::actionColour (int /* id */)
00601 {
00602     // VisG4GeometryTwig guarantees that every logical volume has vis
00603     // attrs and that they are unique.  (FIXME: If this volume is in
00604     // physical mode, the attrs are still shared by many twigs and we
00605     // have to be careful about notifying they all have changed, or
00606     // rather, make sure each gets separate visualisation settings.)
00607 
00608     G4VisAttributes *attrs = const_cast<G4VisAttributes *>
00609                              (m_twig->volume ()
00610                               ->GetLogicalVolume ()
00611                               ->GetVisAttributes ());
00612     ASSERT (attrs);
00613 
00614     // Get the old colour.
00615     G4Colour    colour = attrs->GetColour ();
00616 
00617     // Get the new colour.
00618     QColor      old (int (colour.GetRed () * 255),
00619                      int (colour.GetGreen () * 255),
00620                      int (colour.GetBlue () * 255));
00621     QColor      c = QColorDialog::getColor (old, 0);
00622 
00623     // If the dialog was accepted, change the colour.
00624     if  (c.isValid ())
00625     {
00626         attrs->SetColour (c.red () / 255.,
00627                           c.green () / 255.,
00628                           c.blue () / 255.,
00629                           colour.GetAlpha ());
00630 
00631         IgRepSet::invalidate (m_twig, IgTwig::SELF_MASK);
00632     }
00633 }
00634 
00635 void
00636 VisG4TwigOps::actionTransparency (int /* id */)
00637 {
00638     // VisG4GeometryTwig guarantees that every logical volume has vis
00639     // attrs and that they are unique.  (FIXME: If this volume is in
00640     // physical mode, the attrs are still shared by many twigs and we
00641     // have to be careful about notifying they all have changed, or
00642     // rather, make sure each gets separate visualisation settings.)
00643 
00644     G4VisAttributes *attrs = const_cast<G4VisAttributes *>
00645                              (m_twig->volume ()
00646                               ->GetLogicalVolume ()
00647                               ->GetVisAttributes ());
00648     ASSERT (attrs);
00649 
00650     // Get the old colour.
00651     G4Colour    colour = attrs->GetColour ();
00652 
00653     // Get the new colour.
00654     bool        ok = false;
00655     double      alpha = QInputDialog::getDouble
00656                         ("IGUANA", "Please select transparency (1.0 = opaque)",
00657                          colour.GetAlpha (), 0, 1.0, 3, &ok);
00658     if (ok)
00659     {
00660         attrs->SetColour (colour.GetRed (),
00661                           colour.GetGreen (),
00662                           colour.GetBlue (),
00663                           alpha);
00664         IgRepSet::invalidate (m_twig, IgTwig::SELF_MASK);
00665     }
00666 }
00667 
00668 void
00669 VisG4TwigOps::actionApplyFilter (int id)
00670 {
00671     // Pop up the filter selector.  First populate the list with
00672     // known filters, select the ones we've selected in the past,
00673     // and then get the selection response from the user.
00674     QDialog     *filterDialog = new QDialog (0, "Filters", true);
00675     QVBoxLayout *layout = new QVBoxLayout (filterDialog, 11, 6);
00676     QLabel      *title = new QLabel (filterDialog);
00677     QListBox    *filters = new QListBox (filterDialog);
00678     QHBoxLayout *buttons = new QHBoxLayout (0, 0, 6);
00679     QComboBox   *boolOperation = new QComboBox (filterDialog);    
00680     QPushButton *ok = new QPushButton (filterDialog);
00681     QPushButton *cancel = new QPushButton (filterDialog);
00682     
00683     filterDialog->resize (300, 300);
00684     filterDialog->setCaption ("Filters");
00685 
00686     title->setText ("Please select the filter to apply");
00687     ok->setText ("OK");
00688     cancel->setText ("Cancel");
00689     layout->addWidget (title);
00690 
00691     filters->setSelectionMode (QListBox::Extended);
00692     layout->addWidget (filters);
00693 
00694     boolOperation->insertItem ("Must match all selected filters.");
00695     boolOperation->insertItem ("Must match at least one of the selected filters.");
00696     boolOperation->insertItem ("Must match only one of the selected filters.");
00697     layout->addWidget (boolOperation);    
00698 
00699     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00700     buttons->addWidget (ok);
00701     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00702     buttons->addWidget (cancel);
00703     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00704     layout->addLayout (buttons);
00705 
00706     connect (ok, SIGNAL(clicked()), filterDialog, SLOT(accept()));
00707     connect (cancel, SIGNAL(clicked()), filterDialog, SLOT(reject()));
00708 
00709     // FIXME: Include only materials available in this subtree?
00710     // FIXME: This should be one integrated twig control centre that
00711     // follows current selection, and provides a widget stack to show
00712     // various selection criteria like by material, category, level,
00713     // etc.  (as well as other twig operations)
00714     
00715     ASSERT (VisG4FilterTable::instance ());
00716     VisG4FilterTable *ft = VisG4FilterTable::instance ();
00717 
00718     ASSERT (ft->begin () != ft->end ());
00719     
00720     for (VisG4FilterTable::const_iterator i = ft->begin (); i != ft->end (); ++i)
00721     {
00722         VisG4Filter &filter = *(i->second);
00723         
00724         filters->insertItem (filter.name ().c_str ());
00725         filters->setSelected (filters->count ()-1,
00726                               m_selected.count (filter.name ().c_str ()));
00727     }
00728     
00729     filters->sort ();
00730     
00731     
00732     if (filterDialog->exec () != QDialog::Accepted)
00733         return;
00734 
00735     VisG4VolumeTwig::m_visualizationFilter = 0;
00736     VisG4Filter *currentFilter=0;
00737     VisG4Filter *previousFilter=0;    
00738 
00739     int boolOperationValue = boolOperation->currentItem ();
00740 
00741     for (unsigned int i = 0; i < filters->count (); ++i)
00742     {
00743         std::string name ((const char *) filters->text (i).ascii ());
00744         if (filters->isSelected (i))
00745         {
00746             m_selected.insert (name);       
00747             currentFilter = (*ft)[name.c_str ()];
00748             ASSERT (currentFilter);
00749             
00750             if (VisG4VolumeTwig::m_visualizationFilter == 0)
00751             {           
00752                 VisG4VolumeTwig::m_visualizationFilter = currentFilter;
00753             }
00754             
00755             if (previousFilter != 0)
00756             {
00757                 previousFilter->addFilter (currentFilter);              
00758             }
00759             
00760             currentFilter->setCompositionOperation ((VisG4Filter::CompositionOperations) boolOperationValue);       
00761             previousFilter = currentFilter;
00762             
00763             std::cerr << currentFilter->name () << std::endl;       
00764         }
00765         else    
00766             m_selected.erase (name);
00767     }   
00768     
00769     if (VisG4VolumeTwig::m_visualizationFilter != 0)
00770     {   
00771         QApplication::setOverrideCursor (Qt::waitCursor);
00772         // Enable upwards if in show (FIXME: Reuse IgTwigOps)
00773         IgTwig *update = m_twig;
00774         for (IgTwig *t = m_twig->parent (); t; update = t, t = t->parent ())
00775             t->selfTraverse (true);
00776     
00777         doApplyFilter (true, id, m_twig);
00778         IgRepSet::invalidate (update, IgTwig::FLAGS_MASK | IgTwig::STRUCTURE_MASK);
00779         QApplication::restoreOverrideCursor ();
00780     }    
00781 }
00782 
00783 void
00784 VisG4TwigOps::doApplyFilter (bool show, int id, VisG4VolumeTwig *twig)
00785 {
00786     ASSERT (twig);
00787 
00788     // Dig out some common variables.
00789     VisG4VolumeTwig     *root = twig;
00790     while (VisG4VolumeTwig *x = dynamic_cast<VisG4VolumeTwig *> (root->parent()))
00791         root = x;        
00792     ASSERT (root);    
00793 
00794     G4VPhysicalVolume   *volume = root->volume ();
00795     ASSERT (volume);
00796 
00797     bool                match = false;    
00798 
00799     for (unsigned int i = 0; i < twig->paths (); ++i)
00800     {
00801         bool                    replica = false;
00802         G4VPhysicalVolume       *pv = volume;
00803         G4LogicalVolume         *lv = 0;
00804         G4VSolid                *solid = 0;
00805         G4Transform3D           pos;
00806 
00807         VisG4VolumePicker::apply (twig->path (i), pv, lv, solid, pos, replica);
00808         ASSERT (solid);
00809         ASSERT (pv);
00810         ASSERT (lv);
00811 
00812         // Create a VisSoMaterialDetails structure which describes the
00813         // current twig.
00814         VisSoMaterialDetails details;
00815         details << VisG4MaterialDetails (lv->GetMaterial ());
00816         details << VisG4PVDetails (pv); 
00817         details << VisG4PathDetails (twig->fullName ());        
00818 
00819         //Enable the twig only if the details pass the test
00820         if (VisG4VolumeTwig::m_visualizationFilter->compute (details))
00821         {
00822             match |= true;      
00823         }
00824     }
00825     
00826     if (match == true)
00827         twig->selfVisible (show);
00828     twig->selfTraverse (true);
00829     twig->expand ();
00830 
00831         
00832     // Update children
00833     for (unsigned i = twig->children (); i; --i)
00834     {
00835         IgTwig *child = twig->child (i-1);
00836         ASSERT (dynamic_cast<VisG4VolumeTwig *> (child));
00837         doApplyFilter (show, id, static_cast<VisG4VolumeTwig *> (child));
00838     }    
00839 }
00840 
00841 void
00842 VisG4TwigOps::actionAppearance (int /* id */)
00843 {
00844     QDialog     *materialDialog = new QDialog (0, "Appearance", true);
00845     QVBoxLayout *layout = new QVBoxLayout (materialDialog, 11, 6);
00846     QLabel      *title = new QLabel (materialDialog);
00847     QVBox *dummyBox = new QVBox (materialDialog);       
00848     IgMatEdMainWidget  *materialEditor = new IgMatEdMainWidget (dummyBox, 0);    
00849     QHBoxLayout *buttons = new QHBoxLayout (0, 0, 6);
00850     QPushButton *save = new QPushButton (materialDialog);
00851     QPushButton *ok = new QPushButton (materialDialog);
00852     QPushButton *cancel = new QPushButton (materialDialog);
00853     
00854     materialDialog->resize (700, 300);
00855     materialDialog->setCaption ("Appearance");
00856 
00857     title->setText ("Configure current object material");    
00858     save->setText ("Save");
00859     ok->setText ("OK");
00860     cancel->setText ("Cancel");
00861     layout->addWidget (title);
00862     layout->addWidget (dummyBox);
00863    
00864     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00865     buttons->addWidget (save);
00866     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00867     buttons->addWidget (ok);
00868     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00869     buttons->addWidget (cancel);
00870     buttons->addItem (new QSpacerItem (20, 20, QSizePolicy::Expanding));
00871     layout->addLayout (buttons);
00872 
00873     connect (save, SIGNAL(clicked()), materialDialog, SLOT(accept()));
00874     connect (save, SIGNAL(clicked()), materialDialog, SLOT(show()));
00875     connect (ok, SIGNAL(clicked()), materialDialog, SLOT(accept()));
00876     connect (cancel, SIGNAL(clicked()), materialDialog, SLOT(reject()));
00877 
00878     // Get the name of the material associated with the twig.
00879     VisG4VolumeTwig     *root = m_twig;
00880     while (VisG4VolumeTwig *x = dynamic_cast<VisG4VolumeTwig *> (root->parent()))
00881         root = x;        
00882     ASSERT (root);    
00883 
00884     G4VPhysicalVolume   *volume = root->volume ();
00885     ASSERT (volume);
00886     
00887     bool                replica = false;
00888     G4VPhysicalVolume   *pv = volume;
00889     G4LogicalVolume     *lv = 0;
00890     G4VSolid            *solid = 0;
00891     G4Transform3D       pos;    
00892 
00893     ASSERT (m_twig->paths ());
00894     
00895     VisG4VolumePicker::apply (m_twig->path (0), pv, lv, solid, pos, replica);
00896 
00897     materialEditor->setCurrentG4Material (lv->GetMaterial ()->GetName ());
00898         
00899     save->show ();
00900     ok->show ();
00901     cancel->show ();
00902   
00903     if (materialDialog->exec () != QDialog::Accepted)
00904         return;    
00905 
00906     materialEditor->saveMaterialMap ();
00907     materialEditor->saveSoMaterials ();    
00908     
00909     IgRepSet::invalidate (m_twig, IgTwig::SELF_MASK);
00910 }

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