Logo ROOT  
Reference Guide
TGeoXtru.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Mihaela Gheata 24/01/04
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 /** \class TGeoXtru
13 \ingroup Geometry_classes
14  An extrusion with fixed outline shape in x-y and a sequence
15 of z extents (segments). The overall scale of the outline scales
16 linearly between z points and the center can have an x-y offset.
17 
18 Based on the initial implementation of R. Hatcher
19 
20 ### Creation of TGeoXtru shape
21 
22 A TGeoXtru represents a polygonal extrusion. It is defined by the:
23 1. 'Blueprint' of the arbitrary polygon representing any Z section. This
24  is an arbitrary polygon (convex or not) defined by the X/Y positions of
25  its vertices.
26 1. A sequence of Z sections ordered on the Z axis. Each section defines the
27  'actual' parameters of the polygon at a given Z. The sections may be
28  translated with respect to the blueprint and/or scaled. The TGeoXtru
29  segment in between 2 Z sections is a solid represented by the linear
30  extrusion between the 2 polygons. Two consecutive sections may be defined
31  at same Z position.
32 
33 1. `TGeoXtru *xtru = TGeoXtru(Int_t nz);`
34 
35  where nz=number of Z planes
36 
37 2. `Double_t x[nvertices]; // array of X positions of blueprint polygon vertices`
38 
39  `Double_t y[nvertices]; // array of Y positions of blueprint polygon vertices`
40 
41 3. `xtru->DefinePolygon(nvertices,x,y);`
42 
43 4. `DefineSection(0, z0, x0, y0, scale0); // Z position, offset and scale for first section`
44 
45  `DefineSection(1, z1, x1, y1, scale1); // -''- second section`
46  `....`
47  `DefineSection(nz-1, zn, xn, yn, scalen); // parameters for last section`
48 
49 #### NOTES
50 Currently navigation functionality not fully implemented (only Contains()).
51 Decomposition in concave polygons not implemented - drawing in solid mode
52 within x3d produces incorrect end-faces
53 */
54 
55 #include "TGeoXtru.h"
56 
57 #include <iostream>
58 
59 #include "TBuffer3D.h"
60 #include "TBuffer3DTypes.h"
61 #include "TMath.h"
62 
63 #include "TVirtualGeoPainter.h"
64 #include "TGeoManager.h"
65 #include "TGeoVolume.h"
66 #include "TGeoPolygon.h"
67 
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Constructor.
72 
74  fSeg(0), fIz(0), fXc(0), fYc(0), fPoly(0)
75 {
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Destructor.
80 
82 {
83  delete [] fXc;
84  delete [] fYc;
85  delete fPoly;
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 
91 {
92  if (!fThreadSize) ((TGeoXtru*)this)->CreateThreadData(1);
94  return *fThreadData[tid];
95 }
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 
100 {
101  std::lock_guard<std::mutex> guard(fMutex);
102  std::vector<ThreadData_t*>::iterator i = fThreadData.begin();
103  while (i != fThreadData.end())
104  {
105  delete *i;
106  ++i;
107  }
108  fThreadData.clear();
109  fThreadSize = 0;
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Create thread data for n threads max.
114 
116 {
117  std::lock_guard<std::mutex> guard(fMutex);
118  fThreadData.resize(nthreads);
119  fThreadSize = nthreads;
120  for (Int_t tid=0; tid<nthreads; tid++) {
121  if (fThreadData[tid] == 0) {
122  fThreadData[tid] = new ThreadData_t;
123  ThreadData_t &td = *fThreadData[tid];
124  td.fXc = new Double_t [fNvert];
125  td.fYc = new Double_t [fNvert];
126  memcpy(td.fXc, fX, fNvert*sizeof(Double_t));
127  memcpy(td.fYc, fY, fNvert*sizeof(Double_t));
128  td.fPoly = new TGeoPolygon(fNvert);
129  td.fPoly->SetXY(td.fXc, td.fYc); // initialize with current coordinates
130  td.fPoly->FinishPolygon();
131  if (tid == 0 && td.fPoly->IsIllegalCheck()) {
132  Error("DefinePolygon", "Shape %s of type XTRU has an illegal polygon.", GetName());
133  }
134  }
135  }
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Set current z-plane.
140 
142 {
143  GetThreadData().fIz = iz;
144 }
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Set current segment.
147 
149 {
150  GetThreadData().fSeg = iseg;
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// dummy ctor
155 
157  :TGeoBBox(),
158  fNvert(0),
159  fNz(0),
160  fZcurrent(0.),
161  fX(0),
162  fY(0),
163  fZ(0),
164  fScale(0),
165  fX0(0),
166  fY0(0),
167  fThreadData(0),
168  fThreadSize(0)
169 {
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Default constructor
175 
177  :TGeoBBox(0, 0, 0),
178  fNvert(0),
179  fNz(nz),
180  fZcurrent(0.),
181  fX(0),
182  fY(0),
183  fZ(new Double_t[nz]),
184  fScale(new Double_t[nz]),
185  fX0(new Double_t[nz]),
186  fY0(new Double_t[nz]),
187  fThreadData(0),
188  fThreadSize(0)
189 {
191  if (nz<2) {
192  Error("ctor", "Cannot create TGeoXtru %s with less than 2 Z planes", GetName());
194  return;
195  }
196 }
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 /// Default constructor in GEANT3 style
200 /// - param[0] = nz // number of z planes
201 ///
202 /// - param[1] = z1 // Z position of first plane
203 /// - param[2] = x1 // X position of first plane
204 /// - param[3] = y1 // Y position of first plane
205 /// - param[4] = scale1 // scale factor for first plane
206 /// ...
207 /// - param[4*(nz-1]+1] = zn
208 /// - param[4*(nz-1)+2] = xn
209 /// - param[4*(nz-1)+3] = yn
210 /// - param[4*(nz-1)+4] = scalen
211 
213  :TGeoBBox(0, 0, 0),
214  fNvert(0),
215  fNz(0),
216  fZcurrent(0.),
217  fX(0),
218  fY(0),
219  fZ(0),
220  fScale(0),
221  fX0(0),
222  fY0(0),
223  fThreadData(0),
224  fThreadSize(0)
225 {
227  SetDimensions(param);
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// destructor
232 
234 {
235  if (fX) {delete[] fX; fX = 0;}
236  if (fY) {delete[] fY; fY = 0;}
237  if (fZ) {delete[] fZ; fZ = 0;}
238  if (fScale) {delete[] fScale; fScale = 0;}
239  if (fX0) {delete[] fX0; fX0 = 0;}
240  if (fY0) {delete[] fY0; fY0 = 0;}
241  ClearThreadData();
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Compute capacity [length^3] of this shape.
246 
248 {
249  ThreadData_t& td = GetThreadData();
250  Int_t iz;
251  Double_t capacity = 0;
252  Double_t area, dz, sc1, sc2;
253  TGeoXtru *xtru = (TGeoXtru*)this;
254  xtru->SetCurrentVertices(0.,0.,1.);
255  area = td.fPoly->Area();
256  for (iz=0; iz<fNz-1; iz++) {
257  dz = fZ[iz+1]-fZ[iz];
258  if (TGeoShape::IsSameWithinTolerance(dz,0)) continue;
259  sc1 = fScale[iz];
260  sc2 = fScale[iz+1];
261  capacity += (area*dz/3.)*(sc1*sc1+sc1*sc2+sc2*sc2);
262  }
263  return capacity;
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 /// compute bounding box of the pcon
268 
270 {
271  ThreadData_t& td = GetThreadData();
272  if (!fX || !fZ || !fNvert) {
273  Error("ComputeBBox", "In shape %s polygon not defined", GetName());
275  return;
276  }
277  Double_t zmin = fZ[0];
278  Double_t zmax = fZ[fNz-1];
283  for (Int_t i=0; i<fNz; i++) {
284  SetCurrentVertices(fX0[i], fY0[i], fScale[i]);
285  for (Int_t j=0; j<fNvert; j++) {
286  if (td.fXc[j]<xmin) xmin=td.fXc[j];
287  if (td.fXc[j]>xmax) xmax=td.fXc[j];
288  if (td.fYc[j]<ymin) ymin=td.fYc[j];
289  if (td.fYc[j]>ymax) ymax=td.fYc[j];
290  }
291  }
292  fOrigin[0] = 0.5*(xmin+xmax);
293  fOrigin[1] = 0.5*(ymin+ymax);
294  fOrigin[2] = 0.5*(zmin+zmax);
295  fDX = 0.5*(xmax-xmin);
296  fDY = 0.5*(ymax-ymin);
297  fDZ = 0.5*(zmax-zmin);
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Compute normal to closest surface from POINT.
302 
303 void TGeoXtru::ComputeNormal(const Double_t * /*point*/, const Double_t *dir, Double_t *norm)
304 {
305  ThreadData_t& td = GetThreadData();
306  if (td.fIz<0) {
307  memset(norm,0,3*sizeof(Double_t));
308  norm[2] = (dir[2]>0)?1:-1;
309  return;
310  }
311  Double_t vert[12];
312  GetPlaneVertices(td.fIz, td.fSeg, vert);
313  GetPlaneNormal(vert, norm);
314  Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
315  if (ndotd<0) {
316  norm[0] = -norm[0];
317  norm[1] = -norm[1];
318  norm[2] = -norm[2];
319  }
320 }
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// test if point is inside this shape
324 
325 Bool_t TGeoXtru::Contains(const Double_t *point) const
326 {
327  ThreadData_t& td = GetThreadData();
328  // Check Z range
329  TGeoXtru *xtru = (TGeoXtru*)this;
330  if (point[2]<fZ[0]) return kFALSE;
331  if (point[2]>fZ[fNz-1]) return kFALSE;
332  Int_t iz = TMath::BinarySearch(fNz, fZ, point[2]);
333  if (iz<0 || iz==fNz-1) return kFALSE;
334  if (TGeoShape::IsSameWithinTolerance(point[2],fZ[iz])) {
335  xtru->SetIz(-1);
336  xtru->SetCurrentVertices(fX0[iz],fY0[iz], fScale[iz]);
337  if (td.fPoly->Contains(point)) return kTRUE;
338  if (iz>1 && TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz-1])) {
339  xtru->SetCurrentVertices(fX0[iz-1],fY0[iz-1], fScale[iz-1]);
340  return td.fPoly->Contains(point);
341  } else if (iz<fNz-2 && TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz+1])) {
342  xtru->SetCurrentVertices(fX0[iz+1],fY0[iz+1], fScale[iz+1]);
343  return td.fPoly->Contains(point);
344  }
345  }
346  xtru->SetCurrentZ(point[2], iz);
347  if (TMath::Abs(point[2]-fZ[iz])<TGeoShape::Tolerance() ||
348  TMath::Abs(fZ[iz+1]-point[2])<TGeoShape::Tolerance()) xtru->SetIz(-1);
349  // Now td.fXc,fYc represent the vertices of the section at point[2]
350  return td.fPoly->Contains(point);
351 }
352 
353 ////////////////////////////////////////////////////////////////////////////////
354 /// compute closest distance from point px,py to each corner
355 
357 {
358  const Int_t numPoints = fNvert*fNz;
359  return ShapeDistancetoPrimitive(numPoints, px, py);
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// Draw the section polygon.
364 
366  {
367  ThreadData_t& td = GetThreadData();
368  if (td.fPoly) td.fPoly->Draw(option);
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Compute distance to a Xtru lateral surface.
373 
374 Double_t TGeoXtru::DistToPlane(const Double_t *point, const Double_t *dir, Int_t iz, Int_t ivert, Double_t stepmax, Bool_t in) const
375 {
376  ThreadData_t& td = GetThreadData();
377  Double_t snext;
378  Double_t vert[12];
379  Double_t norm[3];
380  Double_t znew;
381  Double_t pt[3];
382  Double_t safe;
383  if (TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz+1]) && !in) {
384  TGeoXtru *xtru = (TGeoXtru*)this;
385  snext = (fZ[iz]-point[2])/dir[2];
386  if (snext<0) return TGeoShape::Big();
387  pt[0] = point[0]+snext*dir[0];
388  pt[1] = point[1]+snext*dir[1];
389  pt[2] = point[2]+snext*dir[2];
390  if (dir[2] < 0.) xtru->SetCurrentVertices(fX0[iz], fY0[iz], fScale[iz]);
391  else xtru->SetCurrentVertices(fX0[iz+1], fY0[iz+1], fScale[iz+1]);
392  if (!td.fPoly->Contains(pt)) return TGeoShape::Big();
393  return snext;
394  }
395  GetPlaneVertices(iz, ivert, vert);
396  GetPlaneNormal(vert, norm);
397  Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
398  if (in) {
399  if (ndotd<=0) return TGeoShape::Big();
400  safe = (vert[0]-point[0])*norm[0]+
401  (vert[1]-point[1])*norm[1]+
402  (vert[2]-point[2])*norm[2];
403  if (safe<-1.E-8) return TGeoShape::Big(); // direction outwards plane
404  } else {
405  ndotd = -ndotd;
406  if (ndotd<=0) return TGeoShape::Big();
407  safe = (point[0]-vert[0])*norm[0]+
408  (point[1]-vert[1])*norm[1]+
409  (point[2]-vert[2])*norm[2];
410  if (safe<-1.E-8) return TGeoShape::Big(); // direction outwards plane
411  }
412  snext = safe/ndotd;
413  if (snext>stepmax) return TGeoShape::Big();
414  if (fZ[iz]<fZ[iz+1]) {
415  znew = point[2] + snext*dir[2];
416  if (znew<fZ[iz]) return TGeoShape::Big();
417  if (znew>fZ[iz+1]) return TGeoShape::Big();
418  }
419  pt[0] = point[0]+snext*dir[0];
420  pt[1] = point[1]+snext*dir[1];
421  pt[2] = point[2]+snext*dir[2];
422  if (!IsPointInsidePlane(pt, vert, norm)) return TGeoShape::Big();
423  return TMath::Max(snext, 0.);
424 }
425 
426 ////////////////////////////////////////////////////////////////////////////////
427 /// compute distance from inside point to surface of the polycone
428 /// locate Z segment
429 
430 Double_t TGeoXtru::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
431 {
432  ThreadData_t& td = GetThreadData();
433  if (iact<3 && safe) {
434  *safe = Safety(point, kTRUE);
435  if (iact==0) return TGeoShape::Big();
436  if (iact==1 && step<*safe) return TGeoShape::Big();
437  }
438  TGeoXtru *xtru = (TGeoXtru*)this;
439  Int_t iz = TMath::BinarySearch(fNz, fZ, point[2]);
440  if (iz < 0) {
441  if (dir[2]<=0) {
442  xtru->SetIz(-1);
443  return 0.;
444  }
445  iz = 0;
446  }
447  if (iz==fNz-1) {
448  if (dir[2]>=0) {
449  xtru->SetIz(-1);
450  return 0.;
451  }
452  iz--;
453  } else {
454  if (iz>0) {
455  if (TGeoShape::IsSameWithinTolerance(point[2],fZ[iz])) {
456  if (TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz+1]) && dir[2]<0) iz++;
457  else if (TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz-1]) && dir[2]>0) iz--;
458  }
459  }
460  }
461  Bool_t convex = td.fPoly->IsConvex();
462 // Double_t stepmax = step;
463 // if (stepmax>TGeoShape::Big()) stepmax = TGeoShape::Big();
465  Double_t dist, sz;
466  Double_t pt[3];
467  Int_t iv, ipl, inext;
468  // we treat the special case when dir[2]=0
469  if (TGeoShape::IsSameWithinTolerance(dir[2],0)) {
470  for (iv=0; iv<fNvert; iv++) {
471  xtru->SetIz(-1);
472  dist = DistToPlane(point,dir,iz,iv,TGeoShape::Big(),kTRUE);
473  if (dist<snext) {
474  snext = dist;
475  xtru->SetSeg(iv);
476  if (convex) return snext;
477  }
478  }
479  if (snext < 1.E10) return snext;
480  return TGeoShape::Tolerance();
481  }
482 
483  // normal case
484  Int_t incseg = (dir[2]>0)?1:-1;
485  Int_t iznext = iz;
486  Bool_t zexit = kFALSE;
487  while (iz>=0 && iz<fNz-1) {
488  // find the distance to current segment end Z surface
489  ipl = iz+((incseg+1)>>1); // next plane
490  inext = ipl+incseg; // next next plane
491  sz = (fZ[ipl]-point[2])/dir[2];
492  if (sz<snext) {
493  iznext += incseg;
494  // we cross the next Z section before stepmax
495  pt[0] = point[0]+sz*dir[0];
496  pt[1] = point[1]+sz*dir[1];
497  xtru->SetCurrentVertices(fX0[ipl],fY0[ipl],fScale[ipl]);
498  if (td.fPoly->Contains(pt)) {
499  // ray gets through next polygon - is it the last one?
500  if (ipl==0 || ipl==fNz-1) {
501  xtru->SetIz(-1);
502  if (convex) return sz;
503  zexit = kTRUE;
504  snext = sz;
505  }
506  // maybe a Z discontinuity - check this
507  if (!zexit && TGeoShape::IsSameWithinTolerance(fZ[ipl],fZ[inext])) {
508  xtru->SetCurrentVertices(fX0[inext],fY0[inext],fScale[inext]);
509  // if we do not cross the next polygone, we are out
510  if (!td.fPoly->Contains(pt)) {
511  xtru->SetIz(-1);
512  if (convex) return sz;
513  zexit = kTRUE;
514  snext = sz;
515  } else {
516  iznext = inext;
517  }
518  }
519  }
520  } else {
521  iznext = fNz-1; // stop
522  }
523  // ray may cross the lateral surfaces of section iz
524  for (iv=0; iv<fNvert; iv++) {
525  dist = DistToPlane(point,dir,iz,iv,TGeoShape::Big(),kTRUE);
526  if (dist<snext) {
527  xtru->SetIz(iz);
528  xtru->SetSeg(iv);
529  snext = dist;
530  if (convex) return snext;
531  zexit = kTRUE;
532  }
533  }
534  if (zexit) return snext;
535  iz = iznext;
536  }
537  return TGeoShape::Tolerance();
538 }
539 
540 ////////////////////////////////////////////////////////////////////////////////
541 /// compute distance from outside point to surface of the tube
542 /// Warning("DistFromOutside", "not implemented");
543 
544 Double_t TGeoXtru::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
545 {
546  ThreadData_t& td = GetThreadData();
547  if (iact<3 && safe) {
548  *safe = Safety(point, kTRUE);
549  if (iact==0) return TGeoShape::Big();
550  if (iact==1 && step<*safe) return TGeoShape::Big();
551  }
552 // Check if the bounding box is crossed within the requested distance
553  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
554  if (sdist>=step) return TGeoShape::Big();
555  Double_t stepmax = step;
556  if (stepmax>TGeoShape::Big()) stepmax = TGeoShape::Big();
557  Double_t snext = 0.;
558  Int_t i, iv;
559  Double_t pt[3];
560  memcpy(pt,point,3*sizeof(Double_t));
561  TGeoXtru *xtru = (TGeoXtru*)this;
562  // We might get out easy with Z checks
563  Int_t iz = TMath::BinarySearch(fNz, fZ, point[2]);
564  if (iz<0) {
565  if (dir[2]<=0) return TGeoShape::Big();
566  // propagate to first Z plane
567  snext = (fZ[0] - point[2])/dir[2];
568  if (snext>stepmax) return TGeoShape::Big();
569  for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
570  xtru->SetCurrentVertices(fX0[0],fY0[0],fScale[0]);
571  if (td.fPoly->Contains(pt)) {
572  xtru->SetIz(-1);
573  return snext;
574  }
575  iz=0; // valid starting value = first segment
576  stepmax -= snext;
577  } else {
578  if (iz==fNz-1) {
579  if (dir[2]>=0) return TGeoShape::Big();
580  // propagate to last Z plane
581  snext = (fZ[fNz-1] - point[2])/dir[2];
582  if (snext>stepmax) return TGeoShape::Big();
583  for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
584  xtru->SetCurrentVertices(fX0[fNz-1],fY0[fNz-1],fScale[fNz-1]);
585  if (td.fPoly->Contains(pt)) {
586  xtru->SetIz(-1);
587  return snext;
588  }
589  iz = fNz-2; // valid value = last segment
590  stepmax -= snext;
591  }
592  }
593  // Check if the bounding box is missed by the track
594  if (!TGeoBBox::Contains(pt)) {
596  if (dist>stepmax) return TGeoShape::Big();
597  if (dist>1E-6) dist-=1E-6; // decrease snext to make sure we do not cross the xtru
598  else dist = 0;
599  for (i=0; i<3; i++) pt[i] += dist*dir[i]; // we are now closer
600  iz = TMath::BinarySearch(fNz, fZ, pt[2]);
601  if (iz<0) iz=0;
602  else if (iz==fNz-1) iz = fNz-2;
603  snext += dist;
604  stepmax -= dist;
605  }
606  // not the case - we have to do some work...
607  // Start tracking from current iz
608  // - first solve particular case dir[2]=0
609  Bool_t convex = td.fPoly->IsConvex();
610  Bool_t hit = kFALSE;
611  if (TGeoShape::IsSameWithinTolerance(dir[2],0)) {
612  // loop lateral planes to see if we cross something
613  xtru->SetIz(iz);
614  for (iv=0; iv<fNvert; iv++) {
615  Double_t dist = DistToPlane(pt,dir,iz,iv,stepmax,kFALSE);
616  if (dist<stepmax) {
617  xtru->SetSeg(iv);
618  if (convex) return (snext+dist);
619  stepmax = dist;
620  hit = kTRUE;
621  }
622  }
623  if (hit) return (snext+stepmax);
624  return TGeoShape::Big();
625  }
626  // general case
627  Int_t incseg = (dir[2]>0)?1:-1;
628  while (iz>=0 && iz<fNz-1) {
629  // compute distance to lateral planes
630  xtru->SetIz(iz);
631  if (TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz+1])) xtru->SetIz(-1);
632  for (iv=0; iv<fNvert; iv++) {
633  Double_t dist = DistToPlane(pt,dir,iz,iv,stepmax,kFALSE);
634  if (dist<stepmax) {
635  // HIT
636  xtru->SetSeg(iv);
637  if (convex) return (snext+dist);
638  stepmax = dist;
639  hit = kTRUE;
640  }
641  }
642  if (hit) return (snext+stepmax);
643  iz += incseg;
644  }
645  return TGeoShape::Big();
646 }
647 
648 ////////////////////////////////////////////////////////////////////////////////
649 /// Creates the polygon representing the blueprint of any Xtru section.
650 /// - nvert = number of vertices >2
651 /// - xv[nvert] = array of X vertex positions
652 /// - yv[nvert] = array of Y vertex positions
653 ///
654 /// *NOTE* should be called before DefineSection or ctor with 'param'
655 
657 {
658  if (nvert<3) {
659  Error("DefinePolygon","In shape %s cannot create polygon with less than 3 vertices", GetName());
661  return kFALSE;
662  }
663  for (Int_t i=0; i<nvert-1; i++) {
664  for (Int_t j=i+1; j<nvert; j++) {
665  if (TMath::Abs(xv[i]-xv[j])<TGeoShape::Tolerance() &&
666  TMath::Abs(yv[i]-yv[j])<TGeoShape::Tolerance()) {
667  Error("DefinePolygon","In shape %s 2 vertices cannot be identical",GetName());
669 // return kFALSE;
670  }
671  }
672  }
673  fNvert = nvert;
674  if (fX) delete [] fX;
675  fX = new Double_t[nvert];
676  if (fY) delete [] fY;
677  fY = new Double_t[nvert];
678  memcpy(fX,xv,nvert*sizeof(Double_t));
679  memcpy(fY,yv,nvert*sizeof(Double_t));
680 
681  ClearThreadData();
682 
683  return kTRUE;
684 }
685 
686 ////////////////////////////////////////////////////////////////////////////////
687 /// defines z position of a section plane, rmin and rmax at this z.
688 
690 {
691  if ((snum<0) || (snum>=fNz)) return;
692  fZ[snum] = z;
693  fX0[snum] = x0;
694  fY0[snum] = y0;
695  fScale[snum] = scale;
696  if (snum) {
697  if (fZ[snum]<fZ[snum-1]) {
698  Warning("DefineSection", "In shape: %s, Z position of section "
699  "%i, z=%e, not in increasing order, %i, z=%e",
700  GetName(),snum,fZ[snum],snum-1,fZ[snum-1]);
701  return;
702  }
703  }
704  if (snum==(fNz-1)) {
705  ComputeBBox();
707  }
708 }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Return the Z coordinate for segment ipl.
712 
714 {
715  if (ipl<0 || ipl>(fNz-1)) {
716  Error("GetZ","In shape %s, ipl=%i out of range (0,%i)",GetName(),ipl,fNz-1);
717  return 0.;
718  }
719  return fZ[ipl];
720 }
721 ////////////////////////////////////////////////////////////////////////////////
722 /// Returns normal vector to the planar quadrilateral defined by vector VERT.
723 /// The normal points outwards the xtru.
724 
725 void TGeoXtru::GetPlaneNormal(const Double_t *vert, Double_t *norm) const
726 {
727  Double_t cross = 0.;
728  Double_t v1[3], v2[3];
729  v1[0] = vert[9]-vert[0];
730  v1[1] = vert[10]-vert[1];
731  v1[2] = vert[11]-vert[2];
732  v2[0] = vert[3]-vert[0];
733  v2[1] = vert[4]-vert[1];
734  v2[2] = vert[5]-vert[2];
735  norm[0] = v1[1]*v2[2]-v1[2]*v2[1];
736  cross += norm[0]*norm[0];
737  norm[1] = v1[2]*v2[0]-v1[0]*v2[2];
738  cross += norm[1]*norm[1];
739  norm[2] = v1[0]*v2[1]-v1[1]*v2[0];
740  cross += norm[2]*norm[2];
741  if (cross < TGeoShape::Tolerance()) return;
742  cross = 1./TMath::Sqrt(cross);
743  for (Int_t i=0; i<3; i++) norm[i] *= cross;
744 }
745 
746 ////////////////////////////////////////////////////////////////////////////////
747 /// Returns (x,y,z) of 3 vertices of the surface defined by Z sections (iz, iz+1)
748 /// and polygon vertices (ivert, ivert+1). No range check.
749 
750 void TGeoXtru::GetPlaneVertices(Int_t iz, Int_t ivert, Double_t *vert) const
751 {
752  ThreadData_t& td = GetThreadData();
753  Double_t x,y,z1,z2;
754  Int_t iv1 = (ivert+1)%fNvert;
755  Int_t icrt = 0;
756  z1 = fZ[iz];
757  z2 = fZ[iz+1];
758  if (td.fPoly->IsClockwise()) {
759  x = fX[ivert]*fScale[iz]+fX0[iz];
760  y = fY[ivert]*fScale[iz]+fY0[iz];
761  vert[icrt++] = x;
762  vert[icrt++] = y;
763  vert[icrt++] = z1;
764  x = fX[iv1]*fScale[iz]+fX0[iz];
765  y = fY[iv1]*fScale[iz]+fY0[iz];
766  vert[icrt++] = x;
767  vert[icrt++] = y;
768  vert[icrt++] = z1;
769  x = fX[iv1]*fScale[iz+1]+fX0[iz+1];
770  y = fY[iv1]*fScale[iz+1]+fY0[iz+1];
771  vert[icrt++] = x;
772  vert[icrt++] = y;
773  vert[icrt++] = z2;
774  x = fX[ivert]*fScale[iz+1]+fX0[iz+1];
775  y = fY[ivert]*fScale[iz+1]+fY0[iz+1];
776  vert[icrt++] = x;
777  vert[icrt++] = y;
778  vert[icrt++] = z2;
779  } else {
780  x = fX[iv1]*fScale[iz]+fX0[iz];
781  y = fY[iv1]*fScale[iz]+fY0[iz];
782  vert[icrt++] = x;
783  vert[icrt++] = y;
784  vert[icrt++] = z1;
785  x = fX[ivert]*fScale[iz]+fX0[iz];
786  y = fY[ivert]*fScale[iz]+fY0[iz];
787  vert[icrt++] = x;
788  vert[icrt++] = y;
789  vert[icrt++] = z1;
790  x = fX[ivert]*fScale[iz+1]+fX0[iz+1];
791  y = fY[ivert]*fScale[iz+1]+fY0[iz+1];
792  vert[icrt++] = x;
793  vert[icrt++] = y;
794  vert[icrt++] = z2;
795  x = fX[iv1]*fScale[iz+1]+fX0[iz+1];
796  y = fY[iv1]*fScale[iz+1]+fY0[iz+1];
797  vert[icrt++] = x;
798  vert[icrt++] = y;
799  vert[icrt++] = z2;
800  }
801 }
802 ////////////////////////////////////////////////////////////////////////////////
803 /// Check if the quadrilateral defined by VERT contains a coplanar POINT.
804 
806 {
807  Double_t v1[3], v2[3];
808  Double_t cross;
809  Int_t j,k;
810  for (Int_t i=0; i<4; i++) { // loop vertices
811  j = 3*i;
812  k = 3*((i+1)%4);
813  v1[0] = point[0]-vert[j];
814  v1[1] = point[1]-vert[j+1];
815  v1[2] = point[2]-vert[j+2];
816  v2[0] = vert[k]-vert[j];
817  v2[1] = vert[k+1]-vert[j+1];
818  v2[2] = vert[k+2]-vert[j+2];
819  cross = (v1[1]*v2[2]-v1[2]*v2[1])*norm[0]+
820  (v1[2]*v2[0]-v1[0]*v2[2])*norm[1]+
821  (v1[0]*v2[1]-v1[1]*v2[0])*norm[2];
822  if (cross<0) return kFALSE;
823  }
824  return kTRUE;
825 }
826 
827 ////////////////////////////////////////////////////////////////////////////////
828 /// Print actual Xtru parameters.
829 
831 {
832  printf("*** Shape %s: TGeoXtru ***\n", GetName());
833  printf(" Nz = %i\n", fNz);
834  printf(" List of (x,y) of polygon vertices:\n");
835  for (Int_t ivert = 0; ivert<fNvert; ivert++)
836  printf(" x = %11.5f y = %11.5f\n", fX[ivert],fY[ivert]);
837  for (Int_t ipl=0; ipl<fNz; ipl++)
838  printf(" plane %i: z=%11.5f x0=%11.5f y0=%11.5f scale=%11.5f\n", ipl, fZ[ipl], fX0[ipl], fY0[ipl], fScale[ipl]);
839  printf(" Bounding box:\n");
841 }
842 
843 ////////////////////////////////////////////////////////////////////////////////
844 /// Creates a TBuffer3D describing *this* shape.
845 /// Coordinates are in local reference frame.
846 
848 {
849  Int_t nz = GetNz();
850  Int_t nvert = GetNvert();
851  Int_t nbPnts = nz*nvert;
852  Int_t nbSegs = nvert*(2*nz-1);
853  Int_t nbPols = nvert*(nz-1)+2;
854 
856  nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert));
857  if (buff)
858  {
859  SetPoints(buff->fPnts);
860  SetSegsAndPols(*buff);
861  }
862 
863  return buff;
864 }
865 
866 ////////////////////////////////////////////////////////////////////////////////
867 /// Fill TBuffer3D structure for segments and polygons.
868 
870 {
871  Int_t nz = GetNz();
872  Int_t nvert = GetNvert();
873  Int_t c = GetBasicColor();
874 
875  Int_t i,j;
876  Int_t indx = 0, indx2, k;
877  for (i=0; i<nz; i++) {
878  // loop Z planes
879  indx2 = i*nvert;
880  // loop polygon segments
881  for (j=0; j<nvert; j++) {
882  k = (j+1)%nvert;
883  buff.fSegs[indx++] = c;
884  buff.fSegs[indx++] = indx2+j;
885  buff.fSegs[indx++] = indx2+k;
886  }
887  } // total: nz*nvert polygon segments
888  for (i=0; i<nz-1; i++) {
889  // loop Z planes
890  indx2 = i*nvert;
891  // loop polygon segments
892  for (j=0; j<nvert; j++) {
893  k = j + nvert;
894  buff.fSegs[indx++] = c;
895  buff.fSegs[indx++] = indx2+j;
896  buff.fSegs[indx++] = indx2+k;
897  }
898  } // total (nz-1)*nvert lateral segments
899 
900  indx = 0;
901 
902  // fill lateral polygons
903  for (i=0; i<nz-1; i++) {
904  indx2 = i*nvert;
905  for (j=0; j<nvert; j++) {
906  k = (j+1)%nvert;
907  buff.fPols[indx++] = c+j%3;
908  buff.fPols[indx++] = 4;
909  buff.fPols[indx++] = indx2+j;
910  buff.fPols[indx++] = nz*nvert+indx2+k;
911  buff.fPols[indx++] = indx2+nvert+j;
912  buff.fPols[indx++] = nz*nvert+indx2+j;
913  }
914  } // total (nz-1)*nvert polys
915  buff.fPols[indx++] = c+2;
916  buff.fPols[indx++] = nvert;
917  indx2 = 0;
918  for (j = nvert - 1; j >= 0; --j) {
919  buff.fPols[indx++] = indx2+j;
920  }
921 
922  buff.fPols[indx++] = c;
923  buff.fPols[indx++] = nvert;
924  indx2 = (nz-1)*nvert;
925 
926  for (j=0; j<nvert; j++) {
927  buff.fPols[indx++] = indx2+j;
928  }
929 }
930 
931 ////////////////////////////////////////////////////////////////////////////////
932 /// Compute safety to sector iz, returning also the closest segment index.
933 
935 {
936  ThreadData_t& td = GetThreadData();
937  Double_t saf1, saf2, safz, safe;
938  Bool_t in1, in2;
939  Int_t iseg;
940  // segment-break case
941  if (TGeoShape::IsSameWithinTolerance(fZ[iz],fZ[iz+1])) {
942  safz = TMath::Abs(point[2]-fZ[iz]);
943  if (safz>safmin) return TGeoShape::Big();
944  SetCurrentVertices(fX0[iz], fY0[iz], fScale[iz]);
945  saf1 = td.fPoly->Safety(point, iseg);
946  in1 = td.fPoly->Contains(point);
947 // if (!in1 && saf1>safmin) return TGeoShape::Big();
948  SetCurrentVertices(fX0[iz+1], fY0[iz+1], fScale[iz+1]);
949  saf2 = td.fPoly->Safety(point, iseg);
950  in2 = td.fPoly->Contains(point);
951  if ((in1&!in2)|(in2&!in1)) {
952  safe = safz;
953  } else {
954  safe = TMath::Min(saf1,saf2);
955  safe = TMath::Max(safe, safz);
956  }
957  if (safe>safmin) return TGeoShape::Big();
958  return safe;
959  }
960  // normal case
961  safz = fZ[iz]-point[2];
962  if (safz>safmin) return TGeoShape::Big();
963  if (safz<0) {
964  saf1 = point[2]-fZ[iz+1];
965  if (saf1>safmin) return TGeoShape::Big();
966  if (saf1<0) {
967  safz = TMath::Max(safz, saf1); // we are in between the 2 Z segments - we ignore safz
968  } else {
969  safz = saf1;
970  }
971  }
972 
973  // loop segments
974  Bool_t found = kFALSE;
975  Double_t vert[12];
976  Double_t norm[3];
977 // printf("plane %d: safz=%f in=%d\n", iz, safz, in);
978  for (iseg=0; iseg<fNvert; iseg++) {
979  GetPlaneVertices(iz,iseg,vert);
980  GetPlaneNormal(vert, norm);
981  saf1 = (point[0]-vert[0])*norm[0]+(point[1]-vert[1])*norm[1]+(point[2]-vert[2])*norm[2];
982  if (in) saf1 = -saf1;
983 // printf("segment %d: (%f,%f)-(%f,%f) norm=(%f,%f,%f): saf1=%f\n", iseg, vert[0],vert[1],vert[3],vert[4],norm[0],norm[1],norm[2],saf1);
984  if (saf1<-1.E-8) continue;
985  safe = TMath::Max(safz, saf1);
986  safe = TMath::Abs(safe);
987  if (safe>safmin) continue;
988  safmin = safe;
989  found = kTRUE;
990  }
991  if (found) return safmin;
992  return TGeoShape::Big();
993 }
994 
995 ////////////////////////////////////////////////////////////////////////////////
996 /// computes the closest distance from given point to this shape, according
997 /// to option. The matching point on the shape is stored in spoint.
998 ///> localize the Z segment
999 
1000 Double_t TGeoXtru::Safety(const Double_t *point, Bool_t in) const
1001 {
1002  Double_t safmin = TGeoShape::Big();
1003  Double_t safe;
1004  Double_t safz = TGeoShape::Big();
1005  TGeoXtru *xtru = (TGeoXtru*)this;
1006  Int_t iz;
1007  if (in) {
1008  safmin = TMath::Min(point[2]-fZ[0], fZ[fNz-1]-point[2]);
1009  for (iz=0; iz<fNz-1; iz++) {
1010  safe = xtru->SafetyToSector(point, iz, safmin, in);
1011  if (safe<safmin) safmin = safe;
1012  }
1013  return safmin;
1014  }
1015  // Accurate safety is expensive, use the bounding box
1016  if (!TGeoBBox::Contains(point)) return TGeoBBox::Safety(point,in);
1017  iz = TMath::BinarySearch(fNz, fZ, point[2]);
1018  if (iz<0) {
1019  iz = 0;
1020  safz = fZ[0] - point[2];
1021  } else {
1022  if (iz==fNz-1) {
1023  iz = fNz-2;
1024  safz = point[2] - fZ[fNz-1];
1025  }
1026  }
1027  // loop segments from iz up
1028  Int_t i;
1029  for (i=iz; i<fNz-1; i++) {
1030  safe = xtru->SafetyToSector(point,i,safmin, in);
1031  if (safe<safmin) safmin=safe;
1032  }
1033  // loop segments from iz-1 down
1034  for (i=iz-1; i>=0; i--) {
1035  safe = xtru->SafetyToSector(point,i,safmin, in);
1036  if (safe<safmin) safmin=safe;
1037  }
1038  safe = TMath::Min(safmin, safz);
1039  return safe;
1040 }
1041 
1042 ////////////////////////////////////////////////////////////////////////////////
1043 /// Save a primitive as a C++ statement(s) on output stream "out".
1044 
1045 void TGeoXtru::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1046 {
1047  if (TObject::TestBit(kGeoSavePrimitive)) return;
1048  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1049  out << " nz = " << fNz << ";" << std::endl;
1050  out << " nvert = " << fNvert << ";" << std::endl;
1051  out << " TGeoXtru *xtru = new TGeoXtru(nz);" << std::endl;
1052  out << " xtru->SetName(\"" << GetName() << "\");" << std::endl;
1053  Int_t i;
1054  for (i=0; i<fNvert; i++) {
1055  out << " xvert[" << i << "] = " << fX[i] << "; yvert[" << i << "] = " << fY[i] << ";" << std::endl;
1056  }
1057  out << " xtru->DefinePolygon(nvert,xvert,yvert);" << std::endl;
1058  for (i=0; i<fNz; i++) {
1059  out << " zsect = " << fZ[i] << ";" << std::endl;
1060  out << " x0 = " << fX0[i] << ";" << std::endl;
1061  out << " y0 = " << fY0[i] << ";" << std::endl;
1062  out << " scale0 = " << fScale[i] << ";" << std::endl;
1063  out << " xtru->DefineSection(" << i << ",zsect,x0,y0,scale0);" << std::endl;
1064  }
1065  out << " TGeoShape *" << GetPointerName() << " = xtru;" << std::endl;
1067 }
1068 
1069 ////////////////////////////////////////////////////////////////////////////////
1070 /// Recompute current section vertices for a given Z position within range of section iz.
1071 
1073 {
1074  Double_t x0, y0, scale, a, b;
1075  Int_t ind1, ind2;
1076  ind1 = iz;
1077  ind2 = iz+1;
1078  Double_t invdz = 1./(fZ[ind2]-fZ[ind1]);
1079  a = (fX0[ind1]*fZ[ind2]-fX0[ind2]*fZ[ind1])*invdz;
1080  b = (fX0[ind2]-fX0[ind1])*invdz;
1081  x0 = a+b*z;
1082  a = (fY0[ind1]*fZ[ind2]-fY0[ind2]*fZ[ind1])*invdz;
1083  b = (fY0[ind2]-fY0[ind1])*invdz;
1084  y0 = a+b*z;
1085  a = (fScale[ind1]*fZ[ind2]-fScale[ind2]*fZ[ind1])*invdz;
1086  b = (fScale[ind2]-fScale[ind1])*invdz;
1087  scale = a+b*z;
1088  SetCurrentVertices(x0,y0,scale);
1089 }
1090 
1091 ////////////////////////////////////////////////////////////////////////////////
1092 /// Set current vertex coordinates according X0, Y0 and SCALE.
1093 
1095 {
1096  ThreadData_t& td = GetThreadData();
1097  for (Int_t i=0; i<fNvert; i++) {
1098  td.fXc[i] = scale*fX[i] + x0;
1099  td.fYc[i] = scale*fY[i] + y0;
1100  }
1101 }
1102 
1103 ////////////////////////////////////////////////////////////////////////////////
1104 /// - param[0] = nz // number of z planes
1105 ///
1106 /// - param[1] = z1 // Z position of first plane
1107 /// - param[2] = x1 // X position of first plane
1108 /// - param[3] = y1 // Y position of first plane
1109 /// - param[4] = scale1 // scale factor for first plane
1110 /// ...
1111 /// - param[4*(nz-1]+1] = zn
1112 /// - param[4*(nz-1)+2] = xn
1113 /// - param[4*(nz-1)+3] = yn
1114 /// - param[4*(nz-1)+4] = scalen
1115 
1117 {
1118  fNz = (Int_t)param[0];
1119  if (fNz<2) {
1120  Error("SetDimensions","Cannot create TGeoXtru %s with less than 2 Z planes",GetName());
1122  return;
1123  }
1124  if (fZ) delete [] fZ;
1125  if (fScale) delete [] fScale;
1126  if (fX0) delete [] fX0;
1127  if (fY0) delete [] fY0;
1128  fZ = new Double_t[fNz];
1129  fScale = new Double_t[fNz];
1130  fX0 = new Double_t[fNz];
1131  fY0 = new Double_t[fNz];
1132 
1133  for (Int_t i=0; i<fNz; i++)
1134  DefineSection(i, param[1+4*i], param[2+4*i], param[3+4*i], param[4+4*i]);
1135 }
1136 
1137 ////////////////////////////////////////////////////////////////////////////////
1138 /// create polycone mesh points
1139 
1141 {
1142  ThreadData_t& td = GetThreadData();
1143  Int_t i, j;
1144  Int_t indx = 0;
1145  TGeoXtru *xtru = (TGeoXtru*)this;
1146  if (points) {
1147  for (i = 0; i < fNz; i++) {
1148  xtru->SetCurrentVertices(fX0[i], fY0[i], fScale[i]);
1149  if (td.fPoly->IsClockwise()) {
1150  for (j = 0; j < fNvert; j++) {
1151  points[indx++] = td.fXc[j];
1152  points[indx++] = td.fYc[j];
1153  points[indx++] = fZ[i];
1154  }
1155  } else {
1156  for (j = 0; j < fNvert; j++) {
1157  points[indx++] = td.fXc[fNvert-1-j];
1158  points[indx++] = td.fYc[fNvert-1-j];
1159  points[indx++] = fZ[i];
1160  }
1161  }
1162  }
1163  }
1164 }
1165 
1166 ////////////////////////////////////////////////////////////////////////////////
1167 /// create polycone mesh points
1168 
1170 {
1171  ThreadData_t& td = GetThreadData();
1172  Int_t i, j;
1173  Int_t indx = 0;
1174  TGeoXtru *xtru = (TGeoXtru*)this;
1175  if (points) {
1176  for (i = 0; i < fNz; i++) {
1177  xtru->SetCurrentVertices(fX0[i], fY0[i], fScale[i]);
1178  if (td.fPoly->IsClockwise()) {
1179  for (j = 0; j < fNvert; j++) {
1180  points[indx++] = td.fXc[j];
1181  points[indx++] = td.fYc[j];
1182  points[indx++] = fZ[i];
1183  }
1184  } else {
1185  for (j = 0; j < fNvert; j++) {
1186  points[indx++] = td.fXc[fNvert-1-j];
1187  points[indx++] = td.fYc[fNvert-1-j];
1188  points[indx++] = fZ[i];
1189  }
1190  }
1191  }
1192  }
1193 }
1194 
1195 ////////////////////////////////////////////////////////////////////////////////
1196 /// Returns numbers of vertices, segments and polygons composing the shape mesh.
1197 
1198 void TGeoXtru::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
1199 {
1200  Int_t nz = GetNz();
1201  Int_t nv = GetNvert();
1202  nvert = nz*nv;
1203  nsegs = nv*(2*nz-1);
1204  npols = nv*(nz-1)+2;
1205 }
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Return number of vertices of the mesh representation
1209 
1211 {
1212  Int_t numPoints = fNz*fNvert;
1213  return numPoints;
1214 }
1215 
1216 ////////////////////////////////////////////////////////////////////////////////
1217 /// fill size of this 3-D object
1218 
1220 {
1221 }
1222 
1223 ////////////////////////////////////////////////////////////////////////////////
1224 /// Fills a static 3D buffer and returns a reference.
1225 
1226 const TBuffer3D & TGeoXtru::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
1227 {
1228  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
1229 
1230  TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
1231 
1232  if (reqSections & TBuffer3D::kRawSizes) {
1233  Int_t nz = GetNz();
1234  Int_t nvert = GetNvert();
1235  Int_t nbPnts = nz*nvert;
1236  Int_t nbSegs = nvert*(2*nz-1);
1237  Int_t nbPols = nvert*(nz-1)+2;
1238  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert))) {
1240  }
1241  }
1242  // TODO: Push down to TGeoShape?
1243  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
1244  SetPoints(buffer.fPnts);
1245  if (!buffer.fLocalFrame) {
1246  TransformPoints(buffer.fPnts, buffer.NbPnts());
1247  }
1248 
1249  SetSegsAndPols(buffer);
1251  }
1252 
1253  return buffer;
1254 }
1255 
1256 ////////////////////////////////////////////////////////////////////////////////
1257 /// Check the inside status for each of the points in the array.
1258 /// Input: Array of point coordinates + vector size
1259 /// Output: Array of Booleans for the inside of each point
1260 
1261 void TGeoXtru::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
1262 {
1263  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
1264 }
1265 
1266 ////////////////////////////////////////////////////////////////////////////////
1267 /// Compute the normal for an array o points so that norm.dot.dir is positive
1268 /// Input: Arrays of point coordinates and directions + vector size
1269 /// Output: Array of normal directions
1270 
1271 void TGeoXtru::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
1272 {
1273  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1274 }
1275 
1276 ////////////////////////////////////////////////////////////////////////////////
1277 /// Compute distance from array of input points having directions specified by dirs. Store output in dists
1278 
1279 void TGeoXtru::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1280 {
1281  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1282 }
1283 
1284 ////////////////////////////////////////////////////////////////////////////////
1285 /// Compute distance from array of input points having directions specified by dirs. Store output in dists
1286 
1287 void TGeoXtru::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1288 {
1289  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1290 }
1291 
1292 ////////////////////////////////////////////////////////////////////////////////
1293 /// Compute safe distance from each of the points in the input array.
1294 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1295 /// Output: Safety values
1296 
1297 void TGeoXtru::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
1298 {
1299  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1300 }
c
#define c(i)
Definition: RSha256.hxx:101
TGeoBBox::Safety
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
Definition: TGeoBBox.cxx:852
TGeoXtru::Capacity
virtual Double_t Capacity() const
Compute capacity [length^3] of this shape.
Definition: TGeoXtru.cxx:247
ymax
float ymax
Definition: THbookFile.cxx:95
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:100
TObject::TestBit
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
TBuffer3D::SectionsValid
Bool_t SectionsValid(UInt_t mask) const
Definition: TBuffer3D.h:67
TGeoXtru::SetIz
void SetIz(Int_t iz)
Set current z-plane.
Definition: TGeoXtru.cxx:141
TGeoManager::ThreadId
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Definition: TGeoManager.cxx:905
TGeoShape::kGeoXtru
@ kGeoXtru
Definition: TGeoShape.h:61
Option_t
const char Option_t
Definition: RtypesCore.h:66
TBuffer3D::SetSectionsValid
void SetSectionsValid(UInt_t mask)
Definition: TBuffer3D.h:65
TMath::Max
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
TGeoXtru::fY0
Double_t * fY0
Definition: TGeoXtru.h:50
TGeoPolygon::Contains
Bool_t Contains(const Double_t *point) const
Check if a point given by X = point[0], Y = point[1] is inside the polygon.
Definition: TGeoPolygon.cxx:130
TGeoXtru::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoXtru.cxx:1045
TGeoXtru
An extrusion with fixed outline shape in x-y and a sequence of z extents (segments).
Definition: TGeoXtru.h:23
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TGeoXtru::ThreadData_t::fPoly
TGeoPolygon * fPoly
Definition: TGeoXtru.h:31
xmax
float xmax
Definition: THbookFile.cxx:95
TGeoXtru::SetDimensions
virtual void SetDimensions(Double_t *param)
Definition: TGeoXtru.cxx:1116
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
TGeoXtru::fMutex
std::mutex fMutex
size of thread-specific array
Definition: TGeoXtru.h:54
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
TGeoXtru::fNz
Int_t fNz
Definition: TGeoXtru.h:43
TGeoBBox::fOrigin
Double_t fOrigin[3]
Definition: TGeoBBox.h:24
TGeoPolygon::IsConvex
Bool_t IsConvex() const
Definition: TGeoPolygon.h:62
Float_t
float Float_t
Definition: RtypesCore.h:57
TGeoPolygon::Safety
Double_t Safety(const Double_t *point, Int_t &isegment) const
Compute minimum distance from POINT to any segment. Returns segment index.
Definition: TGeoPolygon.cxx:357
TGeoShape::TransformPoints
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
Definition: TGeoShape.cxx:552
TGeoXtru::ThreadData_t::~ThreadData_t
~ThreadData_t()
Destructor.
Definition: TGeoXtru.cxx:81
Int_t
int Int_t
Definition: RtypesCore.h:45
TGeoVolume.h
x
Double_t x[n]
Definition: legend1.C:17
TBuffer3D::NbPnts
UInt_t NbPnts() const
Definition: TBuffer3D.h:80
TGeoShape::SetShapeBit
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
Definition: TGeoShape.cxx:524
TBuffer3D::SetRawSizes
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
Definition: TBuffer3D.cxx:359
TGeoXtru::ComputeNormal
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Definition: TGeoXtru.cxx:303
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TGeoShape::GetBasicColor
Int_t GetBasicColor() const
Get the basic color (0-7).
Definition: TGeoShape.cxx:673
TBuffer3D::fSegs
Int_t * fSegs
Definition: TBuffer3D.h:113
TGeoXtru::ComputeNormal_v
virtual void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
Definition: TGeoXtru.cxx:1271
TGeoXtru::fThreadData
std::vector< ThreadData_t * > fThreadData
Definition: TGeoXtru.h:52
TGeoXtru::~TGeoXtru
virtual ~TGeoXtru()
destructor
Definition: TGeoXtru.cxx:233
b
#define b(i)
Definition: RSha256.hxx:100
bool
TGeoShape::TestShapeBit
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:163
TGeoXtru::DistFromInside_v
virtual void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Definition: TGeoXtru.cxx:1279
TGeoPolygon::IsIllegalCheck
Bool_t IsIllegalCheck() const
Check for illegal crossings between non-consecutive segments.
Definition: TGeoPolygon.cxx:278
TGeoXtru::CreateThreadData
virtual void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
Definition: TGeoXtru.cxx:115
ROOT::Math::gv_detail::dist
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
TGeoXtru::DefinePolygon
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.
Definition: TGeoXtru.cxx:656
TGeoXtru::GetPlaneNormal
void GetPlaneNormal(const Double_t *vert, Double_t *norm) const
Returns normal vector to the planar quadrilateral defined by vector VERT.
Definition: TGeoXtru.cxx:725
TGeoXtru::GetPlaneVertices
void GetPlaneVertices(Int_t iz, Int_t ivert, Double_t *vert) const
Returns (x,y,z) of 3 vertices of the surface defined by Z sections (iz, iz+1) and polygon vertices (i...
Definition: TGeoXtru.cxx:750
TBuffer3D
Generic 3D primitive description class.
Definition: TBuffer3D.h:18
TGeoXtru::ThreadData_t::fSeg
Int_t fSeg
Definition: TGeoXtru.h:27
TGeoXtru::Contains
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape
Definition: TGeoXtru.cxx:325
TGeoXtru::DistFromInside
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from inside point to surface of the polycone locate Z segment
Definition: TGeoXtru.cxx:430
TGeoXtru::GetNvert
Int_t GetNvert() const
Definition: TGeoXtru.h:95
xmin
float xmin
Definition: THbookFile.cxx:95
TBuffer3DTypes::kGeneric
@ kGeneric
Definition: TBuffer3DTypes.h:24
TGeoBBox::InspectShape
virtual void InspectShape() const
Prints shape parameters.
Definition: TGeoBBox.cxx:790
TGeoPolygon
An arbitrary polygon defined by vertices.
Definition: TGeoPolygon.h:20
TGeoPolygon::SetXY
void SetXY(Double_t *x, Double_t *y)
Set X/Y array pointer for the polygon and daughters.
Definition: TGeoPolygon.cxx:439
TObject::SetBit
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
TGeoBBox::fDY
Double_t fDY
Definition: TGeoBBox.h:22
TGeoXtru::GetNz
Int_t GetNz() const
Definition: TGeoXtru.h:94
a
auto * a
Definition: textangle.C:12
TGeoXtru::ThreadData_t::fYc
Double_t * fYc
Definition: TGeoXtru.h:30
TBuffer3D.h
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:101
TGeoShape::kGeoSavePrimitive
@ kGeoSavePrimitive
Definition: TGeoShape.h:65
TGeoXtru::fZcurrent
Double_t fZcurrent
Definition: TGeoXtru.h:44
TGeoXtru::fScale
Double_t * fScale
Definition: TGeoXtru.h:48
TGeoXtru::fX0
Double_t * fX0
Definition: TGeoXtru.h:49
TGeoXtru::DefineSection
virtual void DefineSection(Int_t snum, Double_t z, Double_t x0=0., Double_t y0=0., Double_t scale=1.)
defines z position of a section plane, rmin and rmax at this z.
Definition: TGeoXtru.cxx:689
TBuffer3DTypes.h
TBuffer3D::kRaw
@ kRaw
Definition: TBuffer3D.h:54
TGeoShape::GetName
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:248
TGeoXtru::ThreadData_t::fIz
Int_t fIz
Definition: TGeoXtru.h:28
y
Double_t y[n]
Definition: legend1.C:17
TGeoBBox
Box class.
Definition: TGeoBBox.h:18
TGeoXtru.h
TGeoXtru::ThreadData_t::fXc
Double_t * fXc
Definition: TGeoXtru.h:29
TGeoXtru::ComputeBBox
virtual void ComputeBBox()
compute bounding box of the pcon
Definition: TGeoXtru.cxx:269
TGeoXtru::fNvert
Int_t fNvert
Definition: TGeoXtru.h:42
TGeoBBox::FillBuffer3D
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Definition: TGeoBBox.cxx:1030
TObject::Warning
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:879
TGeoXtru::GetNmeshVertices
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
Definition: TGeoXtru.cxx:1210
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
TGeoXtru::ThreadData_t
Definition: TGeoXtru.h:26
ymin
float ymin
Definition: THbookFile.cxx:95
TGeoXtru::DistFromOutside
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from outside point to surface of the tube Warning("DistFromOutside",...
Definition: TGeoXtru.cxx:544
TMath::BinarySearch
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMathBase.h:278
TGeoXtru::GetThreadData
ThreadData_t & GetThreadData() const
Definition: TGeoXtru.cxx:90
TGeoXtru::SetCurrentVertices
void SetCurrentVertices(Double_t x0, Double_t y0, Double_t scale)
Set current vertex coordinates according X0, Y0 and SCALE.
Definition: TGeoXtru.cxx:1094
TGeoPolygon::FinishPolygon
void FinishPolygon()
Decompose polygon in a convex outscribed part and a list of daughter polygons that have to be subtrac...
Definition: TGeoPolygon.cxx:179
TGeoManager.h
TGeoXtru::Safety
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
Definition: TGeoXtru.cxx:1000
TGeoXtru::IsPointInsidePlane
Bool_t IsPointInsidePlane(const Double_t *point, Double_t *vert, Double_t *norm) const
Check if the quadrilateral defined by VERT contains a coplanar POINT.
Definition: TGeoXtru.cxx:805
TGeoXtru::SafetyToSector
Double_t SafetyToSector(const Double_t *point, Int_t iz, Double_t safmin, Bool_t in)
Compute safety to sector iz, returning also the closest segment index.
Definition: TGeoXtru.cxx:934
TGeoBBox::fDZ
Double_t fDZ
Definition: TGeoBBox.h:23
TGeoPolygon.h
TGeoShape::GetPointerName
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:699
TGeoXtru::SetCurrentZ
void SetCurrentZ(Double_t z, Int_t iz)
Recompute current section vertices for a given Z position within range of section iz.
Definition: TGeoXtru.cxx:1072
TVirtualGeoPainter.h
v1
@ v1
Definition: rootcling_impl.cxx:3666
Double_t
double Double_t
Definition: RtypesCore.h:59
TGeoXtru::GetZ
Double_t * GetZ() const
Definition: TGeoXtru.h:101
TBuffer3D::fLocalFrame
Bool_t fLocalFrame
Definition: TBuffer3D.h:90
TGeoXtru::GetMeshNumbers
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
Definition: TGeoXtru.cxx:1198
TGeoXtru::DistToPlane
Double_t DistToPlane(const Double_t *point, const Double_t *dir, Int_t iz, Int_t ivert, Double_t stepmax, Bool_t in) const
Compute distance to a Xtru lateral surface.
Definition: TGeoXtru.cxx:374
TGeoXtru::MakeBuffer3D
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
Definition: TGeoXtru.cxx:847
v2
@ v2
Definition: rootcling_impl.cxx:3667
points
point * points
Definition: X3DBuffer.c:22
TGeoShape::IsSameWithinTolerance
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
Definition: TGeoShape.cxx:326
TGeoPolygon::IsClockwise
Bool_t IsClockwise() const
Definition: TGeoPolygon.h:61
TGeoXtru::fZ
Double_t * fZ
Definition: TGeoXtru.h:47
TGeoXtru::SetSegsAndPols
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
Definition: TGeoXtru.cxx:869
TGeoXtru::fY
Double_t * fY
Definition: TGeoXtru.h:46
TBuffer3D::kRawSizes
@ kRawSizes
Definition: TBuffer3D.h:53
TGeoXtru::GetBuffer3D
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
Definition: TGeoXtru.cxx:1226
TGeoShape::ShapeDistancetoPrimitive
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Definition: TGeoShape.cxx:259
TGeoXtru::ThreadData_t::ThreadData_t
ThreadData_t()
Constructor.
Definition: TGeoXtru.cxx:73
TGeoShape::kGeoBad
@ kGeoBad
Definition: TGeoShape.h:34
TBuffer3D::fPnts
Double_t * fPnts
Definition: TBuffer3D.h:112
TGeoXtru::InspectShape
virtual void InspectShape() const
Print actual Xtru parameters.
Definition: TGeoXtru.cxx:830
TGeoXtru::ClearThreadData
virtual void ClearThreadData() const
Definition: TGeoXtru.cxx:99
TGeoShape::Tolerance
static Double_t Tolerance()
Definition: TGeoShape.h:91
TGeoXtru::SetPoints
virtual void SetPoints(Double_t *points) const
create polycone mesh points
Definition: TGeoXtru.cxx:1140
TGeoPolygon::Area
Double_t Area() const
Computes area of the polygon in [length^2].
Definition: TGeoPolygon.cxx:114
TGeoBBox::Contains
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
Definition: TGeoBBox.cxx:339
TGeoXtru::Contains_v
virtual void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
Check the inside status for each of the points in the array.
Definition: TGeoXtru.cxx:1261
TGeoShape::Big
static Double_t Big()
Definition: TGeoShape.h:88
pt
TPaveText * pt
Definition: entrylist_figure1.C:7
TGeoXtru::Safety_v
virtual void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
Compute safe distance from each of the points in the input array.
Definition: TGeoXtru.cxx:1297
TBuffer3D::fPols
Int_t * fPols
Definition: TBuffer3D.h:114
TObject::ClassName
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
TGeoXtru::Sizeof3D
virtual void Sizeof3D() const
fill size of this 3-D object
Definition: TGeoXtru.cxx:1219
TGeoXtru::DistancetoPrimitive
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
Definition: TGeoXtru.cxx:356
TGeoBBox::DistFromOutside
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
Compute distance from outside point to surface of the box.
Definition: TGeoBBox.cxx:429
TMath::E
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:96
TGeoXtru::DrawPolygon
void DrawPolygon(Option_t *option="")
Draw the section polygon.
Definition: TGeoXtru.cxx:365
TGeoXtru::fThreadSize
Int_t fThreadSize
Navigation data per thread.
Definition: TGeoXtru.h:53
TGeoBBox::fDX
Double_t fDX
Definition: TGeoBBox.h:21
TGeoXtru::SetSeg
void SetSeg(Int_t iseg)
Set current segment.
Definition: TGeoXtru.cxx:148
snext
#define snext(osub1, osub2)
Definition: triangle.c:1168
TGeoXtru::fX
Double_t * fX
Definition: TGeoXtru.h:45
TGeoXtru::DistFromOutside_v
virtual void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Definition: TGeoXtru.cxx:1287
TMath.h
TGeoPolygon::Draw
virtual void Draw(Option_t *option="")
Draw the polygon.
Definition: TGeoPolygon.cxx:169
int
TGeoXtru::TGeoXtru
TGeoXtru()
dummy ctor
Definition: TGeoXtru.cxx:156