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/// Constructor.
48
50
51////////////////////////////////////////////////////////////////////////////////
52/// Destructor.
53
55
56////////////////////////////////////////////////////////////////////////////////
57
59{
61 /*
62 std::lock_guard<std::mutex> guard(fMutex);
63 if (tid >= fThreadSize) {
64 Error("GetThreadData", "Thread id=%d bigger than maximum declared thread number %d. \nUse
65 TGeoManager::SetMaxThreads properly !!!", tid, fThreadSize);
66 }
67 if (tid >= fThreadSize)
68 {
69 fThreadData.resize(tid + 1);
70 fThreadSize = tid + 1;
71 }
72 if (fThreadData[tid] == 0)
73 {
74 if (fThreadData[tid] == 0)
75 fThreadData[tid] = new ThreadData_t;
76 }
77 */
78 return *fThreadData[tid];
79}
80
81////////////////////////////////////////////////////////////////////////////////
82
84{
85 std::lock_guard<std::mutex> guard(fMutex);
86 std::vector<ThreadData_t *>::iterator i = fThreadData.begin();
87 while (i != fThreadData.end()) {
88 delete *i;
89 ++i;
90 }
91 fThreadData.clear();
92 fThreadSize = 0;
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Create thread data for n threads max.
97
99{
100 std::lock_guard<std::mutex> guard(fMutex);
101 fThreadData.resize(nthreads);
103 for (Int_t tid = 0; tid < nthreads; tid++) {
104 if (fThreadData[tid] == nullptr) {
106 }
107 }
108 // Propagate to components
109 if (fLeft)
111 if (fRight)
113}
114
115////////////////////////////////////////////////////////////////////////////////
116/// Set the selected branch.
117
122
123////////////////////////////////////////////////////////////////////////////////
124/// Default constructor
125
127{
128 fLeft = nullptr;
129 fRight = nullptr;
130 fLeftMat = nullptr;
131 fRightMat = nullptr;
132 fNpoints = 0;
133 fPoints = nullptr;
134 fThreadSize = 0;
136}
137
138////////////////////////////////////////////////////////////////////////////////
139/// Constructor called by TGeoCompositeShape providing 2 subexpressions for the 2 branches.
140
141TGeoBoolNode::TGeoBoolNode(const char *expr1, const char *expr2)
142{
143 fLeft = nullptr;
144 fRight = nullptr;
145 fLeftMat = nullptr;
146 fRightMat = nullptr;
147 fNpoints = 0;
148 fPoints = nullptr;
149 fThreadSize = 0;
151 if (!MakeBranch(expr1, kTRUE)) {
152 return;
153 }
154 if (!MakeBranch(expr2, kFALSE)) {
155 return;
156 }
157}
158
159////////////////////////////////////////////////////////////////////////////////
160/// Constructor providing left and right shapes and matrices (in the Boolean operation).
161
163{
164 fLeft = left;
165 fRight = right;
166 fLeftMat = lmat;
167 fNpoints = 0;
168 fPoints = nullptr;
169 fThreadSize = 0;
171 if (!fLeftMat)
173 else
175 fRightMat = rmat;
176 if (!fRightMat)
178 else
180 if (!fLeft) {
181 Error("ctor", "left shape is NULL");
182 return;
183 }
184 if (!fRight) {
185 Error("ctor", "right shape is NULL");
186 return;
187 }
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Destructor.
192/// --- deletion of components handled by TGeoManager class.
193
195{
196 if (fPoints)
197 delete[] fPoints;
199}
200
201////////////////////////////////////////////////////////////////////////////////
202/// Set fPoints array
203
205{
206 if (fPoints) {
207 delete[] fPoints;
208 fPoints = nullptr;
209 fNpoints = 0;
210 }
211 if (points) {
213 fPoints = new Double_t[3 * fNpoints];
214 memcpy(fPoints, points, 3 * fNpoints * sizeof(Double_t));
215 }
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 && fMeshValid)
226 return fNpoints;
227 // Local points for the left shape
230 if (nleft + nright == 0)
231 return 0;
232
233 // This is an expensive check to make sure the generated points are on the surface of the shape
234 Double_t *points1 = (nleft > 0) ? new Double_t[3 * nleft] : nullptr;
235 if (nleft > 0)
237 // Local points for the right shape
238 Double_t *points2 = (nright > 0) ? new Double_t[3 * nright] : nullptr;
239 if (nright > 0)
241 Double_t *points = new Double_t[3 * (nleft + nright)];
242 for (Int_t i = 0; i < nleft; i++) {
243 fLeftMat->LocalToMaster(&points1[3 * i], &points[3 * itot]);
245 itot++;
246 }
247 for (Int_t i = 0; i < nright; i++) {
248 fRightMat->LocalToMaster(&points2[3 * i], &points[3 * itot]);
250 itot++;
251 }
252
254
255 delete[] points1;
256 delete[] points2;
257 delete[] points;
258 return fNpoints;
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Invalidate mesh caching recursively
263
265{
267 if (fLeft->IsComposite())
268 ((TGeoCompositeShape *)fLeft)->InvalidateMeshCaches();
269 if (fRight->IsComposite())
271}
272
273////////////////////////////////////////////////////////////////////////////////
274/// Implementation of the inside function using just Contains and GetNormal
275
277{
278 return tgeo_impl::Inside(point, this);
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Expands the boolean expression either on left or right branch, creating
283/// component elements (composite shapes and boolean nodes). Returns true on success.
284
286{
289 if (boolop < 0) {
290 Error("MakeBranch", "invalid expression");
291 return kFALSE;
292 }
293 TGeoShape *shape = nullptr;
296
297 if (stransf.Length() == 0) {
299 } else {
301 }
302 if (!mat) {
303 Error("MakeBranch", "transformation %s not found", stransf.Data());
304 return kFALSE;
305 }
306 switch (boolop) {
307 case 0:
308 // elementary shape
310 if (!shape) {
311 Error("MakeBranch", "shape %s not found", sleft.Data());
312 return kFALSE;
313 }
314 break;
315 case 1:
316 // composite shape - union
317 newshape = sleft;
318 newshape += "+";
319 newshape += sright;
320 shape = new TGeoCompositeShape(newshape.Data());
321 break;
322 case 2:
323 // composite shape - difference
324 newshape = sleft;
325 newshape += "-";
326 newshape += sright;
327 shape = new TGeoCompositeShape(newshape.Data());
328 break;
329 case 3:
330 // composite shape - intersection
331 newshape = sleft;
332 newshape += "*";
333 newshape += sright;
334 shape = new TGeoCompositeShape(newshape.Data());
335 break;
336 }
337 if (boolop && (!shape || !shape->IsValid())) {
338 Error("MakeBranch", "Shape %s not valid", newshape.Data());
339 if (shape)
340 delete shape;
341 return kFALSE;
342 }
343 if (left) {
344 fLeft = shape;
345 fLeftMat = mat;
346 } else {
347 fRight = shape;
348 fRightMat = mat;
349 }
350 return kTRUE;
351}
352
353////////////////////////////////////////////////////////////////////////////////
354/// Special schema for feeding the 3D buffers to the painter client.
355
357{
358 TVirtualViewer3D *viewer = gPad->GetViewer3D();
359 if (!viewer)
360 return;
361
362 // Components of composite shape hierarchies for local frame viewers are painted
363 // in coordinate frame of the top level composite shape. So we force
364 // conversion to this. See TGeoPainter::PaintNode for loading of GLMatrix.
365 Bool_t localFrame = kFALSE; // viewer->PreferLocalFrame();
366
369 mat = glmat; // keep a copy
370
371 // Now perform fetch and add of the two components buffers.
372 // Note we assume that composite shapes are always completely added
373 // so don't bother to get addDaughters flag from viewer->AddObject()
374
375 // Setup matrix and fetch/add the left component buffer
376 glmat->Multiply(fLeftMat);
377 // fLeft->Paint(option);
378 if (TGeoCompositeShape *left = dynamic_cast<TGeoCompositeShape *>(fLeft)) {
379 left->PaintComposite(option);
380 } else if (fLeft) {
382 viewer->AddObject(leftBuffer);
383 }
384
385 // Setup matrix and fetch/add the right component buffer
386 *glmat = &mat;
387 glmat->Multiply(fRightMat);
388 // fRight->Paint(option);
389 if (TGeoCompositeShape *right = dynamic_cast<TGeoCompositeShape *>(fRight)) {
390 right->PaintComposite(option);
391 } else if (fRight) {
393 viewer->AddObject(rightBuffer);
394 }
395
396 *glmat = &mat;
397}
398
399////////////////////////////////////////////////////////////////////////////////
400/// Register all matrices of the boolean node and descendents.
401
403{
404 if (!fLeftMat->IsIdentity())
406 if (!fRightMat->IsIdentity())
408 if (fLeft->IsComposite())
409 ((TGeoCompositeShape *)fLeft)->GetBoolNode()->RegisterMatrices();
410 if (fRight->IsComposite())
411 ((TGeoCompositeShape *)fRight)->GetBoolNode()->RegisterMatrices();
412}
413
414////////////////////////////////////////////////////////////////////////////////
415/// Replace one of the matrices. Does not work with TGeoIdentity. Returns true
416/// if replacement was successful.
417
419{
420 if (mat == gGeoIdentity || newmat == gGeoIdentity) {
421 Error("ReplaceMatrix",
422 "Matrices should not be gGeoIdentity. Use default matrix constructor to represent identities.");
423 return kFALSE;
424 }
425 if (!mat || !newmat) {
426 Error("ReplaceMatrix", "Matrices should not be null pointers.");
427 return kFALSE;
428 }
430 if (fLeftMat == mat) {
432 replaced = kTRUE;
433 }
434 if (fRightMat == mat) {
436 replaced = kTRUE;
437 }
438 return replaced;
439}
440
441////////////////////////////////////////////////////////////////////////////////
442/// Save a primitive as a C++ statement(s) on output stream "out".
443
444void TGeoBoolNode::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
445{
448 if (!fLeftMat->IsIdentity()) {
451 }
452 if (!fRightMat->IsIdentity()) {
455 }
456}
457
458////////////////////////////////////////////////////////////////////////////////
459/// Fill buffer with shape vertices.
460
462{
463 TGeoBoolNode *bn = (TGeoBoolNode *)this;
464 Int_t npoints = bn->GetNpoints();
465 memcpy(points, fPoints, 3 * npoints * sizeof(Double_t));
466}
467
468////////////////////////////////////////////////////////////////////////////////
469/// Fill buffer with shape vertices.
470
472{
473 TGeoBoolNode *bn = (TGeoBoolNode *)this;
474 Int_t npoints = bn->GetNpoints();
475 for (Int_t i = 0; i < 3 * npoints; i++)
476 points[i] = fPoints[i];
477}
478
479////////////////////////////////////////////////////////////////////////////////
480/// Register size of this 3D object
481
483{
484 fLeft->Sizeof3D();
485 fRight->Sizeof3D();
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// Make a clone of this. Pointers are preserved.
490
495
496////////////////////////////////////////////////////////////////////////////////
497/// Paint method.
498
500{
501 TVirtualViewer3D *viewer = gPad->GetViewer3D();
502
503 if (!viewer) {
504 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
505 return;
506 }
507
508 viewer->AddCompositeOp(TBuffer3D::kCSUnion);
509
511}
512
513////////////////////////////////////////////////////////////////////////////////
514/// Default constructor
515
517
518////////////////////////////////////////////////////////////////////////////////
519/// Constructor
520
521TGeoUnion::TGeoUnion(const char *expr1, const char *expr2) : TGeoBoolNode(expr1, expr2) {}
522
523////////////////////////////////////////////////////////////////////////////////
524/// Constructor providing pointers to components
525
527 : TGeoBoolNode(left, right, lmat, rmat)
528{
530 Fatal("TGeoUnion", "Unions with a half-space (%s + %s) not allowed", left->GetName(), right->GetName());
531 }
532}
533
534////////////////////////////////////////////////////////////////////////////////
535/// Destructor
536/// --- deletion of components handled by TGeoManager class.
537
539
540////////////////////////////////////////////////////////////////////////////////
541/// Compute bounding box corresponding to a union of two shapes.
542
544{
545 if (((TGeoBBox *)fLeft)->IsNullBox())
547 if (((TGeoBBox *)fRight)->IsNullBox())
549 Double_t vert[48];
550 Double_t pt[3];
551 Int_t i;
552 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
553 xmin = ymin = zmin = TGeoShape::Big();
554 xmax = ymax = zmax = -TGeoShape::Big();
555 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
556 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
557 for (i = 0; i < 8; i++) {
558 fLeftMat->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 for (i = 8; i < 16; i++) {
573 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
574 if (pt[0] < xmin)
575 xmin = pt[0];
576 if (pt[0] > xmax)
577 xmax = pt[0];
578 if (pt[1] < ymin)
579 ymin = pt[1];
580 if (pt[1] > ymax)
581 ymax = pt[1];
582 if (pt[2] < zmin)
583 zmin = pt[2];
584 if (pt[2] > zmax)
585 zmax = pt[2];
586 }
587 dx = 0.5 * (xmax - xmin);
588 origin[0] = 0.5 * (xmin + xmax);
589 dy = 0.5 * (ymax - ymin);
590 origin[1] = 0.5 * (ymin + ymax);
591 dz = 0.5 * (zmax - zmin);
592 origin[2] = 0.5 * (zmin + zmax);
593}
594
595////////////////////////////////////////////////////////////////////////////////
596/// Find if a union of two shapes contains a given point
597
599{
600 Double_t local[3];
601 fLeftMat->MasterToLocal(point, &local[0]);
602 Bool_t inside = fLeft->Contains(&local[0]);
603 if (inside)
604 return kTRUE;
605 fRightMat->MasterToLocal(point, &local[0]);
606 inside = fRight->Contains(&local[0]);
607 return inside;
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
612
613void TGeoUnion::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
614{
616 norm[0] = norm[1] = 0.;
617 norm[2] = 1.;
618 Double_t local[3];
619 Double_t ldir[3], lnorm[3];
620 if (td.fSelected == 1) {
625 return;
626 }
627 if (td.fSelected == 2) {
632 return;
633 }
635 if (fLeft->Contains(local)) {
639 return;
640 }
642 if (fRight->Contains(local)) {
646 return;
647 }
648 // Propagate forward/backward to see which of the components is intersected first
649 local[0] = point[0] + 1E-5 * dir[0];
650 local[1] = point[1] + 1E-5 * dir[1];
651 local[2] = point[2] + 1E-5 * dir[2];
652
653 if (!Contains(local)) {
654 local[0] = point[0] - 1E-5 * dir[0];
655 local[1] = point[1] - 1E-5 * dir[1];
656 local[2] = point[2] - 1E-5 * dir[2];
657 if (!Contains(local))
658 return;
659 }
660 ComputeNormal(local, dir, norm);
661}
662
663////////////////////////////////////////////////////////////////////////////////
664/// Compute minimum distance to shape vertices.
665
667{
668 return 9999;
669}
670
671////////////////////////////////////////////////////////////////////////////////
672/// Computes distance from a given point inside the shape to its boundary.
673
676{
677 if (iact < 3 && safe) {
678 // compute safe distance
679 *safe = Safety(point, kTRUE);
680 if (iact == 0)
681 return TGeoShape::Big();
682 if (iact == 1 && step < *safe)
683 return TGeoShape::Big();
684 }
685
686 Double_t local[3], local1[3], master[3], ldir[3], rdir[3], pushed[3];
687 memcpy(master, point, 3 * sizeof(Double_t));
688 Int_t i;
689 TGeoBoolNode *node = (TGeoBoolNode *)this;
690 Double_t d1 = 0., d2 = 0., snxt = 0., eps = 0.;
695 if (inside1)
697 else
698 memcpy(local1, local, 3 * sizeof(Double_t));
701 if (inside2)
703 if (!(inside1 | inside2)) {
704 // This is a pathological case when the point is on the boundary
706 if (d1 < 1.E-3) {
707 eps = d1 + TGeoShape::Tolerance();
708 for (i = 0; i < 3; i++)
709 local1[i] += eps * ldir[i];
710 inside1 = kTRUE;
712 d1 += eps;
713 } else {
715 if (d2 < 1.E-3) {
716 eps = d2 + TGeoShape::Tolerance();
717 for (i = 0; i < 3; i++)
718 local[i] += eps * rdir[i];
719 inside2 = kTRUE;
721 d2 += eps;
722 }
723 }
724 }
725 while (inside1 || inside2) {
726 if (inside1 && inside2) {
727 if (d1 < d2) {
728 snxt += d1;
729 node->SetSelected(1);
730 // propagate to exit of left shape
731 inside1 = kFALSE;
732 for (i = 0; i < 3; i++)
733 master[i] += d1 * dir[i];
734 // check if propagated point is in right shape
737 if (!inside2)
738 return snxt;
740 if (d2 < TGeoShape::Tolerance())
741 return snxt;
742 } else {
743 snxt += d2;
744 node->SetSelected(2);
745 // propagate to exit of right shape
746 inside2 = kFALSE;
747 for (i = 0; i < 3; i++)
748 master[i] += d2 * dir[i];
749 // check if propagated point is in left shape
752 if (!inside1)
753 return snxt;
755 if (d1 < TGeoShape::Tolerance())
756 return snxt;
757 }
758 }
759 if (inside1) {
760 snxt += d1;
761 node->SetSelected(1);
762 // propagate to exit of left shape
763 inside1 = kFALSE;
764 for (i = 0; i < 3; i++) {
765 master[i] += d1 * dir[i];
766 pushed[i] = master[i] + (1. + d1) * TGeoShape::Tolerance() * dir[i];
767 }
768 // check if propagated point is in right shape
771 if (!inside2)
772 return snxt;
774 if (d2 < TGeoShape::Tolerance())
775 return snxt;
776 d2 += (1. + d1) * TGeoShape::Tolerance();
777 }
778 if (inside2) {
779 snxt += d2;
780 node->SetSelected(2);
781 // propagate to exit of right shape
782 inside2 = kFALSE;
783 for (i = 0; i < 3; i++) {
784 master[i] += d2 * dir[i];
785 pushed[i] = master[i] + (1. + d2) * TGeoShape::Tolerance() * dir[i];
786 }
787 // check if propagated point is in left shape
790 if (!inside1)
791 return snxt;
793 if (d1 < TGeoShape::Tolerance())
794 return snxt;
795 d1 += (1. + d2) * TGeoShape::Tolerance();
796 }
797 }
798 return snxt;
799}
800
801////////////////////////////////////////////////////////////////////////////////
802/// Compute distance from a given outside point to the shape.
803
806{
807 if (iact < 3 && safe) {
808 // compute safe distance
809 *safe = Safety(point, kFALSE);
810 if (iact == 0)
811 return TGeoShape::Big();
812 if (iact == 1 && step < *safe)
813 return TGeoShape::Big();
814 }
815 TGeoBoolNode *node = (TGeoBoolNode *)this;
816 Double_t local[3], ldir[3], rdir[3];
817 Double_t d1, d2, snxt;
818 fLeftMat->MasterToLocal(point, &local[0]);
821 d1 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
822 fRightMat->MasterToLocal(point, &local[0]);
823 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
824 if (d1 < d2) {
825 snxt = d1;
826 node->SetSelected(1);
827 } else {
828 snxt = d2;
829 node->SetSelected(2);
830 }
831 return snxt;
832}
833
834////////////////////////////////////////////////////////////////////////////////
835/// Compute safety distance for a union node;
836
838{
839 Double_t local1[3], local2[3];
844 Bool_t intrue = in1 | in2;
845 if (intrue ^ in)
846 return 0.0;
849 if (in1 && in2)
850 return TMath::Min(saf1, saf2);
851 if (in1)
852 return saf1;
853 if (in2)
854 return saf2;
855 return TMath::Min(saf1, saf2);
856}
857
858////////////////////////////////////////////////////////////////////////////////
859/// Save a primitive as a C++ statement(s) on output stream "out".
860
861void TGeoUnion::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
862{
864 out << " pBoolNode = new TGeoUnion(";
865 out << fLeft->GetPointerName() << ",";
866 out << fRight->GetPointerName() << ",";
867 if (!fLeftMat->IsIdentity())
868 out << fLeftMat->GetPointerName() << ",";
869 else
870 out << "0,";
871 if (!fRightMat->IsIdentity())
872 out << fRightMat->GetPointerName() << ");" << std::endl;
873 else
874 out << "0);" << std::endl;
875}
876
877////////////////////////////////////////////////////////////////////////////////
878/// Register 3D size of this shape.
879
881{
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// Make a clone of this. Pointers are preserved.
887
892
893////////////////////////////////////////////////////////////////////////////////
894/// Paint method.
895
897{
898 TVirtualViewer3D *viewer = gPad->GetViewer3D();
899
900 if (!viewer) {
901 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
902 return;
903 }
904
905 viewer->AddCompositeOp(TBuffer3D::kCSDifference);
906
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Default constructor
912
914
915////////////////////////////////////////////////////////////////////////////////
916/// Constructor
917
919
920////////////////////////////////////////////////////////////////////////////////
921/// Constructor providing pointers to components
922
924 : TGeoBoolNode(left, right, lmat, rmat)
925{
927 Fatal("TGeoSubstraction", "Subtractions from a half-space (%s) not allowed", left->GetName());
928 }
929}
930
931////////////////////////////////////////////////////////////////////////////////
932/// Destructor
933/// --- deletion of components handled by TGeoManager class.
934
936
937////////////////////////////////////////////////////////////////////////////////
938/// Compute bounding box corresponding to a subtraction of two shapes.
939
941{
943 if (box->IsNullBox())
945 Double_t vert[24];
946 Double_t pt[3];
947 Int_t i;
948 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
949 xmin = ymin = zmin = TGeoShape::Big();
950 xmax = ymax = zmax = -TGeoShape::Big();
951 box->SetBoxPoints(&vert[0]);
952 for (i = 0; i < 8; i++) {
953 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
954 if (pt[0] < xmin)
955 xmin = pt[0];
956 if (pt[0] > xmax)
957 xmax = pt[0];
958 if (pt[1] < ymin)
959 ymin = pt[1];
960 if (pt[1] > ymax)
961 ymax = pt[1];
962 if (pt[2] < zmin)
963 zmin = pt[2];
964 if (pt[2] > zmax)
965 zmax = pt[2];
966 }
967 dx = 0.5 * (xmax - xmin);
968 origin[0] = 0.5 * (xmin + xmax);
969 dy = 0.5 * (ymax - ymin);
970 origin[1] = 0.5 * (ymin + ymax);
971 dz = 0.5 * (zmax - zmin);
972 origin[2] = 0.5 * (zmin + zmax);
973}
974
975////////////////////////////////////////////////////////////////////////////////
976/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
977
978void TGeoSubtraction::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
979{
981 norm[0] = norm[1] = 0.;
982 norm[2] = 1.;
983 Double_t local[3], ldir[3], lnorm[3];
984 if (td.fSelected == 1) {
989 return;
990 }
991 if (td.fSelected == 2) {
996 return;
997 }
999 if (fRight->Contains(local)) {
1003 return;
1004 }
1005 fLeftMat->MasterToLocal(point, local);
1006 if (!fLeft->Contains(local)) {
1010 return;
1011 }
1012 // point is inside left shape, but not inside the right
1013 local[0] = point[0] + 1E-5 * dir[0];
1014 local[1] = point[1] + 1E-5 * dir[1];
1015 local[2] = point[2] + 1E-5 * dir[2];
1016 if (Contains(local)) {
1017 local[0] = point[0] - 1E-5 * dir[0];
1018 local[1] = point[1] - 1E-5 * dir[1];
1019 local[2] = point[2] - 1E-5 * dir[2];
1020 if (Contains(local))
1021 return;
1022 }
1023 ComputeNormal(local, dir, norm);
1024}
1025
1026////////////////////////////////////////////////////////////////////////////////
1027/// Find if a subtraction of two shapes contains a given point
1028
1030{
1031 Double_t local[3];
1032 fLeftMat->MasterToLocal(point, &local[0]);
1033 Bool_t inside = fLeft->Contains(&local[0]);
1034 if (!inside)
1035 return kFALSE;
1036 fRightMat->MasterToLocal(point, &local[0]);
1037 inside = !fRight->Contains(&local[0]);
1038 return inside;
1039}
1040
1041////////////////////////////////////////////////////////////////////////////////
1042/// Compute minimum distance to shape vertices
1043
1045{
1046 return 9999;
1047}
1048
1049////////////////////////////////////////////////////////////////////////////////
1050/// Compute distance from a given point inside to the shape boundary.
1051
1053 Double_t *safe) const
1054{
1055 if (iact < 3 && safe) {
1056 // compute safe distance
1057 *safe = Safety(point, kTRUE);
1058 if (iact == 0)
1059 return TGeoShape::Big();
1060 if (iact == 1 && step < *safe)
1061 return TGeoShape::Big();
1062 }
1063 TGeoBoolNode *node = (TGeoBoolNode *)this;
1064 Double_t local[3], ldir[3], rdir[3];
1065 Double_t d1, d2, snxt = 0.;
1066 fLeftMat->MasterToLocal(point, &local[0]);
1067 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1068 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1069 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1070 fRightMat->MasterToLocal(point, &local[0]);
1071 d2 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1072 if (d1 < d2) {
1073 snxt = d1;
1074 node->SetSelected(1);
1075 } else {
1076 snxt = d2;
1077 node->SetSelected(2);
1078 }
1079 return snxt;
1080}
1081
1082////////////////////////////////////////////////////////////////////////////////
1083/// Compute distance from a given point outside to the shape.
1084
1086 Double_t *safe) const
1087{
1088 if (iact < 3 && safe) {
1089 // compute safe distance
1090 *safe = Safety(point, kFALSE);
1091 if (iact == 0)
1092 return TGeoShape::Big();
1093 if (iact == 1 && step < *safe)
1094 return TGeoShape::Big();
1095 }
1096 TGeoBoolNode *node = (TGeoBoolNode *)this;
1097 Double_t local[3], master[3], ldir[3], rdir[3];
1098 memcpy(&master[0], point, 3 * sizeof(Double_t));
1099 Int_t i;
1100 Double_t d1, d2, snxt = 0.;
1101 fRightMat->MasterToLocal(point, &local[0]);
1102 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1103 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1104 // check if inside '-'
1105 Bool_t inside = fRight->Contains(&local[0]);
1106 Double_t epsil = 0.;
1107 while (true) {
1108 if (inside) {
1109 // propagate to outside of '-'
1110 node->SetSelected(2);
1111 d1 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1112 snxt += d1 + epsil;
1113 for (i = 0; i < 3; i++)
1114 master[i] += (d1 + 1E-8) * dir[i];
1115 epsil = 1.E-8;
1116 // now master outside '-'; check if inside '+'
1118 if (fLeft->Contains(&local[0]))
1119 return snxt;
1120 }
1121 // master outside '-' and outside '+' ; find distances to both
1122 node->SetSelected(1);
1124 d2 = fLeft->DistFromOutside(&local[0], &ldir[0], iact, step, safe);
1125 if (d2 > 1E20)
1126 return TGeoShape::Big();
1127
1129 d1 = fRight->DistFromOutside(&local[0], &rdir[0], iact, step, safe);
1130 if (d2 < d1 - TGeoShape::Tolerance()) {
1131 snxt += d2 + epsil;
1132 return snxt;
1133 }
1134 // propagate to '-'
1135 snxt += d1 + epsil;
1136 for (i = 0; i < 3; i++)
1137 master[i] += (d1 + 1E-8) * dir[i];
1138 epsil = 1.E-8;
1139 // now inside '-' and not inside '+'
1141 inside = kTRUE;
1142 }
1143}
1144
1145////////////////////////////////////////////////////////////////////////////////
1146/// Compute safety distance for a union node;
1147
1149{
1150 Double_t local1[3], local2[3];
1151 fLeftMat->MasterToLocal(point, local1);
1155 Bool_t intrue = in1 && (!in2);
1156 if (in ^ intrue)
1157 return 0.0;
1160 if (in1 && in2)
1161 return saf2;
1162 if (in1)
1163 return TMath::Min(saf1, saf2);
1164 if (in2)
1165 return TMath::Max(saf1, saf2);
1166 return saf1;
1167}
1168
1169////////////////////////////////////////////////////////////////////////////////
1170/// Save a primitive as a C++ statement(s) on output stream "out".
1171
1172void TGeoSubtraction::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1173{
1175 out << " pBoolNode = new TGeoSubtraction(";
1176 out << fLeft->GetPointerName() << ",";
1177 out << fRight->GetPointerName() << ",";
1178 if (!fLeftMat->IsIdentity())
1179 out << fLeftMat->GetPointerName() << ",";
1180 else
1181 out << "0,";
1182 if (!fRightMat->IsIdentity())
1183 out << fRightMat->GetPointerName() << ");" << std::endl;
1184 else
1185 out << "0);" << std::endl;
1186}
1187
1188////////////////////////////////////////////////////////////////////////////////
1189/// Register 3D size of this shape.
1190
1192{
1194}
1195
1196////////////////////////////////////////////////////////////////////////////////
1197/// Make a clone of this. Pointers are preserved.
1198
1203
1204////////////////////////////////////////////////////////////////////////////////
1205/// Paint method.
1206
1208{
1209 TVirtualViewer3D *viewer = gPad->GetViewer3D();
1210
1211 if (!viewer) {
1212 Error("Paint", "gPad->GetViewer3D() returned 0, cannot work with composite!\n");
1213 return;
1214 }
1215
1216 viewer->AddCompositeOp(TBuffer3D::kCSIntersection);
1217
1219}
1220
1221////////////////////////////////////////////////////////////////////////////////
1222/// Default constructor
1223
1225
1226////////////////////////////////////////////////////////////////////////////////
1227/// Constructor
1228
1230
1231////////////////////////////////////////////////////////////////////////////////
1232/// Constructor providing pointers to components
1233
1235 : TGeoBoolNode(left, right, lmat, rmat)
1236{
1239 if (hs1 && hs2)
1240 Fatal("ctor", "cannot intersect two half-spaces: %s * %s", left->GetName(), right->GetName());
1241}
1242
1243////////////////////////////////////////////////////////////////////////////////
1244/// Destructor
1245/// --- deletion of components handled by TGeoManager class.
1246
1248
1249////////////////////////////////////////////////////////////////////////////////
1250/// Compute bounding box corresponding to a intersection of two shapes.
1251
1253{
1256 Double_t vert[48];
1257 Double_t pt[3];
1258 Int_t i;
1263 if (!hs1) {
1264 if (((TGeoBBox *)fLeft)->IsNullBox())
1265 fLeft->ComputeBBox();
1266 ((TGeoBBox *)fLeft)->SetBoxPoints(&vert[0]);
1267 for (i = 0; i < 8; i++) {
1268 fLeftMat->LocalToMaster(&vert[3 * i], &pt[0]);
1269 if (pt[0] < xmin1)
1270 xmin1 = pt[0];
1271 if (pt[0] > xmax1)
1272 xmax1 = pt[0];
1273 if (pt[1] < ymin1)
1274 ymin1 = pt[1];
1275 if (pt[1] > ymax1)
1276 ymax1 = pt[1];
1277 if (pt[2] < zmin1)
1278 zmin1 = pt[2];
1279 if (pt[2] > zmax1)
1280 zmax1 = pt[2];
1281 }
1282 }
1283 if (!hs2) {
1284 if (((TGeoBBox *)fRight)->IsNullBox())
1286 ((TGeoBBox *)fRight)->SetBoxPoints(&vert[24]);
1287 for (i = 8; i < 16; i++) {
1288 fRightMat->LocalToMaster(&vert[3 * i], &pt[0]);
1289 if (pt[0] < xmin2)
1290 xmin2 = pt[0];
1291 if (pt[0] > xmax2)
1292 xmax2 = pt[0];
1293 if (pt[1] < ymin2)
1294 ymin2 = pt[1];
1295 if (pt[1] > ymax2)
1296 ymax2 = pt[1];
1297 if (pt[2] < zmin2)
1298 zmin2 = pt[2];
1299 if (pt[2] > zmax2)
1300 zmax2 = pt[2];
1301 }
1302 }
1303 if (hs1) {
1304 dx = 0.5 * (xmax2 - xmin2);
1305 origin[0] = 0.5 * (xmax2 + xmin2);
1306 dy = 0.5 * (ymax2 - ymin2);
1307 origin[1] = 0.5 * (ymax2 + ymin2);
1308 dz = 0.5 * (zmax2 - zmin2);
1309 origin[2] = 0.5 * (zmax2 + zmin2);
1310 return;
1311 }
1312 if (hs2) {
1313 dx = 0.5 * (xmax1 - xmin1);
1314 origin[0] = 0.5 * (xmax1 + xmin1);
1315 dy = 0.5 * (ymax1 - ymin1);
1316 origin[1] = 0.5 * (ymax1 + ymin1);
1317 dz = 0.5 * (zmax1 - zmin1);
1318 origin[2] = 0.5 * (zmax1 + zmin1);
1319 return;
1320 }
1321 Double_t sort[4];
1322 Int_t isort[4];
1323 sort[0] = xmin1;
1324 sort[1] = xmax1;
1325 sort[2] = xmin2;
1326 sort[3] = xmax2;
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 dx = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1335 origin[0] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1336 sort[0] = ymin1;
1337 sort[1] = ymax1;
1338 sort[2] = ymin2;
1339 sort[3] = ymax2;
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 dy = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1348 origin[1] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1349 sort[0] = zmin1;
1350 sort[1] = zmax1;
1351 sort[2] = zmin2;
1352 sort[3] = zmax2;
1353 TMath::Sort(4, &sort[0], &isort[0], kFALSE);
1354 if (isort[1] % 2) {
1355 Warning("ComputeBBox", "shapes %s and %s do not intersect", fLeft->GetName(), fRight->GetName());
1356 dx = dy = dz = 0;
1357 memset(origin, 0, 3 * sizeof(Double_t));
1358 return;
1359 }
1360 dz = 0.5 * (sort[isort[2]] - sort[isort[1]]);
1361 origin[2] = 0.5 * (sort[isort[1]] + sort[isort[2]]);
1362}
1363
1364////////////////////////////////////////////////////////////////////////////////
1365/// Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
1366
1367void TGeoIntersection::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
1368{
1370 Double_t local[3], ldir[3], lnorm[3];
1371 norm[0] = norm[1] = 0.;
1372 norm[2] = 1.;
1373 if (td.fSelected == 1) {
1374 fLeftMat->MasterToLocal(point, local);
1378 return;
1379 }
1380 if (td.fSelected == 2) {
1381 fRightMat->MasterToLocal(point, local);
1385 return;
1386 }
1387 fLeftMat->MasterToLocal(point, local);
1388 if (!fLeft->Contains(local)) {
1392 return;
1393 }
1394 fRightMat->MasterToLocal(point, local);
1395 if (!fRight->Contains(local)) {
1399 return;
1400 }
1401 // point is inside intersection.
1402 local[0] = point[0] + 1E-5 * dir[0];
1403 local[1] = point[1] + 1E-5 * dir[1];
1404 local[2] = point[2] + 1E-5 * dir[2];
1405 if (Contains(local)) {
1406 local[0] = point[0] - 1E-5 * dir[0];
1407 local[1] = point[1] - 1E-5 * dir[1];
1408 local[2] = point[2] - 1E-5 * dir[2];
1409 if (Contains(local))
1410 return;
1411 }
1412 ComputeNormal(local, dir, norm);
1413}
1414
1415////////////////////////////////////////////////////////////////////////////////
1416/// Find if a intersection of two shapes contains a given point
1417
1419{
1420 Double_t local[3];
1421 fLeftMat->MasterToLocal(point, &local[0]);
1422 Bool_t inside = fLeft->Contains(&local[0]);
1423 if (!inside)
1424 return kFALSE;
1425 fRightMat->MasterToLocal(point, &local[0]);
1426 inside = fRight->Contains(&local[0]);
1427 return inside;
1428}
1429
1430////////////////////////////////////////////////////////////////////////////////
1431/// Compute minimum distance to shape vertices
1432
1434{
1435 return 9999;
1436}
1437
1438////////////////////////////////////////////////////////////////////////////////
1439/// Compute distance from a given point inside to the shape boundary.
1440
1442 Double_t *safe) const
1443{
1444 if (iact < 3 && safe) {
1445 // compute safe distance
1446 *safe = Safety(point, kTRUE);
1447 if (iact == 0)
1448 return TGeoShape::Big();
1449 if (iact == 1 && step < *safe)
1450 return TGeoShape::Big();
1451 }
1452 TGeoBoolNode *node = (TGeoBoolNode *)this;
1453 Double_t local[3], ldir[3], rdir[3];
1454 Double_t d1, d2, snxt = 0.;
1455 fLeftMat->MasterToLocal(point, &local[0]);
1456 fLeftMat->MasterToLocalVect(dir, &ldir[0]);
1457 fRightMat->MasterToLocalVect(dir, &rdir[0]);
1458 d1 = fLeft->DistFromInside(&local[0], &ldir[0], iact, step, safe);
1459 fRightMat->MasterToLocal(point, &local[0]);
1460 d2 = fRight->DistFromInside(&local[0], &rdir[0], iact, step, safe);
1461 if (d1 < d2) {
1462 snxt = d1;
1463 node->SetSelected(1);
1464 } else {
1465 snxt = d2;
1466 node->SetSelected(2);
1467 }
1468 return snxt;
1469}
1470
1471////////////////////////////////////////////////////////////////////////////////
1472/// Compute distance from a given point outside to the shape.
1473
1475 Double_t *safe) const
1476{
1478 if (iact < 3 && safe) {
1479 // compute safe distance
1480 *safe = Safety(point, kFALSE);
1481 if (iact == 0)
1482 return TGeoShape::Big();
1483 if (iact == 1 && step < *safe)
1484 return TGeoShape::Big();
1485 }
1486 TGeoBoolNode *node = (TGeoBoolNode *)this;
1487 Double_t lpt[3], rpt[3], master[3], ldir[3], rdir[3];
1488 memcpy(master, point, 3 * sizeof(Double_t));
1489 Int_t i;
1490 Double_t d1 = 0.;
1491 Double_t d2 = 0.;
1492 fLeftMat->MasterToLocal(point, lpt);
1493 fRightMat->MasterToLocal(point, rpt);
1498 node->SetSelected(0);
1499 Double_t snext = 0.0;
1500 if (inleft && inright) {
1501 // It is vey likely to have a numerical issue and the point should
1502 // be logically outside one of the shapes
1503 d1 = fLeft->DistFromInside(lpt, ldir, 3);
1505 if (d1 < 1.E-3)
1506 inleft = kFALSE;
1507 if (d2 < 1.E-3)
1508 inright = kFALSE;
1509 if (inleft && inright)
1510 return snext;
1511 }
1512
1513 while (true) {
1514 d1 = d2 = 0;
1515 if (!inleft) {
1517 d1 = TMath::Max(d1, tol);
1518 if (d1 > 1E20)
1519 return TGeoShape::Big();
1520 }
1521 if (!inright) {
1523 d2 = TMath::Max(d2, tol);
1524 if (d2 > 1E20)
1525 return TGeoShape::Big();
1526 }
1527
1528 if (d1 > d2) {
1529 // propagate to left shape
1530 snext += d1;
1531 node->SetSelected(1);
1532 inleft = kTRUE;
1533 for (i = 0; i < 3; i++)
1534 master[i] += d1 * dir[i];
1536 // Push rpt to avoid a bad boundary condition
1537 for (i = 0; i < 3; i++)
1538 rpt[i] += tol * rdir[i];
1539 // check if propagated point is inside right shape
1541 if (inright)
1542 return snext;
1543 // here inleft=true, inright=false
1544 } else {
1545 // propagate to right shape
1546 snext += d2;
1547 node->SetSelected(2);
1548 inright = kTRUE;
1549 for (i = 0; i < 3; i++)
1550 master[i] += d2 * dir[i];
1552 // Push lpt to avoid a bad boundary condition
1553 for (i = 0; i < 3; i++)
1554 lpt[i] += tol * ldir[i];
1555 // check if propagated point is inside left shape
1557 if (inleft)
1558 return snext;
1559 // here inleft=false, inright=true
1560 }
1561 }
1562 return snext;
1563}
1564
1565////////////////////////////////////////////////////////////////////////////////
1566/// Compute safety distance for a union node;
1567
1569{
1570 Double_t local1[3], local2[3];
1571 fLeftMat->MasterToLocal(point, local1);
1575 Bool_t intrue = in1 & in2;
1576 if (in ^ intrue)
1577 return 0.0;
1580 if (in1 && in2)
1581 return TMath::Min(saf1, saf2);
1582 if (in1)
1583 return saf2;
1584 if (in2)
1585 return saf1;
1586 return TMath::Max(saf1, saf2);
1587}
1588
1589////////////////////////////////////////////////////////////////////////////////
1590/// Save a primitive as a C++ statement(s) on output stream "out".
1591
1592void TGeoIntersection::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1593{
1595 out << " pBoolNode = new TGeoIntersection(";
1596 out << fLeft->GetPointerName() << ",";
1597 out << fRight->GetPointerName() << ",";
1598 if (!fLeftMat->IsIdentity())
1599 out << fLeftMat->GetPointerName() << ",";
1600 else
1601 out << "0,";
1602 if (!fRightMat->IsIdentity())
1603 out << fRightMat->GetPointerName() << ");" << std::endl;
1604 else
1605 out << "0);" << std::endl;
1606}
1607
1608////////////////////////////////////////////////////////////////////////////////
1609/// Register 3D size of this shape.
1610
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:538
float xmin
float ymin
float xmax
float ymax
#define gPad
Generic 3D primitive description class.
Definition TBuffer3D.h:18
@ kCSDifference
Definition TBuffer3D.h:43
@ kCSIntersection
Definition TBuffer3D.h:43
Box class.
Definition TGeoBBox.h:18
Base class for Boolean operations between two shapes.
virtual void Sizeof3D() const
Register size of this 3D object.
Bool_t MakeBranch(const char *expr, Bool_t left)
Flag for mesh cache validity.
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
Bool_t fMeshValid
Mutex for thread data access.
Double_t * fPoints
number of points on the mesh
void InvalidateMeshCaches()
Invalidate mesh caching recursively.
TGeoBoolNode()
Default constructor.
Int_t GetNpoints()
Returns number of vertices for the composite shape described by this node.
TGeoMatrix * fRightMat
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:459
Int_t DistanceToPrimitive(Int_t px, Int_t py) override
Compute minimum distance to shape vertices.
TGeoBoolNode * MakeClone() const override
Make a clone of this. Pointers are preserved.
TGeoIntersection()
Default constructor.
void Sizeof3D() const override
Register 3D size of this shape.
void ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin) override
Compute bounding box corresponding to a intersection of two shapes.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point outside to the shape.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Compute safety distance for a union node;.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point inside to the shape boundary.
void Paint(Option_t *option) override
Paint method.
~TGeoIntersection() override
Destructor — deletion of components handled by TGeoManager class.
Bool_t Contains(const Double_t *point) const override
Find if a intersection of two shapes contains a given point.
TObjArray * GetListOfMatrices() const
static Int_t Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
Parse a string boolean expression and do a syntax check.
TObjArray * GetListOfShapes() const
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Geometrical transformation package.
Definition TGeoMatrix.h:39
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Bool_t IsIdentity() const
Definition TGeoMatrix.h:64
const char * GetPointerName() const
Provide a pointer name containing uid.
Base abstract class for all shapes.
Definition TGeoShape.h:25
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Stub implementation to avoid forcing implementation at this stage.
static Double_t Big()
Definition TGeoShape.h:95
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const =0
virtual void CreateThreadData(Int_t)
Definition TGeoShape.h:75
Bool_t IsValid() const
Definition TGeoShape.h:153
virtual Int_t GetNmeshVertices() const
Definition TGeoShape.h:135
virtual void Sizeof3D() const =0
virtual Bool_t IsComposite() const
Definition TGeoShape.h:139
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const =0
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const =0
const char * GetPointerName() const
Provide a pointer name containing uid.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const =0
const char * GetName() const override
Get the shape name.
virtual void ComputeBBox()=0
static TGeoMatrix * GetTransform()
Returns current transformation matrix that applies to shape.
virtual Bool_t Contains(const Double_t *point) const =0
@ kGeoHalfSpace
Definition TGeoShape.h:62
static Double_t Tolerance()
Definition TGeoShape.h:98
virtual void SetPoints(Double_t *points) const =0
Bool_t TestShapeBit(UInt_t f) const
Definition TGeoShape.h:177
TGeoSubtraction()
Default constructor.
void ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin) override
Compute bounding box corresponding to a subtraction of two shapes.
~TGeoSubtraction() override
Destructor — deletion of components handled by TGeoManager class.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Compute safety distance for a union node;.
TGeoBoolNode * MakeClone() const override
Make a clone of this. Pointers are preserved.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point outside to the shape.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
Bool_t Contains(const Double_t *point) const override
Find if a subtraction of two shapes contains a given point.
void Sizeof3D() const override
Register 3D size of this shape.
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=0, Double_t *safe=nullptr) const override
Compute distance from a given point inside to the shape boundary.
void Paint(Option_t *option) override
Paint method.
Int_t DistanceToPrimitive(Int_t px, Int_t py) override
Compute minimum distance to shape vertices.
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Normal computation in POINT. The orientation is chosen so that DIR.dot.NORM>0.
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:1074
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:852
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1088
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1116
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:249
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:413
TGeoShape::EInside Inside(const Double_t *point, Solid const *solid)
Generic implementation of the inside function using just Contains and GetNormal.
Definition TGeoShape.h:187