00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 // 00027 // $Id$ 00028 // 00029 // ---------------------------------------------------------------------- 00030 // GEANT 4 class source file 00031 // 00032 // G4SurfaceList.cc 00033 // 00034 // ---------------------------------------------------------------------- 00035 00036 #include "G4SurfaceList.hh" 00037 00038 G4SurfaceList::G4SurfaceList() 00039 { 00040 first = index = last = next = temp = (G4Surface*)0; 00041 number_of_elements=0; 00042 } 00043 00044 00045 G4SurfaceList::~G4SurfaceList() 00046 { 00047 EmptyList(); 00048 } 00049 00050 void G4SurfaceList::MoveToFirst(G4Surface* srf) 00051 { 00052 if(number_of_elements) 00053 { 00054 RemovePointer(); 00055 srf->SetNextNode(first); 00056 first = srf; 00057 index=first; 00058 number_of_elements++; 00059 } 00060 } 00061 00062 00063 void G4SurfaceList::AddSurface(G4Surface* srf) 00064 { 00065 if(first == (G4Surface*)0) 00066 { 00067 index = srf; 00068 first = srf; 00069 last = srf; 00070 first->SetNextNode(0); 00071 } 00072 else 00073 { 00074 srf->SetNextNode(last->GetNextNode()); 00075 last->SetNextNode(srf); 00076 last = last->GetNextNode(); 00077 } 00078 00079 number_of_elements++; 00080 index=first; 00081 } 00082 00083 00084 G4Surface* G4SurfaceList::GetSurface() 00085 { 00086 return index; 00087 } 00088 00089 00090 const G4Surface* G4SurfaceList::GetSurface(G4int number) 00091 { 00092 index = first; 00093 for(G4int a=0;a<number;a++) 00094 Step(); 00095 00096 return index; 00097 } 00098 00099 00100 const G4Surface* G4SurfaceList::GetLastSurface() const 00101 { 00102 return last; 00103 } 00104 00105 00106 void G4SurfaceList::RemoveSurface(G4Surface* srf) 00107 { 00108 if(srf!=(G4Surface*)0) 00109 { 00110 number_of_elements--; 00111 temp = first; 00112 00113 if(srf == first) 00114 { 00115 first=first->GetNextNode(); 00116 index = first; 00117 if(number_of_elements == 0)last = first; 00118 delete srf; 00119 return; 00120 } 00121 else 00122 { 00123 while(temp->GetNextNode() != srf) temp = temp->GetNextNode(); 00124 index = srf->GetNextNode(); 00125 temp->SetNextNode(index); 00126 if(srf == last) last = temp; 00127 index = first; 00128 delete srf; 00129 } 00130 } 00131 } 00132 00133 00134 void G4SurfaceList::RemovePointer() 00135 { 00136 // Remove the current pointer from the List 00137 // Do not delete the object itself 00138 if(number_of_elements) 00139 { 00140 if(first != index) 00141 { 00142 temp = first; 00143 00144 // Find previous 00145 while(temp->GetNextNode() != index) temp = temp->GetNextNode(); 00146 00147 // Hop over the one to be removed 00148 temp->SetNextNode(index->GetNextNode()); 00149 00150 // Correct the index pointer 00151 index = temp->GetNextNode(); 00152 } 00153 else 00154 { 00155 // Hop over the first 00156 first = first->GetNextNode(); 00157 index = first; 00158 } 00159 } 00160 00161 number_of_elements--; 00162 } 00163 00164 00165 void G4SurfaceList::EmptyList() 00166 { 00167 //Deletes all surfaces in List 00168 while (first != (G4Surface*)0) 00169 { 00170 temp = first; 00171 first = first->GetNextNode(); 00172 delete temp; 00173 number_of_elements--; 00174 } 00175 00176 last = index = first; 00177 } 00178 00179 00180 void G4SurfaceList::MoveToFirst() 00181 { 00182 index = first; 00183 } 00184 00185 00186 void G4SurfaceList::Step() 00187 { 00188 if(index!=(G4Surface*)0) 00189 index = index->GetNextNode(); 00190 } 00191 00192 00193 void G4SurfaceList::G4SortList() 00194 { 00195 if(number_of_elements == 1) return; 00196 00197 // First create a vector of the surface distances 00198 // to the ray origin 00199 G4Surface** distances = new G4Surface*[number_of_elements]; 00200 G4int x = 0; 00201 MoveToFirst(); 00202 00203 // Copy surface pointers to vector 00204 if(number_of_elements > 1) 00205 { 00206 while(x < number_of_elements) 00207 { 00208 distances[x] = index; 00209 index = index->GetNextNode(); 00210 x++; 00211 } 00212 00213 MoveToFirst(); 00214 00215 // Sort List of pointers using quick G4Sort 00216 QuickG4Sort( distances, 0, number_of_elements-1 ); 00217 00218 // Organize the linked List of surfaces according 00219 // to the quickG4Sorted List. 00220 x = 0; 00221 first = distances[x]; 00222 last = first; 00223 x++; 00224 00225 while (x < number_of_elements) 00226 { 00227 last->SetNextNode(distances[x]); 00228 last = last->GetNextNode(); 00229 x++; 00230 } 00231 00232 last->SetNextNode(0); 00233 MoveToFirst(); 00234 } 00235 00236 delete[] distances; 00237 } 00238 00239 00240 void G4SurfaceList::QuickG4Sort(G4Surface** Dist, G4int left, G4int right) 00241 { 00242 register G4int i=left; 00243 register G4int j=right; 00244 00245 G4Surface* elem1; 00246 G4Surface* elem2 = Dist[(left+right)/2]; 00247 00248 do 00249 { 00250 while ( (Dist[i]->GetDistance() < elem2->GetDistance()) && (i < right) ) 00251 i++; 00252 00253 while ( (elem2->GetDistance() < Dist[j]->GetDistance()) && (j > left)) 00254 j--; 00255 00256 if(i<=j) 00257 { 00258 elem1 = Dist[i]; 00259 Dist[i] = Dist[j]; 00260 Dist[j] = elem1; 00261 i++; 00262 j--; 00263 } 00264 } while (i<=j); 00265 00266 if( left < j ) 00267 QuickG4Sort(Dist, left, j ); 00268 00269 if( i < right ) 00270 QuickG4Sort(Dist, i, right); 00271 }