// @(#):$Id$ // Author: M.Gheata /************************************************************************* * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // TGeoVolumeEditor // // ////////////////////////////////////////////////////////////////////////// /* Editor for geometry volumes and assemblies of volumes. Besides the volume name and line attributes, a TGeoVolume has the following editable categories split vertically by a shutter: - Properties: one can edit the shape and medium components from here. It is also possible to change the existing ones. - Daughters: the main category allowing defining, editing, removing or positioning daughter volumes inside the current edited volume. To add a daughter, one needs to select first a volume and a matrix. Currently no check is performed if the daughter volume creates an extrusion (illegal for tracking). To remove or change the position of an existing daughter, one should simply select the desired daughter from the combo box with the existing ones, then simply click the appropriate button. - Visualization: One can set the visibility of the volume and of its daughters, set the visibility depth and the view type. Selecting "All" will draw the volume and all visible daughters down to the selected level starting from the edited volume. Selecting "Leaves" will draw just the deepest daughters within the selected visibility level, without displaying the containers, while "Only" will just draw the edited volume. - Division: The category becomes active only if there are no daughters of the edited volume added by normal positioning (e.g. from category). The minimum allowed starting value for the selected division axis is automatically selected, while the dslicing step is set to 0 - meaning that only the number of slices matter. */ #include "TGeoVolumeEditor.h" #include "TGeoVolume.h" #include "TGeoPatternFinder.h" #include "TGeoManager.h" #include "TGeoMatrix.h" #include "TVirtualPad.h" #include "TBaseClass.h" #include "TGTab.h" #include "TGComboBox.h" #include "TGButton.h" #include "TGButtonGroup.h" #include "TGTextEntry.h" #include "TGNumberEntry.h" #include "TGLabel.h" #include "TGShutter.h" #include "TG3DLine.h" #include "TGeoTabManager.h" #include "TGedEditor.h" ClassImp(TGeoVolumeEditor) enum ETGeoVolumeWid { kVOL_NAME, kVOL_TITLE, kVOL_SHAPE_SELECT, kVOL_MEDIA_SELECT, kVOL_NODE_SELECT, kVOL_VOL_SELECT, kVOL_MATRIX_SELECT, kVOL_EDIT_SHAPE, kVOL_EDIT_MEDIUM, kVOL_NODEID, kVOL_APPLY, kVOL_CANCEL, kVOL_UNDO, kVOL_VISLEVEL, kVOL_DIVSTART, kVOL_DIVEND, kVOL_DIVSTEP, kVOL_DIVN, kCAT_GENERAL, kCAT_DAUGHTERS, kCAT_DIVISION, kCAT_VIS, kDIV_NAME }; //______________________________________________________________________________ TGeoVolumeEditor::TGeoVolumeEditor(const TGWindow *p, Int_t width, Int_t height, UInt_t options, Pixel_t back) : TGeoGedFrame(p, width, height, options | kVerticalFrame, back) { // Constructor for volume editor. fGeometry = 0; fVolume = 0; fIsModified = kFALSE; fIsAssembly = kFALSE; fIsDivided = kFALSE; // TGShutter for categories fCategories = new TGShutter(this, kSunkenFrame); TGCompositeFrame *container, *f1; Pixel_t color; TGLabel *label; // General settings TGShutterItem *si = new TGShutterItem(fCategories, new TGHotString("Properties"),kCAT_GENERAL); container = (TGCompositeFrame*)si->GetContainer(); container->SetBackgroundColor(GetDefaultFrameBackground()); fCategories->AddItem(si); // TextEntry for volume name f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Volume name"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); gClient->GetColorByName("#ff0000", color); label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); fVolumeName = new TGTextEntry(container, "", kVOL_NAME); fVolumeName->SetDefaultSize(135, fVolumeName->GetDefaultHeight()); fVolumeName->SetToolTipText("Enter the volume name"); container->AddFrame(fVolumeName, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 3, 1, 2, 5)); // Current shape f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Shape and medium"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); gClient->GetColorByName("#ff0000", color); label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 10, 0)); f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame); fSelectedShape = 0; fLSelShape = new TGLabel(f1, "Select shape"); gClient->GetColorByName("#0000ff", color); fLSelShape->SetTextColor(color); fLSelShape->ChangeOptions(kSunkenFrame | kDoubleBorder); f1->AddFrame(fLSelShape, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 1, 1, 2, 2)); fBSelShape = new TGPictureButton(f1, fClient->GetPicture("rootdb_t.xpm"), kVOL_SHAPE_SELECT); fBSelShape->SetToolTipText("Replace with one of the existing shapes"); fBSelShape->Associate(this); f1->AddFrame(fBSelShape, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2)); fEditShape = new TGTextButton(f1, "Edit"); f1->AddFrame(fEditShape, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2)); fEditShape->SetToolTipText("Edit selected shape"); fEditShape->Associate(this); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 2, 2, 0, 0)); // Current medium f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame); fSelectedMedium = 0; fLSelMedium = new TGLabel(f1, "Select medium"); gClient->GetColorByName("#0000ff", color); fLSelMedium->SetTextColor(color); fLSelMedium->ChangeOptions(kSunkenFrame | kDoubleBorder); f1->AddFrame(fLSelMedium, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 1, 1, 2, 2)); fBSelMedium = new TGPictureButton(f1, fClient->GetPicture("rootdb_t.xpm"), kVOL_MEDIA_SELECT); fBSelMedium->SetToolTipText("Replace with one of the existing media"); fBSelMedium->Associate(this); f1->AddFrame(fBSelMedium, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2)); fEditMedium = new TGTextButton(f1, "Edit"); f1->AddFrame(fEditMedium, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2)); fEditMedium->SetToolTipText("Edit selected medium"); fEditMedium->Associate(this); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 2, 2, 0, 0)); // List of daughters si = new TGShutterItem(fCategories, new TGHotString("Daughters"),kCAT_DAUGHTERS); container = (TGCompositeFrame*)si->GetContainer(); container->SetBackgroundColor(GetDefaultFrameBackground()); fCategories->AddItem(si); // Existing daughters f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Existing daughters"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); gClient->GetColorByName("#ff0000", color); label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame | kRaisedFrame); fNodeList = new TGComboBox(f1, kVOL_NODE_SELECT); fNodeList->Resize(100, fVolumeName->GetDefaultHeight()); fNodeList->Associate(this); f1->AddFrame(fNodeList, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 2)); // Buttons for editing matrix and removing node f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame | kSunkenFrame | kFixedWidth); fEditMatrix = new TGTextButton(f1, "Position"); f1->AddFrame(fEditMatrix, new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2)); fEditMatrix->SetToolTipText("Edit the position of selected node"); fEditMatrix->Associate(this); fRemoveNode = new TGTextButton(f1, "Remove"); f1->AddFrame(fRemoveNode, new TGLayoutHints(kLHintsRight, 2, 2, 2, 2)); fRemoveNode->SetToolTipText("Remove the selected node. Cannot undo !)"); fRemoveNode->Associate(this); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 2)); // Adding daughters f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Add daughter"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); gClient->GetColorByName("#ff0000", color); label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 10, 0)); // Select from existing volumes f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame | kFixedWidth); fSelectedVolume = 0; fLSelVolume = new TGLabel(f1, "Select volume"); gClient->GetColorByName("#0000ff", color); fLSelVolume->SetTextColor(color); fLSelVolume->ChangeOptions(kSunkenFrame | kDoubleBorder); f1->AddFrame(fLSelVolume, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 1, 1, 2, 2)); fBSelVolume = new TGPictureButton(f1, fClient->GetPicture("rootdb_t.xpm"), kVOL_VOL_SELECT); fBSelVolume->SetToolTipText("Select one of the existing volumes"); fBSelVolume->Associate(this); f1->AddFrame(fBSelVolume, new TGLayoutHints(kLHintsRight, 1, 1, 2, 2)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 2)); // Matrix selection for nodes f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame | kFixedWidth); fSelectedMatrix = 0; fLSelMatrix = new TGLabel(f1, "Select matrix"); gClient->GetColorByName("#0000ff", color); fLSelMatrix->SetTextColor(color); fLSelMatrix->ChangeOptions(kSunkenFrame | kDoubleBorder); f1->AddFrame(fLSelMatrix, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 1, 1, 2, 2)); fBSelMatrix = new TGPictureButton(f1, fClient->GetPicture("rootdb_t.xpm"), kVOL_MATRIX_SELECT); fBSelMatrix->SetToolTipText("Select one of the existing matrices"); fBSelMatrix->Associate(this); f1->AddFrame(fBSelMatrix, new TGLayoutHints(kLHintsRight, 1, 1, 2, 2)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 2)); // Copy number f1 = new TGCompositeFrame(container, 155, 30, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "Node id"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0)); fCopyNumber = new TGNumberEntry(f1, 0., 5, kVOL_NODEID); fCopyNumber->SetNumStyle(TGNumberFormat::kNESInteger); fCopyNumber->SetNumAttr(TGNumberFormat::kNEANonNegative); fCopyNumber->Resize(20,fCopyNumber->GetDefaultHeight()); TGTextEntry *nef = (TGTextEntry*)fCopyNumber->GetNumberEntry(); nef->SetToolTipText("Enter node copy number"); fCopyNumber->Associate(this); f1->AddFrame(fCopyNumber, new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2)); fAddNode = new TGTextButton(f1, "Add"); f1->AddFrame(fAddNode, new TGLayoutHints(kLHintsRight, 2, 2, 2, 2)); fAddNode->Associate(this); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 2)); // Visualization si = new TGShutterItem(fCategories, new TGHotString("Visualization"),kCAT_VIS); container = (TGCompositeFrame*)si->GetContainer(); container->SetBackgroundColor(GetDefaultFrameBackground()); fCategories->AddItem(si); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Visibility"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); // gClient->GetColorByName("#ff0000", color); // label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth | kSunkenFrame | kDoubleBorder); fBVis[0] = new TGCheckButton(f1, "Volume"); fBVis[1] = new TGCheckButton(f1, "Nodes"); f1->AddFrame(fBVis[0], new TGLayoutHints(kLHintsLeft, 2, 2, 0 ,0)); f1->AddFrame(fBVis[1], new TGLayoutHints(kLHintsRight, 2, 2, 0 ,0)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 0)); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "Depth"), new TGLayoutHints(kLHintsLeft, 2, 2, 4, 0)); // gClient->GetColorByName("#0000ff", color); // label->SetTextColor(color); fEVisLevel = new TGNumberEntry(f1, 0, 5, kVOL_VISLEVEL); fEVisLevel->SetNumStyle(TGNumberFormat::kNESInteger); fEVisLevel->SetNumAttr(TGNumberFormat::kNEAPositive); fEVisLevel->Resize(40,fEVisLevel->GetDefaultHeight()); nef = (TGTextEntry*)fEVisLevel->GetNumberEntry(); nef->SetToolTipText("Set visibility level here"); fEVisLevel->SetNumber(3); fEVisLevel->Associate(this); f1->AddFrame(fEVisLevel, new TGLayoutHints(kLHintsLeft, 2, 2, 0 ,0)); fBAuto = new TGCheckButton(f1,"Auto"); f1->AddFrame(fBAuto, new TGLayoutHints(kLHintsRight, 0, 0, 2, 0)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); TString stitle = "View"; TGButtonGroup *bg = new TGVButtonGroup(container, stitle); fBView[0] = new TGRadioButton(bg, "All"); fBView[1] = new TGRadioButton(bg, "Leaves"); fBView[2] = new TGRadioButton(bg, "Only"); bg->SetRadioButtonExclusive(); bg->Show(); container->AddFrame(bg, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 0)); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth | kSunkenFrame | kDoubleBorder); fBRaytrace = new TGCheckButton(f1,"Raytrace"); f1->AddFrame(fBRaytrace, new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); // Division si = new TGShutterItem(fCategories, new TGHotString("Division"),kCAT_DIVISION); container = (TGCompositeFrame*)si->GetContainer(); container->SetBackgroundColor(GetDefaultFrameBackground()); fCategories->AddItem(si); // TextEntry for division name f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Division name"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); gClient->GetColorByName("#ff0000", color); label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); fDivName = new TGTextEntry(container, new TGTextBuffer(50), kDIV_NAME); fDivName->Resize(135, fVolumeName->GetDefaultHeight()); fDivName->SetToolTipText("Enter the volume name"); container->AddFrame(fDivName, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5)); // Axis selection stitle = "Axis"; f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); bg = new TGVButtonGroup(f1, stitle); fBDiv[0] = new TGRadioButton(bg, "Axis 1"); fBDiv[1] = new TGRadioButton(bg, "Axis 2"); fBDiv[2] = new TGRadioButton(bg, "Axis 3"); bg->Insert(fBDiv[0]); bg->Insert(fBDiv[1]); bg->Insert(fBDiv[2]); bg->SetRadioButtonExclusive(); f1->AddFrame(bg, new TGLayoutHints(kLHintsLeft, 2, 2, 0, 0)); fApplyDiv = new TGTextButton(f1, "Apply"); fApplyDiv->SetToolTipText("Apply new division settings"); f1->AddFrame(fApplyDiv, new TGLayoutHints(kLHintsRight, 0, 2, 30, 0)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); // Division range f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Division parameters"), new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); f1->AddFrame(new TGHorizontal3DLine(f1), new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); // gClient->GetColorByName("#ff0000", color); // label->SetTextColor(color); container->AddFrame(f1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "From"), new TGLayoutHints(kLHintsLeft, 2, 2, 4, 0)); // gClient->GetColorByName("#0000ff", color); // label->SetTextColor(color); fEDivFrom = new TGNumberEntry(f1, 0, 5, kVOL_DIVSTART); // fEDivFrom->SetNumStyle(TGNumberFormat::kNESInteger); // fEDivFrom->SetNumAttr(TGNumberFormat::kNEAPositive); fEDivFrom->Resize(100,fEDivFrom->GetDefaultHeight()); nef = (TGTextEntry*)fEDivFrom->GetNumberEntry(); nef->SetToolTipText("Set start value"); fEDivFrom->Associate(this); f1->AddFrame(fEDivFrom, new TGLayoutHints(kLHintsRight, 2, 2, 0 ,0)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Step"), new TGLayoutHints(kLHintsLeft, 2, 2, 4, 0)); // gClient->GetColorByName("#0000ff", color); // label->SetTextColor(color); fEDivStep = new TGNumberEntry(f1, 0, 5, kVOL_DIVSTEP); // fEDivFrom->SetNumStyle(TGNumberFormat::kNESInteger); fEDivStep->SetNumAttr(TGNumberFormat::kNEANonNegative); fEDivStep->Resize(100,fEDivStep->GetDefaultHeight()); nef = (TGTextEntry*)fEDivStep->GetNumberEntry(); nef->SetToolTipText("Set division step"); fEDivStep->Associate(this); f1->AddFrame(fEDivStep, new TGLayoutHints(kLHintsRight, 2, 2, 0 ,0)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); f1 = new TGCompositeFrame(container, 155, 10, kHorizontalFrame |kFixedWidth); f1->AddFrame(label = new TGLabel(f1, "Nslices"), new TGLayoutHints(kLHintsLeft, 2, 2, 4, 0)); // gClient->GetColorByName("#0000ff", color); // label->SetTextColor(color); fEDivN = new TGNumberEntry(f1, 0, 5, kVOL_DIVN); fEDivN->SetNumStyle(TGNumberFormat::kNESInteger); fEDivN->SetNumAttr(TGNumberFormat::kNEAPositive); fEDivN->Resize(100,fEDivN->GetDefaultHeight()); nef = (TGTextEntry*)fEDivN->GetNumberEntry(); nef->SetToolTipText("Set number of slices"); fEDivN->Associate(this); f1->AddFrame(fEDivN, new TGLayoutHints(kLHintsRight, 2, 2, 0 ,0)); container->AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); fCategories->Resize(163,340); AddFrame(fCategories, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 0, 0, 4, 4)); fCategories->Layout(); fCategories->SetDefaultSize(GetDefaultWidth(), GetDefaultHeight()); } //______________________________________________________________________________ TGeoVolumeEditor::~TGeoVolumeEditor() { // Destructor TGCompositeFrame *cont; cont = (TGCompositeFrame*)fCategories->GetItem("Properties")->GetContainer(); TGeoTabManager::Cleanup(cont); fCategories->GetItem("Properties")->SetCleanup(0); cont = (TGCompositeFrame*)fCategories->GetItem("Daughters")->GetContainer(); TGeoTabManager::Cleanup(cont); fCategories->GetItem("Daughters")->SetCleanup(0); cont = (TGCompositeFrame*)fCategories->GetItem("Visualization")->GetContainer(); TGeoTabManager::Cleanup(cont); fCategories->GetItem("Visualization")->SetCleanup(0); cont = (TGCompositeFrame*)fCategories->GetItem("Division")->GetContainer(); TGeoTabManager::Cleanup(cont); fCategories->GetItem("Division")->SetCleanup(0); delete fBView[0]; delete fBView[1]; delete fBView[2]; delete fBDiv [0]; delete fBDiv [1]; delete fBDiv [2]; Cleanup(); } //______________________________________________________________________________ void TGeoVolumeEditor::ConnectSignals2Slots() { // Connect signals to slots. fVolumeName->Connect("TextChanged(const char *)", "TGeoVolumeEditor", this, "DoVolumeName()"); fDivName->Connect("TextChanged(const char *)", "TGeoVolumeEditor", this, "DoDivName()"); fEditMedium->Connect("Clicked()", "TGeoVolumeEditor", this, "DoEditMedium()"); fEditShape->Connect("Clicked()", "TGeoVolumeEditor", this, "DoEditShape()"); fEditMatrix->Connect("Clicked()", "TGeoVolumeEditor", this, "DoEditMatrix()"); fAddNode->Connect("Clicked()", "TGeoVolumeEditor", this, "DoAddNode()"); fRemoveNode->Connect("Clicked()", "TGeoVolumeEditor", this, "DoRemoveNode()"); fBSelShape->Connect("Clicked()", "TGeoVolumeEditor", this, "DoSelectShape()"); fBSelMedium->Connect("Clicked()", "TGeoVolumeEditor", this, "DoSelectMedium()"); fBSelVolume->Connect("Clicked()", "TGeoVolumeEditor", this, "DoSelectVolume()"); fBSelMatrix->Connect("Clicked()", "TGeoVolumeEditor", this, "DoSelectMatrix()"); fBVis[0]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoVisVolume()"); fBVis[1]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoVisDaughters()"); fBAuto->Connect("Clicked()", "TGeoVolumeEditor", this, "DoVisAuto()"); fEVisLevel->Connect("ValueSet(Long_t)", "TGeoVolumeEditor", this, "DoVisLevel()"); fBView[0]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoViewAll()"); fBView[1]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoViewLeaves()"); fBView[2]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoViewOnly()"); fBDiv[0]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoDivSelAxis()"); fBDiv[1]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoDivSelAxis()"); fBDiv[2]->Connect("Clicked()", "TGeoVolumeEditor", this, "DoDivSelAxis()"); fEDivFrom->Connect("ValueSet(Long_t)", "TGeoVolumeEditor", this, "DoDivFromTo()"); fEDivStep->Connect("ValueSet(Long_t)", "TGeoVolumeEditor", this, "DoDivStep()"); fEDivN->Connect("ValueSet(Long_t)", "TGeoVolumeEditor", this, "DoDivN()"); fBRaytrace->Connect("Clicked()", "TGeoVolumeEditor", this, "DoRaytrace()"); fApplyDiv->Connect("Clicked()", "TGeoVolumeEditor", this, "DoApplyDiv()"); } //______________________________________________________________________________ void TGeoVolumeEditor::SetModel(TObject* obj) { // Connect to the picked volume. if (obj == 0 || !obj->InheritsFrom(TGeoVolume::Class())) { SetActive(kFALSE); return; } fVolume = (TGeoVolume*)obj; fGeometry = fVolume->GetGeoManager(); const char *vname = fVolume->GetName(); fVolumeName->SetText(vname); fSelectedShape = fVolume->GetShape(); if (fSelectedShape) fLSelShape->SetText(fSelectedShape->GetName()); fSelectedMedium = fVolume->GetMedium(); if (fSelectedMedium) fLSelMedium->SetText(fSelectedMedium->GetName()); fNodeList->RemoveEntries(0, fNodeList->GetNumberOfEntries()+1); TIter next2(fVolume->GetNodes()); TGeoNode *node; Int_t icrt = 0; while ((node=(TGeoNode*)next2())) fNodeList->AddEntry(node->GetName(), icrt++); fNodeList->Select(0); fCopyNumber->SetNumber(fVolume->GetNdaughters()+1); if (!fVolume->GetNdaughters() || fVolume->GetFinder()) { fEditMatrix->SetEnabled(kFALSE); fRemoveNode->SetEnabled(kFALSE); } else { fEditMatrix->SetEnabled(kTRUE); fRemoveNode->SetEnabled(kTRUE); } if (!fSelectedVolume) fAddNode->SetEnabled(kFALSE); if (fVolume->IsAssembly()) { fBSelShape->SetEnabled(kFALSE); fBSelMedium->SetEnabled(kFALSE); } fBVis[0]->SetState((fVolume->IsVisible())?kButtonDown:kButtonUp); fBVis[1]->SetState((fVolume->IsVisibleDaughters())?kButtonDown:kButtonUp); fBView[0]->SetState((fVolume->IsVisContainers())?kButtonDown:kButtonUp, kTRUE); fBView[1]->SetState((fVolume->IsVisLeaves())?kButtonDown:kButtonUp, kTRUE); fBView[2]->SetState((fVolume->IsVisOnly())?kButtonDown:kButtonUp, kTRUE); fBRaytrace->SetState((fVolume->IsRaytracing())?kButtonDown:kButtonUp); fBAuto->SetState((fGeometry->GetVisLevel())?kButtonUp:kButtonDown); fEVisLevel->SetNumber(fGeometry->GetVisLevel()); fApplyDiv->SetEnabled(kFALSE); if ((!fVolume->GetFinder() && fVolume->GetNdaughters()) || fVolume->IsAssembly()) { fCategories->GetItem("Division")->GetButton()->SetEnabled(kFALSE); } else { fCategories->GetItem("Division")->GetButton()->SetEnabled(kTRUE); Double_t start=0., step=0., end = 0.; Int_t ndiv = 2, iaxis = 1; TString axis_name; for (Int_t i=0; i<3; i++) { axis_name = fVolume->GetShape()->GetAxisName(i+1); fBDiv[i]->SetText(axis_name); } if (fVolume->GetFinder()) { fDivName->SetText(fVolume->GetNode(0)->GetVolume()->GetName()); iaxis = fVolume->GetFinder()->GetDivAxis(); start = fVolume->GetFinder()->GetStart(); step = fVolume->GetFinder()->GetStep(); ndiv = fVolume->GetFinder()->GetNdiv(); } else { fDivName->SetText("Enter name"); fSelectedShape->GetAxisRange(iaxis,start,end); step = 0; } fBDiv[iaxis-1]->SetState(kButtonDown, kTRUE); fEDivFrom->SetNumber(start); fEDivStep->SetNumber(step); fEDivN->SetNumber(ndiv); } if (fInit) ConnectSignals2Slots(); SetActive(); if (GetParent()==fTabMgr->GetVolumeTab()) fTab->Layout(); } //______________________________________________________________________________ void TGeoVolumeEditor::ActivateBaseClassEditors(TClass* cl) { // Add editors to fGedFrame and exclude TLineEditor. fGedEditor->ExcludeClassEditor(TAttFill::Class()); TGedFrame::ActivateBaseClassEditors(cl); } //______________________________________________________________________________ void TGeoVolumeEditor::DoVolumeName() { // Modify volume name. fVolume->SetName(fVolumeName->GetText()); } //______________________________________________________________________________ void TGeoVolumeEditor::DoSelectShape() { // Select a new shape. TGeoShape *shape = fSelectedShape; new TGeoShapeDialog(fBSelShape, gClient->GetRoot(), 200,300); fSelectedShape = (TGeoShape*)TGeoShapeDialog::GetSelected(); if (fSelectedShape) fLSelShape->SetText(fSelectedShape->GetName()); else fSelectedShape = shape; } //______________________________________________________________________________ void TGeoVolumeEditor::DoSelectMedium() { // Select a new medium. TGeoMedium *med = fSelectedMedium; new TGeoMediumDialog(fBSelMedium, gClient->GetRoot(), 200,300); fSelectedMedium = (TGeoMedium*)TGeoMediumDialog::GetSelected(); if (fSelectedMedium) fLSelMedium->SetText(fSelectedMedium->GetName()); else fSelectedMedium = med; } //______________________________________________________________________________ void TGeoVolumeEditor::DoSelectMatrix() { // Select a matrix for positioning. TGeoMatrix *matrix = fSelectedMatrix; new TGeoMatrixDialog(fBSelMatrix, gClient->GetRoot(), 200,300); fSelectedMatrix = (TGeoMatrix*)TGeoMatrixDialog::GetSelected(); if (fSelectedMatrix) fLSelMatrix->SetText(fSelectedMatrix->GetName()); else fSelectedMatrix = matrix; } //______________________________________________________________________________ void TGeoVolumeEditor::DoSelectVolume() { // Select a daughter volume. TGeoVolume *vol = fSelectedVolume; new TGeoVolumeDialog(fBSelVolume, gClient->GetRoot(), 200,300); fSelectedVolume = (TGeoVolume*)TGeoVolumeDialog::GetSelected(); if (fSelectedVolume) fLSelVolume->SetText(fSelectedVolume->GetName()); else fSelectedVolume = vol; if (fSelectedVolume) fAddNode->SetEnabled(kTRUE); } //______________________________________________________________________________ void TGeoVolumeEditor::DoEditShape() { // Edit the shape of the volume. fTabMgr->GetShapeEditor(fVolume->GetShape()); } //______________________________________________________________________________ void TGeoVolumeEditor::DoEditMedium() { // Edit the medium of the volume. fTabMgr->GetMediumEditor(fVolume->GetMedium()); } //______________________________________________________________________________ void TGeoVolumeEditor::DoEditMatrix() { // Edit the position of the selected node. if (!fVolume->GetNdaughters()) return; Int_t i = fNodeList->GetSelected(); if (i<0) return; fTabMgr->GetMatrixEditor(fVolume->GetNode(i)->GetMatrix()); } //______________________________________________________________________________ void TGeoVolumeEditor::DoAddNode() { // Add a daughter. if (!fSelectedVolume || fVolume->GetFinder()) return; Int_t icopy = fCopyNumber->GetIntNumber(); fVolume->AddNode(fSelectedVolume, icopy, fSelectedMatrix); Int_t nd = fVolume->GetNdaughters(); fNodeList->AddEntry(fVolume->GetNode(nd-1)->GetName(), nd-1); fNodeList->Select(nd-1); fCopyNumber->SetNumber(nd+1); if (fSelectedMatrix) fEditMatrix->SetEnabled(kTRUE); fRemoveNode->SetEnabled(kTRUE); fGeometry->SetTopVisible(); fEditMatrix->SetEnabled(kTRUE); fRemoveNode->SetEnabled(kTRUE); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoRemoveNode() { // Remove a daughter. if (!fVolume->GetNdaughters() || fVolume->GetFinder()) { fRemoveNode->SetEnabled(kFALSE); fEditMatrix->SetEnabled(kFALSE); return; } Int_t i = fNodeList->GetSelected(); if (i<0) return; fVolume->RemoveNode(fVolume->GetNode(i)); fNodeList->RemoveEntries(0, fNodeList->GetNumberOfEntries()+1); TIter next(fVolume->GetNodes()); TGeoNode *node; i = 0; while ((node=(TGeoNode*)next())) fNodeList->AddEntry(node->GetName(), i++); fNodeList->Select(0); fCopyNumber->SetNumber(fVolume->GetNdaughters()+1); if (!fVolume->GetNdaughters()) { fRemoveNode->SetEnabled(kFALSE); fEditMatrix->SetEnabled(kFALSE); fCategories->GetItem("Division")->GetButton()->SetEnabled(kTRUE); Double_t start=0., step=0., end=0.; Int_t ndiv = 2, iaxis = 1; fSelectedShape->GetAxisRange(iaxis,start,end); step = end-start; fBDiv[iaxis-1]->SetState(kButtonDown, kTRUE); fEDivFrom->SetNumber(start); fEDivStep->SetNumber(step); fEDivN->SetNumber(ndiv); } Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoVisVolume() { // Slot for setting volume visible/invisible. Bool_t on = (fBVis[0]->GetState()==kButtonDown)?kTRUE:kFALSE; if (fVolume->IsVisible() == on) return; fVolume->SetVisibility(on); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoVisDaughters() { // Slot for setting daughters visible/invisible. Bool_t on = (fBVis[1]->GetState()==kButtonDown)?kTRUE:kFALSE; if (fVolume->IsVisibleDaughters() == on) return; fVolume->VisibleDaughters(on); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoVisAuto() { // Slot for setting visibility depth auto. Bool_t on = (fBAuto->GetState()==kButtonDown)?kTRUE:kFALSE; if ((fGeometry->GetVisLevel()==0) == on) return; if (on) fGeometry->SetVisLevel(0); else fGeometry->SetVisLevel(fEVisLevel->GetIntNumber()); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoVisLevel() { // Slot for visibility level. fBAuto->SetState(kButtonUp); fGeometry->SetVisLevel(fEVisLevel->GetIntNumber()); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoViewAll() { // Slot for viewing volume and containers. Bool_t on = (fBView[0]->GetState()==kButtonDown)?kTRUE:kFALSE; if (!on) return; if (fVolume->IsVisContainers() == on) return; if (fVolume->IsRaytracing()) { fVolume->Raytrace(kFALSE); fBRaytrace->SetState(kButtonUp); } fVolume->SetVisContainers(on); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoViewLeaves() { // Slot for viewing last leaves only. Bool_t on = (fBView[1]->GetState()==kButtonDown)?kTRUE:kFALSE; if (!on) return; if (fVolume->IsVisLeaves() == on) return; if (fVolume->IsRaytracing()) { fVolume->Raytrace(kFALSE); fBRaytrace->SetState(kButtonUp); } fVolume->SetVisLeaves(on); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoViewOnly() { // Slot for viewing volume only. Bool_t on = (fBView[2]->GetState()==kButtonDown)?kTRUE:kFALSE; if (!on) return; if (fVolume->IsVisOnly() == on) return; if (fVolume->IsRaytracing()) { fVolume->Raytrace(kFALSE); fBRaytrace->SetState(kButtonUp); } fVolume->SetVisOnly(on); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoRaytrace() { // Slot for raytracing. Bool_t on = (fBRaytrace->GetState()==kButtonDown)?kTRUE:kFALSE; if (fVolume->IsRaytracing() == on) return; fVolume->Raytrace(on); Update(); } //______________________________________________________________________________ void TGeoVolumeEditor::DoDivName() { // Modify division name. fApplyDiv->SetEnabled(kTRUE); } //______________________________________________________________________________ void TGeoVolumeEditor::DoDivSelAxis() { // Change division axis and preserve number of slices. Int_t iaxis = 1; for (Int_t i=0; i<3; i++) { if (fBDiv[i]->GetState()!=kButtonDown) continue; iaxis = i+1; break; } TGeoShape *shape = fVolume->GetShape(); if (!shape) { fApplyDiv->SetEnabled(kFALSE); return; } Double_t xlo, xhi; shape->GetAxisRange(iaxis, xlo, xhi); if (xhi <= xlo) { fApplyDiv->SetEnabled(kFALSE); return; } fEDivFrom->SetNumber(xlo); fEDivStep->SetNumber(0); fApplyDiv->SetEnabled(kTRUE); } //______________________________________________________________________________ void TGeoVolumeEditor::DoDivFromTo() { // Handle division range modification. Double_t min, max, xlo, xhi, step; Int_t iaxis = 1; Int_t ndiv; for (Int_t i=0; i<3; i++) { if (fBDiv[i]->GetState()!=kButtonDown) continue; iaxis = i+1; break; } TGeoShape *shape = fVolume->GetShape(); if (!shape) { fApplyDiv->SetEnabled(kFALSE); return; } shape->GetAxisRange(iaxis, xlo, xhi); if (xhi-xlo <= 0) { fApplyDiv->SetEnabled(kFALSE); return; } min = fEDivFrom->GetNumber(); step = fEDivStep->GetNumber(); ndiv = fEDivN->GetIntNumber(); if (minSetNumber(xlo); } max = min + ndiv*step; if (max>xhi) { max = xhi; step = (max-min)/ndiv; fEDivStep->SetNumber(step); } if (min>=max) { fApplyDiv->SetEnabled(kFALSE); return; } fApplyDiv->SetEnabled(kTRUE); } //______________________________________________________________________________ void TGeoVolumeEditor::DoDivStep() { // Handle division step modification. Double_t min, max, xlo, xhi; Int_t iaxis = 1; for (Int_t i=0; i<3; i++) { if (fBDiv[i]->GetState()!=kButtonDown) continue; iaxis = i+1; break; } TGeoShape *shape = fVolume->GetShape(); if (!shape) { fApplyDiv->SetEnabled(kFALSE); return; } shape->GetAxisRange(iaxis, xlo, xhi); if (xhi-xlo <= 0) { fApplyDiv->SetEnabled(kFALSE); return; } min = fEDivFrom->GetNumber(); Double_t step = fEDivStep->GetNumber(); Int_t ndiv = fEDivN->GetIntNumber(); max = min + ndiv*step; // Check if ndiv*step < max-min if (max <= xhi) { fApplyDiv->SetEnabled(kTRUE); return; } // Step too big - set value to fit range max = xhi; step = (max-min)/ndiv; fEDivStep->SetNumber(step); if (step < 0) { fApplyDiv->SetEnabled(kFALSE); return; } fApplyDiv->SetEnabled(kTRUE); } //______________________________________________________________________________ void TGeoVolumeEditor::DoDivN() { // Handle division N modification. Double_t min, max, xlo, xhi; Int_t iaxis = 1; for (Int_t i=0; i<3; i++) { if (fBDiv[i]->GetState()!=kButtonDown) continue; iaxis = i+1; break; } TGeoShape *shape = fVolume->GetShape(); if (!shape) { fApplyDiv->SetEnabled(kFALSE); return; } shape->GetAxisRange(iaxis, xlo, xhi); if (xhi-xlo <= 0) { fApplyDiv->SetEnabled(kFALSE); return; } Double_t step = fEDivStep->GetNumber(); // If step=0 it is discounted if (step==0) { fApplyDiv->SetEnabled(kTRUE); return; } Int_t ndiv = fEDivN->GetIntNumber(); min = fEDivFrom->GetNumber(); max = min + ndiv*step; // Check if ndiv*step < max-min if (max <= xhi) { fApplyDiv->SetEnabled(kTRUE); return; } max = xhi; ndiv = (Int_t)((max-min)/step); fEDivN->SetNumber(ndiv); fApplyDiv->SetEnabled(kTRUE); } //______________________________________________________________________________ void TGeoVolumeEditor::DoApplyDiv() { // Apply current division settings Double_t xlo, xhi, step; Int_t iaxis = 1; Int_t ndiv; for (Int_t i=0; i<3; i++) { if (fBDiv[i]->GetState()!=kButtonDown) continue; iaxis = i+1; break; } TGeoShape *shape = fVolume->GetShape(); if (!shape) { fApplyDiv->SetEnabled(kFALSE); return; } shape->GetAxisRange(iaxis, xlo, xhi); if (xhi-xlo <= 0) { fApplyDiv->SetEnabled(kFALSE); return; } xlo = fEDivFrom->GetNumber(); step = fEDivStep->GetNumber(); ndiv = fEDivN->GetIntNumber(); TGeoPatternFinder *finder = fVolume->GetFinder(); if (finder) { // we have to remove first the existing division TObjArray *nodes = fVolume->GetNodes(); nodes->Delete(); nodes->Clear(); delete finder; fVolume->SetFinder(0); } fVolume->Divide(fDivName->GetText(), iaxis, ndiv, xlo, step); fApplyDiv->SetEnabled(kFALSE); fGeometry->SetTopVisible(); Update(); // fVolume->Draw(); }