ROOT logo
// @(#)root/g3d:$Id$
// 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"
#include "TClass.h"
#include "TMath.h"

ClassImp(TTUBE)


//______________________________________________________________________________
// Begin_Html <P ALIGN=CENTER> <IMG SRC="gif/tube.gif"> </P> End_Html
// 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;
   fDz          = 0.;
   fNdiv        = 0;
   fRmin        = 0.;
   fRmax        = 0.;
}


//______________________________________________________________________________
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();
}

//______________________________________________________________________________
TTUBE::TTUBE(const TTUBE& tu) :
  TShape(tu),
  fRmin(tu.fRmin),
  fRmax(tu.fRmax),
  fDz(tu.fDz),
  fNdiv(tu.fNdiv),
  fAspectRatio(tu.fAspectRatio),
  fSiTab(tu.fSiTab),
  fCoTab(tu.fCoTab)
{ 
   //copy constructor
}

//______________________________________________________________________________
TTUBE& TTUBE::operator=(const TTUBE& tu) 
{
   //assignement operator
   if(this!=&tu) {
      TShape::operator=(tu);
      fRmin=tu.fRmin;
      fRmax=tu.fRmax;
      fDz=tu.fDz;
      fNdiv=tu.fNdiv;
      fAspectRatio=tu.fAspectRatio;
      fSiTab=tu.fSiTab;
      fCoTab=tu.fCoTab;
   } 
   return *this;
}

