00001 // BLGroup.hh 00002 /* 00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com 00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved. 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 http://www.gnu.org/copyleft/gpl.html 00017 */ 00018 00019 #ifndef BLGROUP_HH 00020 #define BLGROUP_HH 00021 00022 #include <vector> 00023 #include "G4RotationMatrix.hh" 00024 #include "G4VPhysicalVolume.hh" 00025 #include "G4ThreeVector.hh" 00026 #include "BLGroupElement.hh" 00027 00028 00029 /** BLGroup - define one group (container for BLElement-s) 00030 * 00031 * NOTE: the class for the group command is BLGroup, not BLCMDgroup. 00032 * This class is too intertwinded between command and infrastructure, 00033 * so a single class was used. 00034 * 00035 * Implements the group command, which begins defining the contents 00036 * of the group; the endgroup command ends the group's definition, and 00037 * computes the size of the group (if it wasn't specified via arguments). 00038 * The group expands to hold its contents, unless its size is specified 00039 * in arguments to the group command. The World is a expandable group. 00040 * 00041 * If radius is set to 0, uses a Tubs with radius equal to the larger 00042 * of the widest or highest element placed into the group; if radius 00043 * is set >0 that is the fixed radius of the Tubs. If radius is not 00044 * set then uses a Box. 00045 **/ 00046 class BLGroup : public BLGroupElement { 00047 struct Child { G4RotationMatrix rot; G4ThreeVector offset; 00048 BLElement *element; G4String rename; }; 00049 static BLGroup *current; 00050 static BLGroup *world; 00051 static G4VPhysicalVolume *worldPhysVol; 00052 BLGroup *prevCurrent; 00053 G4double highZ; 00054 G4double lastZ; 00055 G4double length; 00056 G4double width; 00057 G4double height; 00058 G4double radius; 00059 G4String material; 00060 G4String color; 00061 G4double maxStep; 00062 G4bool fixedLength; 00063 G4bool fixedWidth; 00064 G4bool fixedHeight; 00065 G4ThreeVector offset; // exclusively for the place command 00066 friend class BLCMDendgroup; 00067 public: 00068 /// Default Constructor. registers the command and provides help text. 00069 BLGroup(); 00070 00071 /// Copy Constructor for a real BLGroup. 00072 BLGroup(BLGroup& r) : BLGroupElement(r), offset(0,0,0) 00073 { prevCurrent=0; highZ=0.0; lastZ=0.0; length=r.length; 00074 width=r.width; height=r.height; material=r.material; 00075 radius=r.radius; color = r.color; maxStep = r.maxStep; 00076 fixedLength = r.fixedLength; 00077 fixedWidth = r.fixedWidth; 00078 fixedHeight = r.fixedHeight; } 00079 00080 /// Destructor. 00081 ~BLGroup(); 00082 00083 /// clone() - invalid. 00084 BLElement *clone() { return 0; } 00085 00086 /// commandName() returns "group"; 00087 virtual G4String commandName() { return "group"; } 00088 00089 /// command() implements the group command. 00090 int command(BLArgumentVector& argv, BLArgumentMap& namedArgs); 00091 00092 /// defineNamedArgs() defines the arguments to the command. 00093 void defineNamedArgs(); 00094 00095 /// construct() will construct an instance of this group, and construct 00096 /// its contents recursively. 00097 virtual void construct(G4RotationMatrix *relativeRotation, 00098 G4ThreeVector relativePosition, 00099 G4LogicalVolume *parent, 00100 G4String parentName, 00101 G4RotationMatrix *parentRotation, 00102 G4ThreeVector parentPosition); 00103 00104 /// getLength() returns this group's Length along the Z axis. 00105 G4double getLength() { return length; } 00106 00107 /// getWidth() returns this group's Width along the X axis. 00108 G4double getWidth() { return width; } 00109 00110 /// getHeight() returns this group's height along the Y axis. 00111 G4double getHeight() { return height; } 00112 00113 /// setMinWidth() will increase the width, if necessary. 00114 void setMinWidth(G4double minWidth) 00115 { if(width < minWidth) width = minWidth; } 00116 00117 /// setMinHeight() will increase the height, if necessary. 00118 void setMinHeight(G4double minHeight) 00119 { if(height < minHeight) height = minHeight; } 00120 00121 /// setMinLength() will increase the length, if necessary. 00122 void setMinLength(G4double minLength) 00123 { if(highZ < minLength) highZ = minLength; } 00124 00125 /// setMaterial() sets the name of the group's material. 00126 void setMaterial(G4String mat) { material = mat; } 00127 00128 /// isOK() returns true; individual elements are responsible for 00129 /// their own status. 00130 G4bool isOK() { return true; } 00131 00132 /// isOutside() from BLElement. 00133 bool isOutside(G4ThreeVector &local, G4double tolerance); 00134 00135 /// generatePoints from BLElement. 00136 void generatePoints(int npoints, std::vector<G4ThreeVector> &v); 00137 00138 /// isWithin() from BLGroupElement. 00139 bool isWithin(G4ThreeVector &local, G4double tolerance); 00140 00141 /// placeElement() will place an element within this group. 00142 /// With a rotation, an offset must be given, and the length of the 00143 /// group must have been specified via an argument. 00144 /// Called by the place command. 00145 /// The object being placed is rotated wrt the fixed axes of the 00146 /// group's local coordinates. 00147 /// global=true means use global coordinates for the world group, 00148 /// not centerline coords. 00149 virtual void placeElement(BLElement* element, G4RotationMatrix *rot, 00150 G4ThreeVector& offset, G4String rename, G4bool global=false); 00151 00152 /// placeElement() will place an element within this group. 00153 /// With an offset, the length of the group must have been specified via 00154 /// an argument. 00155 /// Called by the place command. 00156 virtual void placeElement(BLElement* element, G4ThreeVector& offset, 00157 G4String rename, G4bool global=false); 00158 00159 /// placeElement() will place an element within this group. 00160 /// With no offset, this element is placed immediately downstream 00161 /// of the previous element. If necessary, the endgroup command 00162 /// will compute the size of the group and readjust offsets so 00163 /// they are relative to the center of the group. 00164 /// Called by the place command. 00165 virtual void placeElement(BLElement* element, G4String rename, 00166 G4bool global=false); 00167 00168 /// end() will compute the size of the group, if necessary, and 00169 /// pop the current group. 00170 void end(); 00171 00172 /// getOffset() returns the offset for the place command. 00173 G4ThreeVector& getOffset() { return offset; } 00174 00175 /// setOffset() sets the offset for the place command. 00176 void setOffset(G4ThreeVector& offset) { this->offset = offset; } 00177 00178 /// getCurrent() returns a pointer to the current group (innermost 00179 /// active group command). Creates current and world if necessary. 00180 /// Used by the place command. 00181 static BLGroup *getCurrent(); 00182 00183 /// getWorld() returns a pointer to the World group. 00184 /// Creates current and world if necessary. 00185 static BLGroup *getWorld(); 00186 00187 /// constructWorld() constructs the beamline and returns a pointer 00188 /// to its world PhysicalVolume. 00189 static G4VPhysicalVolume *constructWorld(); 00190 private: 00191 BLGroup& operator=(const BLGroup&); // undefined 00192 }; 00193 00194 #endif // BLGROUP_HH