Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoBoolNode.cxx
Go to the documentation of this file.
1// @(#):$Id$
2// Author: Andrei Gheata 30/05/02
3// TGeoBoolNode::Contains and parser implemented by Mihaela Gheata
4
5/*************************************************************************
6 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12#include "TGeoBoolNode.h"
13
14#include <iostream>
15
16#include "TVirtualPad.h"
17#include "TVirtualViewer3D.h"
18#include "TBuffer3D.h"
19#include "TBuffer3DTypes.h"
20#include "TMath.h"
21#include "TGeoCompositeShape.h"
22#include "TGeoMatrix.h"
23#include "TGeoManager.h"
24
25/** \class TGeoBoolNode
26\ingroup Geometry_classes
27
28Base class for Boolean operations between two shapes.
29
30A Boolean node describes a Boolean operation between 'left' and 'right'
31shapes positioned with respect to an ARBITRARY reference frame. The boolean
32node is referenced by a mother composite shape and its shape components may
33be primitive but also composite shapes. The later situation leads to a binary
34tree hierarchy. When the parent composite shape is used to create a volume,
35the reference frame of the volume is chosen to match the frame in which
36node shape components were defined.
37
38The positioned shape components may or may not be disjoint. The specific
39implementations for Boolean nodes are:
40
41 - TGeoUnion - representing the Boolean union of two positioned shapes
42 - TGeoSubtraction - representing the Boolean subtraction of two positioned shapes
43 - TGeoIntersection - representing the Boolean intersection of two positioned shapes
44*/
45
46std::atomic<UInt_t> TGeoBoolNode::fgInstanceCount{0};
47////////////////////////////////////////////////////////////////////////////////
48/// Set the selected branch.
49
54
55////////////////////////////////////////////////////////////////////////////////
56/// Default constructor
57
59{
60 fLeft = nullptr;
61 fRight = nullptr;
62 fLeftMat = nullptr;
63 fRightMat = nullptr;
64 fNpoints = 0;
65 fPoints = nullptr;
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Constructor called by TGeoCompositeShape providing 2 subexpressions for the 2 branches.
70
71TGeoBoolNode::TGeoBoolNode(const char *expr1, const char *expr2)
72{
73 fLeft = nullptr;
74 fRight = nullptr;
75 fLeftMat = nullptr;
76 fRightMat = nullptr;
77 fNpoints = 0;
78 fPoints = nullptr;
79 if (!MakeBranch(expr1, kTRUE)) {
80 return;
81 }
82 if (!MakeBranch(expr2, kFALSE)) {
83 return;
84 }
85}
86
87////////////////////////////////////////////////////////////////////////////////
88/// Constructor providing left and right shapes and matrices (in the Boolean operation).
89
91{
92 fLeft = left;
93 fRight = right;
94 fLeftMat = lmat;
95 fNpoints = 0;
96 fPoints = nullptr;
97 if (!fLeftMat)
99 else
101 fRightMat = rmat;
102 if (!fRightMat)
104 else
106 if (!fLeft) {
107 Error("ctor", "left shape is NULL");
108 return;
109 }
110 if (!fRight) {
111 Error("ctor", "right shape is NULL");
112 return;
113 }
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Destructor.
118/// --- deletion of components handled by TGeoManager class.
119
121{
122 if (fPoints)
123 delete[] fPoints;
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// Set fPoints array
128
130{
131 if (fPoints) {
132 delete[] fPoints;
133 fPoints = nullptr;
134 fNpoints = 0;
135 }
136 if (points) {
138 fPoints = new Double_t[3 * fNpoints];
139 memcpy(fPoints, points, 3 * fNpoints * sizeof(Double_t));
140 }
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Returns number of vertices for the composite shape described by this node.
146
148{
149 Int_t itot = 0;
150 if (fNpoints && fMeshValid)
151 return fNpoints;
152 // Local points for the left shape
155 if (nleft + nright == 0)
156 return 0;
157
158 // This is an expensive check to make sure the generated points are on the surface of the shape
159 Double_t *points1 = (nleft > 0) ? new Double_t[3 * nleft] : nullptr;
160 if (nleft > 0)
162 // Local points for the right shape
163 Double_t *points2 = (nright > 0) ? new Double_t[3 * nright] : nullptr;
164 if (nright > 0)
166 Double_t *points = new Double_t[3 * (nleft + nright)];
167 for (Int_t i = 0; i < nleft; i++) {
168 fLeftMat->LocalToMaster(&points1[3 * i], &points[3 * itot]);
170 itot++;
171 }
172 for (Int_t i = 0; i < nright; i++) {
173 fRightMat->LocalToMaster(&points2[3 * i], &points[3 * itot]);
175 itot++;
176 }
177
179
180 delete[] points1;
181 delete[] points2;
182 delete[] points;
183 return fNpoints;
184}
185
186////////////////////////////////////////////////////////////////////////////////
187/// Invalidate mesh caching recursively
188
190{
192 if (fLeft->IsComposite())
193 ((TGeoCompositeShape *)fLeft)->InvalidateMeshCaches();
194 if (fRight->IsComposite())
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Implementation of the inside function using just Contains and GetNormal
200
202{
203 return tgeo_impl::Inside(point, this);
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Expands the boolean expression either on left or right branch, creating
208/// component elements (composite shapes and boolean nodes). Returns true on success.
209
211{
214 if (boolop < 0) {
215 Error("MakeBranch", "invalid expression");
216 return kFALSE;
217 }
218 TGeoShape *shape = nullptr;
221
222 if (stransf.Length() == 0) {
224 } else {
226 }
227 if (!mat) {
228 Error("MakeBranch", "transformation %s not found", stransf.Data());
229 return kFALSE;
230 }
231 switch (boolop) {
232 case 0:
233 // elementary shape
235 if (!shape) {
236 Error("MakeBranch", "shape %s not found", sleft.Data());
237 return kFALSE;
238 }
239 break;
240 case 1:
241 // composite shape - union
242 newshape = sleft;
243 newshape += "+";
244 newshape += sright;
245 shape = new TGeoCompositeShape(newshape.Data());
246 break;
247 case 2:
248 // composite shape - difference
249 newshape = sleft;
250 newshape += "-";
251 newshape += sright;
252 shape = new TGeoCompositeShape(newshape.Data());
253 break;
254 case 3:
255 // composite shape - intersection
256 newshape = sleft;
257 newshape += "*";
258 newshape += sright;
259 shape = new TGeoCompositeShape(newshape.Data());
260 break;
261 }
262 if (boolop && (!shape || !shape->IsValid())) {
263 Error("MakeBranch", "Shape %s not valid", newshape.Data());
264 if (shape)
265 delete shape;
266 return kFALSE;
267 }
268 if (left) {
269 fLeft = shape;
270 fLeftMat = mat;
271 } else {
272 fRight = shape;
273 fRightMat = mat;
274 }
275 return kTRUE;
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Special schema for feeding the 3D buffers to the painter client.
280
282{
283 TVirtualViewer3D *viewer = gPad->GetViewer3D();
284 if (!viewer)
285 return;
286
287 // Components of composite shape hierarchies for local frame viewers are painted
288 // in coordinate frame of the top level composite shape. So we force
289 // conversion to this. See TGeoPainter::PaintNode for loading of GLMatrix.
290 Bool_t localFrame = kFALSE; // viewer->PreferLocalFrame();
291
294 mat = glmat; // keep a copy
295
296 // Now perform fetch and add of the two components buffers.
297 // Note we assume that composite shapes are always completely added
298 // so don't bother to get addDaughters flag from viewer->AddObject()
299
300 // Setup matrix and fetch/add the left component buffer
301 glmat->Multiply(fLeftMat);
302 // fLeft->Paint(option);
303 if (TGeoCompositeShape *left = dynamic_cast<TGeoCompositeShape *>(fLeft)) {
304 left->PaintComposite(option);
305 } else if (fLeft) {
307 viewer->AddObject(leftBuffer);
308 }
309
310 // Setup matrix and fetch/add the right component buffer
311 *glmat = &mat;
312 glmat->Multiply(fRightMat);
313 // fRight->Paint(option);
314 if (TGeoCompositeShape *right = dynamic_cast<TGeoCompositeShape *>(fRight)) {
315 right->PaintComposite(option);
316 } else if (fRight) {
318 viewer->AddObject(rightBuffer);
319 }
320
321 *glmat = &mat;
322}
323
324////////////////////////////////////////////////////////////////////////////////
325/// Register all matrices of the boolean node and descendents.
326
328{
329 if (!fLeftMat->IsIdentity())
331 if (!fRightMat->IsIdentity())
333 if (fLeft->IsComposite())
334 ((TGeoCompositeShape *)fLeft)->GetBoolNode()->RegisterMatrices();
335 if (fRight->IsComposite())
336 ((TGeoCompositeShape *)fRight)->GetBoolNode()->RegisterMatrices();
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// Replace one of the matrices. Does not work with TGeoIdentity. Returns true
341/// if replacement was successful.
342
344{
345 if (mat == gGeoIdentity || newmat == gGeoIdentity) {
346 Error("ReplaceMatrix",
347 "Matrices should not be gGeoIdentity. Use default matrix constructor to represent identities.");
348 return kFALSE;
349 }
350 if (!mat || !newmat) {
351 Error("ReplaceMatrix", "Matrices should not be null pointers.");
352 return kFALSE;
353 }
355 if (fLeftMat == mat) {
357 replaced = kTRUE;
358 }
359 if (fRightMat == mat) {
361 replaced = kTRUE;
362 }
363 return replaced;
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Save a primitive as a C++ statement(s) on output stream "out".
368
369void TGeoBoolNode::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
370{
373 if (!fLeftMat->IsIdentity()) {
376 }
377 if (!fRightMat->IsIdentity()) {
380 }
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Fill buffer with shape vertices.
385
387{
388 TGeoBoolNode *bn = (TGeoBoolNode *)this;
389 Int_t npoints = bn->GetNpoints();
390 memcpy(points, fPoints, 3 * npoints * sizeof(Double_t));
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Fill buffer with shape vertices.
395
397{
398 TGeoBoolNode *bn = (TGeoBoolNode *)this;
399 Int_t npoints = bn->GetNpoints();
400 for (Int_t i = 0; i < 3 * npoints; i++)
401 points[i] = fPoints[i];
402}
403
404////////////////////////////////////////////////////////////////////////////////
405/// Register size of this 3D object
406
408{
409 fLeft->Sizeof3D();
410 fRight->Sizeof3D();
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Make a clone of this. Pointers are preserved.
415
420
421////////////////////////////////////////////////////////////////////////////////
422/// Paint method.
423
425{
426 TVirtualViewer3D *viewer = gPad->GetViewer3D();
427
428 if (!viewer) {
429 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
430 return;
431 }
432
433 viewer->AddCompositeOp(TBuffer3D::kCSUnion);
434
436}
437
438////////////////////////////////////////////////////////////////////////////////
439/// Default constructor
440
442
443////////////////////////////////////////////////////////////////////////////////
444/// Constructor
445
446TGeoUnion::TGeoUnion(const char *expr1, const char *expr2) : TGeoBoolNode(expr1, expr2) {}
447
448////////////////////////////////////////////////////////////////////////////////
449/// Constructor providing pointers to components
450
452 : TGeoBoolNode(left, right, lmat, rmat)
453{
455 Fatal("TGeoUnion", "Unions with a half-space (%s + %s) not allowed", left->GetName(), right->GetName());
456 }
457}
458
459////////////////////////////////////////////////////////////////////////////////
460/// Destructor
461/// --- deletion of components handled by TGeoManager class.
462
464
465////////////////////////////////////////////////////////////////////////////////
466/// Compute bounding box corresponding to a union of two shapes.
467
469{
470 if (((TGeoBBox *)fLeft)->IsNullBox())
472 if (((TGeoBBox *)fRight)->IsNullBox())
474 Double_t vert[48];
475 Double_t pt[3];
476 Int_t i;
477 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
478 xmin = ymin = zmin = TGeoShape::Big();
479 xmax = ymax = zmax = -TGeoShape::Big();
480 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
481 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
482 for (i = 0; i < 8; i++) {
483 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
484 if (pt[0] < xmin)
485 xmin = pt[0];
486 if (pt[0] > xmax)
487 xmax = pt[0];
488 if (pt[1] < ymin)
489 ymin = pt[1];
490 if (pt[1] > ymax)
491 ymax = pt[1];
492 if (pt[2] < zmin)
493 zmin = pt[2];
494 if (pt[2] > zmax)
495 zmax = pt[2];
496 }
497 for (i = 8; i < 16; i++) {
498 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
499 if (pt[0] < xmin)
500 xmin = pt[0];
501 if (pt[0] > xmax)
502 xmax = pt[0];
503 if (pt[1] < ymin)
504 ymin = pt[1];
505 if (pt[1] > ymax)
506 ymax = pt[1];
507 if (pt[2] < zmin)
508 zmin = pt[2];
509 if (pt[2] > zmax)
510 zmax = pt[2];
511 }
512 dx = 0.5 * (xmax - xmin);
513 origin[0] = 0.5 * (xmin + xmax);
514 dy = 0.5 * (ymax - ymin);
515 origin[1] = 0.5 * (ymin + ymax);
516 dz = 0.5 * (zmax - zmin);
517 origin[2] = 0.5 * (zmin + zmax);
518}
519
520////////////////////////////////////////////////////////////////////////////////
521/// Find if a union of two shapes contains a given point
522
524{
525 Double_t local[3];
526 fLeftMat->MasterToLocal(point, &local[0]);
527 Bool_t inside = fLeft->Contains(&local[0]);
528 if (inside)
529 return kTRUE;
530 fRightMat->MasterToLocal(point, &local[0]);
531 inside = fRight->Contains(&local[0]);
532 return inside;
533}
534
535////////////////////////////////////////////////////////////////////////////////
536/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
537
538void TGeoUnion::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
539{
541 norm[0] = norm[1] = 0.;
542 norm[2] = 1.;
543 Double_t local[3];
544 Double_t ldir[3], lnorm[3];
545 if (td.fSelected == 1) {
550 return;
551 }
552 if (td.fSelected == 2) {
557 return;
558 }
560 if (fLeft->Contains(local)) {
564 return;
565 }
567 if (fRight->Contains(local)) {
571 return;
572 }
573 // Propagate forward/backward to see which of the components is intersected first
574 local[0] = point[0] + 1E-5 * dir[0];
575 local[1] = point[1] + 1E-5 * dir[1];
576 local[2] = point[2] + 1E-5 * dir[2];
577
578 if (!Contains(local)) {
579 local[0] = point[0] - 1E-5 * dir[0];
580 local[1] = point[1] - 1E-5 * dir[1];
581 local[2] = point[2] - 1E-5 * dir[2];
582 if (!Contains(local))
583 return;
584 }
585 ComputeNormal(local, dir, norm);
586}
587
588////////////////////////////////////////////////////////////////////////////////
589/// Compute minimum distance to shape vertices.
590
592{
593 return 9999;
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// Computes distance from a given point inside the shape to its boundary.
598
601{
602 if (iact < 3 && safe) {
603 // compute safe distance
604 *safe = Safety(point, kTRUE);
605 if (iact == 0)
606 return TGeoShape::Big();
607 if (iact == 1 && step < *safe)
608 return TGeoShape::Big();
609 }
610
611 Double_t local[3], local1[3], master[3], ldir[3], rdir[3], pushed[3];
612 memcpy(master, point, 3 * sizeof(Double_t));
613 Int_t i;
614 TGeoBoolNode *node = (TGeoBoolNode *)this;
615 Double_t d1 = 0., d2 = 0., snxt = 0., eps = 0.;
620 if (inside1)
622 else
623 memcpy(local1, local, 3 * sizeof(Double_t));
626 if (inside2)
628 if (!(inside1 | inside2)) {
629 // This is a pathological case when the point is on the boundary
631 if (d1 < 1.E-3) {
632 eps = d1 + TGeoShape::Tolerance();
633 for (i = 0; i < 3; i++)
634 local1[i] += eps * ldir[i];
635 inside1 = kTRUE;
637 d1 += eps;
638 } else {
640 if (d2 < 1.E-3) {
641 eps = d2 + TGeoShape::Tolerance();
642 for (i = 0; i < 3; i++)
643 local[i] += eps * rdir[i];
644 inside2 = kTRUE;
646 d2 += eps;
647 }
648 }
649 }
650 while (inside1 || inside2) {
651 if (inside1 && inside2) {
652 if (d1 < d2) {
653 snxt += d1;
654 node->SetSelected(1);
655 // propagate to exit of left shape
656 inside1 = kFALSE;
657 for (i = 0; i < 3; i++)
658 master[i] += d1 * dir[i];
659 // check if propagated point is in right shape
662 if (!inside2)
663 return snxt;
665 if (d2 < TGeoShape::Tolerance())
666 return snxt;
667 } else {
668 snxt += d2;
669 node->SetSelected(2);
670 // propagate to exit of right shape
671 inside2 = kFALSE;
672 for (i = 0; i < 3; i++)
673 master[i] += d2 * dir[i];
674 // check if propagated point is in left shape
677 if (!inside1)
678 return snxt;
680 if (d1 < TGeoShape::Tolerance())
681 return snxt;
682 }
683 }
684 if (inside1) {
685 snxt += d1;
686 node->SetSelected(1);
687 // propagate to exit of left shape
688 inside1 = kFALSE;
689 for (i = 0; i < 3; i++) {
690 master[i] += d1 * dir[i];
691 pushed[i] = master[i] + (1. + d1) * TGeoShape::Tolerance() * dir[i];
692 }
693 // check if propagated point is in right shape
696 if (!inside2)
697 return snxt;
699 if (d2 < TGeoShape::Tolerance())
700 return snxt;
701 d2 += (1. + d1) * TGeoShape::Tolerance();
702 }
703 if (inside2) {
704 snxt += d2;
705 node->SetSelected(2);
706 // propagate to exit of right shape
707 inside2 = kFALSE;
708 for (i = 0; i < 3; i++) {
709 master[i] += d2 * dir[i];
710 pushed[i] = master[i] + (1. + d2) * TGeoShape::Tolerance() * dir[i];
711 }
712 // check if propagated point is in left shape
715 if (!inside1)
716 return snxt;
718 if (d1 < TGeoShape::Tolerance())
719 return snxt;
720 d1 += (1. + d2) * TGeoShape::Tolerance();
721 }
722 }
723 return snxt;
724}
725
726////////////////////////////////////////////////////////////////////////////////
727/// Compute distance from a given outside point to the shape.
728
731{
732 if (iact < 3 && safe) {
733 // compute safe distance
734 *safe = Safety(point, kFALSE);
735 if (iact == 0)
736 return TGeoShape::Big();
737 if (iact == 1 && step < *safe)
738 return TGeoShape::Big();
739 }
740 TGeoBoolNode *node = (TGeoBoolNode *)this;
741 Double_t local[3], ldir[3], rdir[3];
742 Double_t d1, d2, snxt;
743 fLeftMat->MasterToLocal(point, &local[0]);
746 d1 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
747 fRightMat->MasterToLocal(point, &local[0]);
748 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
749 if (d1 < d2) {
750 snxt = d1;
751 node->SetSelected(1);
752 } else {
753 snxt = d2;
754 node->SetSelected(2);
755 }
756 return snxt;
757}
758
759////////////////////////////////////////////////////////////////////////////////
760/// Compute safety distance for a union node;
761
763{
764 Double_t local1[3], local2[3];
769 Bool_t intrue = in1 | in2;
770 if (intrue ^ in)
771 return 0.0;
774 if (in1 && in2)
775 return TMath::Min(saf1, saf2);
776 if (in1)
777 return saf1;
778 if (in2)
779 return saf2;
780 return TMath::Min(saf1, saf2);
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Save a primitive as a C++ statement(s) on output stream "out".
785
786void TGeoUnion::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
787{
789 out << " pBoolNode = new TGeoUnion(";
790 out << fLeft->GetPointerName() << ",";
791 out << fRight->GetPointerName() << ",";
792 if (!fLeftMat->IsIdentity())
793 out << fLeftMat->GetPointerName() << ",";
794 else
795 out << "0,";
796 if (!fRightMat->IsIdentity())
797 out << fRightMat->GetPointerName() << ");" << std::endl;
798 else
799 out << "0);" << std::endl;
800}
801
802////////////////////////////////////////////////////////////////////////////////
803/// Register 3D size of this shape.
804
806{
808}
809
810////////////////////////////////////////////////////////////////////////////////
811/// Make a clone of this. Pointers are preserved.
812
817
818////////////////////////////////////////////////////////////////////////////////
819/// Paint method.
820
822{
823 TVirtualViewer3D *viewer = gPad->GetViewer3D();
824
825 if (!viewer) {
826 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
827 return;
828 }
829
830 viewer->AddCompositeOp(TBuffer3D::kCSDifference);
831
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// Default constructor
837
839
840////////////////////////////////////////////////////////////////////////////////
841/// Constructor
842
844
845////////////////////////////////////////////////////////////////////////////////
846/// Constructor providing pointers to components
847
849 : TGeoBoolNode(left, right, lmat, rmat)
850{
852 Fatal("TGeoSubstraction", "Subtractions from a half-space (%s) not allowed", left->GetName());
853 }
854}
855
856////////////////////////////////////////////////////////////////////////////////
857/// Destructor
858/// --- deletion of components handled by TGeoManager class.
859
861
862////////////////////////////////////////////////////////////////////////////////
863/// Compute bounding box corresponding to a subtraction of two shapes.
864
866{
868 if (box->IsNullBox())
870 Double_t vert[24];
871 Double_t pt[3];
872 Int_t i;
873 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
874 xmin = ymin = zmin = TGeoShape::Big();
875 xmax = ymax = zmax = -TGeoShape::Big();
876 box->SetBoxPoints(&vert[0]);
877 for (i = 0; i < 8; i++) {
878 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
879 if (pt[0] < xmin)
880 xmin = pt[0];
881 if (pt[0] > xmax)
882 xmax = pt[0];
883 if (pt[1] < ymin)
884 ymin = pt[1];
885 if (pt[1] > ymax)
886 ymax = pt[1];
887 if (pt[2] < zmin)
888 zmin = pt[2];
889 if (pt[2] > zmax)
890 zmax = pt[2];
891 }
892 dx = 0.5 * (xmax - xmin);
893 origin[0] = 0.5 * (xmin + xmax);
894 dy = 0.5 * (ymax - ymin);
895 origin[1] = 0.5 * (ymin + ymax);
896 dz = 0.5 * (zmax - zmin);
897 origin[2] = 0.5 * (zmin + zmax);
898}
899
900////////////////////////////////////////////////////////////////////////////////
901/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
902
903void TGeoSubtraction::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
904{
906 norm[0] = norm[1] = 0.;
907 norm[2] = 1.;
908 Double_t local[3], ldir[3], lnorm[3];
909 if (td.fSelected == 1) {
914 return;
915 }
916 if (td.fSelected == 2) {
921 return;
922 }
924 if (fRight->Contains(local)) {
928 return;
929 }
931 if (!fLeft->Contains(local)) {
935 return;
936 }
937 // point is inside left shape, but not inside the right
938 local[0] = point[0] + 1E-5 * dir[0];
939 local[1] = point[1] + 1E-5 * dir[1];
940 local[2] = point[2] + 1E-5 * dir[2];
941 if (Contains(local)) {
942 local[0] = point[0] - 1E-5 * dir[0];
943 local[1] = point[1] - 1E-5 * dir[1];
944 local[2] = point[2] - 1E-5 * dir[2];
945 if (Contains(local))
946 return;
947 }
948 ComputeNormal(local, dir, norm);
949}
950
951////////////////////////////////////////////////////////////////////////////////
952/// Find if a subtraction of two shapes contains a given point
953
955{
956 Double_t local[3];
957 fLeftMat->MasterToLocal(point, &local[0]);
958 Bool_t inside = fLeft->Contains(&local[0]);
959 if (!inside)
960 return kFALSE;
961 fRightMat->MasterToLocal(point, &local[0]);
962 inside = !fRight->Contains(&local[0]);
963 return inside;
964}
965
966////////////////////////////////////////////////////////////////////////////////
967/// Compute minimum distance to shape vertices
968
970{
971 return 9999;
972}
973
974////////////////////////////////////////////////////////////////////////////////
975/// Compute distance from a given point inside to the shape boundary.
976
978 Double_t *safe) const
979{
980 if (iact < 3 && safe) {
981 // compute safe distance
982 *safe = Safety(point, kTRUE);
983 if (iact == 0)
984 return TGeoShape::Big();
985 if (iact == 1 && step < *safe)
986 return TGeoShape::Big();
987 }
988 TGeoBoolNode *node = (TGeoBoolNode *)this;
989 Double_t local[3], ldir[3], rdir[3];
990 Double_t d1, d2, snxt = 0.;
991 fLeftMat->MasterToLocal(point, &local[0]);
994 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
995 fRightMat->MasterToLocal(point, &local[0]);
996 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
997 if (d1 < d2) {
998 snxt = d1;
999 node->SetSelected(1);
1000 } else {
1001 snxt = d2;
1002 node->SetSelected(2);
1003 }
1004 return snxt;
1005}
1006
1007////////////////////////////////////////////////////////////////////////////////
1008/// Compute distance from a given point outside to the shape.
1009
1011 Double_t *safe) const
1012{
1013 if (iact < 3 && safe) {
1014 // compute safe distance
1015 *safe = Safety(point, kFALSE);
1016 if (iact == 0)
1017 return TGeoShape::Big();
1018 if (iact == 1 && step < *safe)
1019 return TGeoShape::Big();
1020 }
1021 TGeoBoolNode *node = (TGeoBoolNode *)this;
1022 Double_t local[3], master[3], ldir[3], rdir[3];
1023 memcpy(&master[0], point, 3 * sizeof(Double_t));
1024 Int_t i;
1025 Double_t d1, d2, snxt = 0.;
1026 fRightMat->MasterToLocal(point, &local[0]);
1027 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1028 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1029 // check if inside '-'
1030 Bool_t inside = fRight->Contains(&local[0]);
1031 Double_t epsil = 0.;
1032 while (true) {
1033 if (inside) {
1034 // propagate to outside of '-'
1035 node->SetSelected(2);
1036 d1 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1037 snxt += d1 + epsil;
1038 for (i = 0; i < 3; i++)
1039 master[i] += (d1 + 1E-8) * dir[i];
1040 epsil = 1.E-8;
1041 // now master outside '-'; check if inside '+'
1043 if (fLeft->Contains(&local[0]))
1044 return snxt;
1045 }
1046 // master outside '-' and outside '+' ; find distances to both
1047 node->SetSelected(1);
1049 d2 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
1050 if (d2 > 1E20)
1051 return TGeoShape::Big();
1052
1054 d1 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1055 if (d2 < d1 - TGeoShape::Tolerance()) {
1056 snxt += d2 + epsil;
1057 return snxt;
1058 }
1059 // propagate to '-'
1060 snxt += d1 + epsil;
1061 for (i = 0; i < 3; i++)
1062 master[i] += (d1 + 1E-8) * dir[i];
1063 epsil = 1.E-8;
1064 // now inside '-' and not inside '+'
1066 inside = kTRUE;
1067 }
1068}
1069
1070////////////////////////////////////////////////////////////////////////////////
1071/// Compute safety distance for a union node;
1072
1074{
1075 Double_t local1[3], local2[3];
1076 fLeftMat->MasterToLocal(point, local1);
1080 Bool_t intrue = in1 && (!in2);
1081 if (in ^ intrue)
1082 return 0.0;
1085 if (in1 && in2)
1086 return saf2;
1087 if (in1)
1088 return TMath::Min(saf1, saf2);
1089 if (in2)
1090 return TMath::Max(saf1, saf2);
1091 return saf1;
1092}
1093
1094////////////////////////////////////////////////////////////////////////////////
1095/// Save a primitive as a C++ statement(s) on output stream "out".
1096
1097void TGeoSubtraction::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1098{
1100 out << " pBoolNode = new TGeoSubtraction(";
1101 out << fLeft->GetPointerName() << ",";
1102 out << fRight->GetPointerName() << ",";
1103 if (!fLeftMat->IsIdentity())
1104 out << fLeftMat->GetPointerName() << ",";
1105 else
1106 out << "0,";
1107 if (!fRightMat->IsIdentity())
1108 out << fRightMat->GetPointerName() << ");" << std::endl;
1109 else
1110 out << "0);" << std::endl;
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// Register 3D size of this shape.
1115
1117{
1119}
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// Make a clone of this. Pointers are preserved.
1123
1128
1129////////////////////////////////////////////////////////////////////////////////
1130/// Paint method.
1131
1133{
1134 TVirtualViewer3D *viewer = gPad->GetViewer3D();
1135
1136 if (!viewer) {
1137 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
1138 return;
1139 }
1140
1141 viewer->AddCompositeOp(TBuffer3D::kCSIntersection);
1142
1144}
1145
1146////////////////////////////////////////////////////////////////////////////////
1147/// Default constructor
1148
1150
1151////////////////////////////////////////////////////////////////////////////////
1152/// Constructor
1153
1155
1156////////////////////////////////////////////////////////////////////////////////
1157/// Constructor providing pointers to components
1158
1160 : TGeoBoolNode(left, right, lmat, rmat)
1161{
1164 if (hs1 && hs2)
1165 Fatal("ctor", "cannot intersect two half-spaces: %s * %s", left->GetName(), right->GetName());
1166}
1167
1168////////////////////////////////////////////////////////////////////////////////
1169/// Destructor
1170/// --- deletion of components handled by TGeoManager class.
1171
1173
1174////////////////////////////////////////////////////////////////////////////////
1175/// Compute bounding box corresponding to a intersection of two shapes.
1176
1178{
1181 Double_t vert[48];
1182 Double_t pt[3];
1183 Int_t i;
1188 if (!hs1) {
1189 if (((TGeoBBox *)fLeft)->IsNullBox())
1190 fLeft->ComputeBBox();
1191 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
1192 for (i = 0; i < 8; i++) {
1193 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
1194 if (pt[0] < xmin1)
1195 xmin1 = pt[0];
1196 if (pt[0] > xmax1)
1197 xmax1 = pt[0];
1198 if (pt[1] < ymin1)
1199 ymin1 = pt[1];
1200 if (pt[1] > ymax1)
1201 ymax1 = pt[1];
1202 if (pt[2] < zmin1)
1203 zmin1 = pt[2];
1204 if (pt[2] > zmax1)
1205 zmax1 = pt[2];
1206 }
1207 }
1208 if (!hs2) {
1209 if (((TGeoBBox *)fRight)->IsNullBox())
1211 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
1212 for (i = 8; i < 16; i++) {
1213 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
1214 if (pt[0] < xmin2)
1215 xmin2 = pt[0];
1216 if (pt[0] > xmax2)
1217 xmax2 = pt[0];
1218 if (pt[1] < ymin2)
1219 ymin2 = pt[1];
1220 if (pt[1] > ymax2)
1221 ymax2 = pt[1];
1222 if (pt[2] < zmin2)
1223 zmin2 = pt[2];
1224 if (pt[2] > zmax2)
1225 zmax2 = pt[2];
1226 }
1227 }
1228 if (hs1) {
1229 dx = 0.5 * (xmax2 - xmin2);
1230 origin[0] = 0.5 * (xmax2 + xmin2);
1231 dy = 0.5 * (ymax2 - ymin2);
1232 origin[1] = 0.5 * (ymax2 + ymin2);
1233 dz = 0.5 * (zmax2 - zmin2);
1234 origin[2] = 0.5 * (zmax2 + zmin2);
1235 return;
1236 }
1237 if (hs2) {
1238 dx = 0.5 * (xmax1 - xmin1);
1239 origin[0] = 0.5 * (xmax1 + xmin1);
1240 dy = 0.5 * (ymax1 - ymin1);
1241 origin[1] = 0.5 * (ymax1 + ymin1);
1242 dz = 0.5 * (zmax1 - zmin1);
1243 origin[2] = 0.5 * (zmax1 + zmin1);
1244 return;
1245 }
1246 Double_t sort[4];
1247 Int_t isort[4];
1248 sort[0] = xmin1;
1249 sort[1] = xmax1;
1250 sort[2] = xmin2;
1251 sort[3] = xmax2;
1252 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1253 if (isort[1] % 2) {
1254 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1255 dx = dy = dz = 0;
1256 memset(origin, 0, 3 * sizeof(Double_t));
1257 return;
1258 }
1259 dx = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1260 origin[0] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1261 sort[0] = ymin1;
1262 sort[1] = ymax1;
1263 sort[2] = ymin2;
1264 sort[3] = ymax2;
1265 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1266 if (isort[1] % 2) {
1267 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1268 dx = dy = dz = 0;
1269 memset(origin, 0, 3 * sizeof(Double_t));
1270 return;
1271 }
1272 dy = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1273 origin[1] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1274 sort[0] = zmin1;
1275 sort[1] = zmax1;
1276 sort[2] = zmin2;
1277 sort[3] = zmax2;
1278 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1279 if (isort[1] % 2) {
1280 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1281 dx = dy = dz = 0;
1282 memset(origin, 0, 3 * sizeof(Double_t));
1283 return;
1284 }
1285 dz = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1286 origin[2] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1287}
1288
1289////////////////////////////////////////////////////////////////////////////////
1290/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
1291
1292void TGeoIntersection::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
1293{
1295 Double_t local[3], ldir[3], lnorm[3];
1296 norm[0] = norm[1] = 0.;
1297 norm[2] = 1.;
1298 if (td.fSelected == 1) {
1299 fLeftMat->MasterToLocal(point, local);
1303 return;
1304 }
1305 if (td.fSelected == 2) {
1306 fRightMat->MasterToLocal(point, local);
1310 return;
1311 }
1312 fLeftMat->MasterToLocal(point, local);
1313 if (!fLeft->Contains(local)) {
1317 return;
1318 }
1319 fRightMat->MasterToLocal(point, local);
1320 if (!fRight->Contains(local)) {
1324 return;
1325 }
1326 // point is inside intersection.
1327 local[0] = point[0] + 1E-5 * dir[0];
1328 local[1] = point[1] + 1E-5 * dir[1];
1329 local[2] = point[2] + 1E-5 * dir[2];
1330 if (Contains(local)) {
1331 local[0] = point[0] - 1E-5 * dir[0];
1332 local[1] = point[1] - 1E-5 * dir[1];
1333 local[2] = point[2] - 1E-5 * dir[2];
1334 if (Contains(local))
1335 return;
1336 }
1337 ComputeNormal(local, dir, norm);
1338}
1339
1340////////////////////////////////////////////////////////////////////////////////
1341/// Find if a intersection of two shapes contains a given point
1342
1344{
1345 Double_t local[3];
1346 fLeftMat->MasterToLocal(point, &local[0]);
1347 Bool_t inside = fLeft->Contains(&local[0]);
1348 if (!inside)
1349 return kFALSE;
1350 fRightMat->MasterToLocal(point, &local[0]);
1351 inside = fRight->Contains(&local[0]);
1352 return inside;
1353}
1354
1355////////////////////////////////////////////////////////////////////////////////
1356/// Compute minimum distance to shape vertices
1357
1359{
1360 return 9999;
1361}
1362
1363////////////////////////////////////////////////////////////////////////////////
1364/// Compute distance from a given point inside to the shape boundary.
1365
1367 Double_t *safe) const
1368{
1369 if (iact < 3 && safe) {
1370 // compute safe distance
1371 *safe = Safety(point, kTRUE);
1372 if (iact == 0)
1373 return TGeoShape::Big();
1374 if (iact == 1 && step < *safe)
1375 return TGeoShape::Big();
1376 }
1377 TGeoBoolNode *node = (TGeoBoolNode *)this;
1378 Double_t local[3], ldir[3], rdir[3];
1379 Double_t d1, d2, snxt = 0.;
1380 fLeftMat->MasterToLocal(point, &local[0]);
1381 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1382 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1383 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1384 fRightMat->MasterToLocal(point, &local[0]);
1385 d2 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1386 if (d1 < d2) {
1387 snxt = d1;
1388 node->SetSelected(1);
1389 } else {
1390 snxt = d2;
1391 node->SetSelected(2);
1392 }
1393 return snxt;
1394}
1395
1396////////////////////////////////////////////////////////////////////////////////
1397/// Compute distance from a given point outside to the shape.
1398
1400 Double_t *safe) const
1401{
1403 if (iact < 3 && safe) {
1404 // compute safe distance
1405 *safe = Safety(point, kFALSE);
1406 if (iact == 0)
1407 return TGeoShape::Big();
1408 if (iact == 1 && step < *safe)
1409 return TGeoShape::Big();
1410 }
1411 TGeoBoolNode *node = (TGeoBoolNode *)this;
1412 Double_t lpt[3], rpt[3], master[3], ldir[3], rdir[3];
1413 memcpy(master, point, 3 * sizeof(Double_t));
1414 Int_t i;
1415 Double_t d1 = 0.;
1416 Double_t d2 = 0.;
1417 fLeftMat->MasterToLocal(point, lpt);
1418 fRightMat->MasterToLocal(point, rpt);
1423 node->SetSelected(0);
1424 Double_t snext = 0.0;
1425 if (inleft && inright) {
1426 // It is vey likely to have a numerical issue and the point should
1427 // be logically outside one of the shapes
1428 d1 = fLeft->DistFromInside(lpt, ldir, 3);
1430 if (d1 < 1.E-3)
1431 inleft = kFALSE;
1432 if (d2 < 1.E-3)
1433 inright = kFALSE;
1434 if (inleft && inright)
1435 return snext;
1436 }
1437
1438 while (true) {
1439 d1 = d2 = 0;
1440 if (!inleft) {
1442 d1 = TMath::Max(d1, tol);
1443 if (d1 > 1E20)
1444 return TGeoShape::Big();
1445 }
1446 if (!inright) {
1448 d2 = TMath::Max(d2, tol);
1449 if (d2 > 1E20)
1450 return TGeoShape::Big();
1451 }
1452
1453 if (d1 > d2) {
1454 // propagate to left shape
1455 snext += d1;
1456 node->SetSelected(1);
1457 inleft = kTRUE;
1458 for (i = 0; i < 3; i++)
1459 master[i] += d1 * dir[i];
1461 // Push rpt to avoid a bad boundary condition
1462 for (i = 0; i < 3; i++)
1463 rpt[i] += tol * rdir[i];
1464 // check if propagated point is inside right shape
1466 if (inright)
1467 return snext;
1468 // here inleft=true, inright=false
1469 } else {
1470 // propagate to right shape
1471 snext += d2;
1472 node->SetSelected(2);
1473 inright = kTRUE;
1474 for (i = 0; i < 3; i++)
1475 master[i] += d2 * dir[i];
1477 // Push lpt to avoid a bad boundary condition
1478 for (i = 0; i < 3; i++)
1479 lpt[i] += tol * ldir[i];
1480 // check if propagated point is inside left shape
1482 if (inleft)
1483 return snext;
1484 // here inleft=false, inright=true
1485 }
1486 }
1487 return snext;
1488}
1489
1490////////////////////////////////////////////////////////////////////////////////
1491/// Compute safety distance for a union node;
1492
1494{
1495 Double_t local1[3], local2[3];
1496 fLeftMat->MasterToLocal(point, local1);
1500 Bool_t intrue = in1 & in2;
1501 if (in ^ intrue)
1502 return 0.0;
1505 if (in1 && in2)
1506 return TMath::Min(saf1, saf2);
1507 if (in1)
1508 return saf2;
1509 if (in2)
1510 return saf1;
1511 return TMath::Max(saf1, saf2);
1512}
1513
1514////////////////////////////////////////////////////////////////////////////////
1515/// Save a primitive as a C++ statement(s) on output stream "out".
1516
1517void TGeoIntersection::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1518{
1520 out << " pBoolNode = new TGeoIntersection(";
1521 out << fLeft->GetPointerName() << ",";
1522 out << fRight->GetPointerName() << ",";
1523 if (!fLeftMat->IsIdentity())
1524 out << fLeftMat->GetPointerName() << ",";
1525 else
1526 out << "0,";
1527 if (!fRightMat->IsIdentity())
1528 out << fRightMat->GetPointerName() << ");" << std::endl;
1529 else
1530 out << "0);" << std::endl;
1531}
1532
1533////////////////////////////////////////////////////////////////////////////////
1534/// Register 3D size of this shape.
1535
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:538
float xmin
float ymin
float xmax
float ymax
#define gPad
Generic 3D primitive description class.
Definition TBuffer3D.h:18
@ kCSDifference
Definition TBuffer3D.h:43
@ kCSIntersection
Definition TBuffer3D.h:43
Box class.
Definition TGeoBBox.h:18
Base class for Boolean operations between two shapes.
virtual void Sizeof3D() const
Register size of this 3D object.
Int_t fNpoints
! number of points on the mesh
Bool_t MakeBranch(const char *expr, Bool_t left)
Expands the boolean expression either on left or right branch, creating component elements (composite...
TGeoMatrix * fLeftMat
~TGeoBoolNode() override
Destructor.
TGeoShape::EInside Inside(const Double_t *point) const
Implementation of the inside function using just Contains and GetNormal.
TGeoShape * fLeft
Bool_t ReplaceMatrix(TGeoMatrix *mat, TGeoMatrix *newmat)
Replace one of the matrices.
void AssignPoints(Int_t npoints, Double_t *points)
Set fPoints array.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void Paint(Option_t *option) override
Special schema for feeding the 3D buffers to the painter client.
ThreadData_t & GetThreadData() const
Per-thread scratch state, owned by the calling thread and indexed by this node.
virtual void SetPoints(Double_t *points) const
Fill buffer with shape vertices.
void RegisterMatrices()
Register all matrices of the boolean node and descendents.
TGeoShape * fRight
Bool_t fMeshValid
! Flag for mesh cache validity
Double_t * fPoints
! array of mesh points
void InvalidateMeshCaches()
Invalidate mesh caching recursively.
TGeoBoolNode()
Default constructor.
Int_t GetNpoints()
Returns number of vertices for the composite shape described by this node.
TGeoMatrix * fRightMat
static std::atomic< UInt_t > fgInstanceCount
void SetSelected(Int_t sel)
Set the selected branch.
Composite shapes are Boolean combinations of two or more shape components.
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:459
Int_t DistanceToPrimitive(Int_t px, Int_t py) override
Compute minimum distance to shape vertices.
TGeoBoolNode * MakeClone() const override
Make a clone of this. Pointers are preserved.
TGeoIntersection()
Default constructor.
void Sizeof3D() const override
Register 3D size of this shape.
void ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin) override
Compute bounding box corresponding to a intersection of two shapes.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point outside to the shape.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Compute safety distance for a union node;.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point inside to the shape boundary.
void Paint(Option_t *option) override
Paint method.
~TGeoIntersection() override
Destructor — deletion of components handled by TGeoManager class.
Bool_t Contains(const Double_t *point) const override
Find if a intersection of two shapes contains a given point.
TObjArray * GetListOfMatrices() const
static Int_t Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
Parse a string boolean expression and do a syntax check.
TObjArray * GetListOfShapes() const
Geometrical transformation package.
Definition TGeoMatrix.h:39
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Bool_t IsIdentity() const
Definition TGeoMatrix.h:64
const char * GetPointerName() const
Provide a pointer name containing uid.
Base abstract class for all shapes.
Definition TGeoShape.h:25
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Stub implementation to avoid forcing implementation at this stage.
static Double_t Big()
Definition TGeoShape.h:95
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const =0
Bool_t IsValid() const
Definition TGeoShape.h:153
virtual Int_t GetNmeshVertices() const
Definition TGeoShape.h:135
virtual void Sizeof3D() const =0
virtual Bool_t IsComposite() const
Definition TGeoShape.h:139
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const =0
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const =0
const char * GetPointerName() const
Provide a pointer name containing uid.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const =0
const char * GetName() const override
Get the shape name.
virtual void ComputeBBox()=0
static TGeoMatrix * GetTransform()
Returns current transformation matrix that applies to shape.
virtual Bool_t Contains(const Double_t *point) const =0
@ kGeoHalfSpace
Definition TGeoShape.h:62
static Double_t Tolerance()
Definition TGeoShape.h:98
virtual void SetPoints(Double_t *points) const =0
Bool_t TestShapeBit(UInt_t f) const
Definition TGeoShape.h:177
TGeoSubtraction()
Default constructor.
void ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin) override
Compute bounding box corresponding to a subtraction of two shapes.
~TGeoSubtraction() override
Destructor — deletion of components handled by TGeoManager class.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Compute safety distance for a union node;.
TGeoBoolNode * MakeClone() const override
Make a clone of this. Pointers are preserved.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point outside to the shape.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
Bool_t Contains(const Double_t *point) const override
Find if a subtraction of two shapes contains a given point.
void Sizeof3D() const override
Register 3D size of this shape.
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point inside to the shape boundary.
void Paint(Option_t *option) override
Paint method.
Int_t DistanceToPrimitive(Int_t px, Int_t py) override
Compute minimum distance to shape vertices.
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
Int_t DistanceToPrimitive(Int_t px, Int_t py) override
Compute minimum distance to shape vertices.
TGeoBoolNode * MakeClone() const override
Make a clone of this. Pointers are preserved.
void ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin) override
Compute bounding box corresponding to a union of two shapes.
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given outside point to the shape.
Bool_t Contains(const Double_t *point) const override
Find if a union of two shapes contains a given point.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Compute safety distance for a union node;.
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Computes distance from a given point inside the shape to its boundary.
~TGeoUnion() override
Destructor — deletion of components handled by TGeoManager class.
TGeoUnion()
Default constructor.
void Paint(Option_t *option) override
Paint method.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void Sizeof3D() const override
Register 3D size of this shape.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1082
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:857
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1124
Basic string class.
Definition TString.h:137
Abstract 3D shapes viewer.
TPaveText * pt
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:413
TGeoShape::EInside Inside(const Double_t *point, Solid const *solid)
Generic implementation of the inside function using just Contains and GetNormal.
Definition TGeoShape.h:187