Files
geant4/source/geometry/solids/BREPS/src/G4SurfaceList.cc
T
2016-06-08 16:57:27 +02:00

268 lines
5.7 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4SurfaceList.cc,v 1.6 2001/07/11 09:59:48 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
//
// G4SurfaceList.cc
//
// ----------------------------------------------------------------------
#include "G4SurfaceList.hh"
G4SurfaceList::G4SurfaceList()
{
first = index = last = next = temp = (G4Surface*)0;
number_of_elements=0;
}
G4SurfaceList::~G4SurfaceList()
{
EmptyList();
}
void G4SurfaceList::MoveToFirst(G4Surface* srf)
{
if(number_of_elements)
{
RemovePointer();
srf->SetNextNode(first);
first = srf;
index=first;
number_of_elements++;
}
}
void G4SurfaceList::AddSurface(G4Surface* srf)
{
if(first == (G4Surface*)0)
{
index = srf;
first = srf;
last = srf;
first->SetNextNode(0);
}
else
{
srf->SetNextNode(last->GetNextNode());
last->SetNextNode(srf);
last = last->GetNextNode();
}
number_of_elements++;
index=first;
}
G4Surface* G4SurfaceList::GetSurface()
{
return index;
}
const G4Surface* G4SurfaceList::GetSurface(G4int number)
{
index = first;
for(G4int a=0;a<number;a++)
Step();
return index;
}
const G4Surface* G4SurfaceList::GetLastSurface() const
{
return last;
}
void G4SurfaceList::RemoveSurface(G4Surface* srf)
{
if(srf!=(G4Surface*)0)
{
number_of_elements--;
temp = first;
if(srf == first)
{
first=first->GetNextNode();
index = first;
if(number_of_elements == 0)last = first;
delete srf;
return;
}
else
{
while(temp->GetNextNode() != srf) temp = temp->GetNextNode();
index = srf->GetNextNode();
temp->SetNextNode(index);
if(srf == last) last = temp;
index = first;
delete srf;
}
}
}
void G4SurfaceList::RemovePointer()
{
// Remove the current pointer from the List
// Do not delete the object itself
if(number_of_elements)
if(first != index)
{
temp = first;
// Find previous
while(temp->GetNextNode() != index) temp = temp->GetNextNode();
// Hop over the one to be removed
temp->SetNextNode(index->GetNextNode());
// Correct the index pointer
index = temp->GetNextNode();
}
else
{
// Hop over the first
first = first->GetNextNode();
index = first;
}
number_of_elements--;
}
void G4SurfaceList::EmptyList()
{
//Deletes all surfaces in List
while (first != (G4Surface*)0)
{
temp = first;
first = first->GetNextNode();
delete temp;
number_of_elements--;
}
last = index = first;
}
void G4SurfaceList::MoveToFirst()
{
index = first;
}
void G4SurfaceList::Step()
{
if(index!=(G4Surface*)0)
index = index->GetNextNode();
}
void G4SurfaceList::G4SortList()
{
if(number_of_elements == 1) return;
// First create a vector of the surface distances
// to the ray origin
G4Surface** distances = new G4Surface*[number_of_elements];
G4int x = 0;
MoveToFirst();
// Copy surface pointers to vector
if(number_of_elements > 1)
{
while(x < number_of_elements)
{
distances[x] = index;
index = index->GetNextNode();
x++;
}
MoveToFirst();
// Sort List of pointers using quick G4Sort
QuickG4Sort( distances, 0, number_of_elements-1 );
// Organize the linked List of surfaces according
// to the quickG4Sorted List.
x = 0;
first = distances[x];
last = first;
x++;
while (x < number_of_elements)
{
last->SetNextNode(distances[x]);
last = last->GetNextNode();
x++;
}
last->SetNextNode(0);
MoveToFirst();
}
delete[] distances;
}
void G4SurfaceList::QuickG4Sort(G4Surface** Dist, G4int left, G4int right)
{
register G4int i=left;
register G4int j=right;
G4Surface* elem1;
G4Surface* elem2 = Dist[(left+right)/2];
do
{
while ( (Dist[i]->GetDistance() < elem2->GetDistance()) && (i < right) )
i++;
while ( (elem2->GetDistance() < Dist[j]->GetDistance()) && (j > left))
j--;
if(i<=j)
{
elem1 = Dist[i];
Dist[i] = Dist[j];
Dist[j] = elem1;
i++;
j--;
}
} while (i<=j);
if( left < j )
QuickG4Sort(Dist, left, j );
if( i < right )
QuickG4Sort(Dist, i, right);
}