ROOT  6.06/09
Reference Guide
TGeoShape.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 31/01/02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //____________________________________________________________________________
13 // TGeoShape - Base abstract class for all shapes.
14 //____________________________________________________________________________
15 //
16 //
17 // Shapes are geometrical objects that provide the basic modelling
18 // functionality. They provide the definition of the LOCAL frame of coordinates,
19 // with respect to which they are defined. Any implementation of a shape deriving
20 // from the base TGeoShape class has to provide methods for :
21 // - finding out if a point defined in their local frame is or not contained
22 // inside;
23 // - computing the distance from a local point to getting outside/entering the
24 // shape, given a known direction;
25 // - computing the maximum distance in any direction from a local point that
26 // does NOT result in a boundary crossing of the shape (safe distance);
27 // - computing the cosines of the normal vector to the crossed shape surface,
28 // given a starting local point and an ongoing direction.
29 // All the features above are globally managed by the modeller in order to
30 // provide navigation functionality. In addition to those, shapes have also to
31 // implement additional specific abstract methods :
32 // - computation of the minimal box bounding the shape, given that this box have
33 // to be aligned with the local coordinates;
34 // - algorithms for dividing the shape along a given axis and producing resulting
35 // divisions volumes.
36 //
37 // The modeler currently provides a set of 16 basic shapes, which we will call
38 // primitives. It also provides a special class allowing the creation of shapes
39 // made as a result of boolean operations between primitives. These are called
40 // composite shapes and the composition operation can be recursive (composition
41 // of composites). This allows the creation of a quite large number of different
42 // shape topologies and combinations.
43 //
44 // Shapes are named objects and register themselves to the manager class at
45 // creation time. This is responsible for their final deletion. Shapes
46 // can be created without name if their retreival by name is no needed. Generally
47 // shapes are objects that are usefull only at geometry creation stage. The pointer
48 // to a shape is in fact needed only when referring to a given volume and it is
49 // always accessible at that level. A shape may be referenced by several volumes,
50 // therefore its deletion is not possible once volumes were defined based on it.
51 //
52 //
53 //
54 // Creating shapes
55 //================
56 // Shape objects embeed only the minimum set of parameters that are fully
57 // describing a valid physical shape. For instance, a tube is represented by
58 // its half length, the minimum radius and the maximum radius. Shapes are used
59 // togeather with media in order to create volumes, which in their turn
60 // are the main components of the geometrical tree. A specific shape can be created
61 // stand-alone :
62 //
63 // TGeoBBox *box = new TGeoBBox("s_box", halfX, halfY, halfZ); // named
64 // TGeoTube *tub = new TGeoTube(rmin, rmax, halfZ); // no name
65 // ... (see each specific shape constructors)
66 //
67 // Sometimes it is much easier to create a volume having a given shape in one
68 // step, since shapes are not direcly linked in the geometrical tree but volumes
69 // are :
70 //
71 // TGeoVolume *vol_box = gGeoManager->MakeBox("BOX_VOL", "mat1", halfX, halfY, halfZ);
72 // TGeoVolume *vol_tub = gGeoManager->MakeTube("TUB_VOL", "mat2", rmin, rmax, halfZ);
73 // ... (see MakeXXX() utilities in TGeoManager class)
74 //
75 //
76 // Shape queries
77 //===============
78 // Note that global queries related to a geometry are handled by the manager class.
79 // However, shape-related queries might be sometimes usefull.
80 //
81 // A) Bool_t TGeoShape::Contains(const Double_t *point[3])
82 // - this method returns true if POINT is actually inside the shape. The point
83 // has to be defined in the local shape reference. For instance, for a box having
84 // DX, DY and DZ half-lengths a point will be considered inside if :
85 // | -DX <= point[0] <= DX
86 // | -DY <= point[1] <= DY
87 // | -DZ <= point[2] <= DZ
88 //
89 // B) Double_t TGeoShape::DistFromInside(Double_t *point[3], Double_t *dir[3],
90 // Int_t iact, Double_t step, Double_t *safe)
91 // - computes the distance to exiting a shape from a given point INSIDE, along
92 // a given direction. The direction is given by its director cosines with respect
93 // to the local shape coordinate system. This method provides additional
94 // information according the value of IACT input parameter :
95 // IACT = 0 => compute only safe distance and fill it at the location
96 // given by SAFE
97 // IACT = 1 => a proposed STEP is supplied. The safe distance is computed
98 // first. If this is bigger than STEP than the proposed step
99 // is approved and returned by the method since it does not
100 // cross the shape boundaries. Otherwise, the distance to
101 // exiting the shape is computed and returned.
102 // IACT = 2 => compute both safe distance and distance to exiting, ignoring
103 // the proposed step.
104 // IACT > 2 => compute only the distance to exiting, ignoring anything else.
105 //
106 // C) Double_t TGeoShape::DistFromOutside(Double_t *point[3], Double_t *dir[3],
107 // Int_t iact, Double_t step, Double_t *safe)
108 // - computes the distance to entering a shape from a given point OUTSIDE. Acts
109 // in the same way as B).
110 //
111 // D) Double_t Safety(const Double_t *point[3], Bool_t inside)
112 //
113 // - compute maximum shift of a point in any direction that does not change its
114 // INSIDE/OUTSIDE state (does not cross shape boundaries). The state of the point
115 // have to be properly supplied.
116 //
117 // E) Double_t *Normal(Double_t *point[3], Double_t *dir[3], Bool_t inside)
118 //
119 // - returns director cosines of normal to the crossed shape surface from a
120 // given point towards a direction. One has to specify if the point is inside
121 // or outside shape. According to this, the normal will be outwards or inwards
122 // shape respectively. Normal components are statically stored by shape class,
123 // so it has to be copied after retreival in a different array.
124 //
125 // Dividing shapes
126 //=================
127 // Shapes can generally be divided along a given axis. Supported axis are
128 // X, Y, Z, Rxy, Phi, Rxyz. A given shape cannot be divided however on any axis.
129 // The general rule is that that divisions are possible on whatever axis that
130 // produces still known shapes as slices. The division of shapes should not be
131 // performed by TGeoShape::Divide() calls, but rather by TGeoVolume::Divide().
132 // The algorithm for dividing a specific shape is known by the shape object, but
133 // is always invoked in a generic way from the volume level. Details on how to
134 // do that can be found in TGeoVolume class. One can see how all division options
135 // are interpreted and which is their result inside specific shape classes.
136 //_____________________________________________________________________________
137 //
138 //Begin_Html
139 /*
140 <img src="gif/t_shape.jpg">
141 */
142 //End_Html
143 
144 #include "TObjArray.h"
145 #include "TEnv.h"
146 #include "TError.h"
147 
148 #include "TGeoMatrix.h"
149 #include "TGeoManager.h"
150 #include "TGeoVolume.h"
151 #include "TGeoShape.h"
152 #include "TVirtualGeoPainter.h"
153 #include "TBuffer3D.h"
154 #include "TBuffer3DTypes.h"
155 #include "TMath.h"
156 
158 
159 TGeoMatrix *TGeoShape::fgTransform = NULL;
160 Double_t TGeoShape::fgEpsMch = 2.220446049250313e-16;
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Default constructor
163 
165 {
166  fShapeBits = 0;
167  fShapeId = 0;
168  if (!gGeoManager) {
169  gGeoManager = new TGeoManager("Geometry", "default geometry");
170  // gROOT->AddGeoManager(gGeoManager);
171  }
172 // fShapeId = gGeoManager->GetListOfShapes()->GetSize();
173 // gGeoManager->AddShape(this);
174 }
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// Default constructor
178 
180  :TNamed(name, "")
181 {
182  fShapeBits = 0;
183  fShapeId = 0;
184  if (!gGeoManager) {
185  gGeoManager = new TGeoManager("Geometry", "default geometry");
186  // gROOT->AddGeoManager(gGeoManager);
187  }
189  gGeoManager->AddShape(this);
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// Destructor
194 
196 {
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// Test for shape navigation methods. Summary for test numbers:
202 /// 1: DistFromInside/Outside. Sample points inside the shape. Generate
203 /// directions randomly in cos(theta). Compute DistFromInside and move the
204 /// point with bigger distance. Compute DistFromOutside back from new point.
205 /// Plot d-(d1+d2)
206 ///
207 
208 void TGeoShape::CheckShape(Int_t testNo, Int_t nsamples, Option_t *option)
209 {
210  if (!gGeoManager) {
211  Error("CheckShape","No geometry manager");
212  return;
213  }
214  TGeoShape *shape = (TGeoShape*)this;
215  gGeoManager->CheckShape(shape, testNo, nsamples, option);
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Compute machine round-off double precision error as the smallest number that
220 /// if added to 1.0 is different than 1.0.
221 
223 {
224  Double_t temp1 = 1.0;
225  Double_t temp2 = 1.0 + temp1;
226  Double_t mchEps = 0.;
227  while (temp2>1.0) {
228  mchEps = temp1;
229  temp1 /= 2;
230  temp2 = 1.0 + temp1;
231  }
232  fgEpsMch = mchEps;
233  return fgEpsMch;
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 ///static function returning the machine round-off error
238 
240 {
241  return fgEpsMch;
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Get the shape name.
246 
247 const char *TGeoShape::GetName() const
248 {
249  if (!fName[0]) {
250  return ((TObject *)this)->ClassName();
251  }
252  return TNamed::GetName();
253 }
254 
255 ////////////////////////////////////////////////////////////////////////////////
256 /// Returns distance to shape primitive mesh.
257 
259 {
261  if (!painter) return 9999;
262  return painter->ShapeDistancetoPrimitive(this, numpoints, px, py);
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// True if point is closer than epsil to one of the phi planes defined by c1,s1 or c2,s2
267 
269 {
270  Double_t saf1 = TGeoShape::Big();
271  Double_t saf2 = TGeoShape::Big();
272  if (point[0]*c1+point[1]*s1 >= 0) saf1 = TMath::Abs(-point[0]*s1 + point[1]*c1);
273  if (point[0]*c2+point[1]*s2 >= 0) saf2 = TMath::Abs(point[0]*s2 - point[1]*c2);
274  Double_t saf = TMath::Min(saf1,saf2);
275  if (saf<epsil) return kTRUE;
276  return kFALSE;
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Static method to check if a point is in the phi range (phi1, phi2) [degrees]
281 
283 {
284  Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
285  while (phi<phi1) phi+=360.;
286  Double_t ddp = phi-phi1;
287  if (ddp>phi2-phi1) return kFALSE;
288  return kTRUE;
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Compute distance from POINT to semiplane defined by PHI angle along DIR. Computes
293 /// also radius at crossing point. This might be negative in case the crossing is
294 /// on the other side of the semiplane.
295 
297 {
298  snext = rxy = TGeoShape::Big();
299  Double_t nx = -sphi;
300  Double_t ny = cphi;
301  Double_t rxy0 = point[0]*cphi+point[1]*sphi;
302  Double_t rdotn = point[0]*nx + point[1]*ny;
303  if (TMath::Abs(rdotn)<TGeoShape::Tolerance()) {
304  snext = 0.0;
305  rxy = rxy0;
306  return kTRUE;
307  }
308  if (rdotn<0) {
309  rdotn = -rdotn;
310  } else {
311  nx = -nx;
312  ny = -ny;
313  }
314  Double_t ddotn = dir[0]*nx + dir[1]*ny;
315  if (ddotn<=0) return kFALSE;
316  snext = rdotn/ddotn;
317  rxy = rxy0+snext*(dir[0]*cphi+dir[1]*sphi);
318  if (rxy<0) return kFALSE;
319  return kTRUE;
320 }
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// Check if two numbers differ with less than a tolerance.
324 
326 {
327  if (TMath::Abs(a-b)<1.E-10) return kTRUE;
328  return kFALSE;
329 }
330 
331 ////////////////////////////////////////////////////////////////////////////////
332 /// Check if segments (A,B) and (C,D) are crossing,
333 /// where: A(x1,y1), B(x2,y2), C(x3,y3), D(x4,y4)
334 
336 {
338  Bool_t stand1 = kFALSE;
339  Double_t dx1 = x2-x1;
340  Bool_t stand2 = kFALSE;
341  Double_t dx2 = x4-x3;
342  Double_t xm = 0.;
343  Double_t ym = 0.;
344  Double_t a1 = 0.;
345  Double_t b1 = 0.;
346  Double_t a2 = 0.;
347  Double_t b2 = 0.;
348  if (TMath::Abs(dx1) < eps) stand1 = kTRUE;
349  if (TMath::Abs(dx2) < eps) stand2 = kTRUE;
350  if (!stand1) {
351  a1 = (x2*y1-x1*y2)/dx1;
352  b1 = (y2-y1)/dx1;
353  }
354  if (!stand2) {
355  a2 = (x4*y3-x3*y4)/dx2;
356  b2 = (y4-y3)/dx2;
357  }
358  if (stand1 && stand2) {
359  // Segments parallel and vertical
360  if (TMath::Abs(x1-x3)<eps) {
361  // Check if segments are overlapping
362  if ((y3-y1)*(y3-y2)<-eps || (y4-y1)*(y4-y2)<-eps ||
363  (y1-y3)*(y1-y4)<-eps || (y2-y3)*(y2-y4)<-eps) return kTRUE;
364  return kFALSE;
365  }
366  // Different x values
367  return kFALSE;
368  }
369 
370  if (stand1) {
371  // First segment vertical
372  xm = x1;
373  ym = a2+b2*xm;
374  } else {
375  if (stand2) {
376  // Second segment vertical
377  xm = x3;
378  ym = a1+b1*xm;
379  } else {
380  // Normal crossing
381  if (TMath::Abs(b1-b2)<eps) {
382  // Parallel segments, are they aligned
383  if (TMath::Abs(y3-(a1+b1*x3))>eps) return kFALSE;
384  // Aligned segments, are they overlapping
385  if ((x3-x1)*(x3-x2)<-eps || (x4-x1)*(x4-x2)<-eps ||
386  (x1-x3)*(x1-x4)<-eps || (x2-x3)*(x2-x4)<-eps) return kTRUE;
387  return kFALSE;
388  }
389  xm = (a1-a2)/(b2-b1);
390  ym = (a1*b2-a2*b1)/(b2-b1);
391  }
392  }
393  // Check if crossing point is both between A,B and C,D
394  Double_t check = (xm-x1)*(xm-x2)+(ym-y1)*(ym-y2);
395  if (check > -eps) return kFALSE;
396  check = (xm-x3)*(xm-x4)+(ym-y3)*(ym-y4);
397  if (check > -eps) return kFALSE;
398  return kTRUE;
399 }
400 
401 ////////////////////////////////////////////////////////////////////////////////
402 /// compute distance from point (inside phi) to both phi planes. Return minimum.
403 
405  Double_t s2, Double_t c2, Double_t sm, Double_t cm, Bool_t in)
406 {
407  Double_t sfi1=TGeoShape::Big();
408  Double_t sfi2=TGeoShape::Big();
409  Double_t s=0;
410  Double_t un = dir[0]*s1-dir[1]*c1;
411  if (!in) un=-un;
412  if (un>0) {
413  s=-point[0]*s1+point[1]*c1;
414  if (!in) s=-s;
415  if (s>=0) {
416  s /= un;
417  if (((point[0]+s*dir[0])*sm-(point[1]+s*dir[1])*cm)>=0) sfi1=s;
418  }
419  }
420  un = -dir[0]*s2+dir[1]*c2;
421  if (!in) un=-un;
422  if (un>0) {
423  s=point[0]*s2-point[1]*c2;
424  if (!in) s=-s;
425  if (s>=0) {
426  s /= un;
427  if ((-(point[0]+s*dir[0])*sm+(point[1]+s*dir[1])*cm)>=0) sfi2=s;
428  }
429  }
430  return TMath::Min(sfi1, sfi2);
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////
434 /// Static method to compute normal to phi planes.
435 
437 {
438  Double_t saf1 = TGeoShape::Big();
439  Double_t saf2 = TGeoShape::Big();
440  if (point[0]*c1+point[1]*s1 >= 0) saf1 = TMath::Abs(-point[0]*s1 + point[1]*c1);
441  if (point[0]*c2+point[1]*s2 >= 0) saf2 = TMath::Abs(point[0]*s2 - point[1]*c2);
442  Double_t c,s;
443  if (saf1<saf2) {
444  c=c1;
445  s=s1;
446  } else {
447  c=c2;
448  s=s2;
449  }
450  norm[2] = 0;
451  norm[0] = -s;
452  norm[1] = c;
453  if (dir[0]*norm[0]+dir[1]*norm[1] < 0) {
454  norm[0] = s;
455  norm[1] = -c;
456  }
457 }
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// Static method to compute safety w.r.t a phi corner defined by cosines/sines
461 /// of the angles phi1, phi2.
462 
464 {
465  Bool_t inphi = TGeoShape::IsInPhiRange(point, phi1, phi2);
466  if (inphi && !in) return -TGeoShape::Big();
467  phi1 *= TMath::DegToRad();
468  phi2 *= TMath::DegToRad();
469  Double_t c1 = TMath::Cos(phi1);
470  Double_t s1 = TMath::Sin(phi1);
471  Double_t c2 = TMath::Cos(phi2);
472  Double_t s2 = TMath::Sin(phi2);
473  Double_t rsq = point[0]*point[0]+point[1]*point[1];
474  Double_t rproj = point[0]*c1+point[1]*s1;
475  Double_t safsq = rsq-rproj*rproj;
476  if (safsq<0) return 0.;
477  Double_t saf1 = (rproj<0)?TGeoShape::Big():TMath::Sqrt(safsq);
478  rproj = point[0]*c2+point[1]*s2;
479  safsq = rsq-rproj*rproj;
480  if (safsq<0) return 0.;
481  Double_t saf2 = (rproj<0)?TGeoShape::Big():TMath::Sqrt(safsq);
482  Double_t safe = TMath::Min(saf1, saf2); // >0
483  if (safe>1E10) {
484  if (in) return TGeoShape::Big();
485  return -TGeoShape::Big();
486  }
487  return safe;
488 }
489 
490 ////////////////////////////////////////////////////////////////////////////////
491 /// Compute distance from point of coordinates (r,z) to segment (r1,z1):(r2,z2)
492 
494 {
495  Double_t crossp = (z2-z1)*(r-r1)-(z-z1)*(r2-r1);
496  crossp *= (outer) ? 1. : -1.;
497  // Positive crossp means point on the requested side of the (1,2) segment
498  if (crossp < 0) {
499  if (((z-z1)*(z2-z)) > -1.E-10) return 0;
500  return TGeoShape::Big();
501  }
502  // Compute (1,P) dot (1,2)
503  Double_t c1 = (z-z1)*(z2-z1)+(r-r1)*(r2-r1);
504  // Negative c1 means point (1) is closest
505  if (c1<1.E-10) return TMath::Sqrt((r-r1)*(r-r1)+(z-z1)*(z-z1));
506  // Compute (2,P) dot (1,2)
507  Double_t c2 = (z-z2)*(z2-z1)+(r-r2)*(r2-r1);
508  // Positive c2 means point (2) is closest
509  if (c2>-1.E-10) return TMath::Sqrt((r-r2)*(r-r2)+(z-z2)*(z-z2));
510  // The closest point is between (1) and (2)
511  c2 = (z2-z1)*(z2-z1)+(r2-r1)*(r2-r1);
512  // projected length factor with respect to (1,2) length
513  Double_t alpha = c1/c2;
514  Double_t rp = r1 + alpha*(r2-r1);
515  Double_t zp = z1 + alpha*(z2-z1);
516  return TMath::Sqrt((r-rp)*(r-rp)+(z-zp)*(z-zp));
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Equivalent of TObject::SetBit.
521 
523 {
524  if (set) {
525  SetShapeBit(f);
526  } else {
527  ResetShapeBit(f);
528  }
529 }
530 
531 ////////////////////////////////////////////////////////////////////////////////
532 /// Returns current transformation matrix that applies to shape.
533 
535 {
536  return fgTransform;
537 }
538 
539 ////////////////////////////////////////////////////////////////////////////////
540 /// Set current transformation matrix that applies to shape.
541 
543 {
544  fgTransform = matrix;
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Tranform a set of points (LocalToMaster)
549 
551 {
552  UInt_t i,j;
553  Double_t dmaster[3];
554  if (fgTransform) {
555  for (j = 0; j < NbPnts; j++) {
556  i = 3*j;
557  fgTransform->LocalToMaster(&points[i], dmaster);
558  points[i] = dmaster[0];
559  points[i+1] = dmaster[1];
560  points[i+2] = dmaster[2];
561  }
562  return;
563  }
564  if (!gGeoManager) return;
565  Bool_t bomb = (gGeoManager->GetBombMode()==0)?kFALSE:kTRUE;
566 
567  for (j = 0; j < NbPnts; j++) {
568  i = 3*j;
570  TGeoHMatrix *glmat = gGeoManager->GetGLMatrix();
571  if (bomb) glmat->LocalToMasterBomb(&points[i], dmaster);
572  else glmat->LocalToMaster(&points[i], dmaster);
573  } else {
574  if (bomb) gGeoManager->LocalToMasterBomb(&points[i], dmaster);
575  else gGeoManager->LocalToMaster(&points[i],dmaster);
576  }
577  points[i] = dmaster[0];
578  points[i+1] = dmaster[1];
579  points[i+2] = dmaster[2];
580  }
581 }
582 
583 ////////////////////////////////////////////////////////////////////////////////
584 /// Fill the supplied buffer, with sections in desired frame
585 /// See TBuffer3D.h for explanation of sections, frame etc.
586 
587 void TGeoShape::FillBuffer3D(TBuffer3D & buffer, Int_t reqSections, Bool_t localFrame) const
588 {
589  // Catch this common potential error here
590  // We have to set kRawSize (unless already done) to allocate buffer space
591  // before kRaw can be filled
592  if (reqSections & TBuffer3D::kRaw) {
593  if (!(reqSections & TBuffer3D::kRawSizes) && !buffer.SectionsValid(TBuffer3D::kRawSizes)) {
594  R__ASSERT(kFALSE);
595  }
596  }
597 
598  if (reqSections & TBuffer3D::kCore) {
599  // If writing core section all others will be invalid
600  buffer.ClearSectionsValid();
601 
602  // Check/grab some objects we need
603  if (!gGeoManager) {
604  R__ASSERT(kFALSE);
605  return;
606  }
607  const TGeoVolume * paintVolume = gGeoManager->GetPaintVolume();
608  if (!paintVolume) paintVolume = gGeoManager->GetTopVolume();
609  if (!paintVolume) {
610  buffer.fID = const_cast<TGeoShape *>(this);
611  buffer.fColor = 0;
612  buffer.fTransparency = 0;
613 // R__ASSERT(kFALSE);
614 // return;
615  } else {
616  buffer.fID = const_cast<TGeoVolume *>(paintVolume);
617  buffer.fColor = paintVolume->GetLineColor();
618 
619  buffer.fTransparency = paintVolume->GetTransparency();
620  Double_t visdensity = gGeoManager->GetVisDensity();
621  if (visdensity>0 && paintVolume->GetMedium()) {
622  if (paintVolume->GetMaterial()->GetDensity() < visdensity) {
623  buffer.fTransparency = 90;
624  }
625  }
626  }
627 
628  buffer.fLocalFrame = localFrame;
629  Bool_t r1,r2=kFALSE;
631  if (paintVolume && paintVolume->GetShape()) {
632  if (paintVolume->GetShape()->IsReflected()) {
633  // Temporary trick to deal with reflected shapes.
634  // Still lighting gets wrong...
635  if (buffer.Type() < TBuffer3DTypes::kTube) r2 = kTRUE;
636  }
637  }
638  buffer.fReflection = ((r1&(!r2))|(r2&!(r1)));
639 
640  // Set up local -> master translation matrix
641  if (localFrame) {
642  TGeoMatrix * localMasterMat = 0;
643  if (TGeoShape::GetTransform()) {
644  localMasterMat = TGeoShape::GetTransform();
645  } else {
646  localMasterMat = gGeoManager->GetCurrentMatrix();
647 
648  // For overlap drawing the correct matrix needs to obtained in
649  // from GetGLMatrix() - this should not be applied in the case
650  // of composite shapes
652  localMasterMat = gGeoManager->GetGLMatrix();
653  }
654  }
655  if (!localMasterMat) {
656  R__ASSERT(kFALSE);
657  return;
658  }
659  localMasterMat->GetHomogenousMatrix(buffer.fLocalMaster);
660  } else {
661  buffer.SetLocalMasterIdentity();
662  }
663 
664  buffer.SetSectionsValid(TBuffer3D::kCore);
665  }
666 }
667 
668 ////////////////////////////////////////////////////////////////////////////////
669 /// Get the basic color (0-7).
670 
672 {
673  Int_t basicColor = 0; // TODO: Check on sensible fallback
674  if (gGeoManager) {
675  const TGeoVolume * volume = gGeoManager->GetPaintVolume();
676  if (volume) {
677  basicColor = ((volume->GetLineColor() %8) -1) * 4;
678  if (basicColor < 0) basicColor = 0;
679  }
680  }
681  return basicColor;
682 }
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Stub implementation to avoid forcing implementation at this stage
686 
687 const TBuffer3D &TGeoShape::GetBuffer3D(Int_t /*reqSections*/, Bool_t /*localFrame*/) const
688 {
689  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
690  Warning("GetBuffer3D", "this must be implemented for shapes in a TGeoPainter hierarchy. This will be come a pure virtual fn eventually.");
691  return buffer;
692 }
693 
694 ////////////////////////////////////////////////////////////////////////////////
695 /// Provide a pointer name containing uid.
696 
697 const char *TGeoShape::GetPointerName() const
698 {
699  static TString name;
700  Int_t uid = GetUniqueID();
701  if (uid) name = TString::Format("p%s_%d", GetName(),uid);
702  else name = TString::Format("p%s", GetName());
703  return name.Data();
704 }
705 
706 ////////////////////////////////////////////////////////////////////////////////
707 /// Execute mouse actions on this shape.
708 
710 {
711  if (!gGeoManager) return;
713  painter->ExecuteShapeEvent(this, event, px, py);
714 }
715 
716 ////////////////////////////////////////////////////////////////////////////////
717 /// Draw this shape.
718 
720 {
722  if (option && option[0]) {
723  painter->DrawShape(this, option);
724  } else {
725  painter->DrawShape(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
726  }
727 }
728 
729 ////////////////////////////////////////////////////////////////////////////////
730 /// Paint this shape.
731 
733 {
735  if (option && option[0]) {
736  painter->PaintShape(this, option);
737  } else {
738  painter->PaintShape(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
739  }
740 }
const int nx
Definition: kalman.C:16
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const
Fill the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Definition: TGeoShape.cxx:587
void CheckShape(Int_t testNo, Int_t nsamples=10000, Option_t *option="")
Test for shape navigation methods.
Definition: TGeoShape.cxx:208
virtual ~TGeoShape()
Destructor.
Definition: TGeoShape.cxx:195
void CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option)
Test for shape navigation methods.
#define snext(osub1, osub2)
Definition: triangle.c:1167
static Double_t ComputeEpsMch()
Compute machine round-off double precision error as the smallest number that if added to 1...
Definition: TGeoShape.cxx:222
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute mouse actions on this shape.
Definition: TGeoShape.cxx:709
static Double_t EpsMch()
static function returning the machine round-off error
Definition: TGeoShape.cxx:239
const char Option_t
Definition: RtypesCore.h:62
TCanvas * c1
Definition: legend1.C:2
Int_t GetBasicColor() const
Get the basic color (0-7).
Definition: TGeoShape.cxx:671
Double_t DegToRad()
Definition: TMath.h:50
Double_t fLocalMaster[16]
Definition: TBuffer3D.h:94
void SetLocalMasterIdentity()
Set kRaw tessellation section of buffer with supplied sizes.
Definition: TBuffer3D.cxx:294
#define R__ASSERT(e)
Definition: TError.h:98
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:652
TGeoHMatrix * GetCurrentMatrix() const
Definition: TGeoManager.h:483
void ClearSectionsValid()
Clear any sections marked valid.
Definition: TBuffer3D.cxx:284
Double_t RadToDeg()
Definition: TMath.h:49
Basic string class.
Definition: TString.h:137
TObjArray * GetListOfShapes() const
Definition: TGeoManager.h:467
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
const Bool_t kFALSE
Definition: Rtypes.h:92
static Double_t SafetyPhi(const Double_t *point, Bool_t in, Double_t phi1, Double_t phi2)
Static method to compute safety w.r.t a phi corner defined by cosines/sines of the angles phi1...
Definition: TGeoShape.cxx:463
void GetHomogenousMatrix(Double_t *hmat) const
The homogenous matrix associated with the transformation is used for piling up's and visualization...
Definition: TGeoMatrix.cxx:321
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
Definition: TGeoShape.cxx:325
static Double_t Tolerance()
Definition: TGeoShape.h:101
const char * Data() const
Definition: TString.h:349
static const double x2[5]
Bool_t IsMatrixTransform() const
Definition: TGeoManager.h:390
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2334
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
void LocalToMaster(const Double_t *local, Double_t *master) const
Definition: TGeoManager.h:510
const int ny
Definition: kalman.C:17
static Double_t fgEpsMch
Definition: TGeoShape.h:39
TVirtualGeoPainter * GetPainter() const
Definition: TGeoManager.h:193
Int_t Type() const
Definition: TBuffer3D.h:87
static Bool_t IsCrossingSemiplane(const Double_t *point, const Double_t *dir, Double_t cphi, Double_t sphi, Double_t &snext, Double_t &rxy)
Compute distance from POINT to semiplane defined by PHI angle along DIR.
Definition: TGeoShape.cxx:296
static const double x4[22]
void LocalToMasterBomb(const Double_t *local, Double_t *master) const
Definition: TGeoManager.h:512
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:454
TGeoVolume * GetPaintVolume() const
Definition: TGeoManager.h:199
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
TGeoMaterial * GetMaterial() const
Definition: TGeoVolume.h:188
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:499
static void SetTransform(TGeoMatrix *matrix)
Set current transformation matrix that applies to shape.
Definition: TGeoShape.cxx:542
virtual Int_t ShapeDistancetoPrimitive(const TGeoShape *shape, Int_t numpoints, Int_t px, Int_t py) const =0
void SetSectionsValid(UInt_t mask)
Definition: TBuffer3D.h:67
static Double_t SafetySeg(Double_t r, Double_t z, Double_t r1, Double_t z1, Double_t r2, Double_t z2, Bool_t outer)
Compute distance from point of coordinates (r,z) to segment (r1,z1):(r2,z2)
Definition: TGeoShape.cxx:493
Bool_t fLocalFrame
Definition: TBuffer3D.h:92
point * points
Definition: X3DBuffer.c:20
static Bool_t IsSegCrossing(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t x3, Double_t y3, Double_t x4, Double_t y4)
Check if segments (A,B) and (C,D) are crossing, where: A(x1,y1), B(x2,y2), C(x3,y3), D(x4,y4)
Definition: TGeoShape.cxx:335
TGeoShape()
Default constructor.
Definition: TGeoShape.cxx:164
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
Definition: TGeoShape.cxx:550
Int_t GetBombMode() const
Definition: TGeoManager.h:194
ROOT::R::TRInterface & r
Definition: Object.C:4
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
unsigned int r1[N_CITIES]
Definition: simanTSP.cxx:321
void ResetShapeBit(UInt_t f)
Definition: TGeoShape.h:171
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:346
static Double_t DistToPhiMin(const Double_t *point, const Double_t *dir, Double_t s1, Double_t c1, Double_t s2, Double_t c2, Double_t sm, Double_t cm, Bool_t in=kTRUE)
compute distance from point (inside phi) to both phi planes. Return minimum.
Definition: TGeoShape.cxx:404
unsigned int UInt_t
Definition: RtypesCore.h:42
Double_t E()
Definition: TMath.h:54
Bool_t IsCleaning() const
Definition: TGeoManager.h:456
static Bool_t IsInPhiRange(const Double_t *point, Double_t phi1, Double_t phi2)
Static method to check if a point is in the phi range (phi1, phi2) [degrees].
Definition: TGeoShape.cxx:282
Generic 3D primitive description class.
Definition: TBuffer3D.h:19
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TObject * fID
Definition: TBuffer3D.h:89
virtual Color_t GetLineColor() const
Definition: TAttLine.h:47
TString fName
Definition: TNamed.h:36
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:247
static TGeoMatrix * fgTransform
Definition: TGeoShape.h:38
Double_t Cos(Double_t)
Definition: TMath.h:424
virtual Bool_t IsReflected() const
Definition: TGeoShape.h:147
Bool_t fReflection
Definition: TBuffer3D.h:93
static Bool_t IsCloseToPhi(Double_t epsil, const Double_t *point, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
True if point is closer than epsil to one of the phi planes defined by c1,s1 or c2,s2.
Definition: TGeoShape.cxx:268
return c2
Definition: legend2.C:14
virtual Int_t GetSize() const
Definition: TCollection.h:95
TGeoShape * GetShape() const
Definition: TGeoVolume.h:204
static const double x1[5]
TGeoHMatrix * GetGLMatrix() const
Definition: TGeoManager.h:484
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:556
Int_t fShapeId
Definition: TGeoShape.h:82
double Double_t
Definition: RtypesCore.h:55
virtual Bool_t IsComposite() const
Definition: TGeoShape.h:140
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
Int_t fColor
Definition: TBuffer3D.h:90
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Definition: TGeoShape.cxx:258
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:697
static Double_t Big()
Definition: TGeoShape.h:98
Int_t AddShape(const TGeoShape *shape)
Add a shape to the list. Returns index of the shape in list.
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:433
#define name(a, b)
Definition: linkTestLib0.cpp:5
static TGeoMatrix * GetTransform()
Returns current transformation matrix that applies to shape.
Definition: TGeoShape.cxx:534
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
Definition: TGeoShape.cxx:522
Mother of all ROOT objects.
Definition: TObject.h:58
virtual void DrawShape(TGeoShape *shape, Option_t *option="")=0
virtual void ExecuteShapeEvent(TGeoShape *shape, Int_t event, Int_t px, Int_t py)=0
Bool_t IsMatrixReflection() const
Definition: TGeoManager.h:391
virtual Double_t GetDensity() const
Definition: TGeoMaterial.h:106
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:189
Double_t Sin(Double_t)
Definition: TMath.h:421
virtual void LocalToMasterBomb(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:387
#define NULL
Definition: Rtypes.h:82
static void NormalPhi(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
Static method to compute normal to phi planes.
Definition: TGeoShape.cxx:436
Short_t fTransparency
Definition: TBuffer3D.h:91
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Stub implementation to avoid forcing implementation at this stage.
Definition: TGeoShape.cxx:687
Char_t GetTransparency() const
Definition: TGeoVolume.h:203
virtual void Paint(Option_t *option="")
Paint this shape.
Definition: TGeoShape.cxx:732
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void Draw(Option_t *option="")
Draw this shape.
Definition: TGeoShape.cxx:719
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void PaintShape(TGeoShape *shape, Option_t *option="")=0
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
TVirtualGeoPainter * GetGeomPainter()
Make a default painter if none present. Returns pointer to it.
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
UInt_t fShapeBits
Definition: TGeoShape.h:83
Double_t GetVisDensity() const
Definition: TGeoManager.h:200
Bool_t SectionsValid(UInt_t mask) const
Definition: TBuffer3D.h:69
static const double x3[11]
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904