Introduction of the Copyright and cvs Log
[u/mrichter/AliRoot.git] / GEODB / AliGSphere.cxx
CommitLineData
4c039060 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
ab2f6604 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
42ClassImp(AliGSphere)
43
44AliGSphere::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
68AliGSphere::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
92AliGSphere::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
116AliGSphere::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
140AliGSphere::~AliGSphere() {
141 /* Destructor */
142 delete [] fCoThetaTab; // Table of sin(gThemin) .... cos(Theta)
143 delete [] fCoTab;
144 delete [] fSiTab;
145}
146
147// ---------------------------------------------------------------------------
148
149void AliGSphere::DrawShape(Option_t *option)
150{
151 Draw(option);
152 gPad->Update();
153}
154
155//-------------------------------------------------------------------------
156
157//void AliGSphere::Draw()
158void 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
195void 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
405void 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
415void 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
426void 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
466void 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
523void AliGSphere::PaintGLPoints(Float_t *vertex)
524{
525 gGLKernel->PaintCone(vertex,-(GetNumberOfDivisions()+1),fNz+1);
526}
527
528// ---------------------------------------------------------------------------
529
530void 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
556void 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