ROOT logo
// @(#)root/geom:$Id$
// Author: Andrei Gheata   09-02-03

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TVirtualPad.h"
#include "TMath.h"
#include "TNamed.h"
#include "TBrowser.h"
#include "TGeoManager.h"
#include "TGeoVolume.h"
#include "TGeoNode.h"
#include "TGeoBBox.h"
#include "TRandom3.h"
#include "TPolyMarker3D.h"
#include "TVirtualGeoPainter.h"

#include "TGeoOverlap.h"

ClassImp(TGeoOverlap)

//______________________________________________________________________________
// TGeoOverlap - base class describing geometry overlaps. Overlaps apply
//   to the nodes contained inside a volume. These should not overlap to
//   each other nor extrude the shape of their mother volume.
//______________________________________________________________________________

//______________________________________________________________________________
TGeoOverlap::TGeoOverlap()
{
// Default ctor.
   fOverlap = 0;
   fVolume1 = 0;
   fVolume2 = 0;
   fMatrix1 = 0;
   fMatrix2 = 0;
   fMarker  = 0;
}

//______________________________________________________________________________
TGeoOverlap::TGeoOverlap(const char *name, TGeoVolume *vol1, TGeoVolume *vol2,
                         const TGeoMatrix *matrix1, const TGeoMatrix *matrix2,
                         Bool_t isovlp, Double_t ovlp)
            :TNamed("",name)
{
// Creates a named overlap belonging to volume VOL and having the size OVLP.
   fOverlap = ovlp;
   fVolume1  = vol1;
   fVolume2  = vol2;
   fMatrix1 = new TGeoHMatrix();
   *fMatrix1 = matrix1;
   fMatrix2 = new TGeoHMatrix();
   *fMatrix2 = matrix2;
   fMarker  = new TPolyMarker3D();
   fMarker->SetMarkerColor(2);
   SetIsOverlap(isovlp);
   fMarker->SetMarkerStyle(6);
//   fMarker->SetMarkerSize(0.5);
}

//______________________________________________________________________________
TGeoOverlap::~TGeoOverlap()
{
// Destructor.
   if (fMarker) delete fMarker;
   if (fMatrix1) delete fMatrix1;
   if (fMatrix2) delete fMatrix2;
}

//______________________________________________________________________________
void TGeoOverlap::Browse(TBrowser *b)
{
// Define double-click action
   if (!b) return;
   Draw();
}

//______________________________________________________________________________
Int_t TGeoOverlap::Compare(const TObject *obj) const
{
// Method to compare this overlap with another. Returns :
//   -1 - this is smaller than OBJ
//    0 - equal
//    1 - greater 
   TGeoOverlap *other = 0;
   other = (TGeoOverlap*)obj;
   if (!other) {
      Error("Compare", "other object is not TGeoOverlap");
      return 0;
   }
   if (IsExtrusion()) {
      if (other->IsExtrusion()) return (fOverlap<=other->GetOverlap())?1:-1;
      return -1;
   } else {   
      if (other->IsExtrusion()) return 1;
      return (fOverlap<=other->GetOverlap())?1:-1;
   }
}

//______________________________________________________________________________
Int_t TGeoOverlap::DistancetoPrimitive(Int_t px, Int_t py)
{
// Distance to primitive for an overlap.
   return fVolume1->GetGeoManager()->GetGeomPainter()->DistanceToPrimitiveVol(fVolume1, px, py);
}

//______________________________________________________________________________
void TGeoOverlap::Draw(Option_t *option)
{
// Draw the overlap. One daughter will be blue, the other green,
// extruding points red.
   fVolume1->GetGeoManager()->GetGeomPainter()->DrawOverlap(this, option);
   PrintInfo();
}

//______________________________________________________________________________
void TGeoOverlap::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
// Event interception.
   fVolume1->GetGeoManager()->GetGeomPainter()->ExecuteVolumeEvent(fVolume1, event, px, py);
}

//______________________________________________________________________________
void TGeoOverlap::Paint(Option_t *option)
{
// Paint the overlap.
   fVolume1->GetGeoManager()->GetGeomPainter()->PaintOverlap(this, option);
}

//______________________________________________________________________________
void TGeoOverlap::Print(Option_t *) const
{
// Print detailed info.
   PrintInfo();
   printf(" - first volume: %s at position:\n", fVolume1->GetName());
   fMatrix1->Print();   
   fVolume1->InspectShape();   
   printf(" - second volume: %s at position:\n", fVolume2->GetName());
   fMatrix2->Print();   
   fVolume2->InspectShape();   
}

