Introduction of the Copyright and cvs Log
[u/mrichter/AliRoot.git] / GEODB / AliGSphere.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 */
19
20    // -*- C++ -*-
21 // 
22 // 1998/07/23
23 // ---------------------------------------------------------------------------
24 //
25 // AliGSphere Class
26 //
27 // This file is part of the ALICE Geometry Database .
28 //
29 // Author:  Joana E. Santo
30 //
31 // ---------------------------------------------------------------------------
32
33 #include <TView.h>
34 #include <TVirtualPad.h>
35 #include <iostream.h>
36 #include <TCanvas.h>
37 #include <TGLKernelABC.h>
38 #include "TROOT.h"
39 #include "AliGSphere.h"
40
41
42 ClassImp(AliGSphere)
43
44 AliGSphere::AliGSphere()
45 {
46     /* Default Constructor */
47     faX          = 1.;  // Coeff along Ox
48     faY          = 1.;  // Coeff along Oy
49     faZ          = 1.;  // Coeff along Oz
50     fAspectRatio = 1.;  // Relation between asumth and grid size (by default 1.0)
51     fCoTab       = NULL;// Table of cos(fPhimin) .... cos(Phi)
52     fCoThetaTab  = NULL;// Table of sin(gThemin) .... cos(Theta)
53     fName        = "";
54     fNdiv        = 0;   // number of divisions
55     fNz          = 0;   // number of sections
56     fPhimax      = 0.;  // maximum phi
57     fPhimin      = 0.;  // minimum phi
58     fRmax        = 0.;  // maximum radius
59     fRmin        = 0.;  // minimum radius
60     fSiTab       = NULL;// Table of sin(fPhimin) .... sin(Phi)
61     fThemax      = 0.;  // maximum theta
62     fThemin      = 0.;  // minimum theta
63     fTitle       = "";
64 }
65
66 // ---------------------------------------------------------------------------
67
68 AliGSphere::AliGSphere(Text_t *name, Text_t *title, Float_t rmin, Float_t rmax, Float_t themin, Float_t themax, Float_t phimin, Float_t phimax) : AliGShape(name, title)
69 {
70     /* Constructor */
71     faX          = 1.;    // Coeff along Ox
72     faY          = 1.;    // Coeff along Oy
73     faZ          = 1.;    // Coeff along Oz
74     fAspectRatio = 1.;    // Relation between asumth and grid size (by default 1.0)
75     fCoTab       = NULL;  // Table of cos(fPhimin) .... cos(Phi)
76     fCoThetaTab  = NULL;  // Table of sin(gThemin) .... cos(Theta)
77     fNdiv        = 0;     // number of divisions
78     fNz          = 0;     // number of sections
79     fPhimax      = phimax;// maximum phi
80     fPhimin      = phimin;// minimum phi
81     fRmax        = rmax;  // maximum radius
82     fRmin        = rmin;  // minimum radius
83     fSiTab       = NULL;  // Table of sin(fPhimin) .... sin(Phi)
84     fThemax      = themax;// maximum theta
85     fThemin      = themin;// minimum theta
86
87     SetNumberOfDivisions (20);
88 }
89
90 // ---------------------------------------------------------------------------
91
92 AliGSphere::AliGSphere(AliGSphere *sphere) 
93 {
94     /* Copy Constructor */
95     faX          = 1.;    // Coeff along Ox
96     faY          = 1.;    // Coeff along Oy
97     faZ          = 1.;    // Coeff along Oz
98     fAspectRatio = 1.;    // Relation between asumth and grid size (by default 1.0)
99     fColor       = sphere->fColor;
100     fCoTab       = NULL;  // Table of cos(fPhimin) .... cos(Phi)
101     fCoThetaTab  = NULL;  // Table of sin(gThemin) .... cos(Theta)
102     fNdiv        = 0;     // number of divisions
103     fNz          = 0;     // number of sections
104     fPhimax      = sphere->fPhimax;// maximum phi
105     fPhimin      = sphere->fPhimin;// minimum phi
106     fRmax        = sphere->fRmax;  // maximum radius
107     fRmin        = sphere->fRmin;  // minimum radius
108     fSiTab       = NULL;  // Table of sin(fPhimin) .... sin(Phi)
109     fThemax      = sphere->fThemax;// maximum theta
110     fThemin      = sphere->fThemin;// minimum theta
111
112     SetNumberOfDivisions (20);
113 }
114 // ---------------------------------------------------------------------------
115
116 AliGSphere::AliGSphere(Text_t *name, Text_t *title, Float_t rmax) : AliGShape(name, title)
117 {
118     /* Simplified Constructor */
119     faX          = 1.;   // Coeff along Ox
120     faY          = 1.;   // Coeff along Oy
121     faZ          = 1.;   // Coeff along Oz
122     fAspectRatio = 1.;   // Relation between asumth and grid size (by default 1.0)
123     fCoTab       = NULL; // Table of cos(fPhimin) .... cos(Phi)
124     fCoThetaTab  = NULL; // Table of sin(gThemin) .... cos(Theta)
125     fNdiv        = 0;    // number of divisions
126     fNz          = 0;    // number of sections
127     fPhimax      = 360.; // maximum phi
128     fPhimin      = 0.;   // minimum phi
129     fRmax        = rmax; // maximum radius
130     fRmin        = 0.;   // minimum radius
131     fSiTab       = NULL; // Table of sin(fPhimin) .... sin(Phi)
132     fThemax      = 180.; // maximum theta
133     fThemin      = 0.;   // minimum theta
134
135     SetNumberOfDivisions (20);
136 }
137
138 // ---------------------------------------------------------------------------
139
140 AliGSphere::~AliGSphere() {
141     /* Destructor */
142     delete [] fCoThetaTab;  // Table of sin(gThemin) .... cos(Theta)
143     delete [] fCoTab;
144     delete [] fSiTab;
145 }
146
147 // ---------------------------------------------------------------------------
148
149 void AliGSphere::DrawShape(Option_t *option)
150 {
151     Draw(option);
152     gPad->Update();
153 }
154
155 //-------------------------------------------------------------------------
156
157 //void AliGSphere::Draw()
158 void AliGSphere::Draw(Option_t *option)
159 {
160     TString opt = option;
161     opt.ToLower();
162
163     if( !gPad ) {
164         gPad = new TCanvas("AliGSphere","AliGSphere",0,0,400,300);
165         gPad->Range(0,0,1,1);
166         gPad->SetFillColor(32); // Light Green
167         gPad->SetBorderSize(3);
168         gPad->SetBorderMode(0); // -1 (down) 0 (no) 1 (up)
169     }
170     else {
171         if( !opt.Contains("same") ) {
172             gPad->Clear();
173             gPad->SetName("AliGSphere");
174             gPad->SetTitle("AliGSphere");
175         }
176         else {
177             gPad->SetName("AliShapes");
178             gPad->SetTitle("AliShapes"); 
179         }
180     }
181
182     AppendPad(option);
183     TView *view = gPad->GetView();
184
185     if (!view)
186         view = new TView(1);
187
188     view->SetAutoRange(kTRUE);
189     Paint(option);
190     view->SetAutoRange(kFALSE);   
191 }
192
193 // ---------------------------------------------------------------------------
194
195 void AliGSphere::Paint(Option_t *option)
196 {
197 //*-*-*-*-*-*-*-*Paint this 3-D shape with its current attributes*-*-*-*-*-*-*-*
198 //*-*            ================================================
199
200     SetLineColor( GetCol() );
201
202     Int_t i, j;
203     const Int_t n = GetNumberOfDivisions()+1;
204     Int_t nz = fNz+1;
205     Int_t numpoints = 2*n*nz;
206     if (nz < 2) return;
207
208     if (numpoints <= 0) return;
209     //*-* Allocate memory for points *-*
210
211     Float_t *points = new Float_t[3*numpoints];
212     if (!points) return;
213     SetPoints(points);
214
215     if (gPad->GetView3D()) PaintGLPoints(points);
216
217  //==  for (i = 0; i < numpoints; i++)
218  //==          gNode->Local2Master(&points[3*i],&points[3*i]);
219
220     Bool_t specialCase = kFALSE;
221
222     if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01)  //mark this as a very special case, when
223         specialCase = kTRUE;                                  //we have to draw this PCON like a TUBE
224
225     X3DBuffer *buff = new X3DBuffer;
226     if (buff) {
227         buff->numPoints = numpoints;
228         buff->numSegs   = 4*(nz*n-1+(specialCase == kTRUE));
229         buff->numPolys  = 2*(nz*n-1+(specialCase == kTRUE));
230     }
231
232 //*-* Allocate memory for points *-*
233
234     buff->points = points;
235
236     Int_t c = ((GetLineColor() % 8) - 1) * 4;     // Basic colors: 0, 1, ... 7
237     if (c < 0) c = 0;
238
239 //*-* Allocate memory for segments *-*
240
241     Int_t indx, indx2, k;
242     indx = indx2 = 0;
243
244     buff->segs = new Int_t[buff->numSegs*3];
245     if (buff->segs) {
246
247         //inside & outside spheres, number of segments: 2*nz*(n-1)
248         //             special case number of segments: 2*nz*n
249         for (i = 0; i < nz*2; i++) {
250             indx2 = i*n;
251             for (j = 1; j < n; j++) {
252                 buff->segs[indx++] = c;
253                 buff->segs[indx++] = indx2+j-1;
254                 buff->segs[indx++] = indx2+j;
255             }
256             if (specialCase) {
257                 buff->segs[indx++] = c;
258                 buff->segs[indx++] = indx2+j-1;
259                 buff->segs[indx++] = indx2;
260             }
261         }
262
263         //bottom & top lines, number of segments: 2*n
264         for (i = 0; i < 2; i++) {
265             indx2 = i*(nz-1)*2*n;
266             for (j = 0; j < n; j++) {
267                 buff->segs[indx++] = c;
268                 buff->segs[indx++] = indx2+j;
269                 buff->segs[indx++] = indx2+n+j;
270             }
271         }
272
273         //inside & outside spheres, number of segments: 2*(nz-1)*n
274         for (i = 0; i < (nz-1); i++) {
275
276             //inside sphere
277             indx2 = i*n*2;
278             for (j = 0; j < n; j++) {
279                 buff->segs[indx++] = c+2;
280                 buff->segs[indx++] = indx2+j;
281                 buff->segs[indx++] = indx2+n*2+j;
282             }
283             //outside sphere
284             indx2 = i*n*2+n;
285             for (j = 0; j < n; j++) {
286                 buff->segs[indx++] = c+3;
287                 buff->segs[indx++] = indx2+j;
288                 buff->segs[indx++] = indx2+n*2+j;
289             }
290         }
291
292         //left & right sections, number of segments: 2*(nz-2)
293         //          special case number of segments: 0
294         /*if (!specialCase) {
295             for (i = 1; i < (nz-1); i++) {
296                 for (j = 0; j < 2; j++) {
297                     buff->segs[indx++] = c;
298                     buff->segs[indx++] =  2*i    * n + j*(n-1);
299                     buff->segs[indx++] = (2*i+1) * n + j*(n-1);
300                 }
301             }
302         }*/
303     }
304
305
306     Int_t m = n - 1 + (specialCase == kTRUE);
307
308 //*-* Allocate memory for polygons *-*
309
310     indx = 0;
311
312     buff->polys = new Int_t[buff->numPolys*6];
313
314     if (buff->polys) {
315         //bottom & top, number of polygons: 2*(n-1)
316         // special case number of polygons: 2*n
317         for (i = 0; i < 2; i++) {
318             for (j = 0; j < n-1; j++) {
319                 buff->polys[indx++] = c+3;
320                 buff->polys[indx++] = 4;
321                 buff->polys[indx++] = 2*nz*m+i*n+j;
322                 buff->polys[indx++] = i*(nz*2-2)*m+m+j;
323                 buff->polys[indx++] = 2*nz*m+i*n+j+1;
324                 buff->polys[indx++] = i*(nz*2-2)*m+j;
325             }
326             if (specialCase) {
327                 buff->polys[indx++] = c+3;
328                 buff->polys[indx++] = 4;
329                 buff->polys[indx++] = 2*nz*m+i*n+j;
330                 buff->polys[indx++] = i*(nz*2-2)*m+m+j;
331                 buff->polys[indx++] = 2*nz*m+i*n;
332                 buff->polys[indx++] = i*(nz*2-2)*m+j;
333             }
334         }
335
336
337         //inside & outside, number of polygons: (nz-1)*2*(n-1)
338         for (k = 0; k < (nz-1); k++) {
339             for (i = 0; i < 2; i++) {
340                 for (j = 0; j < n-1; j++) {
341                     buff->polys[indx++] = c+i;
342                     buff->polys[indx++] = 4;
343                     buff->polys[indx++] = (2*k+i*1)*m+j;
344                     buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j;
345                     buff->polys[indx++] = (2*k+i*1+2)*m+j;
346                     buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j+1;
347                 }
348                 if (specialCase) {
349                     buff->polys[indx++] = c+i;
350                     buff->polys[indx++] = 4;
351                     buff->polys[indx++] = (2*k+i*1)*m+j;
352                     buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j;
353                     buff->polys[indx++] = (2*k+i*1+2)*m+j;
354                     buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n;
355                 }
356             }
357         }
358
359         //left & right sections, number of polygons: 2*(nz-1)
360         //          special case number of polygons: 0
361         /*if (!specialCase) {
362             indx2 = nz*2*(n-1);
363             for (k = 0; k < (nz-1); k++) {
364                 for (i = 0; i < 2; i++) {
365                     buff->polys[indx++] = c+2;
366                     buff->polys[indx++] = 4;
367                     buff->polys[indx++] = k==0 ? indx2+i*(n-1) : indx2+2*nz*n+2*(k-1)+i;
368                     buff->polys[indx++] = indx2+2*(k+1)*n+i*(n-1);
369                     buff->polys[indx++] = indx2+2*nz*n+2*k+i;
370                     buff->polys[indx++] = indx2+(2*k+3)*n+i*(n-1);
371                 }
372             }
373             buff->polys[indx-8] = indx2+n;
374             buff->polys[indx-2] = indx2+2*n-1;
375         }*/
376     }
377
378     //*-* Paint in the pad
379     //*-* Paint in the pad
380     Bool_t rangeView = strcmp(option,"range")==0 ? kTRUE : kFALSE;
381     PaintShape(buff,rangeView);
382     //PaintShape(buff);
383
384     if (strstr(option, "x3d")) {
385         if(buff && buff->points && buff->segs)
386             FillX3DBuffer(buff);
387         else {
388             gSize3D.numPoints -= buff->numPoints;
389             gSize3D.numSegs   -= buff->numSegs;
390             gSize3D.numPolys  -= buff->numPolys;
391         }
392     }
393
394     delete [] points;
395     if (buff->segs)     delete [] buff->segs;
396     if (buff->polys)    delete [] buff->polys;
397     if (buff)           delete    buff;
398
399     
400
401 }
402
403 // ---------------------------------------------------------------------------
404
405 void AliGSphere::SetEllipse(Float_t *factors)
406 {
407   if (factors[0] > 0) faX = factors[0];
408   if (factors[1] > 0) faY = factors[1];
409   if (factors[2] > 0) faZ = factors[2];
410   MakeTableOfCoSin();
411 }
412
413 // ---------------------------------------------------------------------------
414
415 void AliGSphere::SetNumberOfDivisions (Int_t p)
416 {
417     if (GetNumberOfDivisions () == p)
418         return;
419     fNdiv = p;
420     fNz   = Int_t(fAspectRatio*fNdiv*(fThemax - fThemin )/(fPhimax - fPhimin )) + 1;
421     MakeTableOfCoSin();
422 }
423
424 // ---------------------------------------------------------------------------
425
426 void AliGSphere::SetPoints(Float_t *buff)
427 {
428 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*Create SPHE points*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
429 //*-*                            ==================
430     Int_t i, j;
431     Int_t indx = 0;
432
433     if (buff) {
434         Int_t n = GetNumberOfDivisions()+1;
435
436 //*-* We've to check whether the table does exist and create it
437 //*-* since fCoTab/fSiTab are not saved with any TShape::Streamer function
438         if (!fCoTab)   MakeTableOfCoSin();
439
440         Float_t z;
441         for (i = 0; i < fNz+1; i++)
442         {
443             z = fRmin * fCoThetaTab[i]; // fSinPhiTab[i];
444             Float_t sithet = TMath::Sqrt(TMath::Abs(1-fCoThetaTab[i]*fCoThetaTab[i]));
445             Float_t zi = fRmin*sithet;
446             for (j = 0; j < n; j++)
447             {
448                 buff[indx++] = zi * fCoTab[j];
449                 buff[indx++] = zi * fSiTab[j];
450                 buff[indx++] = z;
451             }
452             z = fRmax * fCoThetaTab[i];
453             zi = fRmax*sithet;
454             for (j = 0; j < n; j++)
455             {
456                 buff[indx++] = zi * fCoTab[j];
457                 buff[indx++] = zi * fSiTab[j];
458                 buff[indx++] = z;
459             }
460         }
461     }
462 }
463
464 // ---------------------------------------------------------------------------
465
466 void AliGSphere::MakeTableOfCoSin()
467 {
468     const Double_t PI  = TMath::ATan(1) * 4.0;
469     const Double_t ragrad  = PI/180.0;
470
471     Float_t dphi = fPhimax - fPhimin;
472     while (dphi > 360) dphi -= 360;
473
474     Float_t dtet = fThemax - fThemin;
475     while (dtet > 180) dtet -= 180;
476
477     Int_t j;
478     Int_t n = GetNumberOfDivisions () + 1;
479     if (fCoTab)
480         delete [] fCoTab; // Delete the old tab if any
481         fCoTab = new Double_t [n];
482     if (!fCoTab ) return;
483
484     if (fSiTab)
485         delete [] fSiTab; // Delete the old tab if any
486     fSiTab = new Double_t [n];
487     if (!fSiTab ) return;
488
489     Double_t range   = Double_t(dphi * ragrad);
490     Double_t phi1    = Double_t(fPhimin  * ragrad);
491     Double_t angstep = range/(n-1);
492
493     Double_t ph = phi1;
494     for (j = 0; j < n; j++)
495     {
496         ph = phi1 + j*angstep;
497         fCoTab[j] = TMath::Cos(ph);
498         fSiTab[j] = TMath::Sin(ph);
499     }
500
501     n  = fNz + 1;
502
503     if (fCoThetaTab)
504         delete [] fCoThetaTab; // Delete the old tab if any
505     fCoThetaTab = new Double_t [n];
506     if (!fCoThetaTab ) return;
507
508     range   = Double_t(dtet * ragrad);
509     phi1    = Double_t(fThemin  * ragrad);
510     angstep = range/(n-1);
511
512     ph = phi1;
513     for (j = 0; j < n; j++)
514     {
515         fCoThetaTab[n-j-1] = TMath::Cos(ph);
516         ph += angstep;
517     }
518
519 }
520
521 // ---------------------------------------------------------------------------
522
523 void AliGSphere::PaintGLPoints(Float_t *vertex)
524 {
525     gGLKernel->PaintCone(vertex,-(GetNumberOfDivisions()+1),fNz+1);
526 }
527
528 // ---------------------------------------------------------------------------
529
530 void AliGSphere::Sizeof3D() const
531 {
532 //*-*-*-*-*-*-*Return total X3D size of this shape with its attributes*-*-*-*-*-*
533 //*-*          =======================================================
534
535     cout << " Entra en AliGSphere::Sizeof3D() " << endl;
536
537     Int_t n;
538
539     n = GetNumberOfDivisions()+1;
540     Int_t nz = fNz+1;
541
542     //cout << " n = " << n << "   y   nz = " << nz << endl;
543
544     Bool_t specialCase = kFALSE;
545
546     if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01)  //mark this as a very special case, when
547           specialCase = kTRUE;                                  //we have to draw this PCON like a TUBE
548
549     gSize3D.numPoints += 2*n*nz;
550     gSize3D.numSegs   += 4*(nz*n-1+(specialCase == kTRUE));
551     gSize3D.numPolys  += 2*(nz*n-1+(specialCase == kTRUE));
552 }
553
554 // ---------------------------------------------------------------------------
555
556 void AliGSphere::Streamer(TBuffer &R__b)
557 {
558    // Stream an object of class AliGSphere.
559
560    if (R__b.IsReading()) {
561       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
562       AliGShape::Streamer(R__b);
563       R__b >> fAspectRatio;
564       R__b.ReadArray(fCoTab); //
565       R__b.ReadArray(fCoThetaTab); //
566       R__b >> fNdiv;
567       R__b >> fNz;
568       R__b.ReadArray(fSiTab); //
569       R__b >> faX;
570       R__b >> faY;
571       R__b >> faZ;
572       R__b >> fPhimax;
573       R__b >> fPhimin;
574       R__b >> fRmax;
575       R__b >> fRmin;
576       R__b >> fThemax;
577       R__b >> fThemin;
578    } else {
579       R__b.WriteVersion(AliGSphere::IsA());
580       AliGShape::Streamer(R__b);
581       R__b << fAspectRatio;
582       R__b.WriteArray(fCoTab, GetNumberOfDivisions()+1); //
583       R__b.WriteArray(fCoThetaTab, fNz+1); //
584       R__b << fNdiv;
585       R__b << fNz;
586       R__b.WriteArray(fSiTab, GetNumberOfDivisions()+1); //
587       R__b << faX;
588       R__b << faY;
589       R__b << faZ;
590       R__b << fPhimax;
591       R__b << fPhimin;
592       R__b << fRmax;
593       R__b << fRmin;
594       R__b << fThemax;
595       R__b << fThemin;
596    }
597 }
598
599 // ---------------------------------------------------------------------------
600