// @(#)root/g3d:$Name: $:$Id: TTUBE.cxx,v 1.12 2005/09/04 14:53:18 brun 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 { 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 { 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 { 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; }