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
46
47////////////////////////////////////////////////////////////////////////////////
48/// Constructor.
49
51
52////////////////////////////////////////////////////////////////////////////////
53/// Destructor.
54
56
57////////////////////////////////////////////////////////////////////////////////
58
60{
62 /*
63 std::lock_guard<std::mutex> guard(fMutex);
64 if (tid >= fThreadSize) {
65 Error("GetThreadData", "Thread id=%d bigger than maximum declared thread number %d. \nUse
66 TGeoManager::SetMaxThreads properly !!!", tid, fThreadSize);
67 }
68 if (tid >= fThreadSize)
69 {
70 fThreadData.resize(tid + 1);
71 fThreadSize = tid + 1;
72 }
73 if (fThreadData[tid] == 0)
74 {
75 if (fThreadData[tid] == 0)
76 fThreadData[tid] = new ThreadData_t;
77 }
78 */
79 return *fThreadData[tid];
80}
81
82////////////////////////////////////////////////////////////////////////////////
83
85{
86 std::lock_guard<std::mutex> guard(fMutex);
87 std::vector<ThreadData_t *>::iterator i = fThreadData.begin();
88 while (i != fThreadData.end()) {
89 delete *i;
90 ++i;
91 }
92 fThreadData.clear();
93 fThreadSize = 0;
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Create thread data for n threads max.
98
100{
101 std::lock_guard<std::mutex> guard(fMutex);
102 fThreadData.resize(nthreads);
104 for (Int_t tid = 0; tid < nthreads; tid++) {
105 if (fThreadData[tid] == nullptr) {
107 }
108 }
109 // Propagate to components
110 if (fLeft)
112 if (fRight)
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Set the selected branch.
118
123
124////////////////////////////////////////////////////////////////////////////////
125/// Default constructor
126
128{
129 fLeft = nullptr;
130 fRight = nullptr;
131 fLeftMat = nullptr;
132 fRightMat = nullptr;
133 fNpoints = 0;
134 fPoints = nullptr;
135 fThreadSize = 0;
137}
138
139////////////////////////////////////////////////////////////////////////////////
140/// Constructor called by TGeoCompositeShape providing 2 subexpressions for the 2 branches.
141
142TGeoBoolNode::TGeoBoolNode(const char *expr1, const char *expr2)
143{
144 fLeft = nullptr;
145 fRight = nullptr;
146 fLeftMat = nullptr;
147 fRightMat = nullptr;
148 fNpoints = 0;
149 fPoints = nullptr;
150 fThreadSize = 0;
152 if (!MakeBranch(expr1, kTRUE)) {
153 return;
154 }
155 if (!MakeBranch(expr2, kFALSE)) {
156 return;
157 }
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Constructor providing left and right shapes and matrices (in the Boolean operation).
162
164{
165 fLeft = left;
166 fRight = right;
167 fLeftMat = lmat;
168 fNpoints = 0;
169 fPoints = nullptr;
170 fThreadSize = 0;
172 if (!fLeftMat)
174 else
176 fRightMat = rmat;
177 if (!fRightMat)
179 else
181 if (!fLeft) {
182 Error("ctor", "left shape is NULL");
183 return;
184 }
185 if (!fRight) {
186 Error("ctor", "right shape is NULL");
187 return;
188 }
189}
190
191////////////////////////////////////////////////////////////////////////////////
192/// Destructor.
193/// --- deletion of components handled by TGeoManager class.
194
196{
197 if (fPoints)
198 delete[] fPoints;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Set fPoints array
204
206{
207 if (fPoints) {
208 delete[] fPoints;
209 fPoints = nullptr;
210 fNpoints = 0;
211 }
212 if (points) {
214 fPoints = new Double_t[3 * fNpoints];
215 memcpy(fPoints, points, 3 * fNpoints * sizeof(Double_t));
216 }
217}
218
219////////////////////////////////////////////////////////////////////////////////
220/// Returns number of vertices for the composite shape described by this node.
221
223{
224 Int_t itot = 0;
225 if (fNpoints)
226 return fNpoints;
227 // Local points for the left shape
230 if (nleft + nright == 0) return 0;
231
232 Double_t *points1 = (nleft > 0) ? new Double_t[3 * nleft] : nullptr;
233 if (nleft > 0) fLeft->SetPoints(points1);
234 // Local points for the right shape
235 Double_t *points2 = (nright > 0) ? new Double_t[3 * nright] : nullptr;
236 if (nright > 0) fRight->SetPoints(points2);
237 Double_t *points = new Double_t[3 * (nleft + nright)];
238 for (Int_t i = 0; i < nleft; i++) {
239 fLeftMat->LocalToMaster(&points1[3 * i], &points[3 * itot]);
241 itot++;
242 }
243 for (Int_t i = 0; i < nright; i++) {
244 fRightMat->LocalToMaster(&points2[3 * i], &points[3 * itot]);
246 itot++;
247 }
248
250
251 delete[] points1;
252 delete[] points2;
253 delete[] points;
254 return fNpoints;
255}
256
257////////////////////////////////////////////////////////////////////////////////
258/// Implementation of the inside function using just Contains and GetNormal
259
261{
262 return tgeo_impl::Inside(point, this);
263}
264
265////////////////////////////////////////////////////////////////////////////////
266/// Expands the boolean expression either on left or right branch, creating
267/// component elements (composite shapes and boolean nodes). Returns true on success.
268
270{
273 if (boolop < 0) {
274 Error("MakeBranch", "invalid expression");
275 return kFALSE;
276 }
277 TGeoShape *shape = nullptr;
280
281 if (stransf.Length() == 0) {
283 } else {
285 }
286 if (!mat) {
287 Error("MakeBranch", "transformation %s not found", stransf.Data());
288 return kFALSE;
289 }
290 switch (boolop) {
291 case 0:
292 // elementary shape
294 if (!shape) {
295 Error("MakeBranch", "shape %s not found", sleft.Data());
296 return kFALSE;
297 }
298 break;
299 case 1:
300 // composite shape - union
301 newshape = sleft;
302 newshape += "+";
303 newshape += sright;
304 shape = new TGeoCompositeShape(newshape.Data());
305 break;
306 case 2:
307 // composite shape - difference
308 newshape = sleft;
309 newshape += "-";
310 newshape += sright;
311 shape = new TGeoCompositeShape(newshape.Data());
312 break;
313 case 3:
314 // composite shape - intersection
315 newshape = sleft;
316 newshape += "*";
317 newshape += sright;
318 shape = new TGeoCompositeShape(newshape.Data());
319 break;
320 }
321 if (boolop && (!shape || !shape->IsValid())) {
322 Error("MakeBranch", "Shape %s not valid", newshape.Data());
323 if (shape)
324 delete shape;
325 return kFALSE;
326 }
327 if (left) {
328 fLeft = shape;
329 fLeftMat = mat;
330 } else {
331 fRight = shape;
332 fRightMat = mat;
333 }
334 return kTRUE;
335}
336
337////////////////////////////////////////////////////////////////////////////////
338/// Special schema for feeding the 3D buffers to the painter client.
339
341{
342 TVirtualViewer3D *viewer = gPad->GetViewer3D();
343 if (!viewer)
344 return;
345
346 // Components of composite shape hierarchies for local frame viewers are painted
347 // in coordinate frame of the top level composite shape. So we force
348 // conversion to this. See TGeoPainter::PaintNode for loading of GLMatrix.
349 Bool_t localFrame = kFALSE; // viewer->PreferLocalFrame();
350
353 mat = glmat; // keep a copy
354
355 // Now perform fetch and add of the two components buffers.
356 // Note we assume that composite shapes are always completely added
357 // so don't bother to get addDaughters flag from viewer->AddObject()
358
359 // Setup matrix and fetch/add the left component buffer
360 glmat->Multiply(fLeftMat);
361 // fLeft->Paint(option);
362 if (TGeoCompositeShape *left = dynamic_cast<TGeoCompositeShape *>(fLeft)) {
363 left->PaintComposite(option);
364 } else if (fLeft) {
366 viewer->AddObject(leftBuffer);
367 }
368
369 // Setup matrix and fetch/add the right component buffer
370 *glmat = &mat;
371 glmat->Multiply(fRightMat);
372 // fRight->Paint(option);
373 if (TGeoCompositeShape *right = dynamic_cast<TGeoCompositeShape *>(fRight)) {
374 right->PaintComposite(option);
375 } else if (fRight) {
377 viewer->AddObject(rightBuffer);
378 }
379
380 *glmat = &mat;
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Register all matrices of the boolean node and descendents.
385
387{
388 if (!fLeftMat->IsIdentity())
390 if (!fRightMat->IsIdentity())
392 if (fLeft->IsComposite())
393 ((TGeoCompositeShape *)fLeft)->GetBoolNode()->RegisterMatrices();
394 if (fRight->IsComposite())
395 ((TGeoCompositeShape *)fRight)->GetBoolNode()->RegisterMatrices();
396}
397
398////////////////////////////////////////////////////////////////////////////////
399/// Replace one of the matrices. Does not work with TGeoIdentity. Returns true
400/// if replacement was successful.
401
403{
404 if (mat == gGeoIdentity || newmat == gGeoIdentity) {
405 Error("ReplaceMatrix",
406 "Matrices should not be gGeoIdentity. Use default matrix constructor to represent identities.");
407 return kFALSE;
408 }
409 if (!mat || !newmat) {
410 Error("ReplaceMatrix", "Matrices should not be null pointers.");
411 return kFALSE;
412 }
414 if (fLeftMat == mat) {
416 replaced = kTRUE;
417 }
418 if (fRightMat == mat) {
420 replaced = kTRUE;
421 }
422 return replaced;
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Save a primitive as a C++ statement(s) on output stream "out".
427
428void TGeoBoolNode::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
429{
432 if (!fLeftMat->IsIdentity()) {
435 }
436 if (!fRightMat->IsIdentity()) {
439 }
440}
441
442////////////////////////////////////////////////////////////////////////////////
443/// Fill buffer with shape vertices.
444
446{
447 TGeoBoolNode *bn = (TGeoBoolNode *)this;
448 Int_t npoints = bn->GetNpoints();
449 memcpy(points, fPoints, 3 * npoints * sizeof(Double_t));
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Fill buffer with shape vertices.
454
456{
457 TGeoBoolNode *bn = (TGeoBoolNode *)this;
458 Int_t npoints = bn->GetNpoints();
459 for (Int_t i = 0; i < 3 * npoints; i++)
460 points[i] = fPoints[i];
461}
462
463////////////////////////////////////////////////////////////////////////////////
464/// Register size of this 3D object
465
467{
468 fLeft->Sizeof3D();
469 fRight->Sizeof3D();
470}
471
472
473////////////////////////////////////////////////////////////////////////////////
474/// Make a clone of this. Pointers are preserved.
475
480
481////////////////////////////////////////////////////////////////////////////////
482/// Paint method.
483
485{
486 TVirtualViewer3D *viewer = gPad->GetViewer3D();
487
488 if (!viewer) {
489 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
490 return;
491 }
492
493 viewer->AddCompositeOp(TBuffer3D::kCSUnion);
494
496}
497
498////////////////////////////////////////////////////////////////////////////////
499/// Default constructor
500
502
503////////////////////////////////////////////////////////////////////////////////
504/// Constructor
505
506TGeoUnion::TGeoUnion(const char *expr1, const char *expr2) : TGeoBoolNode(expr1, expr2) {}
507
508////////////////////////////////////////////////////////////////////////////////
509/// Constructor providing pointers to components
510
512 : TGeoBoolNode(left, right, lmat, rmat)
513{
515 Fatal("TGeoUnion", "Unions with a half-space (%s + %s) not allowed", left->GetName(), right->GetName());
516 }
517}
518
519////////////////////////////////////////////////////////////////////////////////
520/// Destructor
521/// --- deletion of components handled by TGeoManager class.
522
524
525////////////////////////////////////////////////////////////////////////////////
526/// Compute bounding box corresponding to a union of two shapes.
527
529{
530 if (((TGeoBBox *)fLeft)->IsNullBox())
532 if (((TGeoBBox *)fRight)->IsNullBox())
534 Double_t vert[48];
535 Double_t pt[3];
536 Int_t i;
537 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
538 xmin = ymin = zmin = TGeoShape::Big();
539 xmax = ymax = zmax = -TGeoShape::Big();
540 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
541 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
542 for (i = 0; i < 8; i++) {
543 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
544 if (pt[0] < xmin)
545 xmin = pt[0];
546 if (pt[0] > xmax)
547 xmax = pt[0];
548 if (pt[1] < ymin)
549 ymin = pt[1];
550 if (pt[1] > ymax)
551 ymax = pt[1];
552 if (pt[2] < zmin)
553 zmin = pt[2];
554 if (pt[2] > zmax)
555 zmax = pt[2];
556 }
557 for (i = 8; i < 16; i++) {
558 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
559 if (pt[0] < xmin)
560 xmin = pt[0];
561 if (pt[0] > xmax)
562 xmax = pt[0];
563 if (pt[1] < ymin)
564 ymin = pt[1];
565 if (pt[1] > ymax)
566 ymax = pt[1];
567 if (pt[2] < zmin)
568 zmin = pt[2];
569 if (pt[2] > zmax)
570 zmax = pt[2];
571 }
572 dx = 0.5 * (xmax - xmin);
573 origin[0] = 0.5 * (xmin + xmax);
574 dy = 0.5 * (ymax - ymin);
575 origin[1] = 0.5 * (ymin + ymax);
576 dz = 0.5 * (zmax - zmin);
577 origin[2] = 0.5 * (zmin + zmax);
578}
579
580////////////////////////////////////////////////////////////////////////////////
581/// Find if a union of two shapes contains a given point
582
584{
585 Double_t local[3];
586 fLeftMat->MasterToLocal(point, &local[0]);
587 Bool_t inside = fLeft->Contains(&local[0]);
588 if (inside)
589 return kTRUE;
590 fRightMat->MasterToLocal(point, &local[0]);
591 inside = fRight->Contains(&local[0]);
592 return inside;
593}
594
595////////////////////////////////////////////////////////////////////////////////
596/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
597
598void TGeoUnion::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
599{
601 norm[0] = norm[1] = 0.;
602 norm[2] = 1.;
603 Double_t local[3];
604 Double_t ldir[3], lnorm[3];
605 if (td.fSelected == 1) {
610 return;
611 }
612 if (td.fSelected == 2) {
617 return;
618 }
620 if (fLeft->Contains(local)) {
624 return;
625 }
627 if (fRight->Contains(local)) {
631 return;
632 }
633 // Propagate forward/backward to see which of the components is intersected first
634 local[0] = point[0] + 1E-5 * dir[0];
635 local[1] = point[1] + 1E-5 * dir[1];
636 local[2] = point[2] + 1E-5 * dir[2];
637
638 if (!Contains(local)) {
639 local[0] = point[0] - 1E-5 * dir[0];
640 local[1] = point[1] - 1E-5 * dir[1];
641 local[2] = point[2] - 1E-5 * dir[2];
642 if (!Contains(local))
643 return;
644 }
645 ComputeNormal(local, dir, norm);
646}
647
648////////////////////////////////////////////////////////////////////////////////
649/// Compute minimum distance to shape vertices.
650
652{
653 return 9999;
654}
655
656////////////////////////////////////////////////////////////////////////////////
657/// Computes distance from a given point inside the shape to its boundary.
658
661{
662 if (iact < 3 && safe) {
663 // compute safe distance
664 *safe = Safety(point, kTRUE);
665 if (iact == 0)
666 return TGeoShape::Big();
667 if (iact == 1 && step < *safe)
668 return TGeoShape::Big();
669 }
670
671 Double_t local[3], local1[3], master[3], ldir[3], rdir[3], pushed[3];
672 memcpy(master, point, 3 * sizeof(Double_t));
673 Int_t i;
674 TGeoBoolNode *node = (TGeoBoolNode *)this;
675 Double_t d1 = 0., d2 = 0., snxt = 0., eps = 0.;
680 if (inside1)
682 else
683 memcpy(local1, local, 3 * sizeof(Double_t));
686 if (inside2)
688 if (!(inside1 | inside2)) {
689 // This is a pathological case when the point is on the boundary
691 if (d1 < 1.E-3) {
692 eps = d1 + TGeoShape::Tolerance();
693 for (i = 0; i < 3; i++)
694 local1[i] += eps * ldir[i];
695 inside1 = kTRUE;
697 d1 += eps;
698 } else {
700 if (d2 < 1.E-3) {
701 eps = d2 + TGeoShape::Tolerance();
702 for (i = 0; i < 3; i++)
703 local[i] += eps * rdir[i];
704 inside2 = kTRUE;
706 d2 += eps;
707 }
708 }
709 }
710 while (inside1 || inside2) {
711 if (inside1 && inside2) {
712 if (d1 < d2) {
713 snxt += d1;
714 node->SetSelected(1);
715 // propagate to exit of left shape
716 inside1 = kFALSE;
717 for (i = 0; i < 3; i++)
718 master[i] += d1 * dir[i];
719 // check if propagated point is in right shape
722 if (!inside2)
723 return snxt;
725 if (d2 < TGeoShape::Tolerance())
726 return snxt;
727 } else {
728 snxt += d2;
729 node->SetSelected(2);
730 // propagate to exit of right shape
731 inside2 = kFALSE;
732 for (i = 0; i < 3; i++)
733 master[i] += d2 * dir[i];
734 // check if propagated point is in left shape
737 if (!inside1)
738 return snxt;
740 if (d1 < TGeoShape::Tolerance())
741 return snxt;
742 }
743 }
744 if (inside1) {
745 snxt += d1;
746 node->SetSelected(1);
747 // propagate to exit of left shape
748 inside1 = kFALSE;
749 for (i = 0; i < 3; i++) {
750 master[i] += d1 * dir[i];
751 pushed[i] = master[i] + (1. + d1) * TGeoShape::Tolerance() * dir[i];
752 }
753 // check if propagated point is in right shape
756 if (!inside2)
757 return snxt;
759 if (d2 < TGeoShape::Tolerance())
760 return snxt;
761 d2 += (1. + d1) * TGeoShape::Tolerance();
762 }
763 if (inside2) {
764 snxt += d2;
765 node->SetSelected(2);
766 // propagate to exit of right shape
767 inside2 = kFALSE;
768 for (i = 0; i < 3; i++) {
769 master[i] += d2 * dir[i];
770 pushed[i] = master[i] + (1. + d2) * TGeoShape::Tolerance() * dir[i];
771 }
772 // check if propagated point is in left shape
775 if (!inside1)
776 return snxt;
778 if (d1 < TGeoShape::Tolerance())
779 return snxt;
780 d1 += (1. + d2) * TGeoShape::Tolerance();
781 }
782 }
783 return snxt;
784}
785
786////////////////////////////////////////////////////////////////////////////////
787/// Compute distance from a given outside point to the shape.
788
791{
792 if (iact < 3 && safe) {
793 // compute safe distance
794 *safe = Safety(point, kFALSE);
795 if (iact == 0)
796 return TGeoShape::Big();
797 if (iact == 1 && step < *safe)
798 return TGeoShape::Big();
799 }
800 TGeoBoolNode *node = (TGeoBoolNode *)this;
801 Double_t local[3], ldir[3], rdir[3];
802 Double_t d1, d2, snxt;
803 fLeftMat->MasterToLocal(point, &local[0]);
806 d1 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
807 fRightMat->MasterToLocal(point, &local[0]);
808 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
809 if (d1 < d2) {
810 snxt = d1;
811 node->SetSelected(1);
812 } else {
813 snxt = d2;
814 node->SetSelected(2);
815 }
816 return snxt;
817}
818
819////////////////////////////////////////////////////////////////////////////////
820/// Compute safety distance for a union node;
821
823{
824 Double_t local1[3], local2[3];
829 Bool_t intrue = in1 | in2;
830 if (intrue ^ in)
831 return 0.0;
834 if (in1 && in2)
835 return TMath::Min(saf1, saf2);
836 if (in1)
837 return saf1;
838 if (in2)
839 return saf2;
840 return TMath::Min(saf1, saf2);
841}
842
843////////////////////////////////////////////////////////////////////////////////
844/// Save a primitive as a C++ statement(s) on output stream "out".
845
846void TGeoUnion::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
847{
849 out << " pBoolNode = new TGeoUnion(";
850 out << fLeft->GetPointerName() << ",";
851 out << fRight->GetPointerName() << ",";
852 if (!fLeftMat->IsIdentity())
853 out << fLeftMat->GetPointerName() << ",";
854 else
855 out << "0,";
856 if (!fRightMat->IsIdentity())
857 out << fRightMat->GetPointerName() << ");" << std::endl;
858 else
859 out << "0);" << std::endl;
860}
861
862////////////////////////////////////////////////////////////////////////////////
863/// Register 3D size of this shape.
864
866{
868}
869
870
871////////////////////////////////////////////////////////////////////////////////
872/// Make a clone of this. Pointers are preserved.
873
878
879////////////////////////////////////////////////////////////////////////////////
880/// Paint method.
881
883{
884 TVirtualViewer3D *viewer = gPad->GetViewer3D();
885
886 if (!viewer) {
887 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
888 return;
889 }
890
891 viewer->AddCompositeOp(TBuffer3D::kCSDifference);
892
894}
895
896////////////////////////////////////////////////////////////////////////////////
897/// Default constructor
898
900
901////////////////////////////////////////////////////////////////////////////////
902/// Constructor
903
905
906////////////////////////////////////////////////////////////////////////////////
907/// Constructor providing pointers to components
908
910 : TGeoBoolNode(left, right, lmat, rmat)
911{
913 Fatal("TGeoSubstraction", "Subtractions from a half-space (%s) not allowed", left->GetName());
914 }
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Destructor
919/// --- deletion of components handled by TGeoManager class.
920
922
923////////////////////////////////////////////////////////////////////////////////
924/// Compute bounding box corresponding to a subtraction of two shapes.
925
927{
929 if (box->IsNullBox())
931 Double_t vert[24];
932 Double_t pt[3];
933 Int_t i;
934 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
935 xmin = ymin = zmin = TGeoShape::Big();
936 xmax = ymax = zmax = -TGeoShape::Big();
937 box->SetBoxPoints(&vert[0]);
938 for (i = 0; i < 8; i++) {
939 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
940 if (pt[0] < xmin)
941 xmin = pt[0];
942 if (pt[0] > xmax)
943 xmax = pt[0];
944 if (pt[1] < ymin)
945 ymin = pt[1];
946 if (pt[1] > ymax)
947 ymax = pt[1];
948 if (pt[2] < zmin)
949 zmin = pt[2];
950 if (pt[2] > zmax)
951 zmax = pt[2];
952 }
953 dx = 0.5 * (xmax - xmin);
954 origin[0] = 0.5 * (xmin + xmax);
955 dy = 0.5 * (ymax - ymin);
956 origin[1] = 0.5 * (ymin + ymax);
957 dz = 0.5 * (zmax - zmin);
958 origin[2] = 0.5 * (zmin + zmax);
959}
960
961////////////////////////////////////////////////////////////////////////////////
962/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
963
964void TGeoSubtraction::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
965{
967 norm[0] = norm[1] = 0.;
968 norm[2] = 1.;
969 Double_t local[3], ldir[3], lnorm[3];
970 if (td.fSelected == 1) {
975 return;
976 }
977 if (td.fSelected == 2) {
982 return;
983 }
985 if (fRight->Contains(local)) {
989 return;
990 }
992 if (!fLeft->Contains(local)) {
996 return;
997 }
998 // point is inside left shape, but not inside the right
999 local[0] = point[0] + 1E-5 * dir[0];
1000 local[1] = point[1] + 1E-5 * dir[1];
1001 local[2] = point[2] + 1E-5 * dir[2];
1002 if (Contains(local)) {
1003 local[0] = point[0] - 1E-5 * dir[0];
1004 local[1] = point[1] - 1E-5 * dir[1];
1005 local[2] = point[2] - 1E-5 * dir[2];
1006 if (Contains(local))
1007 return;
1008 }
1009 ComputeNormal(local, dir, norm);
1010}
1011
1012////////////////////////////////////////////////////////////////////////////////
1013/// Find if a subtraction of two shapes contains a given point
1014
1016{
1017 Double_t local[3];
1018 fLeftMat->MasterToLocal(point, &local[0]);
1019 Bool_t inside = fLeft->Contains(&local[0]);
1020 if (!inside)
1021 return kFALSE;
1022 fRightMat->MasterToLocal(point, &local[0]);
1023 inside = !fRight->Contains(&local[0]);
1024 return inside;
1025}
1026
1027////////////////////////////////////////////////////////////////////////////////
1028/// Compute minimum distance to shape vertices
1029
1031{
1032 return 9999;
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036/// Compute distance from a given point inside to the shape boundary.
1037
1039 Double_t *safe) const
1040{
1041 if (iact < 3 && safe) {
1042 // compute safe distance
1043 *safe = Safety(point, kTRUE);
1044 if (iact == 0)
1045 return TGeoShape::Big();
1046 if (iact == 1 && step < *safe)
1047 return TGeoShape::Big();
1048 }
1049 TGeoBoolNode *node = (TGeoBoolNode *)this;
1050 Double_t local[3], ldir[3], rdir[3];
1051 Double_t d1, d2, snxt = 0.;
1052 fLeftMat->MasterToLocal(point, &local[0]);
1053 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1054 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1055 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1056 fRightMat->MasterToLocal(point, &local[0]);
1057 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1058 if (d1 < d2) {
1059 snxt = d1;
1060 node->SetSelected(1);
1061 } else {
1062 snxt = d2;
1063 node->SetSelected(2);
1064 }
1065 return snxt;
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Compute distance from a given point outside to the shape.
1070
1072 Double_t *safe) const
1073{
1074 if (iact < 3 && safe) {
1075 // compute safe distance
1076 *safe = Safety(point, kFALSE);
1077 if (iact == 0)
1078 return TGeoShape::Big();
1079 if (iact == 1 && step < *safe)
1080 return TGeoShape::Big();
1081 }
1082 TGeoBoolNode *node = (TGeoBoolNode *)this;
1083 Double_t local[3], master[3], ldir[3], rdir[3];
1084 memcpy(&master[0], point, 3 * sizeof(Double_t));
1085 Int_t i;
1086 Double_t d1, d2, snxt = 0.;
1087 fRightMat->MasterToLocal(point, &local[0]);
1088 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1089 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1090 // check if inside '-'
1091 Bool_t inside = fRight->Contains(&local[0]);
1092 Double_t epsil = 0.;
1093 while (true) {
1094 if (inside) {
1095 // propagate to outside of '-'
1096 node->SetSelected(2);
1097 d1 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1098 snxt += d1 + epsil;
1099 for (i = 0; i < 3; i++)
1100 master[i] += (d1 + 1E-8) * dir[i];
1101 epsil = 1.E-8;
1102 // now master outside '-'; check if inside '+'
1104 if (fLeft->Contains(&local[0]))
1105 return snxt;
1106 }
1107 // master outside '-' and outside '+' ; find distances to both
1108 node->SetSelected(1);
1110 d2 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
1111 if (d2 > 1E20)
1112 return TGeoShape::Big();
1113
1115 d1 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1116 if (d2 < d1 - TGeoShape::Tolerance()) {
1117 snxt += d2 + epsil;
1118 return snxt;
1119 }
1120 // propagate to '-'
1121 snxt += d1 + epsil;
1122 for (i = 0; i < 3; i++)
1123 master[i] += (d1 + 1E-8) * dir[i];
1124 epsil = 1.E-8;
1125 // now inside '-' and not inside '+'
1127 inside = kTRUE;
1128 }
1129}
1130
1131////////////////////////////////////////////////////////////////////////////////
1132/// Compute safety distance for a union node;
1133
1135{
1136 Double_t local1[3], local2[3];
1137 fLeftMat->MasterToLocal(point, local1);
1141 Bool_t intrue = in1 && (!in2);
1142 if (in ^ intrue)
1143 return 0.0;
1146 if (in1 && in2)
1147 return saf2;
1148 if (in1)
1149 return TMath::Min(saf1, saf2);
1150 if (in2)
1151 return TMath::Max(saf1, saf2);
1152 return saf1;
1153}
1154
1155////////////////////////////////////////////////////////////////////////////////
1156/// Save a primitive as a C++ statement(s) on output stream "out".
1157
1158void TGeoSubtraction::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1159{
1161 out << " pBoolNode = new TGeoSubtraction(";
1162 out << fLeft->GetPointerName() << ",";
1163 out << fRight->GetPointerName() << ",";
1164 if (!fLeftMat->IsIdentity())
1165 out << fLeftMat->GetPointerName() << ",";
1166 else
1167 out << "0,";
1168 if (!fRightMat->IsIdentity())
1169 out << fRightMat->GetPointerName() << ");" << std::endl;
1170 else
1171 out << "0);" << std::endl;
1172}
1173
1174////////////////////////////////////////////////////////////////////////////////
1175/// Register 3D size of this shape.
1176
1178{
1180}
1181
1182
1183////////////////////////////////////////////////////////////////////////////////
1184/// Make a clone of this. Pointers are preserved.
1185
1190
1191////////////////////////////////////////////////////////////////////////////////
1192/// Paint method.
1193
1195{
1196 TVirtualViewer3D *viewer = gPad->GetViewer3D();
1197
1198 if (!viewer) {
1199 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
1200 return;
1201 }
1202
1203 viewer->AddCompositeOp(TBuffer3D::kCSIntersection);
1204
1206}
1207
1208////////////////////////////////////////////////////////////////////////////////
1209/// Default constructor
1210
1212
1213////////////////////////////////////////////////////////////////////////////////
1214/// Constructor
1215
1217
1218////////////////////////////////////////////////////////////////////////////////
1219/// Constructor providing pointers to components
1220
1222 : TGeoBoolNode(left, right, lmat, rmat)
1223{
1226 if (hs1 && hs2)
1227 Fatal("ctor", "cannot intersect two half-spaces: %s * %s", left->GetName(), right->GetName());
1228}
1229
1230////////////////////////////////////////////////////////////////////////////////
1231/// Destructor
1232/// --- deletion of components handled by TGeoManager class.
1233
1235
1236////////////////////////////////////////////////////////////////////////////////
1237/// Compute bounding box corresponding to a intersection of two shapes.
1238
1240{
1243 Double_t vert[48];
1244 Double_t pt[3];
1245 Int_t i;
1250 if (!hs1) {
1251 if (((TGeoBBox *)fLeft)->IsNullBox())
1252 fLeft->ComputeBBox();
1253 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
1254 for (i = 0; i < 8; i++) {
1255 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
1256 if (pt[0] < xmin1)
1257 xmin1 = pt[0];
1258 if (pt[0] > xmax1)
1259 xmax1 = pt[0];
1260 if (pt[1] < ymin1)
1261 ymin1 = pt[1];
1262 if (pt[1] > ymax1)
1263 ymax1 = pt[1];
1264 if (pt[2] < zmin1)
1265 zmin1 = pt[2];
1266 if (pt[2] > zmax1)
1267 zmax1 = pt[2];
1268 }
1269 }
1270 if (!hs2) {
1271 if (((TGeoBBox *)fRight)->IsNullBox())
1273 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
1274 for (i = 8; i < 16; i++) {
1275 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
1276 if (pt[0] < xmin2)
1277 xmin2 = pt[0];
1278 if (pt[0] > xmax2)
1279 xmax2 = pt[0];
1280 if (pt[1] < ymin2)
1281 ymin2 = pt[1];
1282 if (pt[1] > ymax2)
1283 ymax2 = pt[1];
1284 if (pt[2] < zmin2)
1285 zmin2 = pt[2];
1286 if (pt[2] > zmax2)
1287 zmax2 = pt[2];
1288 }
1289 }
1290 if (hs1) {
1291 dx = 0.5 * (xmax2 - xmin2);
1292 origin[0] = 0.5 * (xmax2 + xmin2);
1293 dy = 0.5 * (ymax2 - ymin2);
1294 origin[1] = 0.5 * (ymax2 + ymin2);
1295 dz = 0.5 * (zmax2 - zmin2);
1296 origin[2] = 0.5 * (zmax2 + zmin2);
1297 return;
1298 }
1299 if (hs2) {
1300 dx = 0.5 * (xmax1 - xmin1);
1301 origin[0] = 0.5 * (xmax1 + xmin1);
1302 dy = 0.5 * (ymax1 - ymin1);
1303 origin[1] = 0.5 * (ymax1 + ymin1);
1304 dz = 0.5 * (zmax1 - zmin1);
1305 origin[2] = 0.5 * (zmax1 + zmin1);
1306 return;
1307 }
1308 Double_t sort[4];
1309 Int_t isort[4];
1310 sort[0] = xmin1;
1311 sort[1] = xmax1;
1312 sort[2] = xmin2;
1313 sort[3] = xmax2;
1314 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1315 if (isort[1] % 2) {
1316 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1317 dx = dy = dz = 0;
1318 memset(origin, 0, 3 * sizeof(Double_t));
1319 return;
1320 }
1321 dx = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1322 origin[0] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1323 sort[0] = ymin1;
1324 sort[1] = ymax1;
1325 sort[2] = ymin2;
1326 sort[3] = ymax2;
1327 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1328 if (isort[1] % 2) {
1329 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1330 dx = dy = dz = 0;
1331 memset(origin, 0, 3 * sizeof(Double_t));
1332 return;
1333 }
1334 dy = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1335 origin[1] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1336 sort[0] = zmin1;
1337 sort[1] = zmax1;
1338 sort[2] = zmin2;
1339 sort[3] = zmax2;
1340 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1341 if (isort[1] % 2) {
1342 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1343 dx = dy = dz = 0;
1344 memset(origin, 0, 3 * sizeof(Double_t));
1345 return;
1346 }
1347 dz = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1348 origin[2] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1349}
1350
1351////////////////////////////////////////////////////////////////////////////////
1352/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
1353
1354void TGeoIntersection::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
1355{
1357 Double_t local[3], ldir[3], lnorm[3];
1358 norm[0] = norm[1] = 0.;
1359 norm[2] = 1.;
1360 if (td.fSelected == 1) {
1361 fLeftMat->MasterToLocal(point, local);
1365 return;
1366 }
1367 if (td.fSelected == 2) {
1368 fRightMat->MasterToLocal(point, local);
1372 return;
1373 }
1374 fLeftMat->MasterToLocal(point, local);
1375 if (!fLeft->Contains(local)) {
1379 return;
1380 }
1381 fRightMat->MasterToLocal(point, local);
1382 if (!fRight->Contains(local)) {
1386 return;
1387 }
1388 // point is inside intersection.
1389 local[0] = point[0] + 1E-5 * dir[0];
1390 local[1] = point[1] + 1E-5 * dir[1];
1391 local[2] = point[2] + 1E-5 * dir[2];
1392 if (Contains(local)) {
1393 local[0] = point[0] - 1E-5 * dir[0];
1394 local[1] = point[1] - 1E-5 * dir[1];
1395 local[2] = point[2] - 1E-5 * dir[2];
1396 if (Contains(local))
1397 return;
1398 }
1399 ComputeNormal(local, dir, norm);
1400}
1401
1402////////////////////////////////////////////////////////////////////////////////
1403/// Find if a intersection of two shapes contains a given point
1404
1406{
1407 Double_t local[3];
1408 fLeftMat->MasterToLocal(point, &local[0]);
1409 Bool_t inside = fLeft->Contains(&local[0]);
1410 if (!inside)
1411 return kFALSE;
1412 fRightMat->MasterToLocal(point, &local[0]);
1413 inside = fRight->Contains(&local[0]);
1414 return inside;
1415}
1416
1417////////////////////////////////////////////////////////////////////////////////
1418/// Compute minimum distance to shape vertices
1419
1421{
1422 return 9999;
1423}
1424
1425////////////////////////////////////////////////////////////////////////////////
1426/// Compute distance from a given point inside to the shape boundary.
1427
1429 Double_t *safe) const
1430{
1431 if (iact < 3 && safe) {
1432 // compute safe distance
1433 *safe = Safety(point, kTRUE);
1434 if (iact == 0)
1435 return TGeoShape::Big();
1436 if (iact == 1 && step < *safe)
1437 return TGeoShape::Big();
1438 }
1439 TGeoBoolNode *node = (TGeoBoolNode *)this;
1440 Double_t local[3], ldir[3], rdir[3];
1441 Double_t d1, d2, snxt = 0.;
1442 fLeftMat->MasterToLocal(point, &local[0]);
1443 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1444 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1445 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1446 fRightMat->MasterToLocal(point, &local[0]);
1447 d2 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1448 if (d1 < d2) {
1449 snxt = d1;
1450 node->SetSelected(1);
1451 } else {
1452 snxt = d2;
1453 node->SetSelected(2);
1454 }
1455 return snxt;
1456}
1457
1458////////////////////////////////////////////////////////////////////////////////
1459/// Compute distance from a given point outside to the shape.
1460
1462 Double_t *safe) const
1463{
1465 if (iact < 3 && safe) {
1466 // compute safe distance
1467 *safe = Safety(point, kFALSE);
1468 if (iact == 0)
1469 return TGeoShape::Big();
1470 if (iact == 1 && step < *safe)
1471 return TGeoShape::Big();
1472 }
1473 TGeoBoolNode *node = (TGeoBoolNode *)this;
1474 Double_t lpt[3], rpt[3], master[3], ldir[3], rdir[3];
1475 memcpy(master, point, 3 * sizeof(Double_t));
1476 Int_t i;
1477 Double_t d1 = 0.;
1478 Double_t d2 = 0.;
1479 fLeftMat->MasterToLocal(point, lpt);
1480 fRightMat->MasterToLocal(point, rpt);
1485 node->SetSelected(0);
1486 Double_t snext = 0.0;
1487 if (inleft && inright) {
1488 // It is vey likely to have a numerical issue and the point should
1489 // be logically outside one of the shapes
1490 d1 = fLeft->DistFromInside(lpt, ldir, 3);
1492 if (d1 < 1.E-3)
1493 inleft = kFALSE;
1494 if (d2 < 1.E-3)
1495 inright = kFALSE;
1496 if (inleft && inright)
1497 return snext;
1498 }
1499
1500 while (true) {
1501 d1 = d2 = 0;
1502 if (!inleft) {
1504 d1 = TMath::Max(d1, tol);
1505 if (d1 > 1E20)
1506 return TGeoShape::Big();
1507 }
1508 if (!inright) {
1510 d2 = TMath::Max(d2, tol);
1511 if (d2 > 1E20)
1512 return TGeoShape::Big();
1513 }
1514
1515 if (d1 > d2) {
1516 // propagate to left shape
1517 snext += d1;
1518 node->SetSelected(1);
1519 inleft = kTRUE;
1520 for (i = 0; i < 3; i++)
1521 master[i] += d1 * dir[i];
1523 // Push rpt to avoid a bad boundary condition
1524 for (i = 0; i < 3; i++)
1525 rpt[i] += tol * rdir[i];
1526 // check if propagated point is inside right shape
1528 if (inright)
1529 return snext;
1530 // here inleft=true, inright=false
1531 } else {
1532 // propagate to right shape
1533 snext += d2;
1534 node->SetSelected(2);
1535 inright = kTRUE;
1536 for (i = 0; i < 3; i++)
1537 master[i] += d2 * dir[i];
1539 // Push lpt to avoid a bad boundary condition
1540 for (i = 0; i < 3; i++)
1541 lpt[i] += tol * ldir[i];
1542 // check if propagated point is inside left shape
1544 if (inleft)
1545 return snext;
1546 // here inleft=false, inright=true
1547 }
1548 }
1549 return snext;
1550}
1551
1552////////////////////////////////////////////////////////////////////////////////
1553/// Compute safety distance for a union node;
1554
1556{
1557 Double_t local1[3], local2[3];
1558 fLeftMat->MasterToLocal(point, local1);
1562 Bool_t intrue = in1 & in2;
1563 if (in ^ intrue)
1564 return 0.0;
1567 if (in1 && in2)
1568 return TMath::Min(saf1, saf2);
1569 if (in1)
1570 return saf2;
1571 if (in2)
1572 return saf1;
1573 return TMath::Max(saf1, saf2);
1574}
1575
1576////////////////////////////////////////////////////////////////////////////////
1577/// Save a primitive as a C++ statement(s) on output stream "out".
1578
1579void TGeoIntersection::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1580{
1582 out << " pBoolNode = new TGeoIntersection(";
1583 out << fLeft->GetPointerName() << ",";
1584 out << fRight->GetPointerName() << ",";
1585 if (!fLeftMat->IsIdentity())
1586 out << fLeftMat->GetPointerName() << ",";
1587 else
1588 out << "0,";
1589 if (!fRightMat->IsIdentity())
1590 out << fRightMat->GetPointerName() << ");" << std::endl;
1591 else
1592 out << "0);" << std::endl;
1593}
1594
1595////////////////////////////////////////////////////////////////////////////////
1596/// Register 3D size of this shape.
1597
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
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:537
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:17
Base class for Boolean operations between two shapes.
virtual void Sizeof3D() const
Register size of this 3D object.
Bool_t MakeBranch(const char *expr, Bool_t left)
Mutex for thread data access.
TGeoMatrix * fLeftMat
void ClearThreadData() const
std::vector< ThreadData_t * > fThreadData
array of mesh points
~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 CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
void Paint(Option_t *option) override
Special schema for feeding the 3D buffers to the painter client.
virtual void SetPoints(Double_t *points) const
Fill buffer with shape vertices.
Int_t fThreadSize
Navigation data per thread.
std::mutex fMutex
Size for the navigation data array.
void RegisterMatrices()
Register all matrices of the boolean node and descendents.
TGeoShape * fRight
Double_t * fPoints
number of points on the mesh
TGeoBoolNode()
Default constructor.
Int_t GetNpoints()
Returns number of vertices for the composite shape described by this node.
TGeoMatrix * fRightMat
ThreadData_t & GetThreadData() const
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:458
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
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Geometrical transformation package.
Definition TGeoMatrix.h:38
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:63
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:94
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
virtual void CreateThreadData(Int_t)
Definition TGeoShape.h:74
Bool_t IsValid() const
Definition TGeoShape.h:151
virtual Int_t GetNmeshVertices() const
Definition TGeoShape.h:134
virtual void Sizeof3D() const =0
virtual Bool_t IsComposite() const
Definition TGeoShape.h:138
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:97
virtual void SetPoints(Double_t *points) const =0
Bool_t TestShapeBit(UInt_t f) const
Definition TGeoShape.h:175
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.
Boolean node representing a union between two components.
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:1057
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:835
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1099
Basic string class.
Definition TString.h:138
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:251
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
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:432
TGeoShape::EInside Inside(const Double_t *point, Solid const *solid)
Generic implementation of the inside function using just Contains and GetNormal.
Definition TGeoShape.h:185