//______________________________________________________________________________
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) {
         R__b.ReadClassBuffer(TTUBE::Class(), 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 {
      R__b.WriteClassBuffer(TTUBE::Class(),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;
}
 TTUBE.cxx:1
 TTUBE.cxx:2
 TTUBE.cxx:3
 TTUBE.cxx:4
 TTUBE.cxx:5
 TTUBE.cxx:6
 TTUBE.cxx:7
 TTUBE.cxx:8
 TTUBE.cxx:9
 TTUBE.cxx:10
 TTUBE.cxx:11
 TTUBE.cxx:12
 TTUBE.cxx:13
 TTUBE.cxx:14
 TTUBE.cxx:15
 TTUBE.cxx:16
 TTUBE.cxx:17
 TTUBE.cxx:18
 TTUBE.cxx:19
 TTUBE.cxx:20
 TTUBE.cxx:21
 TTUBE.cxx:22
 TTUBE.cxx:23
 TTUBE.cxx:24
 TTUBE.cxx:25
 TTUBE.cxx:26
 TTUBE.cxx:27
 TTUBE.cxx:28
 TTUBE.cxx:29
 TTUBE.cxx:30
 TTUBE.cxx:31
 TTUBE.cxx:32
 TTUBE.cxx:33
 TTUBE.cxx:34
 TTUBE.cxx:35
 TTUBE.cxx:36
 TTUBE.cxx:37
 TTUBE.cxx:38
 TTUBE.cxx:39
 TTUBE.cxx:40
 TTUBE.cxx:41
 TTUBE.cxx:42
 TTUBE.cxx:43
 TTUBE.cxx:44
 TTUBE.cxx:45
 TTUBE.cxx:46
 TTUBE.cxx:47
 TTUBE.cxx:48
 TTUBE.cxx:49
 TTUBE.cxx:50
 TTUBE.cxx:51
 TTUBE.cxx:52
 TTUBE.cxx:53
 TTUBE.cxx:54
 TTUBE.cxx:55
 TTUBE.cxx:56
 TTUBE.cxx:57
 TTUBE.cxx:58
 TTUBE.cxx:59
 TTUBE.cxx:60
 TTUBE.cxx:61
 TTUBE.cxx:62
 TTUBE.cxx:63
 TTUBE.cxx:64
 TTUBE.cxx:65
 TTUBE.cxx:66
 TTUBE.cxx:67
 TTUBE.cxx:68
 TTUBE.cxx:69
 TTUBE.cxx:70
 TTUBE.cxx:71
 TTUBE.cxx:72
 TTUBE.cxx:73
 TTUBE.cxx:74
 TTUBE.cxx:75
 TTUBE.cxx:76
 TTUBE.cxx:77
 TTUBE.cxx:78
 TTUBE.cxx:79
 TTUBE.cxx:80
 TTUBE.cxx:81
 TTUBE.cxx:82
 TTUBE.cxx:83
 TTUBE.cxx:84
 TTUBE.cxx:85
 TTUBE.cxx:86
 TTUBE.cxx:87
 TTUBE.cxx:88
 TTUBE.cxx:89
 TTUBE.cxx:90
 TTUBE.cxx:91
 TTUBE.cxx:92
 TTUBE.cxx:93
 TTUBE.cxx:94
 TTUBE.cxx:95
 TTUBE.cxx:96
 TTUBE.cxx:97
 TTUBE.cxx:98
 TTUBE.cxx:99
 TTUBE.cxx:100
 TTUBE.cxx:101
 TTUBE.cxx:102
 TTUBE.cxx:103
 TTUBE.cxx:104
 TTUBE.cxx:105
 TTUBE.cxx:106
 TTUBE.cxx:107
 TTUBE.cxx:108
 TTUBE.cxx:109
 TTUBE.cxx:110
 TTUBE.cxx:111
 TTUBE.cxx:112
 TTUBE.cxx:113
 TTUBE.cxx:114
 TTUBE.cxx:115
 TTUBE.cxx:116
 TTUBE.cxx:117
 TTUBE.cxx:118
 TTUBE.cxx:119
 TTUBE.cxx:120
 TTUBE.cxx:121
 TTUBE.cxx:122
 TTUBE.cxx:123
 TTUBE.cxx:124
 TTUBE.cxx:125
 TTUBE.cxx:126
 TTUBE.cxx:127
 TTUBE.cxx:128
 TTUBE.cxx:129
 TTUBE.cxx:130
 TTUBE.cxx:131
 TTUBE.cxx:132
 TTUBE.cxx:133
 TTUBE.cxx:134
 TTUBE.cxx:135
 TTUBE.cxx:136
 TTUBE.cxx:137
 TTUBE.cxx:138
 TTUBE.cxx:139
 TTUBE.cxx:140
 TTUBE.cxx:141
 TTUBE.cxx:142
 TTUBE.cxx:143
 TTUBE.cxx:144
 TTUBE.cxx:145
 TTUBE.cxx:146
 TTUBE.cxx:147
 TTUBE.cxx:148
 TTUBE.cxx:149
 TTUBE.cxx:150
 TTUBE.cxx:151
 TTUBE.cxx:152
 TTUBE.cxx:153
 TTUBE.cxx:154
 TTUBE.cxx:155
 TTUBE.cxx:156
 TTUBE.cxx:157
 TTUBE.cxx:158
 TTUBE.cxx:159
 TTUBE.cxx:160
 TTUBE.cxx:161
 TTUBE.cxx:162
 TTUBE.cxx:163
 TTUBE.cxx:164
 TTUBE.cxx:165
 TTUBE.cxx:166
 TTUBE.cxx:167
 TTUBE.cxx:168
 TTUBE.cxx:169
 TTUBE.cxx:170
 TTUBE.cxx:171
 TTUBE.cxx:172
 TTUBE.cxx:173
 TTUBE.cxx:174
 TTUBE.cxx:175
 TTUBE.cxx:176
 TTUBE.cxx:177
 TTUBE.cxx:178
 TTUBE.cxx:179
 TTUBE.cxx:180
 TTUBE.cxx:181
 TTUBE.cxx:182
 TTUBE.cxx:183
 TTUBE.cxx:184
 TTUBE.cxx:185
 TTUBE.cxx:186
 TTUBE.cxx:187
 TTUBE.cxx:188
 TTUBE.cxx:189
 TTUBE.cxx:190
 TTUBE.cxx:191
 TTUBE.cxx:192
 TTUBE.cxx:193
 TTUBE.cxx:194
 TTUBE.cxx:195
 TTUBE.cxx:196
 TTUBE.cxx:197
 TTUBE.cxx:198
 TTUBE.cxx:199
 TTUBE.cxx:200
 TTUBE.cxx:201
 TTUBE.cxx:202
 TTUBE.cxx:203
 TTUBE.cxx:204
 TTUBE.cxx:205
 TTUBE.cxx:206
 TTUBE.cxx:207
 TTUBE.cxx:208
 TTUBE.cxx:209
 TTUBE.cxx:210
 TTUBE.cxx:211
 TTUBE.cxx:212
 TTUBE.cxx:213
 TTUBE.cxx:214
 TTUBE.cxx:215
 TTUBE.cxx:216
 TTUBE.cxx:217
 TTUBE.cxx:218
 TTUBE.cxx:219
 TTUBE.cxx:220
 TTUBE.cxx:221
 TTUBE.cxx:222
 TTUBE.cxx:223
 TTUBE.cxx:224
 TTUBE.cxx:225
 TTUBE.cxx:226
 TTUBE.cxx:227
 TTUBE.cxx:228
 TTUBE.cxx:229
 TTUBE.cxx:230
 TTUBE.cxx:231
 TTUBE.cxx:232
 TTUBE.cxx:233
 TTUBE.cxx:234
 TTUBE.cxx:235
 TTUBE.cxx:236
 TTUBE.cxx:237
 TTUBE.cxx:238
 TTUBE.cxx:239
 TTUBE.cxx:240
 TTUBE.cxx:241
 TTUBE.cxx:242
 TTUBE.cxx:243
 TTUBE.cxx:244
 TTUBE.cxx:245
 TTUBE.cxx:246
 TTUBE.cxx:247
 TTUBE.cxx:248
 TTUBE.cxx:249
 TTUBE.cxx:250
 TTUBE.cxx:251
 TTUBE.cxx:252
 TTUBE.cxx:253
 TTUBE.cxx:254
 TTUBE.cxx:255
 TTUBE.cxx:256
 TTUBE.cxx:257
 TTUBE.cxx:258
 TTUBE.cxx:259
 TTUBE.cxx:260
 TTUBE.cxx:261
 TTUBE.cxx:262
 TTUBE.cxx:263
 TTUBE.cxx:264
 TTUBE.cxx:265
 TTUBE.cxx:266
 TTUBE.cxx:267
 TTUBE.cxx:268
 TTUBE.cxx:269
 TTUBE.cxx:270
 TTUBE.cxx:271
 TTUBE.cxx:272
 TTUBE.cxx:273
 TTUBE.cxx:274
 TTUBE.cxx:275
 TTUBE.cxx:276
 TTUBE.cxx:277
 TTUBE.cxx:278
 TTUBE.cxx:279
 TTUBE.cxx:280
 TTUBE.cxx:281
 TTUBE.cxx:282
 TTUBE.cxx:283
 TTUBE.cxx:284
 TTUBE.cxx:285
 TTUBE.cxx:286
 TTUBE.cxx:287
 TTUBE.cxx:288
 TTUBE.cxx:289
 TTUBE.cxx:290
 TTUBE.cxx:291
 TTUBE.cxx:292
 TTUBE.cxx:293
 TTUBE.cxx:294
 TTUBE.cxx:295
 TTUBE.cxx:296
 TTUBE.cxx:297
 TTUBE.cxx:298
 TTUBE.cxx:299
 TTUBE.cxx:300
 TTUBE.cxx:301
 TTUBE.cxx:302
 TTUBE.cxx:303
 TTUBE.cxx:304
 TTUBE.cxx:305
 TTUBE.cxx:306
 TTUBE.cxx:307
 TTUBE.cxx:308
 TTUBE.cxx:309
 TTUBE.cxx:310
 TTUBE.cxx:311
 TTUBE.cxx:312
 TTUBE.cxx:313
 TTUBE.cxx:314
 TTUBE.cxx:315
 TTUBE.cxx:316
 TTUBE.cxx:317
 TTUBE.cxx:318
 TTUBE.cxx:319
 TTUBE.cxx:320
 TTUBE.cxx:321
 TTUBE.cxx:322
 TTUBE.cxx:323
 TTUBE.cxx:324
 TTUBE.cxx:325
 TTUBE.cxx:326
 TTUBE.cxx:327
 TTUBE.cxx:328
 TTUBE.cxx:329
 TTUBE.cxx:330
 TTUBE.cxx:331
 TTUBE.cxx:332
 TTUBE.cxx:333
 TTUBE.cxx:334
 TTUBE.cxx:335
 TTUBE.cxx:336
 TTUBE.cxx:337
 TTUBE.cxx:338
 TTUBE.cxx:339
 TTUBE.cxx:340
 TTUBE.cxx:341
 TTUBE.cxx:342
 TTUBE.cxx:343
 TTUBE.cxx:344
 TTUBE.cxx:345
 TTUBE.cxx:346
 TTUBE.cxx:347
 TTUBE.cxx:348
 TTUBE.cxx:349
 TTUBE.cxx:350
 TTUBE.cxx:351
 TTUBE.cxx:352
 TTUBE.cxx:353
 TTUBE.cxx:354
 TTUBE.cxx:355
 TTUBE.cxx:356
 TTUBE.cxx:357
 TTUBE.cxx:358
 TTUBE.cxx:359
 TTUBE.cxx:360
 TTUBE.cxx:361
 TTUBE.cxx:362
 TTUBE.cxx:363
 TTUBE.cxx:364
 TTUBE.cxx:365
 TTUBE.cxx:366
 TTUBE.cxx:367
 TTUBE.cxx:368
 TTUBE.cxx:369
 TTUBE.cxx:370
 TTUBE.cxx:371
 TTUBE.cxx:372
 TTUBE.cxx:373
 TTUBE.cxx:374
 TTUBE.cxx:375
 TTUBE.cxx:376
 TTUBE.cxx:377
 TTUBE.cxx:378
 TTUBE.cxx:379
 TTUBE.cxx:380
 TTUBE.cxx:381
 TTUBE.cxx:382