18 #include "volumes/PlacedVolume.h"
19 #include "volumes/UnplacedVolume.h"
20 #include "volumes/UnplacedBox.h"
21 #include "volumes/UnplacedTube.h"
22 #include "volumes/UnplacedCone.h"
23 #include "volumes/UnplacedParaboloid.h"
24 #include "volumes/UnplacedParallelepiped.h"
25 #include "volumes/UnplacedPolyhedron.h"
26 #include "volumes/UnplacedTrd.h"
27 #include "volumes/UnplacedOrb.h"
28 #include "volumes/UnplacedSphere.h"
29 #include "volumes/UnplacedBooleanVolume.h"
30 #include "volumes/UnplacedTorus2.h"
31 #include "volumes/UnplacedTrapezoid.h"
32 #include "volumes/UnplacedPolycone.h"
33 #include "volumes/UnplacedScaledShape.h"
34 #include "volumes/UnplacedGenTrap.h"
35 #include "volumes/UnplacedSExtruVolume.h"
61 TGeoVGShape::TGeoVGShape(TGeoShape *shape, vecgeom::cxx::VPlacedVolume *vgshape)
62 :TGeoBBox(shape->GetName(), 0, 0, 0), fVGShape(vgshape), fShape(shape)
65 const TGeoBBox *box = (
const TGeoBBox*)shape;
66 TGeoBBox::SetBoxDimensions(box->GetDX(), box->GetDY(), box->GetDZ());
67 memcpy(fOrigin, box->GetOrigin(), 3*
sizeof(Double_t));
73 TGeoVGShape::~TGeoVGShape()
83 TGeoVGShape *TGeoVGShape::Create(TGeoShape *shape)
85 vecgeom::cxx::VPlacedVolume *vgshape = TGeoVGShape::CreateVecGeomSolid(shape);
86 if (!vgshape)
return nullptr;
87 return (
new TGeoVGShape(shape, vgshape) );
93 vecgeom::cxx::VPlacedVolume *TGeoVGShape::CreateVecGeomSolid(TGeoShape *shape)
97 vecgeom::cxx::VUnplacedVolume *unplaced = Convert(shape);
98 if (!unplaced)
return nullptr;
101 vecgeom::cxx::LogicalVolume *lvol =
new vecgeom::cxx::LogicalVolume(
"", unplaced);
102 return ( lvol->Place() );
108 vecgeom::cxx::Transformation3D *TGeoVGShape::Convert(TGeoMatrix
const *
const geomatrix) {
109 Double_t
const *
const t = geomatrix->GetTranslation();
110 Double_t
const *
const r = geomatrix->GetRotationMatrix();
111 vecgeom::cxx::Transformation3D *
const transformation =
112 new vecgeom::cxx::Transformation3D(t[0], t[1], t[2], r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8]);
113 return transformation;
119 vecgeom::cxx::VUnplacedVolume* TGeoVGShape::Convert(TGeoShape
const *
const shape)
121 using namespace vecgeom::cxx;
122 VUnplacedVolume *unplaced_volume =
nullptr;
125 if (shape->IsA() == TGeoBBox::Class()) {
126 TGeoBBox
const *
const box =
static_cast<TGeoBBox
const *
>(shape);
127 unplaced_volume =
new UnplacedBox(box->GetDX(), box->GetDY(), box->GetDZ());
131 if (shape->IsA() == TGeoTube::Class()) {
132 TGeoTube
const *
const tube =
static_cast<TGeoTube
const *
>(shape);
133 unplaced_volume =
new GenericUnplacedTube(tube->GetRmin(), tube->GetRmax(), tube->GetDz(), 0., kTwoPi);
137 if (shape->IsA() == TGeoTubeSeg::Class()) {
138 TGeoTubeSeg
const *
const tube =
static_cast<TGeoTubeSeg
const *
>(shape);
140 new GenericUnplacedTube(tube->GetRmin(), tube->GetRmax(), tube->GetDz(), kDegToRad * tube->GetPhi1(),
141 kDegToRad * (tube->GetPhi2() - tube->GetPhi1()));
145 if (shape->IsA() == TGeoConeSeg::Class()) {
146 TGeoConeSeg
const *
const cone =
static_cast<TGeoConeSeg
const *
>(shape);
148 new UnplacedCone(cone->GetRmin1(), cone->GetRmax1(), cone->GetRmin2(), cone->GetRmax2(), cone->GetDz(),
149 kDegToRad * cone->GetPhi1(), kDegToRad * (cone->GetPhi2() - cone->GetPhi1()));
153 if (shape->IsA() == TGeoCone::Class()) {
154 TGeoCone
const *
const cone =
static_cast<TGeoCone
const *
>(shape);
155 unplaced_volume =
new UnplacedCone(cone->GetRmin1(), cone->GetRmax1(), cone->GetRmin2(), cone->GetRmax2(),
156 cone->GetDz(), 0., kTwoPi);
160 if (shape->IsA() == TGeoParaboloid::Class()) {
161 TGeoParaboloid
const *
const p =
static_cast<TGeoParaboloid
const *
>(shape);
162 unplaced_volume =
new UnplacedParaboloid(p->GetRlo(), p->GetRhi(), p->GetDz());
166 if (shape->IsA() == TGeoPara::Class()) {
167 TGeoPara
const *
const p =
static_cast<TGeoPara
const *
>(shape);
169 new UnplacedParallelepiped(p->GetX(), p->GetY(), p->GetZ(), p->GetAlpha(), p->GetTheta(), p->GetPhi());
173 if (shape->IsA() == TGeoPgon::Class()) {
174 TGeoPgon
const *pgon =
static_cast<TGeoPgon
const *
>(shape);
175 unplaced_volume =
new UnplacedPolyhedron(pgon->GetPhi1(),
186 if (shape->IsA() == TGeoTrd2::Class()) {
187 TGeoTrd2
const *
const p =
static_cast<TGeoTrd2
const *
>(shape);
188 unplaced_volume =
new UnplacedTrd(p->GetDx1(), p->GetDx2(), p->GetDy1(), p->GetDy2(), p->GetDz());
192 if (shape->IsA() == TGeoTrd1::Class()) {
193 TGeoTrd1
const *
const p =
static_cast<TGeoTrd1
const *
>(shape);
194 unplaced_volume =
new UnplacedTrd(p->GetDx1(), p->GetDx2(), p->GetDy(), p->GetDz());
198 if (shape->IsA() == TGeoTrap::Class()) {
199 TGeoTrap
const *
const p =
static_cast<TGeoTrap
const *
>(shape);
200 unplaced_volume =
new UnplacedTrapezoid(p->GetDz(), p->GetTheta() * kDegToRad, p->GetPhi() * kDegToRad, p->GetH1(),
201 p->GetBl1(), p->GetTl1(), std::tan(p->GetAlpha1() * kDegToRad), p->GetH2(),
202 p->GetBl2(), p->GetTl2(), std::tan(p->GetAlpha2() * kDegToRad));
206 if (shape->IsA() == TGeoSphere::Class()) {
208 TGeoSphere
const *
const p =
static_cast<TGeoSphere
const *
>(shape);
209 if (p->GetRmin() == 0. && p->GetTheta2() - p->GetTheta1() == 180. && p->GetPhi2() - p->GetPhi1() == 360.) {
210 unplaced_volume =
new UnplacedOrb(p->GetRmax());
212 unplaced_volume =
new UnplacedSphere(p->GetRmin(), p->GetRmax(), p->GetPhi1() * kDegToRad,
213 (p->GetPhi2() - p->GetPhi1()) * kDegToRad, p->GetTheta1() * kDegToRad,
214 (p->GetTheta2() - p->GetTheta1()) * kDegToRad);
218 if (shape->IsA() == TGeoCompositeShape::Class()) {
219 TGeoCompositeShape
const *
const compshape =
static_cast<TGeoCompositeShape
const *
>(shape);
220 TGeoBoolNode
const *
const boolnode = compshape->GetBoolNode();
223 Transformation3D
const *lefttrans = Convert(boolnode->GetLeftMatrix());
224 Transformation3D
const *righttrans = Convert(boolnode->GetRightMatrix());
226 VUnplacedVolume
const *leftunplaced = Convert(boolnode->GetLeftShape());
227 VUnplacedVolume
const *rightunplaced = Convert(boolnode->GetRightShape());
228 if (!leftunplaced || !rightunplaced) {
233 delete rightunplaced;
237 assert(leftunplaced !=
nullptr);
238 assert(rightunplaced !=
nullptr);
241 VPlacedVolume *
const leftplaced = (
new LogicalVolume(
"inner_virtual", leftunplaced))->Place(lefttrans);
243 VPlacedVolume *
const rightplaced = (
new LogicalVolume(
"inner_virtual", rightunplaced))->Place(righttrans);
246 if (boolnode->GetBooleanOperator() == TGeoBoolNode::kGeoSubtraction) {
247 unplaced_volume =
new UnplacedBooleanVolume(kSubtraction, leftplaced, rightplaced);
248 }
else if (boolnode->GetBooleanOperator() == TGeoBoolNode::kGeoIntersection) {
249 unplaced_volume =
new UnplacedBooleanVolume(kIntersection, leftplaced, rightplaced);
250 }
else if (boolnode->GetBooleanOperator() == TGeoBoolNode::kGeoUnion) {
251 unplaced_volume =
new UnplacedBooleanVolume(kUnion, leftplaced, rightplaced);
256 if (shape->IsA() == TGeoTorus::Class()) {
258 TGeoTorus
const *
const p =
static_cast<TGeoTorus
const *
>(shape);
260 new UnplacedTorus2(p->GetRmin(), p->GetRmax(), p->GetR(), p->GetPhi1() * kDegToRad, p->GetDphi() * kDegToRad);
264 if (shape->IsA() == TGeoPcon::Class()) {
265 TGeoPcon
const *
const p =
static_cast<TGeoPcon
const *
>(shape);
266 unplaced_volume =
new UnplacedPolycone(p->GetPhi1() * kDegToRad, p->GetDphi() * kDegToRad, p->GetNz(), p->GetZ(),
267 p->GetRmin(), p->GetRmax());
271 if (shape->IsA() == TGeoScaledShape::Class()) {
272 TGeoScaledShape
const *
const p =
static_cast<TGeoScaledShape
const *
>(shape);
274 VUnplacedVolume *referenced_shape = Convert(p->GetShape());
275 if (!referenced_shape)
return nullptr;
276 const double *scale_root = p->GetScale()->GetScale();
277 unplaced_volume =
new UnplacedScaledShape(referenced_shape, scale_root[0], scale_root[1], scale_root[2]);
281 if (shape->IsA() == TGeoEltu::Class()) {
282 TGeoEltu
const *
const p =
static_cast<TGeoEltu
const *
>(shape);
285 GenericUnplacedTube *tubeUnplaced =
new GenericUnplacedTube(0, p->GetA(), p->GetDZ(), 0, kTwoPi);
286 unplaced_volume =
new UnplacedScaledShape(tubeUnplaced, 1., p->GetB() / p->GetA(), 1.);
290 if (shape->IsA() == TGeoArb8::Class() || shape->IsA() == TGeoGtra::Class()) {
291 TGeoArb8 *p = (TGeoArb8 *)(shape);
293 std::vector<Vector3D<Precision>> vertexlist;
294 const double *vertices = p->GetVertices();
295 Precision verticesx[8], verticesy[8];
296 for (
auto ivert = 0; ivert < 8; ++ivert) {
297 verticesx[ivert] = vertices[2 * ivert];
298 verticesy[ivert] = vertices[2 * ivert + 1];
300 unplaced_volume =
new UnplacedGenTrap(verticesx, verticesy, p->GetDz());
304 if (shape->IsA() == TGeoXtru::Class()) {
305 TGeoXtru *p = (TGeoXtru *)(shape);
307 if (p->GetNz() == 2) {
309 size_t Nvert = (size_t)p->GetNvert();
310 double *x =
new double[Nvert];
311 double *y =
new double[Nvert];
312 for (
size_t i = 0; i < Nvert; ++i) {
317 if (PlanarPolygon::GetOrientation(x, y, Nvert) > 0.) {
319 for (
size_t i = 0; i < Nvert; ++i) {
320 x[Nvert - 1 - i] = p->GetX(i);
321 y[Nvert - 1 - i] = p->GetY(i);
324 unplaced_volume =
new UnplacedSExtruVolume(p->GetNvert(), x, y, p->GetZ()[0], p->GetZ()[1]);
329 if (!unplaced_volume) {
330 printf(
"Unsupported shape for ROOT shape \"%s\" of type %s. "
331 "Using ROOT implementation.\n",
332 shape->GetName(), shape->ClassName());
336 return ( unplaced_volume );
342 void TGeoVGShape::ComputeBBox()
344 fShape->ComputeBBox();
350 Double_t TGeoVGShape::Capacity()
const
352 return fVGShape->Capacity();
358 void TGeoVGShape::ComputeNormal(
const Double_t *point,
const Double_t *, Double_t *norm)
360 vecgeom::cxx::Vector3D<Double_t> vnorm;
361 fVGShape->Normal(vecgeom::cxx::Vector3D<Double_t>(point[0], point[1], point[2]), vnorm);
362 norm[0] = vnorm.x(); norm[1] = vnorm.y(), norm[2] = vnorm.z();
368 Bool_t TGeoVGShape::Contains(
const Double_t *point)
const
370 return ( fVGShape->Contains(vecgeom::cxx::Vector3D<Double_t>(point[0], point[1], point[2])) );
375 Double_t TGeoVGShape::DistFromInside(
const Double_t *point,
const Double_t *dir, Int_t ,
376 Double_t step, Double_t * )
const
378 Double_t dist = fVGShape->DistanceToOut(vecgeom::cxx::Vector3D<Double_t>(point[0], point[1], point[2]),
379 vecgeom::cxx::Vector3D<Double_t>(dir[0], dir[1], dir[2]), step);
380 return ( (dist < 0.)? 0. : dist );
385 Double_t TGeoVGShape::DistFromOutside(
const Double_t *point,
const Double_t *dir, Int_t ,
386 Double_t step, Double_t * )
const
388 Double_t dist = fVGShape->DistanceToIn(vecgeom::cxx::Vector3D<Double_t>(point[0], point[1], point[2]),
389 vecgeom::cxx::Vector3D<Double_t>(dir[0], dir[1], dir[2]), step);
390 return ( (dist < 0.)? 0. : dist );
395 Double_t TGeoVGShape::Safety(
const Double_t *point, Bool_t in)
const
397 Double_t safety = (in) ? fVGShape->SafetyToOut(vecgeom::cxx::Vector3D<Double_t>(point[0], point[1], point[2]))
398 : fVGShape->SafetyToIn(vecgeom::cxx::Vector3D<Double_t>(point[0], point[1], point[2]));
399 return ( (safety < 0.)? 0. : safety );
405 void TGeoVGShape::InspectShape()
const
407 fVGShape->GetUnplacedVolume()->Print();