//______________________________________________________________________________
void TGeoOverlap::PrintInfo() const
{
// Print some info.
   printf(" = Overlap %s: %s ovlp=%g\n", GetName(), GetTitle(),fOverlap);
}

//______________________________________________________________________________
void TGeoOverlap::SetNextPoint(Double_t x, Double_t y, Double_t z)
{
// Set next overlapping point.
   fMarker->SetNextPoint(x,y,z);
}

//______________________________________________________________________________
void TGeoOverlap::SampleOverlap(Int_t npoints)
{
// Draw overlap and sample with random points the overlapping region.
   Draw();
   // Select bounding box of the second volume (may extrude first)
   TPolyMarker3D *marker = 0;
   TGeoBBox *box = (TGeoBBox*)fVolume2->GetShape();
   Double_t dx = box->GetDX();
   Double_t dy = box->GetDY();
   Double_t dz = box->GetDZ();
   Double_t pt[3];
   Double_t master[3];
   const Double_t *orig = box->GetOrigin();
   Int_t ipoint = 0;
   Int_t itry = 0;
   Int_t iovlp = 0;
   while (ipoint < npoints) {
   // Shoot randomly in the bounding box.
      pt[0] = orig[0] - dx + 2.*dx*gRandom->Rndm();
      pt[1] = orig[1] - dy + 2.*dy*gRandom->Rndm();
      pt[2] = orig[2] - dz + 2.*dz*gRandom->Rndm();
      if (!fVolume2->Contains(pt)) {
         itry++;
         if (itry>10000 && !ipoint) {
            Error("SampleOverlap", "No point inside volume!!! - aborting");
            break;
         }
         continue;
      }  
      ipoint++;          
      // Check if the point is inside the first volume
      fMatrix2->LocalToMaster(pt, master);
      fMatrix1->MasterToLocal(master, pt);
      Bool_t in = fVolume1->Contains(pt);
      if (IsOverlap() && !in) continue;
      if (!IsOverlap() && in) continue;
      // The point is in the overlapping region.
      iovlp++;
      if (!marker) {
         marker = new TPolyMarker3D();
         marker->SetMarkerColor(kRed);
      }   
      marker->SetNextPoint(master[0], master[1], master[2]);
   }
   if (!iovlp) return;
   marker->Draw("SAME");
   gPad->Modified();
   gPad->Update();
   Double_t capacity = fVolume1->GetShape()->Capacity();
   capacity *= Double_t(iovlp)/Double_t(npoints);
   Double_t err = 1./TMath::Sqrt(Double_t(iovlp));
   Info("SampleOverlap", "#Overlap %s has %g +/- %g [cm3]",
         GetName(), capacity, err*capacity);
}        

//______________________________________________________________________________
void TGeoOverlap::Sizeof3D() const
{
// Get 3D size of this.
   fVolume1->GetShape()->Sizeof3D();
   fVolume2->GetShape()->Sizeof3D();
}

