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
47
48////////////////////////////////////////////////////////////////////////////////
49/// Constructor.
50
52
53////////////////////////////////////////////////////////////////////////////////
54/// Destructor.
55
57
58////////////////////////////////////////////////////////////////////////////////
59
61{
63 /*
64 std::lock_guard<std::mutex> guard(fMutex);
65 if (tid >= fThreadSize) {
66 Error("GetThreadData", "Thread id=%d bigger than maximum declared thread number %d. \nUse
67 TGeoManager::SetMaxThreads properly !!!", tid, fThreadSize);
68 }
69 if (tid >= fThreadSize)
70 {
71 fThreadData.resize(tid + 1);
72 fThreadSize = tid + 1;
73 }
74 if (fThreadData[tid] == 0)
75 {
76 if (fThreadData[tid] == 0)
77 fThreadData[tid] = new ThreadData_t;
78 }
79 */
80 return *fThreadData[tid];
81}
82
83////////////////////////////////////////////////////////////////////////////////
84
86{
87 std::lock_guard<std::mutex> guard(fMutex);
88 std::vector<ThreadData_t *>::iterator i = fThreadData.begin();
89 while (i != fThreadData.end()) {
90 delete *i;
91 ++i;
92 }
93 fThreadData.clear();
94 fThreadSize = 0;
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// Create thread data for n threads max.
99
101{
102 std::lock_guard<std::mutex> guard(fMutex);
103 fThreadData.resize(nthreads);
105 for (Int_t tid = 0; tid < nthreads; tid++) {
106 if (fThreadData[tid] == nullptr) {
108 }
109 }
110 // Propagate to components
111 if (fLeft)
113 if (fRight)
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Set the selected branch.
119
124
125////////////////////////////////////////////////////////////////////////////////
126/// Default constructor
127
129{
130 fLeft = nullptr;
131 fRight = nullptr;
132 fLeftMat = nullptr;
133 fRightMat = nullptr;
134 fNpoints = 0;
135 fPoints = nullptr;
136 fThreadSize = 0;
138}
139
140////////////////////////////////////////////////////////////////////////////////
141/// Constructor called by TGeoCompositeShape providing 2 subexpressions for the 2 branches.
142
143TGeoBoolNode::TGeoBoolNode(const char *expr1, const char *expr2)
144{
145 fLeft = nullptr;
146 fRight = nullptr;
147 fLeftMat = nullptr;
148 fRightMat = nullptr;
149 fNpoints = 0;
150 fPoints = nullptr;
151 fThreadSize = 0;
153 if (!MakeBranch(expr1, kTRUE)) {
154 return;
155 }
156 if (!MakeBranch(expr2, kFALSE)) {
157 return;
158 }
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Constructor providing left and right shapes and matrices (in the Boolean operation).
163
165{
166 fLeft = left;
167 fRight = right;
168 fLeftMat = lmat;
169 fNpoints = 0;
170 fPoints = nullptr;
171 fThreadSize = 0;
173 if (!fLeftMat)
175 else
177 fRightMat = rmat;
178 if (!fRightMat)
180 else
182 if (!fLeft) {
183 Error("ctor", "left shape is NULL");
184 return;
185 }
186 if (!fRight) {
187 Error("ctor", "right shape is NULL");
188 return;
189 }
190}
191
192////////////////////////////////////////////////////////////////////////////////
193/// Destructor.
194/// --- deletion of components handled by TGeoManager class.
195
197{
198 if (fPoints)
199 delete[] fPoints;
201}
202
203////////////////////////////////////////////////////////////////////////////////
204/// Set fPoints array
205
207{
208 if (fPoints) {
209 delete[] fPoints;
210 fPoints = nullptr;
211 fNpoints = 0;
212 }
213 if (points) {
215 fPoints = new Double_t[3 * fNpoints];
216 memcpy(fPoints, points, 3 * fNpoints * sizeof(Double_t));
217 }
218}
219
220////////////////////////////////////////////////////////////////////////////////
221/// Returns number of vertices for the composite shape described by this node.
222
224{
225 Int_t itot = 0;
226 if (fNpoints)
227 return fNpoints;
228 // Local points for the left shape
231 if (nleft + nright == 0) return 0;
232
233 Double_t *points1 = (nleft > 0) ? new Double_t[3 * nleft] : nullptr;
234 if (nleft > 0) fLeft->SetPoints(points1);
235 // Local points for the right shape
236 Double_t *points2 = (nright > 0) ? new Double_t[3 * nright] : nullptr;
237 if (nright > 0) fRight->SetPoints(points2);
238 Double_t *points = new Double_t[3 * (nleft + nright)];
239 for (Int_t i = 0; i < nleft; i++) {
240 fLeftMat->LocalToMaster(&points1[3 * i], &points[3 * itot]);
242 itot++;
243 }
244 for (Int_t i = 0; i < nright; i++) {
245 fRightMat->LocalToMaster(&points2[3 * i], &points[3 * itot]);
247 itot++;
248 }
249
251
252 delete[] points1;
253 delete[] points2;
254 delete[] points;
255 return fNpoints;
256}
257
258////////////////////////////////////////////////////////////////////////////////
259/// Implementation of the inside function using just Contains and GetNormal
260
262{
263 return tgeo_impl::Inside(point, this);
264}
265
266////////////////////////////////////////////////////////////////////////////////
267/// Expands the boolean expression either on left or right branch, creating
268/// component elements (composite shapes and boolean nodes). Returns true on success.
269
271{
274 if (boolop < 0) {
275 Error("MakeBranch", "invalid expression");
276 return kFALSE;
277 }
278 TGeoShape *shape = nullptr;
281
282 if (stransf.Length() == 0) {
284 } else {
286 }
287 if (!mat) {
288 Error("MakeBranch", "transformation %s not found", stransf.Data());
289 return kFALSE;
290 }
291 switch (boolop) {
292 case 0:
293 // elementary shape
295 if (!shape) {
296 Error("MakeBranch", "shape %s not found", sleft.Data());
297 return kFALSE;
298 }
299 break;
300 case 1:
301 // composite shape - union
302 newshape = sleft;
303 newshape += "+";
304 newshape += sright;
305 shape = new TGeoCompositeShape(newshape.Data());
306 break;
307 case 2:
308 // composite shape - difference
309 newshape = sleft;
310 newshape += "-";
311 newshape += sright;
312 shape = new TGeoCompositeShape(newshape.Data());
313 break;
314 case 3:
315 // composite shape - intersection
316 newshape = sleft;
317 newshape += "*";
318 newshape += sright;
319 shape = new TGeoCompositeShape(newshape.Data());
320 break;
321 }
322 if (boolop && (!shape || !shape->IsValid())) {
323 Error("MakeBranch", "Shape %s not valid", newshape.Data());
324 if (shape)
325 delete shape;
326 return kFALSE;
327 }
328 if (left) {
329 fLeft = shape;
330 fLeftMat = mat;
331 } else {
332 fRight = shape;
333 fRightMat = mat;
334 }
335 return kTRUE;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Special schema for feeding the 3D buffers to the painter client.
340
342{
343 TVirtualViewer3D *viewer = gPad->GetViewer3D();
344 if (!viewer)
345 return;
346
347 // Components of composite shape hierarchies for local frame viewers are painted
348 // in coordinate frame of the top level composite shape. So we force
349 // conversion to this. See TGeoPainter::PaintNode for loading of GLMatrix.
350 Bool_t localFrame = kFALSE; // viewer->PreferLocalFrame();
351
354 mat = glmat; // keep a copy
355
356 // Now perform fetch and add of the two components buffers.
357 // Note we assume that composite shapes are always completely added
358 // so don't bother to get addDaughters flag from viewer->AddObject()
359
360 // Setup matrix and fetch/add the left component buffer
361 glmat->Multiply(fLeftMat);
362 // fLeft->Paint(option);
363 if (TGeoCompositeShape *left = dynamic_cast<TGeoCompositeShape *>(fLeft)) {
364 left->PaintComposite(option);
365 } else if (fLeft) {
367 viewer->AddObject(leftBuffer);
368 }
369
370 // Setup matrix and fetch/add the right component buffer
371 *glmat = &mat;
372 glmat->Multiply(fRightMat);
373 // fRight->Paint(option);
374 if (TGeoCompositeShape *right = dynamic_cast<TGeoCompositeShape *>(fRight)) {
375 right->PaintComposite(option);
376 } else if (fRight) {
378 viewer->AddObject(rightBuffer);
379 }
380
381 *glmat = &mat;
382}
383
384////////////////////////////////////////////////////////////////////////////////
385/// Register all matrices of the boolean node and descendents.
386
388{
389 if (!fLeftMat->IsIdentity())
391 if (!fRightMat->IsIdentity())
393 if (fLeft->IsComposite())
394 ((TGeoCompositeShape *)fLeft)->GetBoolNode()->RegisterMatrices();
395 if (fRight->IsComposite())
396 ((TGeoCompositeShape *)fRight)->GetBoolNode()->RegisterMatrices();
397}
398
399////////////////////////////////////////////////////////////////////////////////
400/// Replace one of the matrices. Does not work with TGeoIdentity. Returns true
401/// if replacement was successful.
402
404{
405 if (mat == gGeoIdentity || newmat == gGeoIdentity) {
406 Error("ReplaceMatrix",
407 "Matrices should not be gGeoIdentity. Use default matrix constructor to represent identities.");
408 return kFALSE;
409 }
410 if (!mat || !newmat) {
411 Error("ReplaceMatrix", "Matrices should not be null pointers.");
412 return kFALSE;
413 }
415 if (fLeftMat == mat) {
417 replaced = kTRUE;
418 }
419 if (fRightMat == mat) {
421 replaced = kTRUE;
422 }
423 return replaced;
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Save a primitive as a C++ statement(s) on output stream "out".
428
429void TGeoBoolNode::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
430{
433 if (!fLeftMat->IsIdentity()) {
436 }
437 if (!fRightMat->IsIdentity()) {
440 }
441}
442
443////////////////////////////////////////////////////////////////////////////////
444/// Fill buffer with shape vertices.
445
447{
448 TGeoBoolNode *bn = (TGeoBoolNode *)this;
449 Int_t npoints = bn->GetNpoints();
450 memcpy(points, fPoints, 3 * npoints * sizeof(Double_t));
451}
452
453////////////////////////////////////////////////////////////////////////////////
454/// Fill buffer with shape vertices.
455
457{
458 TGeoBoolNode *bn = (TGeoBoolNode *)this;
459 Int_t npoints = bn->GetNpoints();
460 for (Int_t i = 0; i < 3 * npoints; i++)
461 points[i] = fPoints[i];
462}
463
464////////////////////////////////////////////////////////////////////////////////
465/// Register size of this 3D object
466
468{
469 fLeft->Sizeof3D();
470 fRight->Sizeof3D();
471}
472
474
475////////////////////////////////////////////////////////////////////////////////
476/// Make a clone of this. Pointers are preserved.
477
482
483////////////////////////////////////////////////////////////////////////////////
484/// Paint method.
485
487{
488 TVirtualViewer3D *viewer = gPad->GetViewer3D();
489
490 if (!viewer) {
491 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
492 return;
493 }
494
495 viewer->AddCompositeOp(TBuffer3D::kCSUnion);
496
498}
499
500////////////////////////////////////////////////////////////////////////////////
501/// Default constructor
502
504
505////////////////////////////////////////////////////////////////////////////////
506/// Constructor
507
508TGeoUnion::TGeoUnion(const char *expr1, const char *expr2) : TGeoBoolNode(expr1, expr2) {}
509
510////////////////////////////////////////////////////////////////////////////////
511/// Constructor providing pointers to components
512
514 : TGeoBoolNode(left, right, lmat, rmat)
515{
517 Fatal("TGeoUnion", "Unions with a half-space (%s + %s) not allowed", left->GetName(), right->GetName());
518 }
519}
520
521////////////////////////////////////////////////////////////////////////////////
522/// Destructor
523/// --- deletion of components handled by TGeoManager class.
524
526
527////////////////////////////////////////////////////////////////////////////////
528/// Compute bounding box corresponding to a union of two shapes.
529
531{
532 if (((TGeoBBox *)fLeft)->IsNullBox())
534 if (((TGeoBBox *)fRight)->IsNullBox())
536 Double_t vert[48];
537 Double_t pt[3];
538 Int_t i;
539 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
540 xmin = ymin = zmin = TGeoShape::Big();
541 xmax = ymax = zmax = -TGeoShape::Big();
542 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
543 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
544 for (i = 0; i < 8; i++) {
545 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
546 if (pt[0] < xmin)
547 xmin = pt[0];
548 if (pt[0] > xmax)
549 xmax = pt[0];
550 if (pt[1] < ymin)
551 ymin = pt[1];
552 if (pt[1] > ymax)
553 ymax = pt[1];
554 if (pt[2] < zmin)
555 zmin = pt[2];
556 if (pt[2] > zmax)
557 zmax = pt[2];
558 }
559 for (i = 8; i < 16; i++) {
560 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
561 if (pt[0] < xmin)
562 xmin = pt[0];
563 if (pt[0] > xmax)
564 xmax = pt[0];
565 if (pt[1] < ymin)
566 ymin = pt[1];
567 if (pt[1] > ymax)
568 ymax = pt[1];
569 if (pt[2] < zmin)
570 zmin = pt[2];
571 if (pt[2] > zmax)
572 zmax = pt[2];
573 }
574 dx = 0.5 * (xmax - xmin);
575 origin[0] = 0.5 * (xmin + xmax);
576 dy = 0.5 * (ymax - ymin);
577 origin[1] = 0.5 * (ymin + ymax);
578 dz = 0.5 * (zmax - zmin);
579 origin[2] = 0.5 * (zmin + zmax);
580}
581
582////////////////////////////////////////////////////////////////////////////////
583/// Find if a union of two shapes contains a given point
584
586{
587 Double_t local[3];
588 fLeftMat->MasterToLocal(point, &local[0]);
589 Bool_t inside = fLeft->Contains(&local[0]);
590 if (inside)
591 return kTRUE;
592 fRightMat->MasterToLocal(point, &local[0]);
593 inside = fRight->Contains(&local[0]);
594 return inside;
595}
596
597////////////////////////////////////////////////////////////////////////////////
598/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
599
600void TGeoUnion::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
601{
603 norm[0] = norm[1] = 0.;
604 norm[2] = 1.;
605 Double_t local[3];
606 Double_t ldir[3], lnorm[3];
607 if (td.fSelected == 1) {
612 return;
613 }
614 if (td.fSelected == 2) {
619 return;
620 }
622 if (fLeft->Contains(local)) {
626 return;
627 }
629 if (fRight->Contains(local)) {
633 return;
634 }
635 // Propagate forward/backward to see which of the components is intersected first
636 local[0] = point[0] + 1E-5 * dir[0];
637 local[1] = point[1] + 1E-5 * dir[1];
638 local[2] = point[2] + 1E-5 * dir[2];
639
640 if (!Contains(local)) {
641 local[0] = point[0] - 1E-5 * dir[0];
642 local[1] = point[1] - 1E-5 * dir[1];
643 local[2] = point[2] - 1E-5 * dir[2];
644 if (!Contains(local))
645 return;
646 }
647 ComputeNormal(local, dir, norm);
648}
649
650////////////////////////////////////////////////////////////////////////////////
651/// Compute minimum distance to shape vertices.
652
654{
655 return 9999;
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// Computes distance from a given point inside the shape to its boundary.
660
663{
664 if (iact < 3 && safe) {
665 // compute safe distance
666 *safe = Safety(point, kTRUE);
667 if (iact == 0)
668 return TGeoShape::Big();
669 if (iact == 1 && step < *safe)
670 return TGeoShape::Big();
671 }
672
673 Double_t local[3], local1[3], master[3], ldir[3], rdir[3], pushed[3];
674 memcpy(master, point, 3 * sizeof(Double_t));
675 Int_t i;
676 TGeoBoolNode *node = (TGeoBoolNode *)this;
677 Double_t d1 = 0., d2 = 0., snxt = 0., eps = 0.;
682 if (inside1)
684 else
685 memcpy(local1, local, 3 * sizeof(Double_t));
688 if (inside2)
690 if (!(inside1 | inside2)) {
691 // This is a pathological case when the point is on the boundary
693 if (d1 < 1.E-3) {
694 eps = d1 + TGeoShape::Tolerance();
695 for (i = 0; i < 3; i++)
696 local1[i] += eps * ldir[i];
697 inside1 = kTRUE;
699 d1 += eps;
700 } else {
702 if (d2 < 1.E-3) {
703 eps = d2 + TGeoShape::Tolerance();
704 for (i = 0; i < 3; i++)
705 local[i] += eps * rdir[i];
706 inside2 = kTRUE;
708 d2 += eps;
709 }
710 }
711 }
712 while (inside1 || inside2) {
713 if (inside1 && inside2) {
714 if (d1 < d2) {
715 snxt += d1;
716 node->SetSelected(1);
717 // propagate to exit of left shape
718 inside1 = kFALSE;
719 for (i = 0; i < 3; i++)
720 master[i] += d1 * dir[i];
721 // check if propagated point is in right shape
724 if (!inside2)
725 return snxt;
727 if (d2 < TGeoShape::Tolerance())
728 return snxt;
729 } else {
730 snxt += d2;
731 node->SetSelected(2);
732 // propagate to exit of right shape
733 inside2 = kFALSE;
734 for (i = 0; i < 3; i++)
735 master[i] += d2 * dir[i];
736 // check if propagated point is in left shape
739 if (!inside1)
740 return snxt;
742 if (d1 < TGeoShape::Tolerance())
743 return snxt;
744 }
745 }
746 if (inside1) {
747 snxt += d1;
748 node->SetSelected(1);
749 // propagate to exit of left shape
750 inside1 = kFALSE;
751 for (i = 0; i < 3; i++) {
752 master[i] += d1 * dir[i];
753 pushed[i] = master[i] + (1. + d1) * TGeoShape::Tolerance() * dir[i];
754 }
755 // check if propagated point is in right shape
758 if (!inside2)
759 return snxt;
761 if (d2 < TGeoShape::Tolerance())
762 return snxt;
763 d2 += (1. + d1) * TGeoShape::Tolerance();
764 }
765 if (inside2) {
766 snxt += d2;
767 node->SetSelected(2);
768 // propagate to exit of right shape
769 inside2 = kFALSE;
770 for (i = 0; i < 3; i++) {
771 master[i] += d2 * dir[i];
772 pushed[i] = master[i] + (1. + d2) * TGeoShape::Tolerance() * dir[i];
773 }
774 // check if propagated point is in left shape
777 if (!inside1)
778 return snxt;
780 if (d1 < TGeoShape::Tolerance())
781 return snxt;
782 d1 += (1. + d2) * TGeoShape::Tolerance();
783 }
784 }
785 return snxt;
786}
787
788////////////////////////////////////////////////////////////////////////////////
789/// Compute distance from a given outside point to the shape.
790
793{
794 if (iact < 3 && safe) {
795 // compute safe distance
796 *safe = Safety(point, kFALSE);
797 if (iact == 0)
798 return TGeoShape::Big();
799 if (iact == 1 && step < *safe)
800 return TGeoShape::Big();
801 }
802 TGeoBoolNode *node = (TGeoBoolNode *)this;
803 Double_t local[3], ldir[3], rdir[3];
804 Double_t d1, d2, snxt;
805 fLeftMat->MasterToLocal(point, &local[0]);
808 d1 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
809 fRightMat->MasterToLocal(point, &local[0]);
810 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
811 if (d1 < d2) {
812 snxt = d1;
813 node->SetSelected(1);
814 } else {
815 snxt = d2;
816 node->SetSelected(2);
817 }
818 return snxt;
819}
820
821////////////////////////////////////////////////////////////////////////////////
822/// Compute safety distance for a union node;
823
825{
826 Double_t local1[3], local2[3];
831 Bool_t intrue = in1 | in2;
832 if (intrue ^ in)
833 return 0.0;
836 if (in1 && in2)
837 return TMath::Min(saf1, saf2);
838 if (in1)
839 return saf1;
840 if (in2)
841 return saf2;
842 return TMath::Min(saf1, saf2);
843}
844
845////////////////////////////////////////////////////////////////////////////////
846/// Save a primitive as a C++ statement(s) on output stream "out".
847
848void TGeoUnion::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
849{
851 out << " pBoolNode = new TGeoUnion(";
852 out << fLeft->GetPointerName() << ",";
853 out << fRight->GetPointerName() << ",";
854 if (!fLeftMat->IsIdentity())
855 out << fLeftMat->GetPointerName() << ",";
856 else
857 out << "0,";
858 if (!fRightMat->IsIdentity())
859 out << fRightMat->GetPointerName() << ");" << std::endl;
860 else
861 out << "0);" << std::endl;
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Register 3D size of this shape.
866
868{
870}
871
873
874////////////////////////////////////////////////////////////////////////////////
875/// Make a clone of this. Pointers are preserved.
876
881
882////////////////////////////////////////////////////////////////////////////////
883/// Paint method.
884
886{
887 TVirtualViewer3D *viewer = gPad->GetViewer3D();
888
889 if (!viewer) {
890 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
891 return;
892 }
893
894 viewer->AddCompositeOp(TBuffer3D::kCSDifference);
895
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Default constructor
901
903
904////////////////////////////////////////////////////////////////////////////////
905/// Constructor
906
908
909////////////////////////////////////////////////////////////////////////////////
910/// Constructor providing pointers to components
911
913 : TGeoBoolNode(left, right, lmat, rmat)
914{
916 Fatal("TGeoSubstraction", "Subtractions from a half-space (%s) not allowed", left->GetName());
917 }
918}
919
920////////////////////////////////////////////////////////////////////////////////
921/// Destructor
922/// --- deletion of components handled by TGeoManager class.
923
925
926////////////////////////////////////////////////////////////////////////////////
927/// Compute bounding box corresponding to a subtraction of two shapes.
928
930{
932 if (box->IsNullBox())
934 Double_t vert[24];
935 Double_t pt[3];
936 Int_t i;
937 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
938 xmin = ymin = zmin = TGeoShape::Big();
939 xmax = ymax = zmax = -TGeoShape::Big();
940 box->SetBoxPoints(&vert[0]);
941 for (i = 0; i < 8; i++) {
942 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
943 if (pt[0] < xmin)
944 xmin = pt[0];
945 if (pt[0] > xmax)
946 xmax = pt[0];
947 if (pt[1] < ymin)
948 ymin = pt[1];
949 if (pt[1] > ymax)
950 ymax = pt[1];
951 if (pt[2] < zmin)
952 zmin = pt[2];
953 if (pt[2] > zmax)
954 zmax = pt[2];
955 }
956 dx = 0.5 * (xmax - xmin);
957 origin[0] = 0.5 * (xmin + xmax);
958 dy = 0.5 * (ymax - ymin);
959 origin[1] = 0.5 * (ymin + ymax);
960 dz = 0.5 * (zmax - zmin);
961 origin[2] = 0.5 * (zmin + zmax);
962}
963
964////////////////////////////////////////////////////////////////////////////////
965/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
966
967void TGeoSubtraction::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
968{
970 norm[0] = norm[1] = 0.;
971 norm[2] = 1.;
972 Double_t local[3], ldir[3], lnorm[3];
973 if (td.fSelected == 1) {
978 return;
979 }
980 if (td.fSelected == 2) {
985 return;
986 }
988 if (fRight->Contains(local)) {
992 return;
993 }
995 if (!fLeft->Contains(local)) {
999 return;
1000 }
1001 // point is inside left shape, but not inside the right
1002 local[0] = point[0] + 1E-5 * dir[0];
1003 local[1] = point[1] + 1E-5 * dir[1];
1004 local[2] = point[2] + 1E-5 * dir[2];
1005 if (Contains(local)) {
1006 local[0] = point[0] - 1E-5 * dir[0];
1007 local[1] = point[1] - 1E-5 * dir[1];
1008 local[2] = point[2] - 1E-5 * dir[2];
1009 if (Contains(local))
1010 return;
1011 }
1012 ComputeNormal(local, dir, norm);
1013}
1014
1015////////////////////////////////////////////////////////////////////////////////
1016/// Find if a subtraction of two shapes contains a given point
1017
1019{
1020 Double_t local[3];
1021 fLeftMat->MasterToLocal(point, &local[0]);
1022 Bool_t inside = fLeft->Contains(&local[0]);
1023 if (!inside)
1024 return kFALSE;
1025 fRightMat->MasterToLocal(point, &local[0]);
1026 inside = !fRight->Contains(&local[0]);
1027 return inside;
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// Compute minimum distance to shape vertices
1032
1034{
1035 return 9999;
1036}
1037
1038////////////////////////////////////////////////////////////////////////////////
1039/// Compute distance from a given point inside to the shape boundary.
1040
1042 Double_t *safe) const
1043{
1044 if (iact < 3 && safe) {
1045 // compute safe distance
1046 *safe = Safety(point, kTRUE);
1047 if (iact == 0)
1048 return TGeoShape::Big();
1049 if (iact == 1 && step < *safe)
1050 return TGeoShape::Big();
1051 }
1052 TGeoBoolNode *node = (TGeoBoolNode *)this;
1053 Double_t local[3], ldir[3], rdir[3];
1054 Double_t d1, d2, snxt = 0.;
1055 fLeftMat->MasterToLocal(point, &local[0]);
1056 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1057 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1058 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1059 fRightMat->MasterToLocal(point, &local[0]);
1060 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1061 if (d1 < d2) {
1062 snxt = d1;
1063 node->SetSelected(1);
1064 } else {
1065 snxt = d2;
1066 node->SetSelected(2);
1067 }
1068 return snxt;
1069}
1070
1071////////////////////////////////////////////////////////////////////////////////
1072/// Compute distance from a given point outside to the shape.
1073
1075 Double_t *safe) const
1076{
1077 if (iact < 3 && safe) {
1078 // compute safe distance
1079 *safe = Safety(point, kFALSE);
1080 if (iact == 0)
1081 return TGeoShape::Big();
1082 if (iact == 1 && step < *safe)
1083 return TGeoShape::Big();
1084 }
1085 TGeoBoolNode *node = (TGeoBoolNode *)this;
1086 Double_t local[3], master[3], ldir[3], rdir[3];
1087 memcpy(&master[0], point, 3 * sizeof(Double_t));
1088 Int_t i;
1089 Double_t d1, d2, snxt = 0.;
1090 fRightMat->MasterToLocal(point, &local[0]);
1091 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1092 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1093 // check if inside '-'
1094 Bool_t inside = fRight->Contains(&local[0]);
1095 Double_t epsil = 0.;
1096 while (true) {
1097 if (inside) {
1098 // propagate to outside of '-'
1099 node->SetSelected(2);
1100 d1 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1101 snxt += d1 + epsil;
1102 for (i = 0; i < 3; i++)
1103 master[i] += (d1 + 1E-8) * dir[i];
1104 epsil = 1.E-8;
1105 // now master outside '-'; check if inside '+'
1107 if (fLeft->Contains(&local[0]))
1108 return snxt;
1109 }
1110 // master outside '-' and outside '+' ; find distances to both
1111 node->SetSelected(1);
1113 d2 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
1114 if (d2 > 1E20)
1115 return TGeoShape::Big();
1116
1118 d1 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1119 if (d2 < d1 - TGeoShape::Tolerance()) {
1120 snxt += d2 + epsil;
1121 return snxt;
1122 }
1123 // propagate to '-'
1124 snxt += d1 + epsil;
1125 for (i = 0; i < 3; i++)
1126 master[i] += (d1 + 1E-8) * dir[i];
1127 epsil = 1.E-8;
1128 // now inside '-' and not inside '+'
1130 inside = kTRUE;
1131 }
1132}
1133
1134////////////////////////////////////////////////////////////////////////////////
1135/// Compute safety distance for a union node;
1136
1138{
1139 Double_t local1[3], local2[3];
1140 fLeftMat->MasterToLocal(point, local1);
1144 Bool_t intrue = in1 && (!in2);
1145 if (in ^ intrue)
1146 return 0.0;
1149 if (in1 && in2)
1150 return saf2;
1151 if (in1)
1152 return TMath::Min(saf1, saf2);
1153 if (in2)
1154 return TMath::Max(saf1, saf2);
1155 return saf1;
1156}
1157
1158////////////////////////////////////////////////////////////////////////////////
1159/// Save a primitive as a C++ statement(s) on output stream "out".
1160
1161void TGeoSubtraction::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1162{
1164 out << " pBoolNode = new TGeoSubtraction(";
1165 out << fLeft->GetPointerName() << ",";
1166 out << fRight->GetPointerName() << ",";
1167 if (!fLeftMat->IsIdentity())
1168 out << fLeftMat->GetPointerName() << ",";
1169 else
1170 out << "0,";
1171 if (!fRightMat->IsIdentity())
1172 out << fRightMat->GetPointerName() << ");" << std::endl;
1173 else
1174 out << "0);" << std::endl;
1175}
1176
1177////////////////////////////////////////////////////////////////////////////////
1178/// Register 3D size of this shape.
1179
1181{
1183}
1184
1186
1187////////////////////////////////////////////////////////////////////////////////
1188/// Make a clone of this. Pointers are preserved.
1189
1194
1195////////////////////////////////////////////////////////////////////////////////
1196/// Paint method.
1197
1199{
1200 TVirtualViewer3D *viewer = gPad->GetViewer3D();
1201
1202 if (!viewer) {
1203 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
1204 return;
1205 }
1206
1207 viewer->AddCompositeOp(TBuffer3D::kCSIntersection);
1208
1210}
1211
1212////////////////////////////////////////////////////////////////////////////////
1213/// Default constructor
1214
1216
1217////////////////////////////////////////////////////////////////////////////////
1218/// Constructor
1219
1221
1222////////////////////////////////////////////////////////////////////////////////
1223/// Constructor providing pointers to components
1224
1226 : TGeoBoolNode(left, right, lmat, rmat)
1227{
1230 if (hs1 && hs2)
1231 Fatal("ctor", "cannot intersect two half-spaces: %s * %s", left->GetName(), right->GetName());
1232}
1233
1234////////////////////////////////////////////////////////////////////////////////
1235/// Destructor
1236/// --- deletion of components handled by TGeoManager class.
1237
1239
1240////////////////////////////////////////////////////////////////////////////////
1241/// Compute bounding box corresponding to a intersection of two shapes.
1242
1244{
1247 Double_t vert[48];
1248 Double_t pt[3];
1249 Int_t i;
1254 if (!hs1) {
1255 if (((TGeoBBox *)fLeft)->IsNullBox())
1256 fLeft->ComputeBBox();
1257 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
1258 for (i = 0; i < 8; i++) {
1259 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
1260 if (pt[0] < xmin1)
1261 xmin1 = pt[0];
1262 if (pt[0] > xmax1)
1263 xmax1 = pt[0];
1264 if (pt[1] < ymin1)
1265 ymin1 = pt[1];
1266 if (pt[1] > ymax1)
1267 ymax1 = pt[1];
1268 if (pt[2] < zmin1)
1269 zmin1 = pt[2];
1270 if (pt[2] > zmax1)
1271 zmax1 = pt[2];
1272 }
1273 }
1274 if (!hs2) {
1275 if (((TGeoBBox *)fRight)->IsNullBox())
1277 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
1278 for (i = 8; i < 16; i++) {
1279 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
1280 if (pt[0] < xmin2)
1281 xmin2 = pt[0];
1282 if (pt[0] > xmax2)
1283 xmax2 = pt[0];
1284 if (pt[1] < ymin2)
1285 ymin2 = pt[1];
1286 if (pt[1] > ymax2)
1287 ymax2 = pt[1];
1288 if (pt[2] < zmin2)
1289 zmin2 = pt[2];
1290 if (pt[2] > zmax2)
1291 zmax2 = pt[2];
1292 }
1293 }
1294 if (hs1) {
1295 dx = 0.5 * (xmax2 - xmin2);
1296 origin[0] = 0.5 * (xmax2 + xmin2);
1297 dy = 0.5 * (ymax2 - ymin2);
1298 origin[1] = 0.5 * (ymax2 + ymin2);
1299 dz = 0.5 * (zmax2 - zmin2);
1300 origin[2] = 0.5 * (zmax2 + zmin2);
1301 return;
1302 }
1303 if (hs2) {
1304 dx = 0.5 * (xmax1 - xmin1);
1305 origin[0] = 0.5 * (xmax1 + xmin1);
1306 dy = 0.5 * (ymax1 - ymin1);
1307 origin[1] = 0.5 * (ymax1 + ymin1);
1308 dz = 0.5 * (zmax1 - zmin1);
1309 origin[2] = 0.5 * (zmax1 + zmin1);
1310 return;
1311 }
1312 Double_t sort[4];
1313 Int_t isort[4];
1314 sort[0] = xmin1;
1315 sort[1] = xmax1;
1316 sort[2] = xmin2;
1317 sort[3] = xmax2;
1318 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1319 if (isort[1] % 2) {
1320 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1321 dx = dy = dz = 0;
1322 memset(origin, 0, 3 * sizeof(Double_t));
1323 return;
1324 }
1325 dx = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1326 origin[0] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1327 sort[0] = ymin1;
1328 sort[1] = ymax1;
1329 sort[2] = ymin2;
1330 sort[3] = ymax2;
1331 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1332 if (isort[1] % 2) {
1333 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1334 dx = dy = dz = 0;
1335 memset(origin, 0, 3 * sizeof(Double_t));
1336 return;
1337 }
1338 dy = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1339 origin[1] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1340 sort[0] = zmin1;
1341 sort[1] = zmax1;
1342 sort[2] = zmin2;
1343 sort[3] = zmax2;
1344 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1345 if (isort[1] % 2) {
1346 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1347 dx = dy = dz = 0;
1348 memset(origin, 0, 3 * sizeof(Double_t));
1349 return;
1350 }
1351 dz = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1352 origin[2] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1353}
1354
1355////////////////////////////////////////////////////////////////////////////////
1356/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
1357
1358void TGeoIntersection::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
1359{
1361 Double_t local[3], ldir[3], lnorm[3];
1362 norm[0] = norm[1] = 0.;
1363 norm[2] = 1.;
1364 if (td.fSelected == 1) {
1365 fLeftMat->MasterToLocal(point, local);
1369 return;
1370 }
1371 if (td.fSelected == 2) {
1372 fRightMat->MasterToLocal(point, local);
1376 return;
1377 }
1378 fLeftMat->MasterToLocal(point, local);
1379 if (!fLeft->Contains(local)) {
1383 return;
1384 }
1385 fRightMat->MasterToLocal(point, local);
1386 if (!fRight->Contains(local)) {
1390 return;
1391 }
1392 // point is inside intersection.
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 local[0] = point[0] - 1E-5 * dir[0];
1398 local[1] = point[1] - 1E-5 * dir[1];
1399 local[2] = point[2] - 1E-5 * dir[2];
1400 if (Contains(local))
1401 return;
1402 }
1403 ComputeNormal(local, dir, norm);
1404}
1405
1406////////////////////////////////////////////////////////////////////////////////
1407/// Find if a intersection of two shapes contains a given point
1408
1410{
1411 Double_t local[3];
1412 fLeftMat->MasterToLocal(point, &local[0]);
1413 Bool_t inside = fLeft->Contains(&local[0]);
1414 if (!inside)
1415 return kFALSE;
1416 fRightMat->MasterToLocal(point, &local[0]);
1417 inside = fRight->Contains(&local[0]);
1418 return inside;
1419}
1420
1421////////////////////////////////////////////////////////////////////////////////
1422/// Compute minimum distance to shape vertices
1423
1425{
1426 return 9999;
1427}
1428
1429////////////////////////////////////////////////////////////////////////////////
1430/// Compute distance from a given point inside to the shape boundary.
1431
1433 Double_t *safe) const
1434{
1435 if (iact < 3 && safe) {
1436 // compute safe distance
1437 *safe = Safety(point, kTRUE);
1438 if (iact == 0)
1439 return TGeoShape::Big();
1440 if (iact == 1 && step < *safe)
1441 return TGeoShape::Big();
1442 }
1443 TGeoBoolNode *node = (TGeoBoolNode *)this;
1444 Double_t local[3], ldir[3], rdir[3];
1445 Double_t d1, d2, snxt = 0.;
1446 fLeftMat->MasterToLocal(point, &local[0]);
1447 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1448 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1449 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1450 fRightMat->MasterToLocal(point, &local[0]);
1451 d2 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1452 if (d1 < d2) {
1453 snxt = d1;
1454 node->SetSelected(1);
1455 } else {
1456 snxt = d2;
1457 node->SetSelected(2);
1458 }
1459 return snxt;
1460}
1461
1462////////////////////////////////////////////////////////////////////////////////
1463/// Compute distance from a given point outside to the shape.
1464
1466 Double_t *safe) const
1467{
1469 if (iact < 3 && safe) {
1470 // compute safe distance
1471 *safe = Safety(point, kFALSE);
1472 if (iact == 0)
1473 return TGeoShape::Big();
1474 if (iact == 1 && step < *safe)
1475 return TGeoShape::Big();
1476 }
1477 TGeoBoolNode *node = (TGeoBoolNode *)this;
1478 Double_t lpt[3], rpt[3], master[3], ldir[3], rdir[3];
1479 memcpy(master, point, 3 * sizeof(Double_t));
1480 Int_t i;
1481 Double_t d1 = 0.;
1482 Double_t d2 = 0.;
1483 fLeftMat->MasterToLocal(point, lpt);
1484 fRightMat->MasterToLocal(point, rpt);
1489 node->SetSelected(0);
1490 Double_t snext = 0.0;
1491 if (inleft && inright) {
1492 // It is vey likely to have a numerical issue and the point should
1493 // be logically outside one of the shapes
1494 d1 = fLeft->DistFromInside(lpt, ldir, 3);
1496 if (d1 < 1.E-3)
1497 inleft = kFALSE;
1498 if (d2 < 1.E-3)
1499 inright = kFALSE;
1500 if (inleft && inright)
1501 return snext;
1502 }
1503
1504 while (true) {
1505 d1 = d2 = 0;
1506 if (!inleft) {
1508 d1 = TMath::Max(d1, tol);
1509 if (d1 > 1E20)
1510 return TGeoShape::Big();
1511 }
1512 if (!inright) {
1514 d2 = TMath::Max(d2, tol);
1515 if (d2 > 1E20)
1516 return TGeoShape::Big();
1517 }
1518
1519 if (d1 > d2) {
1520 // propagate to left shape
1521 snext += d1;
1522 node->SetSelected(1);
1523 inleft = kTRUE;
1524 for (i = 0; i < 3; i++)
1525 master[i] += d1 * dir[i];
1527 // Push rpt to avoid a bad boundary condition
1528 for (i = 0; i < 3; i++)
1529 rpt[i] += tol * rdir[i];
1530 // check if propagated point is inside right shape
1532 if (inright)
1533 return snext;
1534 // here inleft=true, inright=false
1535 } else {
1536 // propagate to right shape
1537 snext += d2;
1538 node->SetSelected(2);
1539 inright = kTRUE;
1540 for (i = 0; i < 3; i++)
1541 master[i] += d2 * dir[i];
1543 // Push lpt to avoid a bad boundary condition
1544 for (i = 0; i < 3; i++)
1545 lpt[i] += tol * ldir[i];
1546 // check if propagated point is inside left shape
1548 if (inleft)
1549 return snext;
1550 // here inleft=false, inright=true
1551 }
1552 }
1553 return snext;
1554}
1555
1556////////////////////////////////////////////////////////////////////////////////
1557/// Compute safety distance for a union node;
1558
1560{
1561 Double_t local1[3], local2[3];
1562 fLeftMat->MasterToLocal(point, local1);
1566 Bool_t intrue = in1 & in2;
1567 if (in ^ intrue)
1568 return 0.0;
1571 if (in1 && in2)
1572 return TMath::Min(saf1, saf2);
1573 if (in1)
1574 return saf2;
1575 if (in2)
1576 return saf1;
1577 return TMath::Max(saf1, saf2);
1578}
1579
1580////////////////////////////////////////////////////////////////////////////////
1581/// Save a primitive as a C++ statement(s) on output stream "out".
1582
1583void TGeoIntersection::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1584{
1586 out << " pBoolNode = new TGeoIntersection(";
1587 out << fLeft->GetPointerName() << ",";
1588 out << fRight->GetPointerName() << ",";
1589 if (!fLeftMat->IsIdentity())
1590 out << fLeftMat->GetPointerName() << ",";
1591 else
1592 out << "0,";
1593 if (!fRightMat->IsIdentity())
1594 out << fRightMat->GetPointerName() << ");" << std::endl;
1595 else
1596 out << "0);" << std::endl;
1597}
1598
1599////////////////////////////////////////////////////////////////////////////////
1600/// Register 3D size of this shape.
1601
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
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.
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:991
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:769
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1005
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1033
Basic string class.
Definition TString.h:139
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:250
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
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:431
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