// @(#)root/g3d:$Name: $:$Id: TTUBE.cxx,v 1.13 2005/11/24 17:28:07 couet Exp $ // Author: Nenad Buncic 18/09/95 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "TTUBE.h" #include "TNode.h" #include "TVirtualPad.h" #include "TBuffer3D.h" #include "TBuffer3DTypes.h" #include "TGeometry.h" ClassImp(TTUBE) //______________________________________________________________________________ //
// TUBE is a tube. It has 6 parameters:
//
// - name name of the shape
// - title shape's title
// - material (see TMaterial)
// - rmin inside radius
// - rmax outside radius
// - dz half length in z
//______________________________________________________________________________
TTUBE::TTUBE()
{
// TUBE shape default constructor
fCoTab = 0;
fSiTab = 0;
fAspectRatio =1;
}
//______________________________________________________________________________
TTUBE::TTUBE(const char *name, const char *title, const char *material, Float_t rmin, Float_t rmax, Float_t dz,Float_t aspect)
: TShape(name, title,material)
{
// TUBE shape normal constructor
fRmin = rmin;
fRmax = rmax;
fDz = dz;
fNdiv = 0;
fCoTab = 0;
fSiTab = 0;
fAspectRatio = aspect;
MakeTableOfCoSin();
}
//______________________________________________________________________________
TTUBE::TTUBE(const char *name, const char *title, const char *material, Float_t rmax, Float_t dz)
: TShape(name, title,material)
{
// TUBE shape "simplified" constructor
fRmin = 0;
fRmax = rmax;
fDz = dz;
fNdiv = 0;
fCoTab = 0;
fSiTab = 0;
fAspectRatio = 1;
MakeTableOfCoSin();
}
//______________________________________________________________________________
void TTUBE::MakeTableOfCoSin() const // Internal cache - const so other const fn can use
{
// Make table of sine and cosine.
const Double_t pi = TMath::ATan(1) * 4.0;
Int_t j;
Int_t n = GetNumberOfDivisions ();
if (fCoTab)
delete [] fCoTab; // Delete the old tab if any
fCoTab = new Double_t [n];
if (!fCoTab ) {
Error("MakeTableOfCoSin()","No cos table done");
return;
}
if (fSiTab) delete [] fSiTab; // Delete the old tab if any
fSiTab = new Double_t [n];
if (!fSiTab ) {
Error("MakeTableOfCoSin()","No sin table done");
return;
}
Double_t range = 2*pi;
Double_t angstep = range/n;
Double_t ph = 0;
for (j = 0; j < n; j++) {
ph = j*angstep;
fCoTab[j] = TMath::Cos(ph);
fSiTab[j] = TMath::Sin(ph);
}
}
//______________________________________________________________________________
TTUBE::~TTUBE()
{
// TUBE shape default destructor
delete [] fCoTab;
delete [] fSiTab;
}
//______________________________________________________________________________
Int_t TTUBE::DistancetoPrimitive(Int_t px, Int_t py)
{
// Compute distance from point px,py to a TUBE
//
// Compute the closest distance of approach from point px,py to each
// computed outline point of the TUBE.
Int_t n = GetNumberOfDivisions();
Int_t numPoints = n*4;
return ShapeDistancetoPrimitive(numPoints,px,py);
}
//______________________________________________________________________________
void TTUBE::SetNumberOfDivisions (Int_t ndiv)
{
// Set number of divisions used to draw this tube
fNdiv = ndiv;
MakeTableOfCoSin();
}
//______________________________________________________________________________
void TTUBE::SetPoints(Double_t *points) const
{
// Create TUBE points
Int_t j, n;
Int_t indx = 0;
n = GetNumberOfDivisions();
if (points) {
if (!fCoTab) MakeTableOfCoSin();
for (j = 0; j < n; j++) {
points[indx+6*n] = points[indx] = fRmin * fCoTab[j];
indx++;
points[indx+6*n] = points[indx] = fAspectRatio*fRmin * fSiTab[j];
indx++;
points[indx+6*n] = fDz;
points[indx] =-fDz;
indx++;
}
for (j = 0; j < n; j++) {
points[indx+6*n] = points[indx] = fRmax * fCoTab[j];
indx++;
points[indx+6*n] = points[indx] = fAspectRatio*fRmax * fSiTab[j];
indx++;
points[indx+6*n]= fDz;
points[indx] =-fDz;
indx++;
}
}
}
//______________________________________________________________________________
void TTUBE::SetSegsAndPols(TBuffer3D & buffer) const
{
// Set segments and polygons.
Int_t i, j;
Int_t n = GetNumberOfDivisions();
Int_t c = GetBasicColor();
for (i = 0; i < 4; i++) {
for (j = 0; j < n; j++) {
buffer.fSegs[(i*n+j)*3 ] = c;
buffer.fSegs[(i*n+j)*3+1] = i*n+j;
buffer.fSegs[(i*n+j)*3+2] = i*n+j+1;
}
buffer.fSegs[(i*n+j-1)*3+2] = i*n;
}
for (i = 4; i < 6; i++) {
for (j = 0; j < n; j++) {
buffer.fSegs[(i*n+j)*3 ] = c+1;
buffer.fSegs[(i*n+j)*3+1] = (i-4)*n+j;
buffer.fSegs[(i*n+j)*3+2] = (i-2)*n+j;
}
}
for (i = 6; i < 8; i++) {
for (j = 0; j < n; j++) {
buffer.fSegs[(i*n+j)*3 ] = c;
buffer.fSegs[(i*n+j)*3+1] = 2*(i-6)*n+j;
buffer.fSegs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j;
}
}
Int_t indx = 0;
i=0;
for (j = 0; j < n; j++) {
indx = 6*(i*n+j);
buffer.fPols[indx ] = c;
buffer.fPols[indx+1] = 4;
buffer.fPols[indx+5] = i*n+j;
buffer.fPols[indx+4] = (4+i)*n+j;
buffer.fPols[indx+3] = (2+i)*n+j;
buffer.fPols[indx+2] = (4+i)*n+j+1;
}
buffer.fPols[indx+2] = (4+i)*n;
i=1;
for (j = 0; j < n; j++) {
indx = 6*(i*n+j);
buffer.fPols[indx ] = c;
buffer.fPols[indx+1] = 4;
buffer.fPols[indx+2] = i*n+j;
buffer.fPols[indx+3] = (4+i)*n+j;
buffer.fPols[indx+4] = (2+i)*n+j;
buffer.fPols[indx+5] = (4+i)*n+j+1;
}
buffer.fPols[indx+5] = (4+i)*n;
i=2;
for (j = 0; j < n; j++) {
indx = 6*(i*n+j);
buffer.fPols[indx ] = c+i;
buffer.fPols[indx+1] = 4;
buffer.fPols[indx+2] = (i-2)*2*n+j;
buffer.fPols[indx+3] = (4+i)*n+j;
buffer.fPols[indx+4] = ((i-2)*2+1)*n+j;
buffer.fPols[indx+5] = (4+i)*n+j+1;
}
buffer.fPols[indx+5] = (4+i)*n;
i=3;
for (j = 0; j < n; j++) {
indx = 6*(i*n+j);
buffer.fPols[indx ] = c+i;
buffer.fPols[indx+1] = 4;
buffer.fPols[indx+5] = (i-2)*2*n+j;
buffer.fPols[indx+4] = (4+i)*n+j;
buffer.fPols[indx+3] = ((i-2)*2+1)*n+j;
buffer.fPols[indx+2] = (4+i)*n+j+1;
}
buffer.fPols[indx+2] = (4+i)*n;
}
//______________________________________________________________________________
void TTUBE::Sizeof3D() const
{
// Return total X3D needed by TNode::ls (when called with option "x")
Int_t n = GetNumberOfDivisions();
gSize3D.numPoints += n*4;
gSize3D.numSegs += n*8;
gSize3D.numPolys += n*4;
}
//______________________________________________________________________________
void TTUBE::Streamer(TBuffer &R__b)
{
// Stream an object of class TTUBE.
if (R__b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
TTUBE::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
return;
}
//====process old versions before automatic schema evolution
TShape::Streamer(R__b);
R__b >> fRmin;
R__b >> fRmax;
R__b >> fDz;
R__b >> fNdiv;
if (R__v > 1) R__b >> fAspectRatio;
R__b.CheckByteCount(R__s, R__c, TTUBE::IsA());
//====end of old versions
} else {
TTUBE::Class()->WriteBuffer(R__b,this);
}
}
//______________________________________________________________________________
const TBuffer3D & TTUBE::GetBuffer3D(Int_t reqSections) const
{
// Get buffer 3d.
static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
TShape::FillBuffer3D(buffer, reqSections);
// TODO: Although we now have a TBuffer3DTube class for
// tube shapes, we do not use it for old geometry tube, as
// OGL viewer needs various rotation matrix info we can't easily
// pass yet. To be revisited.
// We also do not fill the bounding box as derived classes can adjust shape
// leave up to viewer to work out
if (reqSections & TBuffer3D::kRawSizes) {
Int_t n = GetNumberOfDivisions();
Int_t nbPnts = 4*n;
Int_t nbSegs = 8*n;
Int_t nbPols = 4*n;
if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
buffer.SetSectionsValid(TBuffer3D::kRawSizes);
}
}
if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
SetPoints(buffer.fPnts);
if (!buffer.fLocalFrame) {
TransformPoints(buffer.fPnts, buffer.NbPnts());
}
SetSegsAndPols(buffer);
buffer.SetSectionsValid(TBuffer3D::kRaw);
}
return buffer;
}