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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #include "Riostream.h"
00075
00076 #include "TGeoManager.h"
00077 #include "TGeoMatrix.h"
00078 #include "TGeoVolume.h"
00079 #include "TVirtualGeoPainter.h"
00080 #include "TGeoBBox.h"
00081 #include "TVirtualPad.h"
00082 #include "TBuffer3D.h"
00083 #include "TBuffer3DTypes.h"
00084 #include "TMath.h"
00085 #include "TRandom.h"
00086
00087 ClassImp(TGeoBBox)
00088
00089
00090 TGeoBBox::TGeoBBox()
00091 {
00092
00093 SetShapeBit(TGeoShape::kGeoBox);
00094 fDX = fDY = fDZ = 0;
00095 fOrigin[0] = fOrigin[1] = fOrigin[2] = 0.0;
00096 }
00097
00098
00099 TGeoBBox::TGeoBBox(Double_t dx, Double_t dy, Double_t dz, Double_t *origin)
00100 :TGeoShape("")
00101 {
00102
00103 SetShapeBit(TGeoShape::kGeoBox);
00104 fOrigin[0] = fOrigin[1] = fOrigin[2] = 0.0;
00105 SetBoxDimensions(dx, dy, dz, origin);
00106 }
00107
00108
00109 TGeoBBox::TGeoBBox(const char *name, Double_t dx, Double_t dy, Double_t dz, Double_t *origin)
00110 :TGeoShape(name)
00111 {
00112
00113 SetShapeBit(TGeoShape::kGeoBox);
00114 fOrigin[0] = fOrigin[1] = fOrigin[2] = 0.0;
00115 SetBoxDimensions(dx, dy, dz, origin);
00116 }
00117
00118
00119 TGeoBBox::TGeoBBox(Double_t *param)
00120 :TGeoShape("")
00121 {
00122
00123
00124
00125
00126 SetShapeBit(TGeoShape::kGeoBox);
00127 fOrigin[0] = fOrigin[1] = fOrigin[2] = 0.0;
00128 SetDimensions(param);
00129 }
00130
00131
00132 TGeoBBox::~TGeoBBox()
00133 {
00134
00135 }
00136
00137
00138 Bool_t TGeoBBox::AreOverlapping(const TGeoBBox *box1, const TGeoMatrix *mat1, const TGeoBBox *box2, const TGeoMatrix *mat2)
00139 {
00140
00141 Double_t master[3];
00142 Double_t local[3];
00143 Double_t ldir1[3], ldir2[3];
00144 const Double_t *o1 = box1->GetOrigin();
00145 const Double_t *o2 = box2->GetOrigin();
00146
00147 mat1->LocalToMaster(o1, master);
00148 mat2->MasterToLocal(master, local);
00149 if (TGeoBBox::Contains(local,box2->GetDX(),box2->GetDY(),box2->GetDZ(),o2)) return kTRUE;
00150 Double_t distsq = (local[0]-o2[0])*(local[0]-o2[0]) +
00151 (local[1]-o2[1])*(local[1]-o2[1]) +
00152 (local[2]-o2[2])*(local[2]-o2[2]);
00153
00154 Double_t rmaxsq = (box1->GetDX()+box2->GetDX())*(box1->GetDX()+box2->GetDX()) +
00155 (box1->GetDY()+box2->GetDY())*(box1->GetDY()+box2->GetDY()) +
00156 (box1->GetDZ()+box2->GetDZ())*(box1->GetDZ()+box2->GetDZ());
00157 if (distsq > rmaxsq + TGeoShape::Tolerance()) return kFALSE;
00158
00159
00160 Double_t dir[3];
00161 mat1->LocalToMaster(o1, ldir1);
00162 mat2->LocalToMaster(o2, ldir2);
00163 distsq = 1./TMath::Sqrt(distsq);
00164 dir[0] = (ldir2[0]-ldir1[0])*distsq;
00165 dir[1] = (ldir2[1]-ldir1[1])*distsq;
00166 dir[2] = (ldir2[2]-ldir1[2])*distsq;
00167 mat1->MasterToLocalVect(dir, ldir1);
00168 mat2->MasterToLocalVect(dir, ldir2);
00169
00170 Double_t dist1 = TGeoBBox::DistFromInside(o1,ldir1,box1->GetDX(),box1->GetDY(),box1->GetDZ(),o1);
00171
00172 Double_t dist2 = TGeoBBox::DistFromOutside(local,ldir2,box2->GetDX(),box2->GetDY(),box2->GetDZ(),o2);
00173 if (dist1 > dist2) return kTRUE;
00174 return kFALSE;
00175 }
00176
00177
00178 Double_t TGeoBBox::Capacity() const
00179 {
00180
00181 return (8.*fDX*fDY*fDZ);
00182 }
00183
00184
00185 void TGeoBBox::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
00186 {
00187
00188 memset(norm,0,3*sizeof(Double_t));
00189 Double_t saf[3];
00190 Int_t i;
00191 saf[0]=TMath::Abs(TMath::Abs(point[0]-fOrigin[0])-fDX);
00192 saf[1]=TMath::Abs(TMath::Abs(point[1]-fOrigin[1])-fDY);
00193 saf[2]=TMath::Abs(TMath::Abs(point[2]-fOrigin[2])-fDZ);
00194 i = TMath::LocMin(3,saf);
00195 norm[i] = (dir[i]>0)?1:(-1);
00196 }
00197
00198
00199 Bool_t TGeoBBox::CouldBeCrossed(Double_t *point, Double_t *dir) const
00200 {
00201
00202 Double_t mind = fDX;
00203 if (fDY<mind) mind=fDY;
00204 if (fDZ<mind) mind=fDZ;
00205 Double_t dx = fOrigin[0]-point[0];
00206 Double_t dy = fOrigin[1]-point[1];
00207 Double_t dz = fOrigin[2]-point[2];
00208 Double_t do2 = dx*dx+dy*dy+dz*dz;
00209 if (do2<=(mind*mind)) return kTRUE;
00210 Double_t rmax2 = fDX*fDX+fDY*fDY+fDZ*fDZ;
00211 if (do2<=rmax2) return kTRUE;
00212
00213 Double_t doct = dx*dir[0]+dy*dir[1]+dz*dir[2];
00214
00215 if (doct<=0) return kFALSE;
00216 Double_t dirnorm=dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2];
00217 if ((doct*doct)>=(do2-rmax2)*dirnorm) return kTRUE;
00218 return kFALSE;
00219 }
00220
00221
00222 Int_t TGeoBBox::DistancetoPrimitive(Int_t px, Int_t py)
00223 {
00224
00225 const Int_t numPoints = 8;
00226 return ShapeDistancetoPrimitive(numPoints, px, py);
00227 }
00228
00229
00230 TGeoVolume *TGeoBBox::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
00231 Double_t start, Double_t step)
00232 {
00233
00234
00235
00236
00237 TGeoShape *shape;
00238 TGeoVolume *vol;
00239 TGeoVolumeMulti *vmulti;
00240 TGeoPatternFinder *finder;
00241 TString opt = "";
00242 Double_t end = start+ndiv*step;
00243 switch (iaxis) {
00244 case 1:
00245 shape = new TGeoBBox(step/2., fDY, fDZ);
00246 finder = new TGeoPatternX(voldiv, ndiv, start, end);
00247 opt = "X";
00248 break;
00249 case 2:
00250 shape = new TGeoBBox(fDX, step/2., fDZ);
00251 finder = new TGeoPatternY(voldiv, ndiv, start, end);
00252 opt = "Y";
00253 break;
00254 case 3:
00255 shape = new TGeoBBox(fDX, fDY, step/2.);
00256 finder = new TGeoPatternZ(voldiv, ndiv, start, end);
00257 opt = "Z";
00258 break;
00259 default:
00260 Error("Divide", "Wrong axis type for division");
00261 return 0;
00262 }
00263 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
00264 vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
00265 vmulti->AddVolume(vol);
00266 voldiv->SetFinder(finder);
00267 finder->SetDivIndex(voldiv->GetNdaughters());
00268 for (Int_t ic=0; ic<ndiv; ic++) {
00269 voldiv->AddNodeOffset(vol, ic, start+step/2.+ic*step, opt.Data());
00270 ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
00271 }
00272 return vmulti;
00273 }
00274
00275
00276 void TGeoBBox::ComputeBBox()
00277 {
00278
00279 }
00280
00281
00282 Bool_t TGeoBBox::Contains(Double_t *point) const
00283 {
00284
00285 if (TMath::Abs(point[2]-fOrigin[2]) > fDZ) return kFALSE;
00286 if (TMath::Abs(point[0]-fOrigin[0]) > fDX) return kFALSE;
00287 if (TMath::Abs(point[1]-fOrigin[1]) > fDY) return kFALSE;
00288 return kTRUE;
00289 }
00290
00291
00292 Bool_t TGeoBBox::Contains(const Double_t *point, Double_t dx, Double_t dy, Double_t dz, const Double_t *origin)
00293 {
00294
00295 if (TMath::Abs(point[2]-origin[2]) > dz) return kFALSE;
00296 if (TMath::Abs(point[0]-origin[0]) > dx) return kFALSE;
00297 if (TMath::Abs(point[1]-origin[1]) > dy) return kFALSE;
00298 return kTRUE;
00299 }
00300
00301
00302 Double_t TGeoBBox::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00303 {
00304
00305
00306 Double_t s,smin,saf[6];
00307 Double_t newpt[3];
00308 Int_t i;
00309 for (i=0; i<3; i++) newpt[i] = point[i] - fOrigin[i];
00310 saf[0] = fDX+newpt[0];
00311 saf[1] = fDX-newpt[0];
00312 saf[2] = fDY+newpt[1];
00313 saf[3] = fDY-newpt[1];
00314 saf[4] = fDZ+newpt[2];
00315 saf[5] = fDZ-newpt[2];
00316 if (iact<3 && safe) {
00317 smin = saf[0];
00318
00319 for (i=1;i<6;i++) if (saf[i] < smin) smin = saf[i];
00320 *safe = smin;
00321 if (smin<0) *safe = 0.0;
00322 if (iact==0) return TGeoShape::Big();
00323 if (iact==1 && step<*safe) return TGeoShape::Big();
00324 }
00325
00326 smin=TGeoShape::Big();
00327 for (i=0; i<3; i++) {
00328 if (dir[i]!=0) {
00329 s = (dir[i]>0)?(saf[(i<<1)+1]/dir[i]):(-saf[i<<1]/dir[i]);
00330 if (s < 0) return 0.0;
00331 if (s < smin) smin = s;
00332 }
00333 }
00334 return smin;
00335 }
00336
00337
00338 Double_t TGeoBBox::DistFromInside(const Double_t *point,const Double_t *dir,
00339 Double_t dx, Double_t dy, Double_t dz, const Double_t *origin, Double_t )
00340 {
00341
00342
00343 Double_t s,smin,saf[6];
00344 Double_t newpt[3];
00345 Int_t i;
00346 for (i=0; i<3; i++) newpt[i] = point[i] - origin[i];
00347 saf[0] = dx+newpt[0];
00348 saf[1] = dx-newpt[0];
00349 saf[2] = dy+newpt[1];
00350 saf[3] = dy-newpt[1];
00351 saf[4] = dz+newpt[2];
00352 saf[5] = dz-newpt[2];
00353
00354 smin=TGeoShape::Big();
00355 for (i=0; i<3; i++) {
00356 if (dir[i]!=0) {
00357 s = (dir[i]>0)?(saf[(i<<1)+1]/dir[i]):(-saf[i<<1]/dir[i]);
00358 if (s < 0) return 0.0;
00359 if (s < smin) smin = s;
00360 }
00361 }
00362 return smin;
00363 }
00364
00365
00366 Double_t TGeoBBox::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00367 {
00368
00369
00370 Bool_t in = kTRUE;
00371 Double_t saf[3];
00372 Double_t par[3];
00373 Double_t newpt[3];
00374 Int_t i,j;
00375 for (i=0; i<3; i++) newpt[i] = point[i] - fOrigin[i];
00376 par[0] = fDX;
00377 par[1] = fDY;
00378 par[2] = fDZ;
00379 for (i=0; i<3; i++) {
00380 saf[i] = TMath::Abs(newpt[i])-par[i];
00381 if (saf[i]>=step) return TGeoShape::Big();
00382 if (in && saf[i]>0) in=kFALSE;
00383 }
00384 if (iact<3 && safe) {
00385
00386 if (in) {
00387 *safe = 0.0;
00388 } else {
00389 *safe = saf[0];
00390 if (saf[1] > *safe) *safe = saf[1];
00391 if (saf[2] > *safe) *safe = saf[2];
00392 }
00393 if (iact==0) return TGeoShape::Big();
00394 if (iact==1 && step<*safe) return TGeoShape::Big();
00395 }
00396
00397 Double_t coord, snxt=TGeoShape::Big();
00398 Int_t ibreak=0;
00399
00400 if (in) {
00401 j = 0;
00402 Double_t ss = saf[0];
00403 if (saf[1]>ss) {
00404 ss = saf[1];
00405 j = 1;
00406 }
00407 if (saf[2]>ss) j = 2;
00408 if (newpt[j]*dir[j]>0) return TGeoShape::Big();
00409 return 0.0;
00410 }
00411 for (i=0; i<3; i++) {
00412 if (saf[i]<0) continue;
00413 if (newpt[i]*dir[i] >= 0) continue;
00414 snxt = saf[i]/TMath::Abs(dir[i]);
00415 ibreak = 0;
00416 for (j=0; j<3; j++) {
00417 if (j==i) continue;
00418 coord=newpt[j]+snxt*dir[j];
00419 if (TMath::Abs(coord)>par[j]) {
00420 ibreak=1;
00421 break;
00422 }
00423 }
00424 if (!ibreak) return snxt;
00425 }
00426 return TGeoShape::Big();
00427 }
00428
00429
00430 Double_t TGeoBBox::DistFromOutside(const Double_t *point,const Double_t *dir,
00431 Double_t dx, Double_t dy, Double_t dz, const Double_t *origin, Double_t stepmax)
00432 {
00433
00434
00435 Bool_t in = kTRUE;
00436 Double_t saf[3];
00437 Double_t par[3];
00438 Double_t newpt[3];
00439 Int_t i,j;
00440 for (i=0; i<3; i++) newpt[i] = point[i] - origin[i];
00441 par[0] = dx;
00442 par[1] = dy;
00443 par[2] = dz;
00444 for (i=0; i<3; i++) {
00445 saf[i] = TMath::Abs(newpt[i])-par[i];
00446 if (saf[i]>=stepmax) return TGeoShape::Big();
00447 if (in && saf[i]>0) in=kFALSE;
00448 }
00449
00450 if (in) return 0.0;
00451 Double_t coord, snxt=TGeoShape::Big();
00452 Int_t ibreak=0;
00453 for (i=0; i<3; i++) {
00454 if (saf[i]<0) continue;
00455 if (newpt[i]*dir[i] >= 0) continue;
00456 snxt = saf[i]/TMath::Abs(dir[i]);
00457 ibreak = 0;
00458 for (j=0; j<3; j++) {
00459 if (j==i) continue;
00460 coord=newpt[j]+snxt*dir[j];
00461 if (TMath::Abs(coord)>par[j]) {
00462 ibreak=1;
00463 break;
00464 }
00465 }
00466 if (!ibreak) return snxt;
00467 }
00468 return TGeoShape::Big();
00469 }
00470
00471
00472 const char *TGeoBBox::GetAxisName(Int_t iaxis) const
00473 {
00474
00475 switch (iaxis) {
00476 case 1:
00477 return "X";
00478 case 2:
00479 return "Y";
00480 case 3:
00481 return "Z";
00482 default:
00483 return "UNDEFINED";
00484 }
00485 }
00486
00487
00488 Double_t TGeoBBox::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
00489 {
00490
00491 xlo = 0;
00492 xhi = 0;
00493 Double_t dx = 0;
00494 switch (iaxis) {
00495 case 1:
00496 xlo = fOrigin[0]-fDX;
00497 xhi = fOrigin[0]+fDX;
00498 dx = 2*fDX;
00499 return dx;
00500 case 2:
00501 xlo = fOrigin[1]-fDY;
00502 xhi = fOrigin[1]+fDY;
00503 dx = 2*fDY;
00504 return dx;
00505 case 3:
00506 xlo = fOrigin[2]-fDZ;
00507 xhi = fOrigin[2]+fDZ;
00508 dx = 2*fDZ;
00509 return dx;
00510 }
00511 return dx;
00512 }
00513
00514
00515 void TGeoBBox::GetBoundingCylinder(Double_t *param) const
00516 {
00517
00518
00519 param[0] = 0.;
00520 param[1] = fDX*fDX+fDY*fDY;
00521 param[2] = 0.;
00522 param[3] = 360.;
00523 }
00524
00525
00526 Double_t TGeoBBox::GetFacetArea(Int_t index) const
00527 {
00528
00529
00530
00531
00532 Double_t area = 0.;
00533 switch (index) {
00534 case 0:
00535 area = 8.*(fDX*fDY + fDX*fDZ + fDY*fDZ);
00536 return area;
00537 case 1:
00538 case 6:
00539 area = 4.*fDX*fDY;
00540 return area;
00541 case 2:
00542 case 4:
00543 area = 4.*fDX*fDZ;
00544 return area;
00545 case 3:
00546 case 5:
00547 area = 4.*fDY*fDZ;
00548 return area;
00549 }
00550 return area;
00551 }
00552
00553
00554 Bool_t TGeoBBox::GetPointsOnFacet(Int_t index, Int_t npoints, Double_t *array) const
00555 {
00556
00557
00558
00559
00560
00561
00562 if (index<0 || index>6) return kFALSE;
00563 Double_t surf[6];
00564 Double_t area = 0.;
00565 if (index==0) {
00566 for (Int_t isurf=0; isurf<6; isurf++) {
00567 surf[isurf] = TGeoBBox::GetFacetArea(isurf+1);
00568 if (isurf>0) surf[isurf] += surf[isurf-1];
00569 }
00570 area = surf[5];
00571 }
00572
00573 for (Int_t i=0; i<npoints; i++) {
00574
00575 Double_t *point = &array[3*i];
00576 Int_t surfindex = index;
00577 if (surfindex==0) {
00578 Double_t val = area*gRandom->Rndm();
00579 surfindex = 2+TMath::BinarySearch(6, surf, val);
00580 if (surfindex>6) surfindex=6;
00581 }
00582 switch (surfindex) {
00583 case 1:
00584 point[0] = -fDX + 2*fDX*gRandom->Rndm();
00585 point[1] = -fDY + 2*fDY*gRandom->Rndm();
00586 point[2] = -fDZ;
00587 break;
00588 case 2:
00589 point[0] = -fDX + 2*fDX*gRandom->Rndm();
00590 point[1] = -fDY;
00591 point[2] = -fDZ + 2*fDZ*gRandom->Rndm();
00592 break;
00593 case 3:
00594 point[0] = -fDX;
00595 point[1] = -fDY + 2*fDY*gRandom->Rndm();
00596 point[2] = -fDZ + 2*fDZ*gRandom->Rndm();
00597 break;
00598 case 4:
00599 point[0] = -fDX + 2*fDX*gRandom->Rndm();
00600 point[1] = fDY;
00601 point[2] = -fDZ + 2*fDZ*gRandom->Rndm();
00602 break;
00603 case 5:
00604 point[0] = fDX;
00605 point[1] = -fDY + 2*fDY*gRandom->Rndm();
00606 point[2] = -fDZ + 2*fDZ*gRandom->Rndm();
00607 break;
00608 case 6:
00609 point[0] = -fDX + 2*fDX*gRandom->Rndm();
00610 point[1] = -fDY + 2*fDY*gRandom->Rndm();
00611 point[2] = fDZ;
00612 break;
00613 }
00614 }
00615 return kTRUE;
00616 }
00617
00618
00619 Bool_t TGeoBBox::GetPointsOnSegments(Int_t npoints, Double_t *array) const
00620 {
00621
00622
00623
00624 if (npoints<GetNmeshVertices()) {
00625 Error("GetPointsOnSegments", "You should require at least %d points", GetNmeshVertices());
00626 return kFALSE;
00627 }
00628 TBuffer3D &buff = (TBuffer3D &)GetBuffer3D(TBuffer3D::kRawSizes | TBuffer3D::kRaw, kTRUE);
00629 Int_t npnts = buff.NbPnts();
00630 Int_t nsegs = buff.NbSegs();
00631
00632 memcpy(array, buff.fPnts, 3*npnts*sizeof(Double_t));
00633 Int_t ipoints = npoints - npnts;
00634 Int_t icrt = 3*npnts;
00635 Int_t nperseg = (Int_t)(Double_t(ipoints)/nsegs);
00636 Double_t *p0, *p1;
00637 Double_t x,y,z, dx,dy,dz;
00638 for (Int_t i=0; i<nsegs; i++) {
00639 p0 = &array[3*buff.fSegs[3*i+1]];
00640 p1 = &array[3*buff.fSegs[3*i+2]];
00641 if (i==(nsegs-1)) nperseg = ipoints;
00642 dx = (p1[0]-p0[0])/(nperseg+1);
00643 dy = (p1[1]-p0[1])/(nperseg+1);
00644 dz = (p1[2]-p0[2])/(nperseg+1);
00645 for (Int_t j=0; j<nperseg; j++) {
00646 x = p0[0] + (j+1)*dx;
00647 y = p0[1] + (j+1)*dy;
00648 z = p0[2] + (j+1)*dz;
00649 array[icrt++] = x; array[icrt++] = y; array[icrt++] = z;
00650 ipoints--;
00651 }
00652 }
00653 return kTRUE;
00654 }
00655
00656
00657 Int_t TGeoBBox::GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const
00658 {
00659
00660 dx=dy=dz=0;
00661 if (mat->IsRotation()) {
00662 Error("GetFittingBox", "cannot handle parametrized rotated volumes");
00663 return 1;
00664 }
00665
00666 Double_t origin[3];
00667 mat->LocalToMaster(parambox->GetOrigin(), origin);
00668 if (!Contains(origin)) {
00669 Error("GetFittingBox", "wrong matrix - parametrized box is outside this");
00670 return 1;
00671 }
00672
00673 Double_t xlo=0, xhi=0;
00674 Double_t dd[3];
00675 dd[0] = parambox->GetDX();
00676 dd[1] = parambox->GetDY();
00677 dd[2] = parambox->GetDZ();
00678 for (Int_t iaxis=0; iaxis<3; iaxis++) {
00679 if (dd[iaxis]>=0) continue;
00680 TGeoBBox::GetAxisRange(iaxis+1, xlo, xhi);
00681
00682 dd[iaxis] = TMath::Min(origin[iaxis]-xlo, xhi-origin[iaxis]);
00683 if (dd[iaxis]<0) {
00684 Error("GetFittingBox", "wrong matrix");
00685 return 1;
00686 }
00687 }
00688 dx = dd[0];
00689 dy = dd[1];
00690 dz = dd[2];
00691 return 0;
00692 }
00693
00694
00695 TGeoShape *TGeoBBox::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const
00696 {
00697
00698
00699 if (!TestShapeBit(kGeoRunTimeShape)) return 0;
00700 Double_t dx, dy, dz;
00701 Int_t ierr = mother->GetFittingBox(this, mat, dx, dy, dz);
00702 if (ierr) {
00703 Error("GetMakeRuntimeShape", "cannot fit this to mother");
00704 return 0;
00705 }
00706 return (new TGeoBBox(dx, dy, dz));
00707 }
00708
00709
00710 void TGeoBBox::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
00711 {
00712
00713 nvert = 8;
00714 nsegs = 12;
00715 npols = 6;
00716 }
00717
00718
00719 void TGeoBBox::InspectShape() const
00720 {
00721
00722 printf("*** Shape %s: TGeoBBox ***\n", GetName());
00723 printf(" dX = %11.5f\n", fDX);
00724 printf(" dY = %11.5f\n", fDY);
00725 printf(" dZ = %11.5f\n", fDZ);
00726 printf(" origin: x=%11.5f y=%11.5f z=%11.5f\n", fOrigin[0], fOrigin[1], fOrigin[2]);
00727 }
00728
00729
00730 TBuffer3D *TGeoBBox::MakeBuffer3D() const
00731 {
00732
00733
00734 TBuffer3D* buff = new TBuffer3D(TBuffer3DTypes::kGeneric, 8, 24, 12, 36, 6, 36);
00735 if (buff)
00736 {
00737 SetPoints(buff->fPnts);
00738 SetSegsAndPols(*buff);
00739 }
00740
00741 return buff;
00742 }
00743
00744
00745 void TGeoBBox::SetSegsAndPols(TBuffer3D &buff) const
00746 {
00747
00748 Int_t c = GetBasicColor();
00749
00750 buff.fSegs[ 0] = c ; buff.fSegs[ 1] = 0 ; buff.fSegs[ 2] = 1 ;
00751 buff.fSegs[ 3] = c+1 ; buff.fSegs[ 4] = 1 ; buff.fSegs[ 5] = 2 ;
00752 buff.fSegs[ 6] = c+1 ; buff.fSegs[ 7] = 2 ; buff.fSegs[ 8] = 3 ;
00753 buff.fSegs[ 9] = c ; buff.fSegs[10] = 3 ; buff.fSegs[11] = 0 ;
00754 buff.fSegs[12] = c+2 ; buff.fSegs[13] = 4 ; buff.fSegs[14] = 5 ;
00755 buff.fSegs[15] = c+2 ; buff.fSegs[16] = 5 ; buff.fSegs[17] = 6 ;
00756 buff.fSegs[18] = c+3 ; buff.fSegs[19] = 6 ; buff.fSegs[20] = 7 ;
00757 buff.fSegs[21] = c+3 ; buff.fSegs[22] = 7 ; buff.fSegs[23] = 4 ;
00758 buff.fSegs[24] = c ; buff.fSegs[25] = 0 ; buff.fSegs[26] = 4 ;
00759 buff.fSegs[27] = c+2 ; buff.fSegs[28] = 1 ; buff.fSegs[29] = 5 ;
00760 buff.fSegs[30] = c+1 ; buff.fSegs[31] = 2 ; buff.fSegs[32] = 6 ;
00761 buff.fSegs[33] = c+3 ; buff.fSegs[34] = 3 ; buff.fSegs[35] = 7 ;
00762
00763 buff.fPols[ 0] = c ; buff.fPols[ 1] = 4 ; buff.fPols[ 2] = 0 ;
00764 buff.fPols[ 3] = 9 ; buff.fPols[ 4] = 4 ; buff.fPols[ 5] = 8 ;
00765 buff.fPols[ 6] = c+1 ; buff.fPols[ 7] = 4 ; buff.fPols[ 8] = 1 ;
00766 buff.fPols[ 9] = 10 ; buff.fPols[10] = 5 ; buff.fPols[11] = 9 ;
00767 buff.fPols[12] = c ; buff.fPols[13] = 4 ; buff.fPols[14] = 2 ;
00768 buff.fPols[15] = 11 ; buff.fPols[16] = 6 ; buff.fPols[17] = 10 ;
00769 buff.fPols[18] = c+1 ; buff.fPols[19] = 4 ; buff.fPols[20] = 3 ;
00770 buff.fPols[21] = 8 ; buff.fPols[22] = 7 ; buff.fPols[23] = 11 ;
00771 buff.fPols[24] = c+2 ; buff.fPols[25] = 4 ; buff.fPols[26] = 0 ;
00772 buff.fPols[27] = 3 ; buff.fPols[28] = 2 ; buff.fPols[29] = 1 ;
00773 buff.fPols[30] = c+3 ; buff.fPols[31] = 4 ; buff.fPols[32] = 4 ;
00774 buff.fPols[33] = 5 ; buff.fPols[34] = 6 ; buff.fPols[35] = 7 ;
00775 }
00776
00777
00778 Double_t TGeoBBox::Safety(Double_t *point, Bool_t in) const
00779 {
00780
00781
00782 Double_t safe, safy, safz;
00783 if (in) {
00784 safe = fDX - TMath::Abs(point[0]-fOrigin[0]);
00785 safy = fDY - TMath::Abs(point[1]-fOrigin[1]);
00786 safz = fDZ - TMath::Abs(point[2]-fOrigin[2]);
00787 if (safy < safe) safe = safy;
00788 if (safz < safe) safe = safz;
00789 } else {
00790 safe = -fDX + TMath::Abs(point[0]-fOrigin[0]);
00791 safy = -fDY + TMath::Abs(point[1]-fOrigin[1]);
00792 safz = -fDZ + TMath::Abs(point[2]-fOrigin[2]);
00793 if (safy > safe) safe = safy;
00794 if (safz > safe) safe = safz;
00795 }
00796 return safe;
00797 }
00798
00799
00800 void TGeoBBox::SavePrimitive(ostream &out, Option_t * )
00801 {
00802
00803 if (TObject::TestBit(kGeoSavePrimitive)) return;
00804 out << " // Shape: " << GetName() << " type: " << ClassName() << endl;
00805 out << " dx = " << fDX << ";" << endl;
00806 out << " dy = " << fDY << ";" << endl;
00807 out << " dz = " << fDZ << ";" << endl;
00808 if (!TGeoShape::IsSameWithinTolerance(fOrigin[0],0) ||
00809 !TGeoShape::IsSameWithinTolerance(fOrigin[1],0) ||
00810 !TGeoShape::IsSameWithinTolerance(fOrigin[2],0)) {
00811 out << " origin[0] = " << fOrigin[0] << ";" << endl;
00812 out << " origin[1] = " << fOrigin[1] << ";" << endl;
00813 out << " origin[2] = " << fOrigin[2] << ";" << endl;
00814 out << " TGeoShape *" << GetPointerName() << " = new TGeoBBox(\"" << GetName() << "\", dx,dy,dz,origin);" << endl;
00815 } else {
00816 out << " TGeoShape *" << GetPointerName() << " = new TGeoBBox(\"" << GetName() << "\", dx,dy,dz);" << endl;
00817 }
00818 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
00819 }
00820
00821
00822 void TGeoBBox::SetBoxDimensions(Double_t dx, Double_t dy, Double_t dz, Double_t *origin)
00823 {
00824
00825 fDX = dx;
00826 fDY = dy;
00827 fDZ = dz;
00828 if (origin) {
00829 fOrigin[0] = origin[0];
00830 fOrigin[1] = origin[1];
00831 fOrigin[2] = origin[2];
00832 }
00833 if (TMath::Abs(fDX)<TGeoShape::Tolerance() &&
00834 TMath::Abs(fDY)<TGeoShape::Tolerance() &&
00835 TMath::Abs(fDZ)<TGeoShape::Tolerance()) return;
00836 if ((fDX<0) || (fDY<0) || (fDZ<0)) SetShapeBit(kGeoRunTimeShape);
00837 }
00838
00839
00840 void TGeoBBox::SetDimensions(Double_t *param)
00841 {
00842
00843
00844
00845
00846 if (!param) {
00847 Error("SetDimensions", "null parameters");
00848 return;
00849 }
00850 fDX = param[0];
00851 fDY = param[1];
00852 fDZ = param[2];
00853 if (TMath::Abs(fDX)<TGeoShape::Tolerance() &&
00854 TMath::Abs(fDY)<TGeoShape::Tolerance() &&
00855 TMath::Abs(fDZ)<TGeoShape::Tolerance()) return;
00856 if ((fDX<0) || (fDY<0) || (fDZ<0)) SetShapeBit(kGeoRunTimeShape);
00857 }
00858
00859
00860 void TGeoBBox::SetBoxPoints(Double_t *points) const
00861 {
00862
00863 TGeoBBox::SetPoints(points);
00864 }
00865
00866
00867 void TGeoBBox::SetPoints(Double_t *points) const
00868 {
00869
00870 if (!points) return;
00871 Double_t xmin,xmax,ymin,ymax,zmin,zmax;
00872 xmin = -fDX+fOrigin[0];
00873 xmax = fDX+fOrigin[0];
00874 ymin = -fDY+fOrigin[1];
00875 ymax = fDY+fOrigin[1];
00876 zmin = -fDZ+fOrigin[2];
00877 zmax = fDZ+fOrigin[2];
00878 points[ 0] = xmin; points[ 1] = ymin; points[ 2] = zmin;
00879 points[ 3] = xmin; points[ 4] = ymax; points[ 5] = zmin;
00880 points[ 6] = xmax; points[ 7] = ymax; points[ 8] = zmin;
00881 points[ 9] = xmax; points[10] = ymin; points[11] = zmin;
00882 points[12] = xmin; points[13] = ymin; points[14] = zmax;
00883 points[15] = xmin; points[16] = ymax; points[17] = zmax;
00884 points[18] = xmax; points[19] = ymax; points[20] = zmax;
00885 points[21] = xmax; points[22] = ymin; points[23] = zmax;
00886 }
00887
00888
00889 void TGeoBBox::SetPoints(Float_t *points) const
00890 {
00891
00892 if (!points) return;
00893 Double_t xmin,xmax,ymin,ymax,zmin,zmax;
00894 xmin = -fDX+fOrigin[0];
00895 xmax = fDX+fOrigin[0];
00896 ymin = -fDY+fOrigin[1];
00897 ymax = fDY+fOrigin[1];
00898 zmin = -fDZ+fOrigin[2];
00899 zmax = fDZ+fOrigin[2];
00900 points[ 0] = xmin; points[ 1] = ymin; points[ 2] = zmin;
00901 points[ 3] = xmin; points[ 4] = ymax; points[ 5] = zmin;
00902 points[ 6] = xmax; points[ 7] = ymax; points[ 8] = zmin;
00903 points[ 9] = xmax; points[10] = ymin; points[11] = zmin;
00904 points[12] = xmin; points[13] = ymin; points[14] = zmax;
00905 points[15] = xmin; points[16] = ymax; points[17] = zmax;
00906 points[18] = xmax; points[19] = ymax; points[20] = zmax;
00907 points[21] = xmax; points[22] = ymin; points[23] = zmax;
00908 }
00909
00910
00911 void TGeoBBox::Sizeof3D() const
00912 {
00913
00914
00915
00916 }
00917
00918
00919 const TBuffer3D & TGeoBBox::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
00920 {
00921
00922 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00923
00924 FillBuffer3D(buffer, reqSections, localFrame);
00925
00926
00927
00928 if (reqSections & TBuffer3D::kRawSizes) {
00929 if (buffer.SetRawSizes(8, 3*8, 12, 3*12, 6, 6*6)) {
00930 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00931 }
00932 }
00933 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
00934 SetPoints(buffer.fPnts);
00935 if (!buffer.fLocalFrame) {
00936 TransformPoints(buffer.fPnts, buffer.NbPnts());
00937 }
00938
00939 SetSegsAndPols(buffer);
00940 buffer.SetSectionsValid(TBuffer3D::kRaw);
00941 }
00942
00943 return buffer;
00944 }
00945
00946
00947 void TGeoBBox::FillBuffer3D(TBuffer3D & buffer, Int_t reqSections, Bool_t localFrame) const
00948 {
00949
00950
00951 TGeoShape::FillBuffer3D(buffer, reqSections, localFrame);
00952
00953 if (reqSections & TBuffer3D::kBoundingBox) {
00954 Double_t halfLengths[3] = { fDX, fDY, fDZ };
00955 buffer.SetAABoundingBox(fOrigin, halfLengths);
00956
00957 if (!buffer.fLocalFrame) {
00958 TransformPoints(buffer.fBBVertex[0], 8);
00959 }
00960 buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
00961 }
00962 }