14 #define _USE_MATH_DEFINES
31 #include <TGeoMatrix.h>
32 #include <TGeoBoolNode.h>
33 #include <TGeoScaledShape.h>
34 #include <TGeoCompositeShape.h>
44 template <
typename T>
inline T* get_ptr(
const TGeoShape* shape) {
45 if ( shape && shape->IsA() == T::Class() )
return (T*)shape;
46 except(
"Dimension",
"Invalid shape pointer!");
49 inline void invalidSetDimensionCall(
const TGeoShape* sh,
const std::vector<double>& params) {
50 except(
"Solid",
"+++ Shape:%s setDimension: Invalid number of parameters: %ld",
51 (sh ? typeName(
typeid(*sh)) : typeName(
typeid(sh))).c_str(), params.size());
53 template <
typename T>
inline bool check_shape_type(
const Handle<TGeoShape>& solid) {
54 return solid.isValid() && solid->IsA() == T::Class();
60 return check_shape_type<typename SOLID::Object>(solid);
83 return check_shape_type<TGeoConeSeg>(solid) || check_shape_type<TGeoCone>(solid);
86 return check_shape_type<TGeoTubeSeg>(solid)
87 || check_shape_type<TGeoCtub>(solid)
88 || check_shape_type<TwistedTubeObject>(solid);
91 return check_shape_type<TGeoPcon>(solid) || check_shape_type<TGeoPgon>(solid);
95 TClass* c = solid->IsA();
96 return c==TGeoArb8::Class() || c==TGeoTrap::Class() || c==TGeoGtra::Class();
101 return check_shape_type<TwistedTubeObject>(solid);
104 return check_shape_type<TGeoCompositeShape>(solid)
108 return check_shape_type<TGeoCompositeShape>(solid)
112 TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.
ptr();
113 return sh && sh->IsA() == TGeoCompositeShape::Class()
114 && sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoSubtraction;
117 TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.
ptr();
118 return sh && sh->IsA() == TGeoCompositeShape::Class()
119 && sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoUnion;
122 TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.
ptr();
123 return sh && sh->IsA() == TGeoCompositeShape::Class()
124 && sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoIntersection;
129 return check_shape_type<typename SOLID::Object>(solid);
154 return check_shape_type<TwistedTubeObject>(solid)
158 return check_shape_type<TGeoCompositeShape>(solid)
162 return check_shape_type<TGeoCompositeShape>(solid)
166 TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.
ptr();
167 return sh && sh->IsA() == TGeoCompositeShape::Class()
168 && sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoSubtraction
172 TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.
ptr();
173 return sh && sh->IsA() == TGeoCompositeShape::Class()
174 && sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoUnion
175 && ::strcmp(sh->GetTitle(),
UNION_TAG) == 0;
178 TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.
ptr();
179 return sh && sh->IsA() == TGeoCompositeShape::Class()
180 && sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoIntersection
187 TClass* cl = sh->IsA();
188 if ( cl == TGeoShapeAssembly::Class() )
190 else if ( cl == TGeoBBox::Class() )
192 else if ( cl == TGeoHalfSpace::Class() )
194 else if ( cl == TGeoPgon::Class() )
196 else if ( cl == TGeoPcon::Class() )
198 else if ( cl == TGeoConeSeg::Class() )
200 else if ( cl == TGeoCone::Class() )
202 else if ( cl == TGeoTube::Class() )
204 else if ( cl == TGeoTubeSeg::Class() )
206 else if ( cl == TGeoCtub::Class() )
208 else if ( cl == TGeoEltu::Class() )
210 else if ( cl == TwistedTubeObject::Class() )
212 else if ( cl == TGeoTrd1::Class() )
214 else if ( cl == TGeoTrd2::Class() )
216 else if ( cl == TGeoParaboloid::Class() )
218 else if ( cl == TGeoHype::Class() )
222 else if ( cl == TGeoTrap::Class() )
224 else if ( cl == TGeoArb8::Class() )
226 else if ( cl == TGeoSphere::Class() )
228 else if ( cl == TGeoTorus::Class() )
230 else if ( cl == TGeoXtru::Class() )
232 else if ( cl == TGeoScaledShape::Class() )
234 else if ( cl == TGeoTessellated::Class() )
247 except(
"Solid",
"Failed to type of shape: %s [%s]",
248 sh->GetName(), cl->GetName() );
251 except(
"Solid",
"Failed to access dimensions [Invalid handle].");
255 template <
typename T> std::vector<double>
dimensions(
const TGeoShape* shape) {
256 std::stringstream str;
258 str <<
"Shape: dimension(" << typeName(
typeid(*shape)) <<
"): Invalid call!";
260 str <<
"Shape: dimension<TGeoShape): Invalid call && pointer!";
261 throw std::runtime_error(str.str());
264 const auto* sh = get_ptr<TGeoShapeAssembly>(shape);
265 return { sh->GetDX(), sh->GetDY(), sh->GetDZ() };
268 const auto* sh = get_ptr<TGeoBBox>(shape);
269 return { sh->GetDX(), sh->GetDY(), sh->GetDZ() };
272 auto* sh = get_ptr<TGeoHalfSpace>(shape);
273 return { sh->GetPoint()[0], sh->GetPoint()[1], sh->GetPoint()[2],
274 sh->GetNorm()[0], sh->GetNorm()[1], sh->GetNorm()[2] };
277 const TGeoPcon* sh = get_ptr<TGeoPcon>(shape);
278 std::vector<double> pars { sh->GetPhi1()*units::deg, sh->GetDphi()*units::deg, double(sh->GetNz()) };
279 pars.reserve(3+3*sh->GetNz());
280 for (Int_t i = 0; i < sh->GetNz(); ++i) {
281 pars.emplace_back(sh->GetZ(i));
282 pars.emplace_back(sh->GetRmin(i));
283 pars.emplace_back(sh->GetRmax(i));
288 const TGeoConeSeg* sh = get_ptr<TGeoConeSeg>(shape);
289 return { sh->GetDz(), sh->GetRmin1(), sh->GetRmax1(), sh->GetRmin2(), sh->GetRmax2(),
290 sh->GetPhi1()*units::deg, sh->GetPhi2()*units::deg };
293 const TGeoCone* sh = get_ptr<TGeoCone>(shape);
294 return { sh->GetDz(), sh->GetRmin1(), sh->GetRmax1(), sh->GetRmin2(), sh->GetRmax2() };
297 const TGeoTube* sh = get_ptr<TGeoTube>(shape);
298 return { sh->GetRmin(), sh->GetRmax(), sh->GetDz() };
301 const TGeoTubeSeg* sh = get_ptr<TGeoTubeSeg>(shape);
302 return { sh->GetRmin(), sh->GetRmax(), sh->GetDz(), sh->GetPhi1()*units::deg, sh->GetPhi2()*units::deg };
305 const TwistedTubeObject* sh = get_ptr<TwistedTubeObject>(shape);
306 return { sh->GetPhiTwist(), sh->GetRmin(), sh->GetRmax(),
307 sh->GetNegativeEndZ(), sh->GetPositiveEndZ(),
308 double(sh->GetNsegments()), sh->GetPhi2()*units::deg };
311 const TGeoCtub* sh = get_ptr<TGeoCtub>(shape);
312 const Double_t* lo = sh->GetNlow();
313 const Double_t* hi = sh->GetNhigh();
314 return { sh->GetRmin(), sh->GetRmax(), sh->GetDz(),
315 sh->GetPhi1()*units::deg, sh->GetPhi2()*units::deg,
316 lo[0], lo[1], lo[2], hi[0], hi[1], hi[2] };
319 const TGeoEltu* sh = get_ptr<TGeoEltu>(shape);
320 return { sh->GetA(), sh->GetB(), sh->GetDz() };
323 const TGeoTrd1* sh = get_ptr<TGeoTrd1>(shape);
324 return { sh->GetDx1(), sh->GetDx2(), sh->GetDy(), sh->GetDz() };
327 const TGeoTrd2* sh = get_ptr<TGeoTrd2>(shape);
328 return { sh->GetDx1(), sh->GetDx2(), sh->GetDy1(), sh->GetDy2(), sh->GetDz() };
331 const TGeoParaboloid* sh = get_ptr<TGeoParaboloid>(shape);
332 return { sh->GetRlo(), sh->GetRhi(), sh->GetDz() };
335 const TGeoHype* sh = get_ptr<TGeoHype>(shape);
336 return { sh->GetDz(),
337 sh->GetRmin(), sh->GetStIn()*units::deg,
338 sh->GetRmax(), sh->GetStOut()*units::deg };
341 const TGeoSphere* sh = get_ptr<TGeoSphere>(shape);
342 return { sh->GetRmin(), sh->GetRmax(),
343 sh->GetTheta1()*units::deg, sh->GetTheta2()*units::deg,
344 sh->GetPhi1()*units::deg, sh->GetPhi2()*units::deg };
347 const TGeoTorus* sh = get_ptr<TGeoTorus>(shape);
348 return { sh->GetR(), sh->GetRmin(), sh->GetRmax(),
349 sh->GetPhi1()*units::deg, sh->GetDphi()*units::deg };
352 const TGeoPgon* sh = get_ptr<TGeoPgon>(shape);
353 std::vector<double> pars { sh->GetPhi1()*units::deg, sh->GetDphi()*units::deg, double(sh->GetNedges()), double(sh->GetNz()) };
354 pars.reserve(4+3*sh->GetNz());
355 for (Int_t i = 0; i < sh->GetNz(); ++i) {
356 pars.emplace_back(sh->GetZ(i));
357 pars.emplace_back(sh->GetRmin(i));
358 pars.emplace_back(sh->GetRmax(i));
363 const TGeoXtru* sh = get_ptr<TGeoXtru>(shape);
364 Int_t nz = sh->GetNz();
365 std::vector<double> pars { double(nz) };
366 pars.reserve(1+4*nz);
367 for(Int_t i=0; i<nz; ++i) {
368 pars.emplace_back(sh->GetZ(i));
369 pars.emplace_back(sh->GetXOffset(i));
370 pars.emplace_back(sh->GetYOffset(i));
371 pars.emplace_back(sh->GetScale(i));
376 TGeoArb8* sh = get_ptr<TGeoArb8>(shape);
377 struct _V {
double xy[8][2]; } *vtx = (_V*)sh->GetVertices();
378 std::vector<double> pars { sh->GetDz() };
379 for ( std::size_t i=0; i<8; ++i ) {
380 pars.emplace_back(vtx->xy[i][0]);
381 pars.emplace_back(vtx->xy[i][1]);
386 const TGeoTrap* sh = get_ptr<TGeoTrap>(shape);
387 return { sh->GetDz(), sh->GetTheta()*units::deg, sh->GetPhi()*units::deg,
388 sh->GetH1(), sh->GetBl1(), sh->GetTl1(), sh->GetAlpha1()*units::deg,
389 sh->GetH2(), sh->GetBl2(), sh->GetTl2(), sh->GetAlpha2()*units::deg };
392 const TGeoGtra* sh = get_ptr<TGeoGtra>(shape);
393 return { sh->GetDz(), sh->GetTheta()*units::deg, sh->GetPhi()*units::deg,
394 sh->GetH1(), sh->GetBl1(), sh->GetTl1(), sh->GetAlpha1()*units::deg,
395 sh->GetH2(), sh->GetBl2(), sh->GetTl2(), sh->GetAlpha2()*units::deg,
396 sh->GetTwistAngle()*units::deg };
399 TGeoScaledShape* sh = get_ptr<TGeoScaledShape>(shape);
400 TGeoShape* s_sh = sh->GetShape();
401 const Double_t* scale = sh->GetScale()->GetScale();
402 std::vector<double> pars {scale[0],scale[1],scale[2]};
404 for(
auto p : s_pars) pars.push_back(p);
409 TGeoTessellated* sh = get_ptr<TGeoTessellated>(shape);
410 int num_facet = sh->GetNfacets();
411 int num_vtx = sh->GetNvertices();
412 std::vector<double> pars;
414 printout(DEBUG,
"TessellatedSolid",
"+++ Saving %d vertices, %d facets",num_vtx, num_facet);
415 pars.reserve(num_facet*5+num_vtx*3+2);
416 pars.emplace_back(num_vtx);
417 pars.emplace_back(num_facet);
418 for(
int i=0; i<num_vtx; ++i) {
419 const auto&
v = sh->GetVertex(i);
420 pars.emplace_back(
v.x());
421 pars.emplace_back(
v.y());
422 pars.emplace_back(
v.z());
424 for(
int i=0; i<num_facet; ++i) {
425 const TGeoFacet& f = sh->GetFacet(i);
426 pars.emplace_back(
double(f.GetNvert()));
427 for(
int j=0, n=f.GetNvert(); j<n; ++j) {
428 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
430 pars.emplace_back(
double(idx));
432 pars.emplace_back(
double(f.GetVertexIndex(j)));
440 const TGeoCompositeShape* sh = get_ptr<TGeoCompositeShape>(shape);
441 const TGeoBoolNode*
boolean = sh->GetBoolNode();
442 TGeoMatrix* right_matrix =
boolean->GetRightMatrix();
443 TGeoShape* left_solid =
boolean->GetLeftShape();
444 TGeoShape* right_solid =
boolean->GetRightShape();
446 TGeoBoolNode::EGeoBoolType oper =
boolean->GetBooleanOperator();
447 TGeoMatrix* left_matrix =
boolean->GetRightMatrix();
448 const Double_t* left_tr = left_matrix->GetTranslation();
449 const Double_t* left_rot = left_matrix->GetRotationMatrix();
450 const Double_t* right_tr = right_matrix->GetTranslation();
451 const Double_t* right_rot = right_matrix->GetRotationMatrix();
453 std::vector<double> pars { double(oper) };
457 pars.insert(pars.end(), left_par.begin(), left_par.end());
458 pars.insert(pars.end(), left_rot, left_rot+9);
459 pars.insert(pars.end(), left_tr, left_tr+3);
461 pars.insert(pars.end(), right_par.begin(), right_par.end());
462 pars.insert(pars.end(), right_rot, right_rot+9);
463 pars.insert(pars.end(), right_tr, right_tr+3);
468 {
return dimensions<typename T::Object>(get_ptr<typename T::Object>(shape.
ptr())); }
498 const TGeoCompositeShape* sh = get_ptr<TGeoCompositeShape>(shape.
ptr());
499 TGeoMatrix* right_matrix = sh->GetBoolNode()->GetRightMatrix();
500 std::stringstream params(right_matrix->GetTitle());
501 std::vector<double> pars;
503 #ifdef DIMENSION_DEBUG
505 << right_matrix->GetTitle() << endl;
507 for(std::size_t i=0; i<7; ++i) {
510 pars.emplace_back(val);
511 if ( !params.good() ) {
512 except(
"PseudoTrap",
"+++ dimensions: Invalid parameter stream.");
519 const TGeoCompositeShape* sh = get_ptr<TGeoCompositeShape>(shape.ptr());
520 TGeoMatrix* right_matrix = sh->GetBoolNode()->GetRightMatrix();
521 std::stringstream params(right_matrix->GetTitle());
522 std::vector<double> pars;
524 for(std::size_t i=0; i<8; ++i) {
527 pars.emplace_back(val);
528 if ( !params.good() ) {
529 except(
"TruncatedTube",
"+++ dimensions: Invalid parameter stream.");
535 template <> std::vector<double>
dimensions<Solid>(
const Handle<TGeoShape>& shape) {
537 TClass* cl = shape->IsA();
538 if ( cl == TGeoShapeAssembly::Class() )
540 else if ( cl == TGeoBBox::Class() )
542 else if ( cl == TGeoHalfSpace::Class() )
544 else if ( cl == TGeoPgon::Class() )
546 else if ( cl == TGeoPcon::Class() )
548 else if ( cl == TGeoConeSeg::Class() )
550 else if ( cl == TGeoCone::Class() )
552 else if ( cl == TGeoTube::Class() )
554 else if ( cl == TGeoTubeSeg::Class() )
556 else if ( cl == TGeoCtub::Class() )
558 else if ( cl == TGeoEltu::Class() )
560 else if ( cl == TwistedTubeObject::Class() )
562 else if ( cl == TGeoTrd1::Class() )
564 else if ( cl == TGeoTrd2::Class() )
566 else if ( cl == TGeoParaboloid::Class() )
568 else if ( cl == TGeoHype::Class() )
570 else if ( cl == TGeoGtra::Class() )
572 else if ( cl == TGeoTrap::Class() )
574 else if ( cl == TGeoArb8::Class() )
576 else if ( cl == TGeoSphere::Class() )
578 else if ( cl == TGeoTorus::Class() )
580 else if ( cl == TGeoXtru::Class() )
582 else if ( cl == TGeoScaledShape::Class() )
584 else if ( cl == TGeoTessellated::Class() )
590 else if ( cl == TGeoCompositeShape::Class() )
593 printout(ERROR,
"Solid",
"Failed to access dimensions for shape of type:%s.",
598 except(
"Solid",
"Failed to access dimensions [Invalid handle].");
611 template <
typename T>
void set_dimensions(T shape,
const std::vector<double>& ) {
612 std::stringstream str;
614 str <<
"Shape: set_dimension(" << typeName(
typeid(*shape)) <<
"): Invalid call!";
616 str <<
"Shape: set_dimension<TGeoShape): Invalid call && pointer!";
617 throw std::runtime_error(str.str());
620 template <>
void set_dimensions(TGeoShapeAssembly* ,
const std::vector<double>& ) {
621 printout(WARNING,
"ShapelessSolid",
"+++ setDimensions is a compatibility call. Nothing implemented.");
623 template <>
void set_dimensions(TGeoBBox* sh,
const std::vector<double>& params) {
625 if ( pars.size() != 3 ) {
626 invalidSetDimensionCall(sh,params);
630 template <>
void set_dimensions(TGeoHalfSpace* sh,
const std::vector<double>& params) {
632 if ( params.size() != 6 ) {
633 invalidSetDimensionCall(sh,params);
637 template <>
void set_dimensions(TGeoPcon* sh,
const std::vector<double>& params) {
638 if ( params.size() < 3 ) {
639 invalidSetDimensionCall(sh,params);
641 std::size_t nz = std::size_t(params[2]);
642 if ( params.size() != 3 + 3*nz ) {
643 invalidSetDimensionCall(sh,params);
645 std::vector<double> pars = params;
646 pars[0] /= units::deg;
647 pars[1] /= units::deg;
651 if ( params.size() != 7 ) {
652 invalidSetDimensionCall(sh,params);
655 pars[5] /= units::deg;
656 pars[6] /= units::deg;
659 template <>
void set_dimensions(TGeoCone* sh,
const std::vector<double>& params) {
661 if ( params.size() != 5 ) {
662 invalidSetDimensionCall(sh,params);
666 template <>
void set_dimensions(TGeoTube* sh,
const std::vector<double>& params) {
667 if ( params.size() != 3 ) {
668 invalidSetDimensionCall(sh,params);
673 template <>
void set_dimensions(TGeoTubeSeg* sh,
const std::vector<double>& params) {
674 if ( params.size() != 5 ) {
675 invalidSetDimensionCall(sh,params);
678 pars[3] /= units::deg;
679 pars[4] /= units::deg;
683 if ( params.size() != 7 ) {
684 invalidSetDimensionCall(sh,params);
694 pars[2] = (-pars[3]+pars[4])/2.0;
700 template <>
void set_dimensions(TGeoCtub* sh,
const std::vector<double>& params) {
701 if ( params.size() != 11 ) {
702 invalidSetDimensionCall(sh,params);
705 pars[3] /= units::deg;
706 pars[4] /= units::deg;
709 template <>
void set_dimensions(TGeoEltu* sh,
const std::vector<double>& params) {
711 if ( params.size() != 3 ) {
712 invalidSetDimensionCall(sh,params);
716 template <>
void set_dimensions(TGeoTrd1* sh,
const std::vector<double>& params) {
718 if ( params.size() != 4 ) {
719 invalidSetDimensionCall(sh,params);
723 template <>
void set_dimensions(TGeoTrd2* sh,
const std::vector<double>& params) {
725 if ( params.size() != 5 ) {
726 invalidSetDimensionCall(sh,params);
730 template <>
void set_dimensions(TGeoParaboloid* sh,
const std::vector<double>& params) {
732 if ( params.size() != 3 ) {
733 invalidSetDimensionCall(sh,params);
737 template <>
void set_dimensions(TGeoHype* sh,
const std::vector<double>& params) {
738 if ( params.size() != 5 ) {
739 invalidSetDimensionCall(sh,params);
741 double pars[] = { params[0], params[1], params[2]/units::deg, params[3], params[4]/units::deg };
744 template <>
void set_dimensions(TGeoSphere* sh,
const std::vector<double>& params) {
745 if ( params.size() < 2 ) {
746 invalidSetDimensionCall(sh,params);
748 double pars[] = { params[0], params[1], 0.0,
M_PI/units::deg, 0.0, 2*
M_PI/units::deg };
749 if (params.size() > 2) pars[2] = params[2]/units::deg;
750 if (params.size() > 3) pars[3] = params[3]/units::deg;
751 if (params.size() > 4) pars[4] = params[4]/units::deg;
752 if (params.size() > 5) pars[5] = params[5]/units::deg;
753 Sphere(sh).
access()->SetDimensions(pars, params.size());
756 template <>
void set_dimensions(TGeoTorus* sh,
const std::vector<double>& params) {
757 if ( params.size() != 5 ) {
758 invalidSetDimensionCall(sh,params);
760 double pars[] = { params[0], params[1], params[2], params[3]/units::deg, params[4]/units::deg };
763 template <>
void set_dimensions(TGeoPgon* sh,
const std::vector<double>& params) {
765 if ( params.size() < 4 || params.size() != 4 + 3*std::size_t(params[3]) ) {
766 invalidSetDimensionCall(sh,params);
768 pars[0] /= units::deg;
769 pars[1] /= units::deg;
772 template <>
void set_dimensions(TGeoXtru* sh,
const std::vector<double>& params) {
774 if ( params.size() < 1 || params.size() != 1 + 4*std::size_t(params[0]) ) {
775 invalidSetDimensionCall(sh,params);
779 template <>
void set_dimensions(TGeoArb8* sh,
const std::vector<double>& params) {
780 if ( params.size() != 17 ) {
781 invalidSetDimensionCall(sh,params);
786 template <>
void set_dimensions(TGeoTrap* sh,
const std::vector<double>& params) {
788 if ( params.size() != 11 ) {
789 invalidSetDimensionCall(sh,params);
791 pars[1] /= units::deg;
792 pars[2] /= units::deg;
793 pars[6] /= units::deg;
794 pars[10] /= units::deg;
797 template <>
void set_dimensions(TGeoGtra* sh,
const std::vector<double>& params) {
799 if ( params.size() != 12 ) {
800 invalidSetDimensionCall(sh,params);
802 pars[1] /= units::deg;
803 pars[2] /= units::deg;
804 pars[6] /= units::deg;
805 pars[10] /= units::deg;
806 pars[11] /= units::deg;
809 template <>
void set_dimensions(TGeoScaledShape* sh,
const std::vector<double>& params) {
810 Solid s_sh(sh->GetShape());
811 sh->GetScale()->SetScale(params[0], params[1], params[2]);
813 s_sh.
access()->SetDimensions(&pars[3]);
816 template <>
void set_dimensions(TGeoTessellated* sh,
const std::vector<double>& params) {
817 int num_vtx = params[0];
818 int num_facet = params[1];
819 std::vector<TessellatedSolid::Vertex> vertices;
820 std::size_t i_par = 1;
821 printout(DEBUG,
"TessellatedSolid",
"+++ Loading %d vertices, %d facets",num_vtx, num_facet);
822 for (
int i=0; i<num_vtx; ++i) {
823 double x = params[++i_par];
824 double y = params[++i_par];
825 double z = params[++i_par];
826 vertices.emplace_back(x, y, z);
828 std::string nam = sh->GetName();
829 std::string tit = sh->GetTitle();
830 sh->~TGeoTessellated();
831 new(sh) TGeoTessellated(nam.c_str(), vertices);
832 sh->SetTitle(tit.c_str());
833 for (
int i=0; i<num_facet; ++i) {
835 int n_vtx = params[++i_par];
836 i0 = n_vtx>0 ? params[++i_par] : -1;
837 i1 = n_vtx>1 ? params[++i_par] : -1;
838 i2 = n_vtx>2 ? params[++i_par] : -1;
839 i3 = n_vtx>3 ? params[++i_par] : -1;
841 sh->AddFacet(i0,i1,i2);
842 else if ( n_vtx == 4 )
843 sh->AddFacet(i0,i1,i2,i3);
845 sh->CloseShape(
true,
true,
false);
848 template <>
void set_dimensions(TGeoCompositeShape*,
const std::vector<double>&) {
851 TGeoCompositeShape* sh = (TGeoCompositeShape*) shape;
852 TGeoBoolNode*
boolean = sh->GetBoolNode();
853 TGeoMatrix* right_matrix =
boolean->GetRightMatrix();
854 TGeoShape* left_solid =
boolean->GetLeftShape();
855 TGeoShape* right_solid =
boolean->GetRightShape();
859 #ifdef DIMENSION_DEBUG
860 throw std::runtime_error(
"Composite shape. setDimensions is not implemented!");
920 TGeoCompositeShape* sh = (TGeoCompositeShape*) shape.
ptr();
921 TGeoBoolNode*
boolean = sh->GetBoolNode();
922 TGeoMatrix* right_matrix =
boolean->GetRightMatrix();
923 TGeoShape* left_solid =
boolean->GetLeftShape();
924 TGeoShape* right_solid =
boolean->GetRightShape();
925 TGeoTubeSeg* tubs = (TGeoTubeSeg*)left_solid;
926 TGeoBBox* box = (TGeoBBox*)right_solid;
927 double dz = params[0];
928 double rmin = params[1];
929 double rmax = params[2];
930 double startPhi = params[3]/units::deg;
931 double deltaPhi = params[4]/units::deg;
932 double cutAtStart = params[5];
933 double cutAtDelta = params[6];
934 bool cutInside = params[7] > 0.5;
935 #ifdef DIMENSION_DEBUG
937 << right_matrix->GetTitle() << endl;
940 if( rmin <= 0 || rmax <= 0 || cutAtStart <= 0 || cutAtDelta <= 0 )
941 except(
TRUNCATEDTUBE_TAG,
"++ 0 <= rIn,cutAtStart,rOut,cutAtDelta,rOut violated!");
942 else if( rmin >= rmax )
944 else if( startPhi != 0. )
947 double r = cutAtStart;
948 double R = cutAtDelta;
950 double cath = r - R * std::cos( deltaPhi*units::deg );
951 double hypo = std::sqrt( r*r + R*R - 2.*r*R * std::cos( deltaPhi*units::deg ));
952 double cos_alpha = cath / hypo;
953 double alpha = std::acos( cos_alpha );
954 double sin_alpha = std::sin( std::fabs(alpha) );
959 double boxX = 1.1*rmax + rmax/sin_alpha;
962 double boxZ = 1.1 * dz;
965 xBox = r - boxY / sin_alpha;
967 xBox = r + boxY / sin_alpha;
971 rot.RotateZ( -alpha/units::deg );
972 double box_dim[] = {boxX, boxY, boxZ};
973 double tub_dim[] = {rmin, rmax, dz, startPhi, deltaPhi};
974 box->SetDimensions(box_dim);
975 tubs->SetDimensions(tub_dim);
976 TGeoCombiTrans* combi = (TGeoCombiTrans*)right_matrix;
977 combi->SetRotation(rot);
978 combi->SetTranslation(xBox, 0, 0);
982 TGeoCompositeShape* sh = (TGeoCompositeShape*) shape.
ptr();
983 TGeoBoolNode*
boolean = sh->GetBoolNode();
984 TGeoMatrix* right_matrix =
boolean->GetRightMatrix();
985 TGeoShape* left_solid =
boolean->GetLeftShape();
986 TGeoShape* right_solid =
boolean->GetRightShape();
987 double x1 = params[0];
988 double x2 = params[1];
989 double y1 = params[2];
990 double y2 = params[3];
991 double z = params[4];
992 double r = params[5];
993 bool atMinusZ = params[6] > 0.5;
994 double x = atMinusZ ? x1 : x2;
996 bool intersec =
false;
997 double displacement = 0;
1000 double halfOpeningAngle = std::asin( x / std::abs( r ))/units::deg;
1002 double delta = std::sqrt( r * r - x * x );
1004 #ifdef DIMENSION_DEBUG
1006 << right_matrix->GetTitle() << endl;
1010 if( r < 0 && std::abs(r) >= x ) {
1012 h = y1 < y2 ? y2 : y1;
1015 displacement = - halfZ -
delta;
1016 startPhi = 90.0 - halfOpeningAngle;
1019 displacement = halfZ +
delta;
1020 startPhi = -90.0 - halfOpeningAngle;
1023 else if( r > 0 && std::abs(r) >= x ) {
1025 displacement = - halfZ +
delta;
1026 startPhi = 270.0 - halfOpeningAngle;
1031 displacement = halfZ -
delta;
1032 startPhi = 90.0 - halfOpeningAngle;
1039 double trd2_dim[] = { x1, x2, y1, y2, halfZ };
1040 double tube_dim[] = { 0.0, std::abs(r), h, startPhi, startPhi + halfOpeningAngle*2. };
1041 if( intersec && left_solid->IsA() == TGeoTrd2::Class() ) {
1042 left_solid->SetDimensions(trd2_dim);
1043 right_solid->SetDimensions(tube_dim);
1045 else if ( right_solid->IsA() == TGeoCompositeShape::Class() ) {
1046 double box_dim[] = { 1.1*x, 1.1*h, std::sqrt(r*r-x*x) };
1047 TGeoCompositeShape* comp = (TGeoCompositeShape*)right_solid;
1048 TGeoBoolNode* b_s = comp->GetBoolNode();
1049 b_s->GetLeftShape()->SetDimensions(tube_dim);
1050 b_s->GetRightShape()->SetDimensions(box_dim);
1051 left_solid->SetDimensions(trd2_dim);
1054 except(
"PseudoTrap",
"+++ Incompatible change of parameters.");
1056 ((TGeoTranslation*)right_matrix)->SetTranslation(0,0,displacement);
1057 std::stringstream str;
1058 str << x1 <<
" " << x2 <<
" " << y1 <<
" " << y2 <<
" " << z <<
" "
1059 << r <<
" " << char(atMinusZ ?
'1' :
'0') <<
" ";
1060 right_matrix->SetTitle(str.str().c_str());
1065 if ( shape.
ptr() ) {
1066 TClass* cl = shape->IsA();
1068 if ( cl == TGeoShapeAssembly::Class() )
1070 else if ( cl == TGeoBBox::Class() )
1072 else if ( cl == TGeoHalfSpace::Class() )
1074 else if ( cl == TGeoPcon::Class() )
1076 else if ( cl == TGeoConeSeg::Class() )
1078 else if ( cl == TGeoCone::Class() )
1080 else if ( cl == TGeoTube::Class() )
1082 else if ( cl == TGeoTubeSeg::Class() )
1084 else if ( cl == TGeoCtub::Class() )
1086 else if ( cl == TGeoEltu::Class() )
1088 else if ( cl == TwistedTubeObject::Class() )
1090 else if ( cl == TGeoTrd1::Class() )
1092 else if ( cl == TGeoTrd2::Class() )
1094 else if ( cl == TGeoParaboloid::Class() )
1096 else if ( cl == TGeoHype::Class() )
1098 else if ( cl == TGeoSphere::Class() )
1100 else if ( cl == TGeoTorus::Class() )
1102 else if ( cl == TGeoTrap::Class() )
1104 else if ( cl == TGeoPgon::Class() )
1106 else if ( cl == TGeoXtru::Class() )
1108 else if ( cl == TGeoArb8::Class() )
1110 else if ( cl == TGeoTessellated::Class() )
1112 else if ( cl == TGeoScaledShape::Class() ) {
1113 TGeoScaledShape* sh = (TGeoScaledShape*) shape.
ptr();
1126 else if ( isA<BooleanSolid>(solid) )
1129 printout(ERROR,
"Solid",
"Failed to set dimensions for shape of type:%s.",cl->GetName() );
1132 except(
"Solid",
"set_shape_dimensions: Failed to set dimensions [Invalid handle].");
1135 template <>
void set_dimensions(
const TGeoShape* shape,
const std::vector<double>& params) {
1136 set_dimensions<Solid>(
Solid(shape), params);
1140 set_dimensions<Solid>(
Solid(shape), params);
1144 set_dimensions<Solid>(solid, params);
1150 return "[Invalid shape]";
1153 std::stringstream log;
1154 TClass* cl = shape->IsA();
1155 int prec = log.precision();
1156 log.setf(std::ios::fixed,std::ios::floatfield);
1157 log << std::setprecision(precision);
1158 log << cl->GetName();
1159 if ( cl == TGeoBBox::Class() ) {
1160 TGeoBBox* sh = (TGeoBBox*) shape;
1161 log <<
" x:" << sh->GetDX()
1162 <<
" y:" << sh->GetDY()
1163 <<
" z:" << sh->GetDZ();
1165 else if ( cl == TGeoHalfSpace::Class() ) {
1166 TGeoHalfSpace* sh = (TGeoHalfSpace*)(
const_cast<TGeoShape*
>(shape));
1167 log <<
" Point: (" << sh->GetPoint()[0] <<
", " << sh->GetPoint()[1] <<
", " << sh->GetPoint()[2] <<
") "
1168 <<
" Normal: (" << sh->GetNorm()[0] <<
", " << sh->GetNorm()[1] <<
", " << sh->GetNorm()[2] <<
") ";
1170 else if ( cl == TGeoTube::Class() ) {
1171 const TGeoTube* sh = (
const TGeoTube*) shape;
1172 log <<
" rmin:" << sh->GetRmin() <<
" rmax:" << sh->GetRmax() <<
" dz:" << sh->GetDz();
1174 else if ( cl == TGeoTubeSeg::Class() ) {
1175 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*) shape;
1176 log <<
" rmin:" << sh->GetRmin() <<
" rmax:" << sh->GetRmax() <<
" dz:" << sh->GetDz()
1177 <<
" Phi1:" << sh->GetPhi1() <<
" Phi2:" << sh->GetPhi2();
1179 else if ( cl == TGeoCtub::Class() ) {
1180 const TGeoCtub* sh = (
const TGeoCtub*) shape;
1181 const Double_t* hi = sh->GetNhigh();
1182 const Double_t* lo = sh->GetNlow();
1183 log <<
" rmin:" << sh->GetRmin() <<
" rmax:" << sh->GetRmax() <<
" dz:" << sh->GetDz()
1184 <<
" Phi1:" << sh->GetPhi1() <<
" Phi2:" << sh->GetPhi2()
1185 <<
" lx:" << lo[0] <<
" ly:" << lo[1] <<
" lz:" << lo[2]
1186 <<
" hx:" << hi[0] <<
" hy:" << hi[1] <<
" hz:" << hi[2];
1188 else if ( cl == TGeoEltu::Class() ) {
1189 const TGeoEltu* sh = (
const TGeoEltu*) shape;
1190 log <<
" A:" << sh->GetA() <<
" B:" << sh->GetB() <<
" dz:" << sh->GetDz();
1192 else if ( cl == TGeoTrd1::Class() ) {
1193 const TGeoTrd1* sh = (
const TGeoTrd1*) shape;
1194 log <<
" x1:" << sh->GetDx1() <<
" x2:" << sh->GetDx2() <<
" y:" << sh->GetDy() <<
" z:" << sh->GetDz();
1196 else if ( cl == TGeoTrd2::Class() ) {
1197 const TGeoTrd2* sh = (
const TGeoTrd2*) shape;
1198 log <<
" x1:" << sh->GetDx1() <<
" x2:" << sh->GetDx2()
1199 <<
" y1:" << sh->GetDy1() <<
" y2:" << sh->GetDy2() <<
" z:" << sh->GetDz();
1201 else if ( cl == TGeoTrap::Class() ) {
1202 const TGeoTrap* sh = (
const TGeoTrap*) shape;
1203 log <<
" dz:" << sh->GetDz() <<
" Theta:" << sh->GetTheta() <<
" Phi:" << sh->GetPhi()
1204 <<
" H1:" << sh->GetH1() <<
" Bl1:" << sh->GetBl1() <<
" Tl1:" << sh->GetTl1() <<
" Alpha1:" << sh->GetAlpha1()
1205 <<
" H2:" << sh->GetH2() <<
" Bl2:" << sh->GetBl2() <<
" Tl2:" << sh->GetTl2() <<
" Alpha2:" << sh->GetAlpha2();
1207 else if ( cl == TGeoHype::Class() ) {
1208 const TGeoHype* sh = (
const TGeoHype*) shape;
1209 log <<
" rmin:" << sh->GetRmin() <<
" rmax:" << sh->GetRmax() <<
" dz:" << sh->GetDz()
1210 <<
" StIn:" << sh->GetStIn() <<
" StOut:" << sh->GetStOut();
1212 else if ( cl == TGeoPgon::Class() ) {
1213 const TGeoPgon* sh = (
const TGeoPgon*) shape;
1214 log <<
" Phi1:" << sh->GetPhi1() <<
" dPhi:" << sh->GetDphi()
1215 <<
" NEdges:" << sh->GetNedges() <<
" Nz:" << sh->GetNz();
1216 for(
int i=0, n=sh->GetNz(); i<n; ++i) {
1217 log <<
" i=" << i <<
" z:" << sh->GetZ(i)
1218 <<
" r:[" << sh->GetRmin(i) <<
"," << sh->GetRmax(i) <<
"]";
1221 else if ( cl == TGeoPcon::Class() ) {
1222 const TGeoPcon* sh = (
const TGeoPcon*) shape;
1223 log <<
" Phi1:" << sh->GetPhi1() <<
" dPhi:" << sh->GetDphi() <<
" Nz:" << sh->GetNz();
1224 for(
int i=0, n=sh->GetNz(); i<n; ++i) {
1225 log <<
" i=" << i <<
" z:" << sh->GetZ(i)
1226 <<
" r:[" << sh->GetRmin(i) <<
"," << sh->GetRmax(i) <<
"]";
1229 else if ( cl == TGeoCone::Class() ) {
1230 const TGeoCone* sh = (
const TGeoCone*) shape;
1231 log <<
" rmin1:" << sh->GetRmin1() <<
" rmax1:" << sh->GetRmax1()
1232 <<
" rmin2:" << sh->GetRmin2() <<
" rmax2:" << sh->GetRmax2()
1233 <<
" dz:" << sh->GetDz();
1235 else if ( cl == TGeoConeSeg::Class() ) {
1237 log <<
" rmin1:" << sh->GetRmin1() <<
" rmax1:" << sh->GetRmax1()
1238 <<
" rmin2:" << sh->GetRmin2() <<
" rmax2:" << sh->GetRmax2()
1239 <<
" dz:" << sh->GetDz()
1240 <<
" Phi1:" << sh->GetPhi1() <<
" Phi2:" << sh->GetPhi2();
1242 else if ( cl == TGeoParaboloid::Class() ) {
1243 const TGeoParaboloid* sh = (
const TGeoParaboloid*) shape;
1244 log <<
" dz:" << sh->GetDz() <<
" RLo:" << sh->GetRlo() <<
" Rhi:" << sh->GetRhi();
1246 else if ( cl == TGeoSphere::Class() ) {
1247 const TGeoSphere* sh = (
const TGeoSphere*) shape;
1248 log <<
" rmin:" << sh->GetRmin() <<
" rmax:" << sh->GetRmax()
1249 <<
" Phi1:" << sh->GetPhi1() <<
" Phi2:" << sh->GetPhi2()
1250 <<
" Theta1:" << sh->GetTheta1() <<
" Theta2:" << sh->GetTheta2();
1252 else if ( cl == TGeoTorus::Class() ) {
1253 const TGeoTorus* sh = (
const TGeoTorus*) shape;
1254 log <<
" rmin:" << sh->GetRmin() <<
" rmax:" << sh->GetRmax() <<
" r:" << sh->GetR()
1255 <<
" Phi1:" << sh->GetPhi1() <<
" dPhi:" << sh->GetDphi();
1257 else if ( cl == TGeoArb8::Class() ) {
1258 TGeoArb8* sh = (TGeoArb8*) shape;
1259 const Double_t*
v = sh->GetVertices();
1260 log <<
" dz:" << sh->GetDz();
1261 for(
int i=0; i<8; ++i) {
1262 log <<
" x[" << i <<
"]:" << *
v; ++
v;
1263 log <<
" y[" << i <<
"]:" << *
v; ++
v;
1266 else if ( cl == TGeoXtru::Class() ) {
1267 const TGeoXtru* sh = (
const TGeoXtru*) shape;
1268 log <<
" X: " << sh->GetX(0)
1269 <<
" Y: " << sh->GetY(0)
1270 <<
" Z: " << sh->GetZ(0)
1271 <<
" Xoff:" << sh->GetXOffset(0)
1272 <<
" Yoff:" << sh->GetYOffset(0)
1273 <<
" Nvtx:" << sh->GetNvert()
1274 <<
" Nz: " << sh->GetNz();
1276 else if (shape->IsA() == TGeoCompositeShape::Class() ) {
1277 const TGeoCompositeShape* sh = (
const TGeoCompositeShape*) shape;
1278 const TGeoBoolNode*
boolean = sh->GetBoolNode();
1279 const TGeoShape* left =
boolean->GetLeftShape();
1280 const TGeoShape* right =
boolean->GetRightShape();
1281 TGeoBoolNode::EGeoBoolType oper =
boolean->GetBooleanOperator();
1282 if (oper == TGeoBoolNode::kGeoSubtraction)
1283 log <<
"Subtraction: ";
1284 else if (oper == TGeoBoolNode::kGeoUnion)
1286 else if (oper == TGeoBoolNode::kGeoIntersection)
1287 log <<
"Intersection: ";
1290 log << std::setprecision(prec);
1297 std::stringstream os;
1300 Int_t nvert = 0, nsegs = 0, npols = 0;
1302 sol->GetMeshNumbers(nvert, nsegs, npols);
1303 Double_t* points =
new Double_t[3*nvert];
1304 sol->SetPoints(points);
1306 os << std::setw(16) << std::left << sol->IsA()->GetName()
1307 <<
" " << nvert <<
" Mesh-points:" << std::endl;
1308 os << std::setw(16) << std::left << sol->IsA()->GetName() <<
" " << sol->GetName()
1309 <<
" N(mesh)=" << sol->GetNmeshVertices()
1310 <<
" N(vert)=" << nvert <<
" N(seg)=" << nsegs <<
" N(pols)=" << npols << std::endl;
1312 for(Int_t i=0; i<nvert; ++i) {
1313 Double_t* p = points + 3*i;
1314 os << std::setw(16) << std::left << sol->IsA()->GetName() <<
" " << std::setw(3) << std::left << i
1315 <<
" Local (" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << p[0]/dd4hep::cm
1316 <<
", " << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << p[1]/dd4hep::cm
1317 <<
", " << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << p[2]/dd4hep::cm
1318 <<
")" << std::endl;
1321 const Double_t* org = box->GetOrigin();
1322 os << std::setw(16) << std::left << sol->IsA()->GetName()
1323 <<
" Bounding box: "
1324 <<
" dx=" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << box->GetDX()/dd4hep::cm
1325 <<
" dy=" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << box->GetDY()/dd4hep::cm
1326 <<
" dz=" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << box->GetDZ()/dd4hep::cm
1327 <<
" Origin: x=" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << org[0]/dd4hep::cm
1328 <<
" y=" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << org[1]/dd4hep::cm
1329 <<
" z=" << std::setw(7) << std::setprecision(prec) << std::fixed << std::right << org[2]/dd4hep::cm