00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "Riostream.h"
00028
00029 #include "TGeoCone.h"
00030 #include "TGeoManager.h"
00031 #include "TGeoVolume.h"
00032 #include "TVirtualGeoPainter.h"
00033 #include "TGeoSphere.h"
00034 #include "TVirtualPad.h"
00035 #include "TBuffer3D.h"
00036 #include "TBuffer3DTypes.h"
00037 #include "TMath.h"
00038
00039 ClassImp(TGeoSphere)
00040
00041
00042 TGeoSphere::TGeoSphere()
00043 {
00044
00045 SetShapeBit(TGeoShape::kGeoSph);
00046 fNz = 0;
00047 fNseg = 0;
00048 fRmin = 0.0;
00049 fRmax = 0.0;
00050 fTheta1 = 0.0;
00051 fTheta2 = 180.0;
00052 fPhi1 = 0.0;
00053 fPhi2 = 360.0;
00054 }
00055
00056
00057 TGeoSphere::TGeoSphere(Double_t rmin, Double_t rmax, Double_t theta1,
00058 Double_t theta2, Double_t phi1, Double_t phi2)
00059 :TGeoBBox(0, 0, 0)
00060 {
00061
00062 SetShapeBit(TGeoShape::kGeoSph);
00063 SetSphDimensions(rmin, rmax, theta1, theta2, phi1, phi2);
00064 ComputeBBox();
00065 SetNumberOfDivisions(20);
00066 }
00067
00068
00069 TGeoSphere::TGeoSphere(const char *name, Double_t rmin, Double_t rmax, Double_t theta1,
00070 Double_t theta2, Double_t phi1, Double_t phi2)
00071 :TGeoBBox(name, 0, 0, 0)
00072 {
00073
00074 SetShapeBit(TGeoShape::kGeoSph);
00075 SetSphDimensions(rmin, rmax, theta1, theta2, phi1, phi2);
00076 ComputeBBox();
00077 SetNumberOfDivisions(20);
00078 }
00079
00080
00081 TGeoSphere::TGeoSphere(Double_t *param, Int_t )
00082 :TGeoBBox(0, 0, 0)
00083 {
00084
00085
00086
00087 SetShapeBit(TGeoShape::kGeoSph);
00088 SetDimensions(param);
00089 ComputeBBox();
00090 SetNumberOfDivisions(20);
00091 }
00092
00093
00094 TGeoSphere::~TGeoSphere()
00095 {
00096
00097 }
00098
00099
00100 Double_t TGeoSphere::Capacity() const
00101 {
00102
00103 Double_t th1 = fTheta1*TMath::DegToRad();
00104 Double_t th2 = fTheta2*TMath::DegToRad();
00105 Double_t ph1 = fPhi1*TMath::DegToRad();
00106 Double_t ph2 = fPhi2*TMath::DegToRad();
00107 Double_t capacity = (1./3.)*(fRmax*fRmax*fRmax-fRmin*fRmin*fRmin)*
00108 TMath::Abs(TMath::Cos(th1)-TMath::Cos(th2))*
00109 TMath::Abs(ph2-ph1);
00110 return capacity;
00111 }
00112
00113
00114 void TGeoSphere::ComputeBBox()
00115 {
00116
00117
00118 if (TGeoShape::IsSameWithinTolerance(TMath::Abs(fTheta2-fTheta1),180)) {
00119 if (TGeoShape::IsSameWithinTolerance(TMath::Abs(fPhi2-fPhi1),360)) {
00120 TGeoBBox::SetBoxDimensions(fRmax, fRmax, fRmax);
00121 memset(fOrigin, 0, 3*sizeof(Double_t));
00122 return;
00123 }
00124 }
00125 Double_t st1 = TMath::Sin(fTheta1*TMath::DegToRad());
00126 Double_t st2 = TMath::Sin(fTheta2*TMath::DegToRad());
00127 Double_t r1min, r1max, r2min, r2max, rmin, rmax;
00128 r1min = TMath::Min(fRmax*st1, fRmax*st2);
00129 r1max = TMath::Max(fRmax*st1, fRmax*st2);
00130 r2min = TMath::Min(fRmin*st1, fRmin*st2);
00131 r2max = TMath::Max(fRmin*st1, fRmin*st2);
00132 if (((fTheta1<=90) && (fTheta2>=90)) || ((fTheta2<=90) && (fTheta1>=90))) {
00133 r1max = fRmax;
00134 r2max = fRmin;
00135 }
00136 rmin = TMath::Min(r1min, r2min);
00137 rmax = TMath::Max(r1max, r2max);
00138
00139 Double_t xc[4];
00140 Double_t yc[4];
00141 xc[0] = rmax*TMath::Cos(fPhi1*TMath::DegToRad());
00142 yc[0] = rmax*TMath::Sin(fPhi1*TMath::DegToRad());
00143 xc[1] = rmax*TMath::Cos(fPhi2*TMath::DegToRad());
00144 yc[1] = rmax*TMath::Sin(fPhi2*TMath::DegToRad());
00145 xc[2] = rmin*TMath::Cos(fPhi1*TMath::DegToRad());
00146 yc[2] = rmin*TMath::Sin(fPhi1*TMath::DegToRad());
00147 xc[3] = rmin*TMath::Cos(fPhi2*TMath::DegToRad());
00148 yc[3] = rmin*TMath::Sin(fPhi2*TMath::DegToRad());
00149
00150 Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
00151 Double_t xmax = xc[TMath::LocMax(4, &xc[0])];
00152 Double_t ymin = yc[TMath::LocMin(4, &yc[0])];
00153 Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
00154 Double_t dp = fPhi2-fPhi1;
00155 if (dp<0) dp+=360;
00156 Double_t ddp = -fPhi1;
00157 if (ddp<0) ddp+= 360;
00158 if (ddp>360) ddp-=360;
00159 if (ddp<=dp) xmax = rmax;
00160 ddp = 90-fPhi1;
00161 if (ddp<0) ddp+= 360;
00162 if (ddp>360) ddp-=360;
00163 if (ddp<=dp) ymax = rmax;
00164 ddp = 180-fPhi1;
00165 if (ddp<0) ddp+= 360;
00166 if (ddp>360) ddp-=360;
00167 if (ddp<=dp) xmin = -rmax;
00168 ddp = 270-fPhi1;
00169 if (ddp<0) ddp+= 360;
00170 if (ddp>360) ddp-=360;
00171 if (ddp<=dp) ymin = -rmax;
00172 xc[0] = fRmax*TMath::Cos(fTheta1*TMath::DegToRad());
00173 xc[1] = fRmax*TMath::Cos(fTheta2*TMath::DegToRad());
00174 xc[2] = fRmin*TMath::Cos(fTheta1*TMath::DegToRad());
00175 xc[3] = fRmin*TMath::Cos(fTheta2*TMath::DegToRad());
00176 Double_t zmin = xc[TMath::LocMin(4, &xc[0])];
00177 Double_t zmax = xc[TMath::LocMax(4, &xc[0])];
00178
00179
00180 fOrigin[0] = (xmax+xmin)/2;
00181 fOrigin[1] = (ymax+ymin)/2;
00182 fOrigin[2] = (zmax+zmin)/2;;
00183 fDX = (xmax-xmin)/2;
00184 fDY = (ymax-ymin)/2;
00185 fDZ = (zmax-zmin)/2;
00186 }
00187
00188
00189 void TGeoSphere::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
00190 {
00191
00192 Double_t rxy2 = point[0]*point[0]+point[1]*point[1];
00193 Double_t r2 = rxy2+point[2]*point[2];
00194 Double_t r=TMath::Sqrt(r2);
00195 Bool_t rzero=kFALSE;
00196 if (r<=1E-20) rzero=kTRUE;
00197
00198 Double_t phi=0;
00199 Double_t th=0.;
00200 if (!rzero) th = TMath::ACos(point[2]/r);
00201
00202
00203 phi=TMath::ATan2(point[1], point[0]);
00204
00205 Double_t saf[4];
00206 saf[0]=(TGeoShape::IsSameWithinTolerance(fRmin,0) && !TestShapeBit(kGeoThetaSeg) && !TestShapeBit(kGeoPhiSeg))?TGeoShape::Big():TMath::Abs(r-fRmin);
00207 saf[1]=TMath::Abs(fRmax-r);
00208 saf[2]=saf[3]= TGeoShape::Big();
00209 if (TestShapeBit(kGeoThetaSeg)) {
00210 if (fTheta1>0) {
00211 saf[2] = r*TMath::Abs(TMath::Sin(th-fTheta1*TMath::DegToRad()));
00212 }
00213 if (fTheta2<180) {
00214 saf[3] = r*TMath::Abs(TMath::Sin(fTheta2*TMath::DegToRad()-th));
00215 }
00216 }
00217 Int_t i = TMath::LocMin(4,saf);
00218 if (TestShapeBit(kGeoPhiSeg)) {
00219 Double_t c1 = TMath::Cos(fPhi1*TMath::DegToRad());
00220 Double_t s1 = TMath::Sin(fPhi1*TMath::DegToRad());
00221 Double_t c2 = TMath::Cos(fPhi2*TMath::DegToRad());
00222 Double_t s2 = TMath::Sin(fPhi2*TMath::DegToRad());
00223 if (TGeoShape::IsCloseToPhi(saf[i], point,c1,s1,c2,s2)) {
00224 TGeoShape::NormalPhi(point,dir,norm,c1,s1,c2,s2);
00225 return;
00226 }
00227 }
00228 if (i>1) {
00229 if (i==2) th=(fTheta1<90)?(fTheta1+90):(fTheta1-90);
00230 else th=(fTheta2<90)?(fTheta2+90):(fTheta2-90);
00231 th *= TMath::DegToRad();
00232 }
00233
00234 norm[0] = TMath::Sin(th)*TMath::Cos(phi);
00235 norm[1] = TMath::Sin(th)*TMath::Sin(phi);
00236 norm[2] = TMath::Cos(th);
00237 if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
00238 norm[0] = -norm[0];
00239 norm[1] = -norm[1];
00240 norm[2] = -norm[2];
00241 }
00242 }
00243
00244
00245 Int_t TGeoSphere::IsOnBoundary(Double_t *point) const
00246 {
00247
00248
00249
00250
00251
00252
00253
00254 Int_t icode = 0;
00255 Double_t tol = TGeoShape::Tolerance();
00256 Double_t r2 = point[0]*point[0]+point[1]*point[1]+point[2]*point[2];
00257 Double_t drsqout = r2-fRmax*fRmax;
00258
00259 if (TMath::Abs(drsqout)<2.*fRmax*tol) return 2;
00260 Double_t drsqin = r2;
00261
00262 if (TestShapeBit(kGeoRSeg)) {
00263 drsqin -= fRmin*fRmin;
00264 if (TMath::Abs(drsqin)<2.*fRmin*tol) return 1;
00265 }
00266 if (TestShapeBit(kGeoPhiSeg)) {
00267 Double_t phi = TMath::ATan2(point[1], point[0]);
00268 if (phi<0) phi+=2*TMath::Pi();
00269 Double_t phi1 = fPhi1*TMath::DegToRad();
00270 Double_t phi2 = fPhi2*TMath::DegToRad();
00271 Double_t ddp = phi-phi1;
00272 if (r2*ddp*ddp < tol*tol) return 3;
00273 ddp = phi - phi2;
00274 if (r2*ddp*ddp < tol*tol) return 4;
00275 }
00276 if (TestShapeBit(kGeoThetaSeg)) {
00277 Double_t r = TMath::Sqrt(r2);
00278 Double_t theta = TMath::ACos(point[2]/r2);
00279 Double_t theta1 = fTheta1*TMath::DegToRad();
00280 Double_t theta2 = fTheta2*TMath::DegToRad();
00281 Double_t ddt;
00282 if (fTheta1>0) {
00283 ddt = TMath::Abs(theta-theta1);
00284 if (r*ddt < tol) return 5;
00285 }
00286 if (fTheta2<180) {
00287 ddt = TMath::Abs(theta-theta2);
00288 if (r*ddt < tol) return 6;
00289 }
00290 }
00291 return icode;
00292 }
00293
00294
00295 Bool_t TGeoSphere::IsPointInside(Double_t *point, Bool_t checkR, Bool_t checkTh, Bool_t checkPh) const
00296 {
00297
00298 Double_t r2 = point[0]*point[0]+point[1]*point[1]+point[2]*point[2];
00299 if (checkR) {
00300 if (TestShapeBit(kGeoRSeg) && (r2<fRmin*fRmin)) return kFALSE;
00301 if (r2>fRmax*fRmax) return kFALSE;
00302 }
00303 if (r2<1E-20) return kTRUE;
00304 if (checkPh && TestShapeBit(kGeoPhiSeg)) {
00305 Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
00306 while (phi < fPhi1) phi+=360.;
00307 Double_t dphi = fPhi2 -fPhi1;
00308 Double_t ddp = phi - fPhi1;
00309 if (ddp > dphi) return kFALSE;
00310 }
00311 if (checkTh && TestShapeBit(kGeoThetaSeg)) {
00312 r2=TMath::Sqrt(r2);
00313
00314 Double_t theta = TMath::ACos(point[2]/r2)*TMath::RadToDeg();
00315 if ((theta<fTheta1) || (theta>fTheta2)) return kFALSE;
00316 }
00317 return kTRUE;
00318 }
00319
00320
00321 Bool_t TGeoSphere::Contains(Double_t *point) const
00322 {
00323
00324
00325 Double_t r2=point[0]*point[0]+point[1]*point[1]+point[2]*point[2];
00326 if (TestShapeBit(kGeoRSeg) && (r2<fRmin*fRmin)) return kFALSE;
00327 if (r2>fRmax*fRmax) return kFALSE;
00328 if (r2<1E-20) return kTRUE;
00329
00330 if (TestShapeBit(kGeoPhiSeg)) {
00331 Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
00332 if (phi < 0 ) phi+=360.;
00333 Double_t dphi = fPhi2 -fPhi1;
00334 if (dphi < 0) dphi+=360.;
00335 Double_t ddp = phi - fPhi1;
00336 if (ddp < 0) ddp += 360.;
00337 if (ddp > dphi) return kFALSE;
00338 }
00339 if (TestShapeBit(kGeoThetaSeg)) {
00340 r2=TMath::Sqrt(r2);
00341
00342 Double_t theta = TMath::ACos(point[2]/r2)*TMath::RadToDeg();
00343 if ((theta<fTheta1) || (theta>fTheta2)) return kFALSE;
00344 }
00345 return kTRUE;
00346 }
00347
00348
00349 Int_t TGeoSphere::DistancetoPrimitive(Int_t px, Int_t py)
00350 {
00351
00352 Int_t n = fNseg+1;
00353 Int_t nz = fNz+1;
00354 const Int_t numPoints = 2*n*nz;
00355 return ShapeDistancetoPrimitive(numPoints, px, py);
00356 }
00357
00358
00359 Double_t TGeoSphere::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00360 {
00361
00362
00363 Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
00364 if (sdist>=step) return TGeoShape::Big();
00365 Double_t saf[6];
00366 Double_t r1,r2,z1,z2,dz,si,ci;
00367 Double_t rxy2 = point[0]*point[0]+point[1]*point[1];
00368 Double_t rxy = TMath::Sqrt(rxy2);
00369 r2 = rxy2+point[2]*point[2];
00370 Double_t r=TMath::Sqrt(r2);
00371 Bool_t rzero=kFALSE;
00372 Double_t phi=0;
00373 if (r<1E-20) rzero=kTRUE;
00374
00375 Double_t th=0.;
00376 if (TestShapeBit(kGeoThetaSeg) && (!rzero)) {
00377 th = TMath::ACos(point[2]/r)*TMath::RadToDeg();
00378 }
00379
00380 if (TestShapeBit(kGeoPhiSeg)) {
00381 phi=TMath::ATan2(point[1], point[0])*TMath::RadToDeg();
00382 if (phi<0) phi+=360.;
00383 }
00384 if (iact<3 && safe) {
00385 saf[0]=(r<fRmin)?fRmin-r:TGeoShape::Big();
00386 saf[1]=(r>fRmax)?(r-fRmax):TGeoShape::Big();
00387 saf[2]=saf[3]=saf[4]=saf[5]= TGeoShape::Big();
00388 if (TestShapeBit(kGeoThetaSeg)) {
00389 if (th < fTheta1) {
00390 saf[2] = r*TMath::Sin((fTheta1-th)*TMath::DegToRad());
00391 }
00392 if (th > fTheta2) {
00393 saf[3] = r*TMath::Sin((th-fTheta2)*TMath::DegToRad());
00394 }
00395 }
00396 if (TestShapeBit(kGeoPhiSeg)) {
00397 Double_t dph1=phi-fPhi1;
00398 if (dph1<0) dph1+=360.;
00399 if (dph1<=90.) saf[4]=rxy*TMath::Sin(dph1*TMath::DegToRad());
00400 Double_t dph2=fPhi2-phi;
00401 if (dph2<0) dph2+=360.;
00402 if (dph2>90.) saf[5]=rxy*TMath::Sin(dph2*TMath::DegToRad());
00403 }
00404 *safe = saf[TMath::LocMin(6, &saf[0])];
00405 if (iact==0) return TGeoShape::Big();
00406 if (iact==1 && step<*safe) return TGeoShape::Big();
00407 }
00408
00409
00410 Double_t snxt = TGeoShape::Big();
00411 Double_t rdotn = point[0]*dir[0]+point[1]*dir[1]+point[2]*dir[2];
00412 Bool_t fullsph = (!TestShapeBit(kGeoThetaSeg) && !TestShapeBit(kGeoPhiSeg))?kTRUE:kFALSE;
00413 if (r>fRmax) {
00414 Double_t b = rdotn;
00415 Double_t c = r2-fRmax*fRmax;
00416 Double_t d=b*b-c;
00417 if (d<0) return TGeoShape::Big();
00418 }
00419 if (fullsph) {
00420 Bool_t inrmax = kFALSE;
00421 Bool_t inrmin = kFALSE;
00422 if (r<=fRmax+TGeoShape::Tolerance()) inrmax = kTRUE;
00423 if (r>=fRmin-TGeoShape::Tolerance()) inrmin = kTRUE;
00424 if (inrmax && inrmin) {
00425 if ((fRmax-r) < (r-fRmin)) {
00426
00427 if (rdotn>=0) return TGeoShape::Big();
00428 return 0.0;
00429 }
00430
00431 if (TGeoShape::IsSameWithinTolerance(fRmin,0) || rdotn>=0) return 0.0;
00432
00433 return DistToSphere(point, dir, fRmin, kFALSE, kFALSE);
00434 }
00435 }
00436
00437
00438 if (r<fRmin) {
00439
00440 snxt = DistToSphere(point, dir, fRmin, kTRUE);
00441 if (snxt<1E20) return snxt;
00442 } else {
00443 if (r>fRmax) {
00444
00445 snxt = DistToSphere(point, dir, fRmax, kTRUE);
00446 if (snxt<1E20) return snxt;
00447
00448 if (fRmin>0) snxt = DistToSphere(point, dir, fRmin, kTRUE, kFALSE);
00449 } else {
00450
00451 if (fRmin>0) snxt = DistToSphere(point, dir, fRmin, kTRUE, kFALSE);
00452 }
00453 }
00454
00455 Double_t ptnew[3];
00456 Double_t b,delta, znew;
00457 Double_t snext = snxt;
00458 Double_t st1=TGeoShape::Big(), st2=TGeoShape::Big();
00459 if (TestShapeBit(kGeoThetaSeg)) {
00460 if (fTheta1>0) {
00461 if (TGeoShape::IsSameWithinTolerance(fTheta1,90)) {
00462
00463 if (point[2]*dir[2]<0) {
00464 snxt = -point[2]/dir[2];
00465 ptnew[0] = point[0]+snxt*dir[0];
00466 ptnew[1] = point[1]+snxt*dir[1];
00467 ptnew[2] = 0;
00468
00469 if (IsPointInside(&ptnew[0], kTRUE, kFALSE, kTRUE)) return TMath::Min(snxt,snext);
00470 }
00471 } else {
00472 si = TMath::Sin(fTheta1*TMath::DegToRad());
00473 ci = TMath::Cos(fTheta1*TMath::DegToRad());
00474 if (ci>0) {
00475 r1 = fRmin*si;
00476 z1 = fRmin*ci;
00477 r2 = fRmax*si;
00478 z2 = fRmax*ci;
00479 } else {
00480 r1 = fRmax*si;
00481 z1 = fRmax*ci;
00482 r2 = fRmin*si;
00483 z2 = fRmin*ci;
00484 }
00485 dz = 0.5*(z2-z1);
00486 ptnew[0] = point[0];
00487 ptnew[1] = point[1];
00488 ptnew[2] = point[2]-0.5*(z1+z2);
00489 if (TestShapeBit(kGeoPhiSeg)) {
00490 st1 = TGeoConeSeg::DistToCons(point, dir, r1, z1, r2, z2, fPhi1, fPhi2);
00491 } else {
00492 TGeoCone::DistToCone(ptnew, dir, dz, r1, r2, b, delta);
00493 if (delta>0) {
00494 st1 = -b-delta;
00495 znew = ptnew[2]+st1*dir[2];
00496 if (st1<0 || TMath::Abs(znew)>dz) {
00497 st1 = -b+delta;
00498 znew = ptnew[2]+st1*dir[2];
00499 if (st1<0 || TMath::Abs(znew)>dz) st1=TGeoShape::Big();
00500 }
00501 }
00502 }
00503 }
00504 }
00505
00506 if (fTheta2<180) {
00507 if (TGeoShape::IsSameWithinTolerance(fTheta2,90)) {
00508
00509 if (point[2]*dir[2]<0) {
00510 snxt = -point[2]/dir[2];
00511 ptnew[0] = point[0]+snxt*dir[0];
00512 ptnew[1] = point[1]+snxt*dir[1];
00513 ptnew[2] = 0;
00514
00515 if (IsPointInside(&ptnew[0], kTRUE, kFALSE, kTRUE)) return TMath::Min(snxt,snext);
00516 }
00517 } else {
00518 si = TMath::Sin(fTheta2*TMath::DegToRad());
00519 ci = TMath::Cos(fTheta2*TMath::DegToRad());
00520 if (ci>0) {
00521 r1 = fRmin*si;
00522 z1 = fRmin*ci;
00523 r2 = fRmax*si;
00524 z2 = fRmax*ci;
00525 } else {
00526 r1 = fRmax*si;
00527 z1 = fRmax*ci;
00528 r2 = fRmin*si;
00529 z2 = fRmin*ci;
00530 }
00531 dz = 0.5*(z2-z1);
00532 ptnew[0] = point[0];
00533 ptnew[1] = point[1];
00534 ptnew[2] = point[2]-0.5*(z1+z2);
00535 if (TestShapeBit(kGeoPhiSeg)) {
00536 st2 = TGeoConeSeg::DistToCons(point, dir, r1, z1, r2, z2, fPhi1, fPhi2);
00537 } else {
00538 TGeoCone::DistToCone(ptnew, dir, dz, r1, r2, b, delta);
00539 if (delta>0) {
00540 st2 = -b-delta;
00541 znew = ptnew[2]+st2*dir[2];
00542 if (st2<0 || TMath::Abs(znew)>dz) {
00543 st2 = -b+delta;
00544 znew = ptnew[2]+st2*dir[2];
00545 if (st2<0 || TMath::Abs(znew)>dz) st2=TGeoShape::Big();
00546 }
00547 }
00548 }
00549 }
00550 }
00551 }
00552 snxt = TMath::Min(st1, st2);
00553 snxt = TMath::Min(snxt,snext);
00554
00555 if (TestShapeBit(kGeoPhiSeg)) {
00556 Double_t s1 = TMath::Sin(fPhi1*TMath::DegToRad());
00557 Double_t c1 = TMath::Cos(fPhi1*TMath::DegToRad());
00558 Double_t s2 = TMath::Sin(fPhi2*TMath::DegToRad());
00559 Double_t c2 = TMath::Cos(fPhi2*TMath::DegToRad());
00560 Double_t phim = 0.5*(fPhi1+fPhi2);
00561 Double_t sm = TMath::Sin(phim*TMath::DegToRad());
00562 Double_t cm = TMath::Cos(phim*TMath::DegToRad());
00563 Double_t sfi1=TGeoShape::Big();
00564 Double_t sfi2=TGeoShape::Big();
00565 Double_t s=0;
00566 Double_t safety, un;
00567 safety = point[0]*s1-point[1]*c1;
00568 if (safety>0) {
00569 un = dir[0]*s1-dir[1]*c1;
00570 if (un<0) {
00571 s=-safety/un;
00572 ptnew[0] = point[0]+s*dir[0];
00573 ptnew[1] = point[1]+s*dir[1];
00574 ptnew[2] = point[2]+s*dir[2];
00575 if ((ptnew[1]*cm-ptnew[0]*sm)<=0) {
00576 sfi1=s;
00577 if (IsPointInside(&ptnew[0], kTRUE, kTRUE, kFALSE) && sfi1<snxt) return sfi1;
00578 }
00579 }
00580 }
00581 safety = -point[0]*s2+point[1]*c2;
00582 if (safety>0) {
00583 un = -dir[0]*s2+dir[1]*c2;
00584 if (un<0) {
00585 s=-safety/un;
00586 ptnew[0] = point[0]+s*dir[0];
00587 ptnew[1] = point[1]+s*dir[1];
00588 ptnew[2] = point[2]+s*dir[2];
00589 if ((ptnew[1]*cm-ptnew[0]*sm)>=0) {
00590 sfi2=s;
00591 if (IsPointInside(&ptnew[0], kTRUE, kTRUE, kFALSE) && sfi2<snxt) return sfi2;
00592 }
00593 }
00594 }
00595 }
00596 return snxt;
00597 }
00598
00599
00600 Double_t TGeoSphere::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00601 {
00602
00603 Double_t saf[6];
00604 Double_t rxy2 = point[0]*point[0]+point[1]*point[1];
00605 Double_t rxy = TMath::Sqrt(rxy2);
00606 Double_t rad2 = rxy2+point[2]*point[2];
00607 Double_t r=TMath::Sqrt(rad2);
00608 Bool_t rzero=kFALSE;
00609 if (r<=1E-20) rzero=kTRUE;
00610
00611 Double_t phi=0;;
00612 Double_t th=0.;
00613 if (TestShapeBit(kGeoThetaSeg) && (!rzero)) {
00614 th = TMath::ACos(point[2]/r)*TMath::RadToDeg();
00615 }
00616
00617 if (TestShapeBit(kGeoPhiSeg)) {
00618 phi=TMath::ATan2(point[1], point[0])*TMath::RadToDeg();
00619 if (phi<0) phi+=360.;
00620 }
00621 if (iact<3 && safe) {
00622 saf[0]=(TGeoShape::IsSameWithinTolerance(fRmin,0))?TGeoShape::Big():r-fRmin;
00623 saf[1]=fRmax-r;
00624 saf[2]=saf[3]=saf[4]=saf[5]= TGeoShape::Big();
00625 if (TestShapeBit(kGeoThetaSeg)) {
00626 if (fTheta1>0) {
00627 saf[2] = r*TMath::Sin((th-fTheta1)*TMath::DegToRad());
00628 }
00629 if (fTheta2<180) {
00630 saf[3] = r*TMath::Sin((fTheta2-th)*TMath::DegToRad());
00631 }
00632 }
00633 if (TestShapeBit(kGeoPhiSeg)) {
00634 Double_t dph1=phi-fPhi1;
00635 if (dph1<0) dph1+=360.;
00636 if (dph1<=90.) saf[4]=rxy*TMath::Sin(dph1*TMath::DegToRad());
00637 Double_t dph2=fPhi2-phi;
00638 if (dph2<0) dph2+=360.;
00639 if (dph2<=90.) saf[5]=rxy*TMath::Sin(dph2*TMath::DegToRad());
00640 }
00641 *safe = saf[TMath::LocMin(6, &saf[0])];
00642 if (iact==0) return TGeoShape::Big();
00643 if (iact==1 && step<*safe) return TGeoShape::Big();
00644 }
00645
00646 Double_t snxt = TGeoShape::Big();
00647 if (rzero) {
00648
00649 return fRmax;
00650 }
00651
00652 Double_t b,delta, znew;
00653 Double_t rdotn = point[0]*dir[0]+point[1]*dir[1]+point[2]*dir[2];
00654 Double_t sn1 = TGeoShape::Big();
00655
00656 if (fRmin>0) {
00657
00658 if (r <= fRmin+TGeoShape::Tolerance()) {
00659 if (rdotn<0) return 0.0;
00660 } else {
00661 if (rdotn<0) sn1 = DistToSphere(point, dir, fRmin, kFALSE);
00662 }
00663 }
00664 Double_t sn2 = TGeoShape::Big();
00665
00666 if (r >= fRmax-TGeoShape::Tolerance()) {
00667 if (rdotn>=0) return 0.0;
00668 }
00669 sn2 = DistToSphere(point, dir, fRmax, kFALSE);
00670 Double_t sr = TMath::Min(sn1, sn2);
00671
00672 sn1 = TGeoShape::Big();
00673 sn2 = TGeoShape::Big();
00674 if (TestShapeBit(kGeoThetaSeg)) {
00675 if (TGeoShape::IsSameWithinTolerance(fTheta1,90)) {
00676
00677 if (point[2]*dir[2]<0) sn1 = -point[2]/dir[2];
00678 } else {
00679 if (fTheta1>0) {
00680 Double_t r1,r2,z1,z2,dz,ptnew[3];
00681 Double_t si = TMath::Sin(fTheta1*TMath::DegToRad());
00682 Double_t ci = TMath::Cos(fTheta1*TMath::DegToRad());
00683 if (ci>0) {
00684 r1 = fRmin*si;
00685 z1 = fRmin*ci;
00686 r2 = fRmax*si;
00687 z2 = fRmax*ci;
00688 } else {
00689 r1 = fRmax*si;
00690 z1 = fRmax*ci;
00691 r2 = fRmin*si;
00692 z2 = fRmin*ci;
00693 }
00694 dz = 0.5*(z2-z1);
00695 ptnew[0] = point[0];
00696 ptnew[1] = point[1];
00697 ptnew[2] = point[2]-0.5*(z1+z2);
00698 if (TestShapeBit(kGeoPhiSeg)) {
00699 sn1 = TGeoConeSeg::DistToCons(point, dir, r1, z1, r2, z2, fPhi1, fPhi2);
00700 } else {
00701 TGeoCone::DistToCone(ptnew, dir, dz, r1, r2, b, delta);
00702 if (delta>0) {
00703 sn1 = -b-delta;
00704 znew = ptnew[2]+sn1*dir[2];
00705 if (sn1<0 || TMath::Abs(znew)>dz) {
00706 sn1 = -b+delta;
00707 znew = ptnew[2]+sn1*dir[2];
00708 if (sn1<0 || TMath::Abs(znew)>dz) sn1=TGeoShape::Big();
00709 }
00710 }
00711 }
00712 }
00713 }
00714 if (TGeoShape::IsSameWithinTolerance(fTheta2,90)) {
00715
00716 if (point[2]*dir[2]<0) sn1 = -point[2]/dir[2];
00717 } else {
00718 if (fTheta2<180) {
00719 Double_t r1,r2,z1,z2,dz,ptnew[3];
00720 Double_t si = TMath::Sin(fTheta2*TMath::DegToRad());
00721 Double_t ci = TMath::Cos(fTheta2*TMath::DegToRad());
00722 if (ci>0) {
00723 r1 = fRmin*si;
00724 z1 = fRmin*ci;
00725 r2 = fRmax*si;
00726 z2 = fRmax*ci;
00727 } else {
00728 r1 = fRmax*si;
00729 z1 = fRmax*ci;
00730 r2 = fRmin*si;
00731 z2 = fRmin*ci;
00732 }
00733 dz = 0.5*(z2-z1);
00734 ptnew[0] = point[0];
00735 ptnew[1] = point[1];
00736 ptnew[2] = point[2]-0.5*(z1+z2);
00737 if (TestShapeBit(kGeoPhiSeg)) {
00738 sn2 = TGeoConeSeg::DistToCons(point, dir, r1, z1, r2, z2, fPhi1, fPhi2);
00739 } else {
00740 TGeoCone::DistToCone(ptnew, dir, dz, r1, r2, b, delta);
00741 if (delta>0) {
00742 sn2 = -b-delta;
00743 znew = ptnew[2]+sn2*dir[2];
00744 if (sn2<0 || TMath::Abs(znew)>dz) {
00745 sn2 = -b+delta;
00746 znew = ptnew[2]+sn2*dir[2];
00747 if (sn2<0 || TMath::Abs(znew)>dz) sn2=TGeoShape::Big();
00748 }
00749 }
00750 }
00751 }
00752 }
00753 }
00754 Double_t st = TMath::Min(sn1,sn2);
00755 Double_t sp = TGeoShape::Big();
00756 if (TestShapeBit(kGeoPhiSeg)) {
00757 Double_t s1 = TMath::Sin(fPhi1*TMath::DegToRad());
00758 Double_t c1 = TMath::Cos(fPhi1*TMath::DegToRad());
00759 Double_t s2 = TMath::Sin(fPhi2*TMath::DegToRad());
00760 Double_t c2 = TMath::Cos(fPhi2*TMath::DegToRad());
00761 Double_t phim = 0.5*(fPhi1+fPhi2);
00762 Double_t sm = TMath::Sin(phim*TMath::DegToRad());
00763 Double_t cm = TMath::Cos(phim*TMath::DegToRad());
00764 sp = TGeoShape::DistToPhiMin(point, dir, s1, c1, s2, c2, sm, cm);
00765 }
00766 snxt = TMath::Min(sr, st);
00767 snxt = TMath::Min(snxt, sp);
00768 return snxt;
00769 }
00770
00771
00772 Double_t TGeoSphere::DistToSphere(Double_t *point, Double_t *dir, Double_t rsph, Bool_t check, Bool_t firstcross) const
00773 {
00774
00775 if (rsph<=0) return TGeoShape::Big();
00776 Double_t s=TGeoShape::Big();
00777 Double_t r2 = point[0]*point[0]+point[1]*point[1]+point[2]*point[2];
00778 Double_t b = point[0]*dir[0]+point[1]*dir[1]+point[2]*dir[2];
00779 Double_t c = r2-rsph*rsph;
00780 Bool_t in = (c<=0)?kTRUE:kFALSE;
00781 Double_t d;
00782
00783 d=b*b-c;
00784 if (d<0) return TGeoShape::Big();
00785 Double_t pt[3];
00786 Int_t i;
00787 d = TMath::Sqrt(d);
00788 if (in) {
00789 s=-b+d;
00790 } else {
00791 s = (firstcross)?(-b-d):(-b+d);
00792 }
00793 if (s<0) return TGeoShape::Big();
00794 if (!check) return s;
00795 for (i=0; i<3; i++) pt[i]=point[i]+s*dir[i];
00796
00797 if (IsPointInside(&pt[0], kFALSE)) return s;
00798 return TGeoShape::Big();
00799 }
00800
00801
00802 TGeoVolume *TGeoSphere::Divide(TGeoVolume * , const char * , Int_t , Int_t ,
00803 Double_t , Double_t )
00804 {
00805
00806 Error("Divide", "Division of a sphere not implemented");
00807 return 0;
00808 }
00809
00810
00811 const char *TGeoSphere::GetAxisName(Int_t iaxis) const
00812 {
00813
00814 switch (iaxis) {
00815 case 1:
00816 return "R";
00817 case 2:
00818 return "THETA";
00819 case 3:
00820 return "PHI";
00821 default:
00822 return "UNDEFINED";
00823 }
00824 }
00825
00826
00827 Double_t TGeoSphere::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
00828 {
00829
00830 xlo = 0;
00831 xhi = 0;
00832 Double_t dx = 0;
00833 switch (iaxis) {
00834 case 1:
00835 xlo = fRmin;
00836 xhi = fRmax;
00837 dx = xhi-xlo;
00838 return dx;
00839 case 2:
00840 xlo = fPhi1;
00841 xhi = fPhi2;
00842 dx = xhi-xlo;
00843 return dx;
00844 case 3:
00845 xlo = fTheta1;
00846 xhi = fTheta2;
00847 dx = xhi-xlo;
00848 return dx;
00849 }
00850 return dx;
00851 }
00852
00853
00854 void TGeoSphere::GetBoundingCylinder(Double_t *param) const
00855 {
00856
00857
00858 Double_t smin = TMath::Sin(fTheta1*TMath::DegToRad());
00859 Double_t smax = TMath::Sin(fTheta2*TMath::DegToRad());
00860 if (smin>smax) {
00861 Double_t a = smin;
00862 smin = smax;
00863 smax = a;
00864 }
00865 param[0] = fRmin*smin;
00866 param[0] *= param[0];
00867 if (((90.-fTheta1)*(fTheta2-90.))>=0) smax = 1.;
00868 param[1] = fRmax*smax;
00869 param[1] *= param[1];
00870 param[2] = (fPhi1<0)?(fPhi1+360.):fPhi1;
00871 param[3] = fPhi2;
00872 if (TGeoShape::IsSameWithinTolerance(param[3]-param[2],360)) {
00873 param[2] = 0.;
00874 param[3] = 360.;
00875 }
00876 while (param[3]<param[2]) param[3]+=360.;
00877 }
00878
00879
00880 void TGeoSphere::InspectShape() const
00881 {
00882
00883 printf("*** Shape %s: TGeoSphere ***\n", GetName());
00884 printf(" Rmin = %11.5f\n", fRmin);
00885 printf(" Rmax = %11.5f\n", fRmax);
00886 printf(" Th1 = %11.5f\n", fTheta1);
00887 printf(" Th2 = %11.5f\n", fTheta2);
00888 printf(" Ph1 = %11.5f\n", fPhi1);
00889 printf(" Ph2 = %11.5f\n", fPhi2);
00890 printf(" Bounding box:\n");
00891 TGeoBBox::InspectShape();
00892 }
00893
00894
00895 TBuffer3D *TGeoSphere::MakeBuffer3D() const
00896 {
00897
00898
00899
00900 Bool_t full = kTRUE;
00901 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
00902 Int_t ncenter = 1;
00903 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
00904 Int_t nup = (fTheta1>0)?0:1;
00905 Int_t ndown = (fTheta2<180)?0:1;
00906
00907 Int_t nlat = fNz+1-(nup+ndown);
00908
00909 Int_t nlong = fNseg;
00910 if (TestShapeBit(kGeoPhiSeg)) nlong++;
00911
00912 Int_t nbPnts = nlat*nlong+nup+ndown+ncenter;
00913 if (TestShapeBit(kGeoRSeg)) nbPnts *= 2;
00914
00915 Int_t nbSegs = nlat*fNseg + (nlat-1+nup+ndown)*nlong;
00916 if (TestShapeBit(kGeoRSeg)) nbSegs *= 2;
00917 if (TestShapeBit(kGeoPhiSeg)) nbSegs += 2*nlat+nup+ndown;
00918 nbSegs += nlong * (2-nup - ndown);
00919
00920 Int_t nbPols = fNz*fNseg;
00921 if (TestShapeBit(kGeoRSeg)) nbPols *=2;
00922 if (TestShapeBit(kGeoPhiSeg)) nbPols += 2*fNz;
00923 nbPols += (2-nup-ndown)*fNseg;
00924
00925 TBuffer3D* buff = new TBuffer3D(TBuffer3DTypes::kGeneric,
00926 nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols);
00927
00928 if (buff)
00929 {
00930 SetPoints(buff->fPnts);
00931 SetSegsAndPols(*buff);
00932 }
00933
00934 return buff;
00935 }
00936
00937
00938 void TGeoSphere::SetSegsAndPols(TBuffer3D & buff) const
00939 {
00940
00941 Bool_t full = kTRUE;
00942 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
00943 Int_t ncenter = 1;
00944 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
00945 Int_t nup = (fTheta1>0)?0:1;
00946 Int_t ndown = (fTheta2<180)?0:1;
00947
00948 Int_t nlat = fNz+1-(nup+ndown);
00949
00950 Int_t nlong = fNseg;
00951 if (TestShapeBit(kGeoPhiSeg)) nlong++;
00952
00953 Int_t nbPnts = nlat*nlong+nup+ndown+ncenter;
00954 if (TestShapeBit(kGeoRSeg)) nbPnts *= 2;
00955
00956 Int_t nbSegs = nlat*fNseg + (nlat-1+nup+ndown)*nlong;
00957 if (TestShapeBit(kGeoRSeg)) nbSegs *= 2;
00958 if (TestShapeBit(kGeoPhiSeg)) nbSegs += 2*nlat+nup+ndown;
00959 nbSegs += nlong * (2-nup - ndown);
00960
00961 Int_t nbPols = fNz*fNseg;
00962 if (TestShapeBit(kGeoRSeg)) nbPols *=2;
00963 if (TestShapeBit(kGeoPhiSeg)) nbPols += 2*fNz;
00964 nbPols += (2-nup-ndown)*fNseg;
00965
00966 Int_t c = GetBasicColor();
00967 Int_t i, j;
00968 Int_t indx;
00969 indx = 0;
00970
00971
00972
00973 Int_t indpar = 0;
00974 for (i=0; i<nlat; i++) {
00975 for (j=0; j<fNseg; j++) {
00976 buff.fSegs[indx++] = c;
00977 buff.fSegs[indx++] = i*nlong+j;
00978 buff.fSegs[indx++] = i*nlong+(j+1)%nlong;
00979 }
00980 }
00981
00982
00983 Int_t indlong = indpar + nlat*fNseg;
00984 for (i=0; i<nlat-1; i++) {
00985 for (j=0; j<nlong; j++) {
00986 buff.fSegs[indx++] = c;
00987 buff.fSegs[indx++] = i*nlong+j;
00988 buff.fSegs[indx++] = (i+1)*nlong+j;
00989 }
00990 }
00991 Int_t indup = indlong + (nlat-1)*nlong;
00992
00993
00994 if (nup) {
00995 Int_t indpup = nlat*nlong;
00996 for (j=0; j<nlong; j++) {
00997 buff.fSegs[indx++] = c;
00998 buff.fSegs[indx++] = j;
00999 buff.fSegs[indx++] = indpup;
01000 }
01001 }
01002 Int_t inddown = indup + nup*nlong;
01003
01004
01005 if (ndown) {
01006 Int_t indpdown = nlat*nlong+nup;
01007 for (j=0; j<nlong; j++) {
01008 buff.fSegs[indx++] = c;
01009 buff.fSegs[indx++] = (nlat-1)*nlong+j;
01010 buff.fSegs[indx++] = indpdown;
01011 }
01012 }
01013 Int_t indparin = inddown + ndown*nlong;
01014 Int_t indlongin = indparin;
01015 Int_t indupin = indparin;
01016 Int_t inddownin = indparin;
01017 Int_t indphi = indparin;
01018
01019 Int_t indptin = nlat*nlong + nup + ndown;
01020 Int_t iptcenter = indptin;
01021
01022 if (TestShapeBit(kGeoRSeg)) {
01023 indlongin = indparin + nlat*fNseg;
01024 indupin = indlongin + (nlat-1)*nlong;
01025 inddownin = indupin + nup*nlong;
01026
01027
01028 for (i=0; i<nlat; i++) {
01029 for (j=0; j<fNseg; j++) {
01030 buff.fSegs[indx++] = c+1;
01031 buff.fSegs[indx++] = indptin + i*nlong+j;
01032 buff.fSegs[indx++] = indptin + i*nlong+(j+1)%nlong;
01033 }
01034 }
01035
01036
01037 for (i=0; i<nlat-1; i++) {
01038 for (j=0; j<nlong; j++) {
01039 buff.fSegs[indx++] = c+1;
01040 buff.fSegs[indx++] = indptin + i*nlong+j;
01041 buff.fSegs[indx++] = indptin + (i+1)*nlong+j;
01042 }
01043 }
01044
01045
01046 if (nup) {
01047 Int_t indupltop = indptin + nlat*nlong;
01048 for (j=0; j<nlong; j++) {
01049 buff.fSegs[indx++] = c+1;
01050 buff.fSegs[indx++] = indptin + j;
01051 buff.fSegs[indx++] = indupltop;
01052 }
01053 }
01054
01055
01056 if (ndown) {
01057 Int_t indpdown = indptin + nlat*nlong+nup;
01058 for (j=0; j<nlong; j++) {
01059 buff.fSegs[indx++] = c+1;
01060 buff.fSegs[indx++] = indptin + (nlat-1)*nlong+j;
01061 buff.fSegs[indx++] = indpdown;
01062 }
01063 }
01064 indphi = inddownin + ndown*nlong;
01065 }
01066 Int_t indtheta = indphi;
01067
01068 if (TestShapeBit(kGeoPhiSeg)) {
01069 indtheta += 2*nlat + nup + ndown;
01070 for (j=0; j<nlat; j++) {
01071 buff.fSegs[indx++] = c+2;
01072 buff.fSegs[indx++] = j*nlong;
01073 if (TestShapeBit(kGeoRSeg)) buff.fSegs[indx++] = indptin + j*nlong;
01074 else buff.fSegs[indx++] = iptcenter;
01075 }
01076 for (j=0; j<nlat; j++) {
01077 buff.fSegs[indx++] = c+2;
01078 buff.fSegs[indx++] = (j+1)*nlong-1;
01079 if (TestShapeBit(kGeoRSeg)) buff.fSegs[indx++] = indptin + (j+1)*nlong-1;
01080 else buff.fSegs[indx++] = iptcenter;
01081 }
01082 if (nup) {
01083 buff.fSegs[indx++] = c+2;
01084 buff.fSegs[indx++] = nlat*nlong;
01085 if (TestShapeBit(kGeoRSeg)) buff.fSegs[indx++] = indptin + nlat*nlong;
01086 else buff.fSegs[indx++] = iptcenter;
01087 }
01088 if (ndown) {
01089 buff.fSegs[indx++] = c+2;
01090 buff.fSegs[indx++] = nlat*nlong+nup;
01091 if (TestShapeBit(kGeoRSeg)) buff.fSegs[indx++] = indptin + nlat*nlong+nup;
01092 else buff.fSegs[indx++] = iptcenter;
01093 }
01094 }
01095
01096 if (!nup) {
01097 for (j=0; j<nlong; j++) {
01098 buff.fSegs[indx++] = c+2;
01099 buff.fSegs[indx++] = j;
01100 if (TestShapeBit(kGeoRSeg)) buff.fSegs[indx++] = indptin + j;
01101 else buff.fSegs[indx++] = iptcenter;
01102 }
01103 }
01104 if (!ndown) {
01105 for (j=0; j<nlong; j++) {
01106 buff.fSegs[indx++] = c+2;
01107 buff.fSegs[indx++] = (nlat-1)*nlong + j;
01108 if (TestShapeBit(kGeoRSeg)) buff.fSegs[indx++] = indptin + (nlat-1)*nlong +j;
01109 else buff.fSegs[indx++] = iptcenter;
01110 }
01111 }
01112
01113 indx = 0;
01114
01115 for (i=0; i<nlat-1; i++) {
01116 for (j=0; j<fNseg; j++) {
01117 buff.fPols[indx++] = c;
01118 buff.fPols[indx++] = 4;
01119 buff.fPols[indx++] = indpar+i*fNseg+j;
01120 buff.fPols[indx++] = indlong+i*nlong+(j+1)%nlong;
01121 buff.fPols[indx++] = indpar+(i+1)*fNseg+j;
01122 buff.fPols[indx++] = indlong+i*nlong+j;
01123 }
01124 }
01125
01126 if (nup) {
01127 for (j=0; j<fNseg; j++) {
01128 buff.fPols[indx++] = c;
01129 buff.fPols[indx++] = 3;
01130 buff.fPols[indx++] = indup + j;
01131 buff.fPols[indx++] = indup + (j+1)%nlong;
01132 buff.fPols[indx++] = indpar + j;
01133 }
01134 }
01135
01136 if (ndown) {
01137 for (j=0; j<fNseg; j++) {
01138 buff.fPols[indx++] = c;
01139 buff.fPols[indx++] = 3;
01140 buff.fPols[indx++] = inddown + j;
01141 buff.fPols[indx++] = indpar + (nlat-1)*fNseg + j;
01142 buff.fPols[indx++] = inddown + (j+1)%nlong;
01143 }
01144 }
01145
01146
01147 if (TestShapeBit(kGeoRSeg)) {
01148 for (i=0; i<nlat-1; i++) {
01149 for (j=0; j<fNseg; j++) {
01150 buff.fPols[indx++] = c+1;
01151 buff.fPols[indx++] = 4;
01152 buff.fPols[indx++] = indparin+i*fNseg+j;
01153 buff.fPols[indx++] = indlongin+i*nlong+j;
01154 buff.fPols[indx++] = indparin+(i+1)*fNseg+j;
01155 buff.fPols[indx++] = indlongin+i*nlong+(j+1)%nlong;
01156 }
01157 }
01158
01159 if (nup) {
01160 for (j=0; j<fNseg; j++) {
01161 buff.fPols[indx++] = c+1;
01162 buff.fPols[indx++] = 3;
01163 buff.fPols[indx++] = indupin + j;
01164 buff.fPols[indx++] = indparin + j;
01165 buff.fPols[indx++] = indupin + (j+1)%nlong;
01166 }
01167 }
01168
01169 if (ndown) {
01170 for (j=0; j<fNseg; j++) {
01171 buff.fPols[indx++] = c+1;
01172 buff.fPols[indx++] = 3;
01173 buff.fPols[indx++] = inddownin + j;
01174 buff.fPols[indx++] = inddownin + (j+1)%nlong;
01175 buff.fPols[indx++] = indparin + (nlat-1)*fNseg + j;
01176 }
01177 }
01178 }
01179
01180 if (TestShapeBit(kGeoPhiSeg)) {
01181 for (i=0; i<nlat-1; i++) {
01182 buff.fPols[indx++] = c+2;
01183 if (TestShapeBit(kGeoRSeg)) {
01184 buff.fPols[indx++] = 4;
01185 buff.fPols[indx++] = indlong + i*nlong;
01186 buff.fPols[indx++] = indphi + i + 1;
01187 buff.fPols[indx++] = indlongin + i*nlong;
01188 buff.fPols[indx++] = indphi + i;
01189 } else {
01190 buff.fPols[indx++] = 3;
01191 buff.fPols[indx++] = indlong + i*nlong;
01192 buff.fPols[indx++] = indphi + i + 1;
01193 buff.fPols[indx++] = indphi + i;
01194 }
01195 }
01196 for (i=0; i<nlat-1; i++) {
01197 buff.fPols[indx++] = c+2;
01198 if (TestShapeBit(kGeoRSeg)) {
01199 buff.fPols[indx++] = 4;
01200 buff.fPols[indx++] = indlong + (i+1)*nlong-1;
01201 buff.fPols[indx++] = indphi + nlat + i;
01202 buff.fPols[indx++] = indlongin + (i+1)*nlong-1;
01203 buff.fPols[indx++] = indphi + nlat + i + 1;
01204 } else {
01205 buff.fPols[indx++] = 3;
01206 buff.fPols[indx++] = indlong + (i+1)*nlong-1;
01207 buff.fPols[indx++] = indphi + nlat + i;
01208 buff.fPols[indx++] = indphi + nlat + i + 1;
01209 }
01210 }
01211 if (nup) {
01212 buff.fPols[indx++] = c+2;
01213 if (TestShapeBit(kGeoRSeg)) {
01214 buff.fPols[indx++] = 4;
01215 buff.fPols[indx++] = indup;
01216 buff.fPols[indx++] = indphi;
01217 buff.fPols[indx++] = indupin;
01218 buff.fPols[indx++] = indphi + 2*nlat;
01219 } else {
01220 buff.fPols[indx++] = 3;
01221 buff.fPols[indx++] = indup;
01222 buff.fPols[indx++] = indphi;
01223 buff.fPols[indx++] = indphi + 2*nlat;
01224 }
01225 buff.fPols[indx++] = c+2;
01226 if (TestShapeBit(kGeoRSeg)) {
01227 buff.fPols[indx++] = 4;
01228 buff.fPols[indx++] = indup+nlong-1;
01229 buff.fPols[indx++] = indphi + 2*nlat;
01230 buff.fPols[indx++] = indupin+nlong-1;
01231 buff.fPols[indx++] = indphi + nlat;
01232 } else {
01233 buff.fPols[indx++] = 3;
01234 buff.fPols[indx++] = indup+nlong-1;
01235 buff.fPols[indx++] = indphi + 2*nlat;
01236 buff.fPols[indx++] = indphi + nlat;
01237 }
01238 }
01239 if (ndown) {
01240 buff.fPols[indx++] = c+2;
01241 if (TestShapeBit(kGeoRSeg)) {
01242 buff.fPols[indx++] = 4;
01243 buff.fPols[indx++] = inddown;
01244 buff.fPols[indx++] = indphi + 2*nlat + nup;
01245 buff.fPols[indx++] = inddownin;
01246 buff.fPols[indx++] = indphi + nlat-1;
01247 } else {
01248 buff.fPols[indx++] = 3;
01249 buff.fPols[indx++] = inddown;
01250 buff.fPols[indx++] = indphi + 2*nlat + nup;
01251 buff.fPols[indx++] = indphi + nlat-1;
01252 }
01253 buff.fPols[indx++] = c+2;
01254 if (TestShapeBit(kGeoRSeg)) {
01255 buff.fPols[indx++] = 4;
01256 buff.fPols[indx++] = inddown+nlong-1;
01257 buff.fPols[indx++] = indphi + 2*nlat-1;
01258 buff.fPols[indx++] = inddownin+nlong-1;
01259 buff.fPols[indx++] = indphi + 2*nlat+nup;
01260 } else {
01261 buff.fPols[indx++] = 3;
01262 buff.fPols[indx++] = inddown+nlong-1;
01263 buff.fPols[indx++] = indphi + 2*nlat-1;
01264 buff.fPols[indx++] = indphi + 2*nlat+nup;
01265 }
01266 }
01267 }
01268
01269 if (!nup) {
01270 for (j=0; j<fNseg; j++) {
01271 buff.fPols[indx++] = c+2;
01272 if (TestShapeBit(kGeoRSeg)) {
01273 buff.fPols[indx++] = 4;
01274 buff.fPols[indx++] = indpar+j;
01275 buff.fPols[indx++] = indtheta + j;
01276 buff.fPols[indx++] = indparin + j;
01277 buff.fPols[indx++] = indtheta + (j+1)%nlong;
01278 } else {
01279 buff.fPols[indx++] = 3;
01280 buff.fPols[indx++] = indpar+j;
01281 buff.fPols[indx++] = indtheta + j;
01282 buff.fPols[indx++] = indtheta + (j+1)%nlong;
01283 }
01284 }
01285 }
01286 if (!ndown) {
01287 for (j=0; j<fNseg; j++) {
01288 buff.fPols[indx++] = c+2;
01289 if (TestShapeBit(kGeoRSeg)) {
01290 buff.fPols[indx++] = 4;
01291 buff.fPols[indx++] = indpar+(nlat-1)*fNseg+j;
01292 buff.fPols[indx++] = indtheta + (1-nup)*nlong +(j+1)%nlong;
01293 buff.fPols[indx++] = indparin + (nlat-1)*fNseg + j;
01294 buff.fPols[indx++] = indtheta + (1-nup)*nlong + j;
01295 } else {
01296 buff.fPols[indx++] = 3;
01297 buff.fPols[indx++] = indpar+(nlat-1)*fNseg+j;
01298 buff.fPols[indx++] = indtheta + (1-nup)*nlong +(j+1)%nlong;
01299 buff.fPols[indx++] = indtheta + (1-nup)*nlong + j;
01300 }
01301 }
01302 }
01303 }
01304
01305
01306 Double_t TGeoSphere::Safety(Double_t *point, Bool_t in) const
01307 {
01308
01309
01310 Double_t r2 = point[0]*point[0]+point[1]*point[1]+point[2]*point[2];
01311 Double_t r=TMath::Sqrt(r2);
01312 Bool_t rzero=kFALSE;
01313 if (r<=1E-20) rzero=kTRUE;
01314
01315 Double_t th=0.;
01316 if (TestShapeBit(kGeoThetaSeg) && (!rzero)) {
01317 th = TMath::ACos(point[2]/r)*TMath::RadToDeg();
01318 }
01319 Double_t saf[4];
01320 saf[0]=(TGeoShape::IsSameWithinTolerance(fRmin,0) && !TestShapeBit(kGeoThetaSeg) && !TestShapeBit(kGeoPhiSeg))?TGeoShape::Big():r-fRmin;
01321 saf[1]=fRmax-r;
01322 saf[2]=saf[3]= TGeoShape::Big();
01323 if (TestShapeBit(kGeoThetaSeg)) {
01324 if (fTheta1>0) saf[2] = r*TMath::Sin((th-fTheta1)*TMath::DegToRad());
01325 if (fTheta2<180) saf[3] = r*TMath::Sin((fTheta2-th)*TMath::DegToRad());
01326 }
01327 Double_t safphi = TGeoShape::Big();
01328 Double_t safe = TGeoShape::Big();
01329 if (TestShapeBit(kGeoPhiSeg)) safphi = TGeoShape::SafetyPhi(point,in,fPhi1,fPhi2);
01330 if (in) {
01331 safe = saf[TMath::LocMin(4,saf)];
01332 return TMath::Min(safe,safphi);
01333 }
01334 for (Int_t i=0; i<4; i++) saf[i]=-saf[i];
01335 safe = saf[TMath::LocMax(4, saf)];
01336 if (TestShapeBit(kGeoPhiSeg)) return TMath::Max(safe, safphi);
01337 return safe;
01338 }
01339
01340
01341 void TGeoSphere::SavePrimitive(ostream &out, Option_t * )
01342 {
01343
01344 if (TObject::TestBit(kGeoSavePrimitive)) return;
01345 out << " // Shape: " << GetName() << " type: " << ClassName() << endl;
01346 out << " rmin = " << fRmin << ";" << endl;
01347 out << " rmax = " << fRmax << ";" << endl;
01348 out << " theta1 = " << fTheta1<< ";" << endl;
01349 out << " theta2 = " << fTheta2 << ";" << endl;
01350 out << " phi1 = " << fPhi1 << ";" << endl;
01351 out << " phi2 = " << fPhi2 << ";" << endl;
01352 out << " TGeoShape *" << GetPointerName() << " = new TGeoSphere(\"" << GetName() << "\",rmin,rmax,theta1, theta2,phi1,phi2);" << endl;
01353 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
01354 }
01355
01356
01357 void TGeoSphere::SetSphDimensions(Double_t rmin, Double_t rmax, Double_t theta1,
01358 Double_t theta2, Double_t phi1, Double_t phi2)
01359 {
01360
01361 if (rmin >= rmax) {
01362 Error("SetDimensions", "invalid parameters rmin/rmax");
01363 return;
01364 }
01365 fRmin = rmin;
01366 fRmax = rmax;
01367 if (rmin>0) SetShapeBit(kGeoRSeg);
01368 if (theta1 >= theta2 || theta1<0 || theta1>180 || theta2>180) {
01369 Error("SetDimensions", "invalid parameters theta1/theta2");
01370 return;
01371 }
01372 fTheta1 = theta1;
01373 fTheta2 = theta2;
01374 if ((theta2-theta1)<180.) SetShapeBit(kGeoThetaSeg);
01375 fPhi1 = phi1;
01376 if (phi1<0) fPhi1+=360.;
01377 fPhi2 = phi2;
01378 while (fPhi2<=fPhi1) fPhi2+=360.;
01379 if (!TGeoShape::IsSameWithinTolerance(TMath::Abs(phi2-phi1),360)) SetShapeBit(kGeoPhiSeg);
01380 }
01381
01382
01383 void TGeoSphere::SetDimensions(Double_t *param)
01384 {
01385
01386 Double_t rmin = param[0];
01387 Double_t rmax = param[1];
01388 Double_t theta1 = 0;
01389 Double_t theta2 = 180.;
01390 Double_t phi1 = 0;
01391 Double_t phi2 = 360.;
01392
01393
01394
01395
01396 SetSphDimensions(rmin, rmax, theta1, theta2, phi1, phi2);
01397 }
01398
01399
01400 void TGeoSphere::SetNumberOfDivisions(Int_t p)
01401 {
01402
01403 fNseg = p;
01404 Double_t dphi = fPhi2 - fPhi1;
01405 if (dphi<0) dphi+=360;
01406 Double_t dtheta = TMath::Abs(fTheta2-fTheta1);
01407 fNz = Int_t(fNseg*dtheta/dphi) +1;
01408 if (fNz<2) fNz=2;
01409 }
01410
01411
01412 void TGeoSphere::SetPoints(Double_t *points) const
01413 {
01414
01415 if (!points) {
01416 Error("SetPoints", "Input array is NULL");
01417 return;
01418 }
01419 Bool_t full = kTRUE;
01420 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
01421 Int_t ncenter = 1;
01422 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
01423 Int_t nup = (fTheta1>0)?0:1;
01424 Int_t ndown = (fTheta2<180)?0:1;
01425
01426 Int_t nlat = fNz+1-(nup+ndown);
01427
01428 Int_t nlong = fNseg;
01429 if (TestShapeBit(kGeoPhiSeg)) nlong++;
01430
01431
01432
01433 Int_t i,j ;
01434 Double_t phi1 = fPhi1*TMath::DegToRad();
01435 Double_t phi2 = fPhi2*TMath::DegToRad();
01436 Double_t dphi = (phi2-phi1)/fNseg;
01437 Double_t theta1 = fTheta1*TMath::DegToRad();
01438 Double_t theta2 = fTheta2*TMath::DegToRad();
01439 Double_t dtheta = (theta2-theta1)/fNz;
01440 Double_t z,zi,theta,phi,cphi,sphi;
01441 Int_t indx=0;
01442
01443
01444
01445
01446
01447 for (i = 0; i < nlat; i++) {
01448 theta = theta1+(nup+i)*dtheta;
01449 z = fRmax * TMath::Cos(theta);
01450 zi = fRmax * TMath::Sin(theta);
01451
01452 for (j = 0; j < nlong; j++) {
01453 phi = phi1+j*dphi;
01454 cphi = TMath::Cos(phi);
01455 sphi = TMath::Sin(phi);
01456 points[indx++] = zi * cphi;
01457 points[indx++] = zi * sphi;
01458 points[indx++] = z;
01459 }
01460 }
01461
01462 if (nup) {
01463
01464 points[indx++] = 0.;
01465 points[indx++] = 0.;
01466 points[indx++] = fRmax;
01467 }
01468 if (ndown) {
01469
01470 points[indx++] = 0.;
01471 points[indx++] = 0.;
01472 points[indx++] = -fRmax;
01473 }
01474
01475
01476 if (TestShapeBit(kGeoRSeg)) {
01477
01478 for (i = 0; i < nlat; i++) {
01479 theta = theta1+(nup+i)*dtheta;
01480 z = fRmin * TMath::Cos(theta);
01481 zi = fRmin * TMath::Sin(theta);
01482
01483 for (j = 0; j < nlong; j++) {
01484 phi = phi1+j*dphi;
01485 cphi = TMath::Cos(phi);
01486 sphi = TMath::Sin(phi);
01487 points[indx++] = zi * cphi;
01488 points[indx++] = zi * sphi;
01489 points[indx++] = z;
01490 }
01491 }
01492
01493 if (nup) {
01494
01495 points[indx++] = 0.;
01496 points[indx++] = 0.;
01497 points[indx++] = fRmin;
01498 }
01499 if (ndown) {
01500
01501 points[indx++] = 0.;
01502 points[indx++] = 0.;
01503 points[indx++] = -fRmin;
01504 }
01505 }
01506
01507 if (ncenter) {
01508
01509 points[indx++] = 0.;
01510 points[indx++] = 0.;
01511 points[indx++] = 0.;
01512 }
01513 }
01514
01515
01516 void TGeoSphere::SetPoints(Float_t *points) const
01517 {
01518
01519 if (!points) {
01520 Error("SetPoints", "Input array is NULL");
01521 return;
01522 }
01523 Bool_t full = kTRUE;
01524 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
01525 Int_t ncenter = 1;
01526 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
01527 Int_t nup = (fTheta1>0)?0:1;
01528 Int_t ndown = (fTheta2<180)?0:1;
01529
01530 Int_t nlat = fNz+1-(nup+ndown);
01531
01532 Int_t nlong = fNseg;
01533 if (TestShapeBit(kGeoPhiSeg)) nlong++;
01534
01535
01536
01537 Int_t i,j ;
01538 Double_t phi1 = fPhi1*TMath::DegToRad();
01539 Double_t phi2 = fPhi2*TMath::DegToRad();
01540 Double_t dphi = (phi2-phi1)/fNseg;
01541 Double_t theta1 = fTheta1*TMath::DegToRad();
01542 Double_t theta2 = fTheta2*TMath::DegToRad();
01543 Double_t dtheta = (theta2-theta1)/fNz;
01544 Double_t z,zi,theta,phi,cphi,sphi;
01545 Int_t indx=0;
01546
01547
01548
01549
01550
01551 for (i = 0; i < nlat; i++) {
01552 theta = theta1+(nup+i)*dtheta;
01553 z = fRmax * TMath::Cos(theta);
01554 zi = fRmax * TMath::Sin(theta);
01555
01556 for (j = 0; j < nlong; j++) {
01557 phi = phi1+j*dphi;
01558 cphi = TMath::Cos(phi);
01559 sphi = TMath::Sin(phi);
01560 points[indx++] = zi * cphi;
01561 points[indx++] = zi * sphi;
01562 points[indx++] = z;
01563 }
01564 }
01565
01566 if (nup) {
01567
01568 points[indx++] = 0.;
01569 points[indx++] = 0.;
01570 points[indx++] = fRmax;
01571 }
01572 if (ndown) {
01573
01574 points[indx++] = 0.;
01575 points[indx++] = 0.;
01576 points[indx++] = -fRmax;
01577 }
01578
01579
01580 if (TestShapeBit(kGeoRSeg)) {
01581
01582 for (i = 0; i < nlat; i++) {
01583 theta = theta1+(nup+i)*dtheta;
01584 z = fRmin * TMath::Cos(theta);
01585 zi = fRmin * TMath::Sin(theta);
01586
01587 for (j = 0; j < nlong; j++) {
01588 phi = phi1+j*dphi;
01589 cphi = TMath::Cos(phi);
01590 sphi = TMath::Sin(phi);
01591 points[indx++] = zi * cphi;
01592 points[indx++] = zi * sphi;
01593 points[indx++] = z;
01594 }
01595 }
01596
01597 if (nup) {
01598
01599 points[indx++] = 0.;
01600 points[indx++] = 0.;
01601 points[indx++] = fRmin;
01602 }
01603 if (ndown) {
01604
01605 points[indx++] = 0.;
01606 points[indx++] = 0.;
01607 points[indx++] = -fRmin;
01608 }
01609 }
01610
01611 if (ncenter) {
01612
01613 points[indx++] = 0.;
01614 points[indx++] = 0.;
01615 points[indx++] = 0.;
01616 }
01617 }
01618
01619
01620 void TGeoSphere::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
01621 {
01622
01623 TGeoSphere * localThis = const_cast<TGeoSphere *>(this);
01624 localThis->SetNumberOfDivisions(gGeoManager->GetNsegments());
01625 Bool_t full = kTRUE;
01626 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
01627 Int_t ncenter = 1;
01628 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
01629 Int_t nup = (fTheta1>0)?0:1;
01630 Int_t ndown = (fTheta2<180)?0:1;
01631
01632 Int_t nlat = fNz+1-(nup+ndown);
01633
01634 Int_t nlong = fNseg;
01635 if (TestShapeBit(kGeoPhiSeg)) nlong++;
01636
01637 nvert = nlat*nlong+nup+ndown+ncenter;
01638 if (TestShapeBit(kGeoRSeg)) nvert *= 2;
01639
01640 nsegs = nlat*fNseg + (nlat-1+nup+ndown)*nlong;
01641 if (TestShapeBit(kGeoRSeg)) nsegs *= 2;
01642 if (TestShapeBit(kGeoPhiSeg)) nsegs += 2*nlat+nup+ndown;
01643 nsegs += nlong * (2-nup - ndown);
01644
01645 npols = fNz*fNseg;
01646 if (TestShapeBit(kGeoRSeg)) npols *=2;
01647 if (TestShapeBit(kGeoPhiSeg)) npols += 2*fNz;
01648 npols += (2-nup-ndown)*fNseg;
01649 }
01650
01651
01652 Int_t TGeoSphere::GetNmeshVertices() const
01653 {
01654
01655 Bool_t full = kTRUE;
01656 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
01657 Int_t ncenter = 1;
01658 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
01659 Int_t nup = (fTheta1>0)?0:1;
01660 Int_t ndown = (fTheta2<180)?0:1;
01661
01662 Int_t nlat = fNz+1-(nup+ndown);
01663
01664 Int_t nlong = fNseg;
01665 if (TestShapeBit(kGeoPhiSeg)) nlong++;
01666
01667
01668
01669 Int_t numPoints = 0;
01670 if (TestShapeBit(kGeoRSeg)) numPoints = 2*(nlat*nlong+nup+ndown);
01671 else numPoints = nlat*nlong+nup+ndown+ncenter;
01672 return numPoints;
01673 }
01674
01675
01676 void TGeoSphere::Sizeof3D() const
01677 {
01678
01679 }
01680
01681
01682 const TBuffer3D & TGeoSphere::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
01683 {
01684
01685 static TBuffer3DSphere buffer;
01686
01687 TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
01688
01689 if (reqSections & TBuffer3D::kShapeSpecific) {
01690 buffer.fRadiusInner = fRmin;
01691 buffer.fRadiusOuter = fRmax;
01692 buffer.fThetaMin = fTheta1;
01693 buffer.fThetaMax = fTheta2;
01694 buffer.fPhiMin = fPhi1;
01695 buffer.fPhiMax = fPhi2;
01696 buffer.SetSectionsValid(TBuffer3D::kShapeSpecific);
01697 }
01698 if (reqSections & TBuffer3D::kRawSizes) {
01699
01700 TGeoSphere * localThis = const_cast<TGeoSphere *>(this);
01701 localThis->SetNumberOfDivisions(gGeoManager->GetNsegments());
01702
01703 Bool_t full = kTRUE;
01704 if (TestShapeBit(kGeoThetaSeg) || TestShapeBit(kGeoPhiSeg)) full = kFALSE;
01705 Int_t ncenter = 1;
01706 if (full || TestShapeBit(kGeoRSeg)) ncenter = 0;
01707 Int_t nup = (fTheta1>0)?0:1;
01708 Int_t ndown = (fTheta2<180)?0:1;
01709
01710 Int_t nlat = fNz+1-(nup+ndown);
01711
01712 Int_t nlong = fNseg;
01713 if (TestShapeBit(kGeoPhiSeg)) nlong++;
01714
01715 Int_t nbPnts = nlat*nlong+nup+ndown+ncenter;
01716 if (TestShapeBit(kGeoRSeg)) nbPnts *= 2;
01717
01718 Int_t nbSegs = nlat*fNseg + (nlat-1+nup+ndown)*nlong;
01719 if (TestShapeBit(kGeoRSeg)) nbSegs *= 2;
01720 if (TestShapeBit(kGeoPhiSeg)) nbSegs += 2*nlat+nup+ndown;
01721 nbSegs += nlong * (2-nup - ndown);
01722
01723 Int_t nbPols = fNz*fNseg;
01724 if (TestShapeBit(kGeoRSeg)) nbPols *=2;
01725 if (TestShapeBit(kGeoPhiSeg)) nbPols += 2*fNz;
01726 nbPols += (2-nup-ndown)*fNseg;
01727
01728 if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
01729 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
01730 }
01731 }
01732 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
01733 SetPoints(buffer.fPnts);
01734 if (!buffer.fLocalFrame) {
01735 TransformPoints(buffer.fPnts, buffer.NbPnts());
01736 }
01737 SetSegsAndPols(buffer);
01738 buffer.SetSectionsValid(TBuffer3D::kRaw);
01739 }
01740
01741 return buffer;
01742 }