31 ClassImp(TGeoScaledShape);
36 TGeoScaledShape::TGeoScaledShape()
46 TGeoScaledShape::TGeoScaledShape(
const char *name, TGeoShape *shape, TGeoScale *scale)
51 if (!fScale->IsRegistered()) fScale->RegisterYourself();
58 TGeoScaledShape::TGeoScaledShape(TGeoShape *shape, TGeoScale *scale)
62 if (!fScale->IsRegistered()) fScale->RegisterYourself();
69 TGeoScaledShape::~TGeoScaledShape()
76 Double_t TGeoScaledShape::Capacity()
const
78 Double_t capacity = fShape->Capacity();
79 const Double_t *scale = fScale->GetScale();
80 capacity *= scale[0]*scale[1]*scale[2];
87 void TGeoScaledShape::ComputeBBox()
90 Error(
"ComputeBBox",
"Scaled shape %s without shape", GetName());
93 if (fShape->IsAssembly()) fShape->ComputeBBox();
94 TGeoBBox *box = (TGeoBBox*)fShape;
95 const Double_t *orig = box->GetOrigin();
96 Double_t point[3], master[3];
97 point[0] = box->GetDX();
98 point[1] = box->GetDY();
99 point[2] = box->GetDZ();
101 fScale->LocalToMaster(orig, fOrigin);
102 fScale->LocalToMaster(point, master);
103 fDX = TMath::Abs(master[0]);
104 fDY = TMath::Abs(master[1]);
105 fDZ = TMath::Abs(master[2]);
111 void TGeoScaledShape::ComputeNormal(
const Double_t *point,
const Double_t *dir, Double_t *norm)
113 Double_t local[3], ldir[3], lnorm[3];
114 fScale->MasterToLocal(point,local);
115 fScale->MasterToLocalVect(dir,ldir);
116 TGeoMatrix::Normalize(ldir);
117 fShape->ComputeNormal(local,ldir,lnorm);
119 fScale->MasterToLocalVect(lnorm, norm);
120 TGeoMatrix::Normalize(norm);
126 Bool_t TGeoScaledShape::Contains(
const Double_t *point)
const
129 fScale->MasterToLocal(point,local);
130 return fShape->Contains(local);
136 Int_t TGeoScaledShape::DistancetoPrimitive(Int_t px, Int_t py)
138 Int_t n = fShape->GetNmeshVertices();
139 return ShapeDistancetoPrimitive(n, px, py);
145 Double_t TGeoScaledShape::DistFromInside(
const Double_t *point,
const Double_t *dir, Int_t iact, Double_t step, Double_t *safe)
const
147 Double_t local[3], ldir[3];
149 fScale->MasterToLocal(point,local);
150 lstep = fScale->MasterToLocal(step, dir);
151 fScale->MasterToLocalVect(dir,ldir);
152 TGeoMatrix::Normalize(ldir);
153 Double_t dist = fShape->DistFromInside(local,ldir, iact, lstep, safe);
154 if (iact<3 && safe) *safe = fScale->LocalToMaster(*safe);
155 dist = fScale->LocalToMaster(dist, ldir);
163 Double_t TGeoScaledShape::DistFromOutside(
const Double_t *point,
const Double_t *dir, Int_t iact, Double_t step, Double_t *safe)
const
165 Double_t local[3], ldir[3];
168 fScale->MasterToLocal(point,local);
170 lstep = fScale->MasterToLocal(step, dir);
171 fScale->MasterToLocalVect(dir,ldir);
172 TGeoMatrix::Normalize(ldir);
174 Double_t dist = fShape->DistFromOutside(local,ldir, iact, lstep, safe);
176 if (safe) *safe = fScale->LocalToMaster(*safe);
177 dist = fScale->LocalToMaster(dist, ldir);
185 TGeoVolume *TGeoScaledShape::Divide(TGeoVolume * ,
const char *divname, Int_t , Int_t ,
186 Double_t , Double_t )
188 Error(
"Divide",
"Scaled shapes cannot be divided. Division volume %s not created", divname);
195 const TBuffer3D & TGeoScaledShape::GetBuffer3D(Int_t reqSections, Bool_t localFrame)
const
197 TBuffer3D &buffer = (TBuffer3D &)fShape->GetBuffer3D(reqSections, localFrame);
200 Double_t halfLengths[3] = { fDX, fDY, fDZ };
201 buffer.SetAABoundingBox(fOrigin, halfLengths);
202 if (!buffer.fLocalFrame) {
203 TransformPoints(buffer.fBBVertex[0], 8);
206 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
207 SetPoints(buffer.fPnts);
208 if (!buffer.fLocalFrame) {
209 TransformPoints(buffer.fPnts, buffer.NbPnts());
219 TGeoShape *TGeoScaledShape::GetMakeRuntimeShape(TGeoShape * , TGeoMatrix * )
const
221 Error(
"GetMakeRuntimeShape",
"Scaled shapes cannot be parametrized.");
228 void TGeoScaledShape::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols)
const
230 fShape->GetMeshNumbers(nvert, nsegs, npols);
236 void TGeoScaledShape::InspectShape()
const
238 printf(
"*** Shape %s: TGeoScaledShape ***\n", GetName());
240 fShape->InspectShape();
241 TGeoBBox::InspectShape();
247 Bool_t TGeoScaledShape::IsAssembly()
const
249 return fShape->IsAssembly();
255 Bool_t TGeoScaledShape::IsReflected()
const
257 return fScale->IsReflection();
264 TBuffer3D *TGeoScaledShape::MakeBuffer3D()
const
266 TBuffer3D *buff = fShape->MakeBuffer3D();
267 if (buff) SetPoints(buff->fPnts);
274 TGeoShape *TGeoScaledShape::MakeScaledShape(
const char *name, TGeoShape *shape, TGeoScale *scale)
276 TGeoShape *new_shape;
277 if (shape->IsA() == TGeoScaledShape::Class()) {
278 TGeoScaledShape *sshape = (TGeoScaledShape*)shape;
279 TGeoScale *old_scale = sshape->GetScale();
280 TGeoShape *old_shape = sshape->GetShape();
281 scale->SetScale(scale->GetScale()[0]*old_scale->GetScale()[0],
282 scale->GetScale()[1]*old_scale->GetScale()[1],
283 scale->GetScale()[2]*old_scale->GetScale()[2]);
284 new_shape =
new TGeoScaledShape(name, old_shape, scale);
287 new_shape =
new TGeoScaledShape(name, shape, scale);
294 void TGeoScaledShape::SetSegsAndPols(TBuffer3D &buff)
const
296 fShape->SetSegsAndPols(buff);
303 Double_t TGeoScaledShape::Safety(
const Double_t *point, Bool_t in)
const
306 fScale->MasterToLocal(point,local);
307 Double_t safe = fShape->Safety(local,in);
308 safe = fScale->LocalToMaster(safe);
315 void TGeoScaledShape::SavePrimitive(std::ostream &out, Option_t *option)
317 if (TObject::TestBit(kGeoSavePrimitive))
return;
318 out <<
" // Shape: " << GetName() <<
" type: " << ClassName() << std::endl;
319 if (!fShape || !fScale) {
320 out <<
"##### Invalid shape or scale !. Aborting. #####" << std::endl;
323 fShape->SavePrimitive(out, option);
324 TString sname = fShape->GetPointerName();
325 const Double_t *sc = fScale->GetScale();
326 out <<
" // Scale factor:" << std::endl;
327 out <<
" TGeoScale *pScale = new TGeoScale(\"" << fScale->GetName()
328 <<
"\"," << sc[0] <<
"," << sc[1] <<
"," << sc[2] <<
");" << std::endl;
329 out <<
" TGeoScaledShape *" << GetPointerName() <<
" = new TGeoScaledShape(\""
330 << GetName() <<
"\"," << sname <<
", pScale);" << std::endl;
336 void TGeoScaledShape::SetPoints(Double_t *points)
const
338 Int_t npts = fShape->GetNmeshVertices();
339 fShape->SetPoints(points);
341 for (Int_t i=0; i<npts; i++) {
342 fScale->LocalToMaster(&points[3*i], master);
343 memcpy(&points[3*i], master, 3*
sizeof(Double_t));
350 void TGeoScaledShape::SetPoints(Float_t *points)
const
352 Int_t npts = fShape->GetNmeshVertices();
353 fShape->SetPoints(points);
357 for (Int_t i=0; i<npts; i++) {
359 local[0] = points[index];
360 local[1] = points[index+1];
361 local[2] = points[index+2];
362 fScale->LocalToMaster(local, master);
363 points[index] = master[0];
364 points[index+1] = master[1];
365 points[index+2] = master[2];
374 void TGeoScaledShape::Contains_v(
const Double_t *points, Bool_t *inside, Int_t vecsize)
const
376 for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
384 void TGeoScaledShape::ComputeNormal_v(
const Double_t *points,
const Double_t *dirs, Double_t *norms, Int_t vecsize)
386 for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
392 void TGeoScaledShape::DistFromInside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
394 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
400 void TGeoScaledShape::DistFromOutside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
402 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
410 void TGeoScaledShape::Safety_v(
const Double_t *points,
const Bool_t *inside, Double_t *safe, Int_t vecsize)
const
412 for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);