//______________________________________________________________________________
void TGeoOverlap::Validate() const
{
// Validate this overlap.
   Double_t point[3];
   Double_t local[3];
   Double_t safe1,safe2;
   Int_t npoints = fMarker->GetN();
   for (Int_t i=0; i<npoints; i++) {
      fMarker->GetPoint(i, point[0], point[1], point[2]);
      if (IsExtrusion()) {
         fMatrix1->MasterToLocal(point,local);
         safe1 = fVolume1->GetShape()->Safety(local, kFALSE);
         printf("point %d: safe1=%f\n", i, safe1);
      } else {
         fMatrix1->MasterToLocal(point,local);  
         safe1 = fVolume1->GetShape()->Safety(local, kTRUE);
         fMatrix2->MasterToLocal(point,local);  
         safe2 = fVolume2->GetShape()->Safety(local, kTRUE);
         printf("point %d: safe1=%f safe2=%f\n", i, safe1,safe2);
      }
   }
}
         
         
 TGeoOverlap.cxx:1
 TGeoOverlap.cxx:2
 TGeoOverlap.cxx:3
 TGeoOverlap.cxx:4
 TGeoOverlap.cxx:5
 TGeoOverlap.cxx:6
 TGeoOverlap.cxx:7
 TGeoOverlap.cxx:8
 TGeoOverlap.cxx:9
 TGeoOverlap.cxx:10
 TGeoOverlap.cxx:11
 TGeoOverlap.cxx:12
 TGeoOverlap.cxx:13
 TGeoOverlap.cxx:14
 TGeoOverlap.cxx:15
 TGeoOverlap.cxx:16
 TGeoOverlap.cxx:17
 TGeoOverlap.cxx:18
 TGeoOverlap.cxx:19
 TGeoOverlap.cxx:20
 TGeoOverlap.cxx:21
 TGeoOverlap.cxx:22
 TGeoOverlap.cxx:23
 TGeoOverlap.cxx:24
 TGeoOverlap.cxx:25
 TGeoOverlap.cxx:26
 TGeoOverlap.cxx:27
 TGeoOverlap.cxx:28
 TGeoOverlap.cxx:29
 TGeoOverlap.cxx:30
 TGeoOverlap.cxx:31
 TGeoOverlap.cxx:32
 TGeoOverlap.cxx:33
 TGeoOverlap.cxx:34
 TGeoOverlap.cxx:35
 TGeoOverlap.cxx:36
 TGeoOverlap.cxx:37
 TGeoOverlap.cxx:38
 TGeoOverlap.cxx:39
 TGeoOverlap.cxx:40
 TGeoOverlap.cxx:41
 TGeoOverlap.cxx:42
 TGeoOverlap.cxx:43
 TGeoOverlap.cxx:44
 TGeoOverlap.cxx:45
 TGeoOverlap.cxx:46
 TGeoOverlap.cxx:47
 TGeoOverlap.cxx:48
 TGeoOverlap.cxx:49
 TGeoOverlap.cxx:50
 TGeoOverlap.cxx:51
 TGeoOverlap.cxx:52
 TGeoOverlap.cxx:53
 TGeoOverlap.cxx:54
 TGeoOverlap.cxx:55
 TGeoOverlap.cxx:56
 TGeoOverlap.cxx:57
 TGeoOverlap.cxx:58
 TGeoOverlap.cxx:59
 TGeoOverlap.cxx:60
 TGeoOverlap.cxx:61
 TGeoOverlap.cxx:62
 TGeoOverlap.cxx:63
 TGeoOverlap.cxx:64
 TGeoOverlap.cxx:65
 TGeoOverlap.cxx:66
 TGeoOverlap.cxx:67
 TGeoOverlap.cxx:68
 TGeoOverlap.cxx:69
 TGeoOverlap.cxx:70
 TGeoOverlap.cxx:71
 TGeoOverlap.cxx:72
 TGeoOverlap.cxx:73
 TGeoOverlap.cxx:74
 TGeoOverlap.cxx:75
 TGeoOverlap.cxx:76
 TGeoOverlap.cxx:77
 TGeoOverlap.cxx:78
 TGeoOverlap.cxx:79
 TGeoOverlap.cxx:80
 TGeoOverlap.cxx:81
 TGeoOverlap.cxx:82
 TGeoOverlap.cxx:83
 TGeoOverlap.cxx:84
 TGeoOverlap.cxx:85
 TGeoOverlap.cxx:86
 TGeoOverlap.cxx:87
 TGeoOverlap.cxx:88
 TGeoOverlap.cxx:89
 TGeoOverlap.cxx:90
 TGeoOverlap.cxx:91
 TGeoOverlap.cxx:92
 TGeoOverlap.cxx:93
 TGeoOverlap.cxx:94
 TGeoOverlap.cxx:95
 TGeoOverlap.cxx:96
 TGeoOverlap.cxx:97
 TGeoOverlap.cxx:98
 TGeoOverlap.cxx:99
 TGeoOverlap.cxx:100
 TGeoOverlap.cxx:101
 TGeoOverlap.cxx:102
 TGeoOverlap.cxx:103
 TGeoOverlap.cxx:104
 TGeoOverlap.cxx:105
 TGeoOverlap.cxx:106
 TGeoOverlap.cxx:107
 TGeoOverlap.cxx:108
 TGeoOverlap.cxx:109
 TGeoOverlap.cxx:110
 TGeoOverlap.cxx:111
 TGeoOverlap.cxx:112
 TGeoOverlap.cxx:113
 TGeoOverlap.cxx:114
 TGeoOverlap.cxx:115
 TGeoOverlap.cxx:116
 TGeoOverlap.cxx:117
 TGeoOverlap.cxx:118
 TGeoOverlap.cxx:119
 TGeoOverlap.cxx:120
 TGeoOverlap.cxx:121
 TGeoOverlap.cxx:122
 TGeoOverlap.cxx:123
 TGeoOverlap.cxx:124
 TGeoOverlap.cxx:125
 TGeoOverlap.cxx:126
 TGeoOverlap.cxx:127
 TGeoOverlap.cxx:128
 TGeoOverlap.cxx:129
 TGeoOverlap.cxx:130
 TGeoOverlap.cxx:131
 TGeoOverlap.cxx:132
 TGeoOverlap.cxx:133
 TGeoOverlap.cxx:134
 TGeoOverlap.cxx:135
 TGeoOverlap.cxx:136
 TGeoOverlap.cxx:137
 TGeoOverlap.cxx:138
 TGeoOverlap.cxx:139
 TGeoOverlap.cxx:140
 TGeoOverlap.cxx:141
 TGeoOverlap.cxx:142
 TGeoOverlap.cxx:143
 TGeoOverlap.cxx:144
 TGeoOverlap.cxx:145
 TGeoOverlap.cxx:146
 TGeoOverlap.cxx:147
 TGeoOverlap.cxx:148
 TGeoOverlap.cxx:149
 TGeoOverlap.cxx:150
 TGeoOverlap.cxx:151
 TGeoOverlap.cxx:152
 TGeoOverlap.cxx:153
 TGeoOverlap.cxx:154
 TGeoOverlap.cxx:155
 TGeoOverlap.cxx:156
 TGeoOverlap.cxx:157
 TGeoOverlap.cxx:158
 TGeoOverlap.cxx:159
 TGeoOverlap.cxx:160
 TGeoOverlap.cxx:161
 TGeoOverlap.cxx:162
 TGeoOverlap.cxx:163
 TGeoOverlap.cxx:164
 TGeoOverlap.cxx:165
 TGeoOverlap.cxx:166
 TGeoOverlap.cxx:167
 TGeoOverlap.cxx:168
 TGeoOverlap.cxx:169
 TGeoOverlap.cxx:170
 TGeoOverlap.cxx:171
 TGeoOverlap.cxx:172
 TGeoOverlap.cxx:173
 TGeoOverlap.cxx:174
 TGeoOverlap.cxx:175
 TGeoOverlap.cxx:176
 TGeoOverlap.cxx:177
 TGeoOverlap.cxx:178
 TGeoOverlap.cxx:179
 TGeoOverlap.cxx:180
 TGeoOverlap.cxx:181
 TGeoOverlap.cxx:182
 TGeoOverlap.cxx:183
 TGeoOverlap.cxx:184
 TGeoOverlap.cxx:185
 TGeoOverlap.cxx:186
 TGeoOverlap.cxx:187
 TGeoOverlap.cxx:188
 TGeoOverlap.cxx:189
 TGeoOverlap.cxx:190
 TGeoOverlap.cxx:191
 TGeoOverlap.cxx:192
 TGeoOverlap.cxx:193
 TGeoOverlap.cxx:194
 TGeoOverlap.cxx:195
 TGeoOverlap.cxx:196
 TGeoOverlap.cxx:197
 TGeoOverlap.cxx:198
 TGeoOverlap.cxx:199
 TGeoOverlap.cxx:200
 TGeoOverlap.cxx:201
 TGeoOverlap.cxx:202
 TGeoOverlap.cxx:203
 TGeoOverlap.cxx:204
 TGeoOverlap.cxx:205
 TGeoOverlap.cxx:206
 TGeoOverlap.cxx:207
 TGeoOverlap.cxx:208
 TGeoOverlap.cxx:209
 TGeoOverlap.cxx:210
 TGeoOverlap.cxx:211
 TGeoOverlap.cxx:212
 TGeoOverlap.cxx:213
 TGeoOverlap.cxx:214
 TGeoOverlap.cxx:215
 TGeoOverlap.cxx:216
 TGeoOverlap.cxx:217
 TGeoOverlap.cxx:218
 TGeoOverlap.cxx:219
 TGeoOverlap.cxx:220
 TGeoOverlap.cxx:221
 TGeoOverlap.cxx:222
 TGeoOverlap.cxx:223
 TGeoOverlap.cxx:224
 TGeoOverlap.cxx:225
 TGeoOverlap.cxx:226
 TGeoOverlap.cxx:227
 TGeoOverlap.cxx:228
 TGeoOverlap.cxx:229
 TGeoOverlap.cxx:230
 TGeoOverlap.cxx:231
 TGeoOverlap.cxx:232
 TGeoOverlap.cxx:233
 TGeoOverlap.cxx:234
 TGeoOverlap.cxx:235
 TGeoOverlap.cxx:236
 TGeoOverlap.cxx:237
 TGeoOverlap.cxx:238
 TGeoOverlap.cxx:239
 TGeoOverlap.cxx:240
 TGeoOverlap.cxx:241
 TGeoOverlap.cxx:242
 TGeoOverlap.cxx:243
 TGeoOverlap.cxx:244
 TGeoOverlap.cxx:245
 TGeoOverlap.cxx:246
 TGeoOverlap.cxx:247
 TGeoOverlap.cxx:248
 TGeoOverlap.cxx:249
 TGeoOverlap.cxx:250
 TGeoOverlap.cxx:251