Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // class G4DrawVoxels implementation 27 // 28 // Define G4DrawVoxelsDebug for debugging information on G4cout 29 // 30 // 29/07/1999 first comitted version L.G. 31 // -------------------------------------------------------------------- 32 33 #include "G4DrawVoxels.hh" 34 #include "G4AffineTransform.hh" 35 #include "G4SmartVoxelHeader.hh" 36 #include "G4LogicalVolume.hh" 37 #include "G4VSolid.hh" 38 #include "G4VVisManager.hh" 39 #include "G4Colour.hh" 40 #include "G4TransportationManager.hh" 41 #include "G4TouchableHandle.hh" 42 43 #define voxel_width 0 44 45 // Private Constructor 46 // 47 G4DrawVoxels::G4DrawVoxels() 48 { 49 fVoxelsVisAttributes[0].SetColour(G4Colour(1.,0.,0.)); 50 fVoxelsVisAttributes[1].SetColour(G4Colour(0.,1.,0.)); 51 fVoxelsVisAttributes[2].SetColour(G4Colour(0.,0.,1.)); 52 fBoundingBoxVisAttributes.SetColour(G4Colour(.3,0.,.2)); 53 } 54 55 // Methods that allow changing colors of the drawing 56 // 57 void G4DrawVoxels::SetVoxelsVisAttributes(G4VisAttributes& VA_voxelX, 58 G4VisAttributes& VA_voxelY, 59 G4VisAttributes& VA_voxelZ) 60 { 61 fVoxelsVisAttributes[0] = VA_voxelX; 62 fVoxelsVisAttributes[1] = VA_voxelY; 63 fVoxelsVisAttributes[2] = VA_voxelZ; 64 } 65 66 void G4DrawVoxels::SetBoundingBoxVisAttributes(G4VisAttributes& VA_boundingbox) 67 { 68 fBoundingBoxVisAttributes = VA_boundingbox; 69 } 70 71 // -------------------------------------------------------------------- 72 73 void 74 G4DrawVoxels::ComputeVoxelPolyhedra(const G4LogicalVolume* lv, 75 const G4SmartVoxelHeader* header, 76 G4VoxelLimits& limit, 77 G4PlacedPolyhedronList* ppl) const 78 { 79 // Let's draw the selected voxelisation now ! 80 81 G4VSolid* solid = lv->GetSolid(); 82 83 G4double dx=kInfinity, dy=kInfinity, dz=kInfinity; 84 G4double xmax=0, xmin=0, ymax=0, ymin=0, zmax=0, zmin=0; 85 86 if (lv->GetNoDaughters()<=0) 87 { 88 return; 89 } 90 91 // Let's get the data for the voxelisation 92 93 solid->CalculateExtent(kXAxis,limit,G4AffineTransform(),xmin,xmax); 94 // G4AffineTransform() is identity 95 solid->CalculateExtent(kYAxis,limit,G4AffineTransform(),ymin,ymax); 96 // extents according to the axis of the local frame 97 solid->CalculateExtent(kZAxis,limit,G4AffineTransform(),zmin,zmax); 98 dx = xmax-xmin; 99 dy = ymax-ymin; 100 dz = zmax-zmin; 101 102 // Preparing the colored bounding polyhedronBox for the pVolume 103 // 104 G4PolyhedronBox bounding_polyhedronBox(dx*0.5,dy*0.5,dz*0.5); 105 bounding_polyhedronBox.SetVisAttributes(&fBoundingBoxVisAttributes); 106 G4ThreeVector t_centerofBoundingBox((xmin+xmax)*0.5, 107 (ymin+ymax)*0.5, 108 (zmin+zmax)*0.5); 109 110 ppl->push_back(G4PlacedPolyhedron(bounding_polyhedronBox, 111 G4Translate3D(t_centerofBoundingBox))); 112 113 G4ThreeVector t_FirstCenterofVoxelPlane; 114 const G4VisAttributes* voxelsVisAttributes = nullptr; 115 116 G4ThreeVector unit_translation_vector; 117 G4ThreeVector current_translation_vector; 118 119 switch(header->GetAxis()) 120 { 121 case kXAxis: 122 dx=voxel_width; 123 unit_translation_vector=G4ThreeVector(1,0,0); 124 t_FirstCenterofVoxelPlane=G4ThreeVector(xmin,(ymin+ymax)*0.5, 125 (zmin+zmax)*0.5); 126 voxelsVisAttributes=&fVoxelsVisAttributes[0]; 127 break; 128 case kYAxis: 129 dy=voxel_width; 130 t_FirstCenterofVoxelPlane=G4ThreeVector((xmin+xmax)*0.5,ymin, 131 (zmin+zmax)*0.5); 132 unit_translation_vector=G4ThreeVector(0,1,0); 133 voxelsVisAttributes=&fVoxelsVisAttributes[1]; 134 break; 135 case kZAxis: 136 dz=voxel_width; 137 t_FirstCenterofVoxelPlane=G4ThreeVector((xmin+xmax)*0.5, 138 (ymin+ymax)*0.5,zmin); 139 unit_translation_vector=G4ThreeVector(0,0,1); 140 voxelsVisAttributes=&fVoxelsVisAttributes[2]; 141 break; 142 default: 143 break; 144 }; 145 146 G4PolyhedronBox voxel_plane(dx*0.5,dy*0.5,dz*0.5); 147 voxel_plane.SetVisAttributes(voxelsVisAttributes); 148 149 G4SmartVoxelProxy* slice = header->GetSlice(0); 150 std::size_t slice_no = 0, no_slices = header->GetNoSlices(); 151 G4double beginning = header->GetMinExtent(), 152 step = (header->GetMaxExtent()-beginning)/no_slices; 153 154 while (slice_no<no_slices) 155 { 156 if (slice->IsHeader()) 157 { 158 G4VoxelLimits newlimit(limit); 159 newlimit.AddLimit(header->GetAxis(), beginning+step*slice_no, 160 beginning+step*(slice->GetHeader()->GetMaxEquivalentSliceNo()+1)); 161 ComputeVoxelPolyhedra(lv,slice->GetHeader(), newlimit, ppl); 162 } 163 current_translation_vector = unit_translation_vector; 164 current_translation_vector *= step*slice_no; 165 166 ppl->push_back(G4PlacedPolyhedron(voxel_plane, 167 G4Translate3D(current_translation_vector 168 + t_FirstCenterofVoxelPlane))); 169 slice_no = (slice->IsHeader() 170 ? slice->GetHeader()->GetMaxEquivalentSliceNo()+1 171 : slice->GetNode()->GetMaxEquivalentSliceNo()+1); 172 if (slice_no<no_slices) { slice=header->GetSlice(slice_no); } 173 } 174 } 175 176 // -------------------------------------------------------------------- 177 178 G4PlacedPolyhedronList* 179 G4DrawVoxels::CreatePlacedPolyhedra(const G4LogicalVolume* lv) const 180 { 181 auto pplist = new G4PlacedPolyhedronList; 182 G4VoxelLimits limits; // Working object for recursive call. 183 ComputeVoxelPolyhedra(lv,lv->GetVoxelHeader(),limits,pplist); 184 return pplist; //it s up to the calling program to destroy it then! 185 } 186 187 // -------------------------------------------------------------------- 188 189 void G4DrawVoxels::DrawVoxels(const G4LogicalVolume* lv) const 190 { 191 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); 192 193 if (lv->GetNoDaughters()<=0) 194 { 195 return; 196 } 197 198 // Computing the transformation according to the world volume 199 // (the drawing is directly in the world volume while the axis 200 // are relative to the mother volume of lv's daughter.) 201 202 G4TouchableHandle aTouchable = 203 G4TransportationManager::GetTransportationManager()-> 204 GetNavigatorForTracking()->CreateTouchableHistoryHandle(); 205 G4AffineTransform globTransform = 206 aTouchable->GetHistory()->GetTopTransform().Inverse(); 207 G4Transform3D transf3D(globTransform.NetRotation(), 208 globTransform.NetTranslation()); 209 210 G4PlacedPolyhedronList* pplist = CreatePlacedPolyhedra(lv); 211 if(pVVisManager != nullptr) 212 { 213 // Drawing the bounding and voxel polyhedra for the pVolume 214 // 215 for (const auto & i : *pplist) 216 { 217 pVVisManager->Draw(i.GetPolyhedron(), 218 i.GetTransform()*transf3D); 219 } 220 } 221 else 222 { 223 G4Exception("G4DrawVoxels::DrawVoxels()", 224 "GeomNav1002", JustWarning, 225 "Pointer to visualization manager is null!"); 226 } 227 delete pplist; 228 } 229