181 ClassImp(TGeoCompositeShape);
186 void TGeoCompositeShape::ClearThreadData()
const
188 if (fNode) fNode->ClearThreadData();
194 void TGeoCompositeShape::CreateThreadData(Int_t nthreads)
196 if (fNode) fNode->CreateThreadData(nthreads);
202 TGeoCompositeShape::TGeoCompositeShape()
205 SetShapeBit(TGeoShape::kGeoComb);
212 TGeoCompositeShape::TGeoCompositeShape(
const char *name,
const char *expression)
215 SetShapeBit(TGeoShape::kGeoComb);
218 MakeNode(expression);
220 Error(
"ctor",
"Composite %s: cannot parse expression: %s", name, expression);
229 TGeoCompositeShape::TGeoCompositeShape(
const char *expression)
232 SetShapeBit(TGeoShape::kGeoComb);
234 MakeNode(expression);
236 TString message = TString::Format(
"Composite (no name) could not parse expression %s", expression);
237 Error(
"ctor",
"%s", message.Data());
246 TGeoCompositeShape::TGeoCompositeShape(
const char *name, TGeoBoolNode *node)
252 Error(
"ctor",
"Composite shape %s has null node", name);
261 TGeoCompositeShape::~TGeoCompositeShape()
263 if (fNode)
delete fNode;
269 Double_t TGeoCompositeShape::Capacity()
const
272 if (!gRandom) gRandom =
new TRandom3();
273 Double_t vbox = 8*fDX*fDY*fDZ;
277 pt[0] = fOrigin[0]-fDX+2*fDX*gRandom->Rndm();
278 pt[1] = fOrigin[1]-fDY+2*fDY*gRandom->Rndm();
279 pt[2] = fOrigin[2]-fDZ+2*fDZ*gRandom->Rndm();
281 if (Contains(pt)) iin++;
283 Double_t capacity = iin*vbox/igen;
290 void TGeoCompositeShape::ComputeBBox()
292 if(fNode) fNode->ComputeBBox(fDX, fDY, fDZ, fOrigin);
298 void TGeoCompositeShape::ComputeNormal(
const Double_t *point,
const Double_t *dir, Double_t *norm)
300 if (fNode) fNode->ComputeNormal(point,dir,norm);
306 Bool_t TGeoCompositeShape::Contains(
const Double_t *point)
const
308 if (fNode)
return fNode->Contains(point);
315 Int_t TGeoCompositeShape::DistancetoPrimitive(Int_t px, Int_t py)
317 const Int_t numPoints = GetNmeshVertices();
318 return ShapeDistancetoPrimitive(numPoints, px, py);
325 Double_t TGeoCompositeShape::DistFromOutside(
const Double_t *point,
const Double_t *dir, Int_t iact,
326 Double_t step, Double_t *safe)
const
328 Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
329 if (sdist>=step)
return TGeoShape::Big();
330 if (fNode)
return fNode->DistFromOutside(point, dir, iact, step, safe);
331 return TGeoShape::Big();
337 Double_t TGeoCompositeShape::DistFromInside(
const Double_t *point,
const Double_t *dir, Int_t iact,
338 Double_t step, Double_t *safe)
const
340 if (fNode)
return fNode->DistFromInside(point, dir, iact, step, safe);
341 return TGeoShape::Big();
347 TGeoVolume *TGeoCompositeShape::Divide(TGeoVolume * ,
const char * , Int_t ,
348 Int_t , Double_t , Double_t )
350 Error(
"Divide",
"Composite shapes cannot be divided");
357 void TGeoCompositeShape::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols)
const
359 nvert = GetNmeshVertices();
367 void TGeoCompositeShape::InspectShape()
const
369 printf(
"*** TGeoCompositeShape : %s = %s\n", GetName(), GetTitle());
370 printf(
" Bounding box:\n");
371 TGeoBBox::InspectShape();
379 void TGeoCompositeShape::MakeNode(
const char *expression)
381 if (fNode)
delete fNode;
383 SetTitle(expression);
384 TString sleft, sright, smat;
386 boolop = TGeoManager::Parse(expression, sleft, sright, smat);
389 Error(
"MakeNode",
"parser error");
393 Warning(
"MakeNode",
"no geometrical transformation allowed at this level");
396 Error(
"MakeNode",
"Expression has no boolean operation");
399 fNode =
new TGeoUnion(sleft.Data(), sright.Data());
402 fNode =
new TGeoSubtraction(sleft.Data(), sright.Data());
405 fNode =
new TGeoIntersection(sleft.Data(), sright.Data());
414 Bool_t TGeoCompositeShape::PaintComposite(Option_t *option)
const
416 Bool_t addChildren = kTRUE;
418 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
419 TVirtualViewer3D * viewer = gPad->GetViewer3D();
420 if (!painter || !viewer)
return kFALSE;
425 Bool_t preferLocal = viewer->PreferLocalFrame();
426 if (TBuffer3D::GetCSLevel()) preferLocal = kFALSE;
427 static TBuffer3D buffer(TBuffer3DTypes::kComposite);
428 FillBuffer3D(buffer, TBuffer3D::kCore|TBuffer3D::kBoundingBox,
431 Bool_t paintComponents = kTRUE;
434 if (!TBuffer3D::GetCSLevel())
435 paintComponents = viewer->OpenComposite(buffer, &addChildren);
437 TBuffer3D::IncCSLevel();
440 TGeoHMatrix *matrix = (TGeoHMatrix*)TGeoShape::GetTransform();
441 TGeoHMatrix backup(*matrix);
442 if (preferLocal) matrix->Clear();
443 if (paintComponents) fNode->Paint(option);
444 if (preferLocal) *matrix = backup;
446 if (!TBuffer3D::DecCSLevel())
447 viewer->CloseComposite();
456 void TGeoCompositeShape::RegisterYourself()
458 if (gGeoManager->GetListOfShapes()->FindObject(
this))
return;
459 gGeoManager->AddShape(
this);
462 TGeoCompositeShape *comp;
464 matrix = fNode->GetLeftMatrix();
465 if (!matrix->IsRegistered()) matrix->RegisterYourself();
466 else if (!gGeoManager->GetListOfMatrices()->FindObject(matrix)) {
467 gGeoManager->GetListOfMatrices()->Add(matrix);
469 matrix = fNode->GetRightMatrix();
470 if (!matrix->IsRegistered()) matrix->RegisterYourself();
471 else if (!gGeoManager->GetListOfMatrices()->FindObject(matrix)) {
472 gGeoManager->GetListOfMatrices()->Add(matrix);
474 shape = fNode->GetLeftShape();
475 if (!gGeoManager->GetListOfShapes()->FindObject(shape)) {
476 if (shape->IsComposite()) {
477 comp = (TGeoCompositeShape*)shape;
478 comp->RegisterYourself();
480 gGeoManager->AddShape(shape);
483 shape = fNode->GetRightShape();
484 if (!gGeoManager->GetListOfShapes()->FindObject(shape)) {
485 if (shape->IsComposite()) {
486 comp = (TGeoCompositeShape*)shape;
487 comp->RegisterYourself();
489 gGeoManager->AddShape(shape);
499 Double_t TGeoCompositeShape::Safety(
const Double_t *point, Bool_t in)
const
501 if (fNode)
return fNode->Safety(point,in);
508 void TGeoCompositeShape::SavePrimitive(std::ostream &out, Option_t *option )
510 if (TObject::TestBit(kGeoSavePrimitive))
return;
511 if (fNode) fNode->SavePrimitive(out,option);
512 out <<
" // Shape: " << GetName() <<
" type: " << ClassName() << std::endl;
513 out <<
" TGeoShape *" << GetPointerName() <<
" = new TGeoCompositeShape(\"" << GetName() <<
"\", pBoolNode);" << std::endl;
514 if (strlen(GetTitle())) out <<
" " << GetPointerName() <<
"->SetTitle(\"" << GetTitle() <<
"\");" << std::endl;
515 TObject::SetBit(TGeoShape::kGeoSavePrimitive);
521 void TGeoCompositeShape::SetPoints(Double_t *points)
const
523 if (fNode) fNode->SetPoints(points);
529 void TGeoCompositeShape::SetPoints(Float_t *points)
const
531 if (fNode) fNode->SetPoints(points);
537 void TGeoCompositeShape::Sizeof3D()
const
539 if (fNode) fNode->Sizeof3D();
545 Int_t TGeoCompositeShape::GetNmeshVertices()
const
547 if (!fNode)
return 0;
548 return fNode->GetNpoints();
556 void TGeoCompositeShape::Contains_v(
const Double_t *points, Bool_t *inside, Int_t vecsize)
const
558 for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
566 void TGeoCompositeShape::ComputeNormal_v(
const Double_t *points,
const Double_t *dirs, Double_t *norms, Int_t vecsize)
568 for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
574 void TGeoCompositeShape::DistFromInside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
576 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
582 void TGeoCompositeShape::DistFromOutside_v(
const Double_t *points,
const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step)
const
584 for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
592 void TGeoCompositeShape::Safety_v(
const Double_t *points,
const Bool_t *inside, Double_t *safe, Int_t vecsize)
const
594 for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);