diff --git a/geom/inc/TGeoMatrix.h b/geom/inc/TGeoMatrix.h
index b629abaff06561f4081fefddee48f6eb57a0825c..3c86b53215065db2e97a4bc0b621dbc20399b0eb 100644
--- a/geom/inc/TGeoMatrix.h
+++ b/geom/inc/TGeoMatrix.h
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoMatrix.h,v 1.22 2005/10/03 06:54:51 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoMatrix.h,v 1.23 2005/11/18 16:07:58 brun Exp $
 // Author: Andrei Gheata   25/10/01
 
 /*************************************************************************
@@ -184,6 +184,7 @@ public :
    void                 FastRotZ(Double_t *sincos);
    void                 GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2,
                                   Double_t &theta3, Double_t &phi3) const;
+   void                 GetAngles(Double_t &phi, Double_t &theta, Double_t &psi) const;
    Double_t             GetPhiRotation(Bool_t fixX=kFALSE) const;
    virtual void         LocalToMaster(const Double_t *local, Double_t *master) const;
    virtual void         LocalToMasterVect(const Double_t *local, Double_t *master) const {TGeoRotation::LocalToMaster(local, master);}
@@ -196,7 +197,7 @@ public :
    virtual void         RotateY(Double_t angle);
    virtual void         RotateZ(Double_t angle);
    virtual void         SavePrimitive(ofstream &out, Option_t *option);
-   void                 SetAngles(Double_t alpha, Double_t beta, Double_t gamma);
+   void                 SetAngles(Double_t phi, Double_t theta, Double_t psi);
    void                 SetAngles(Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
                                   Double_t theta3, Double_t phi3);
    void                 SetMatrix(const Double_t *rot) {memcpy(&fRotationMatrix[0], rot, 9*sizeof(Double_t));CheckMatrix();}
diff --git a/geom/inc/TGeoNode.h b/geom/inc/TGeoNode.h
index 75495cb152293e55964ca9332e68ae5686d9165e..2e45ee17de87139b2cfeff05da7b8018f6770f9a 100644
--- a/geom/inc/TGeoNode.h
+++ b/geom/inc/TGeoNode.h
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoNode.h,v 1.20 2006/01/31 14:02:36 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoNode.h,v 1.21 2006/02/08 11:03:06 brun Exp $
 // Author: Andrei Gheata   24/10/01
 
 /*************************************************************************
@@ -37,6 +37,7 @@
 #endif
 
 // forward declarations
+class TString;
 class TGeoVolume;
 class TGeoShape;
 class TGeoMedium;
@@ -106,6 +107,7 @@ public:
    Bool_t            IsVirtual() const {return TObject::TestBit(kGeoNodeVC);}
    Bool_t            IsVisible() const {return (TGeoAtt::IsVisible() && fVolume->IsVisible());}
    Bool_t            IsVisDaughters() const {return (TGeoAtt::IsVisDaughters() && fVolume->IsVisDaughters());}
+   Bool_t            MayOverlap(Int_t iother) const;
 
    virtual TGeoNode *MakeCopyNode() const {return 0;}
    Double_t          Safety(Double_t *point, Bool_t in=kTRUE) const;
@@ -200,14 +202,18 @@ class TGeoIterator
 {
 private:
    TGeoVolume       *fTop;                  // Top volume of the iterated branch
+   Bool_t            fMustResume;           // Private flag to resume from current node.
+   Bool_t            fMustStop;             // Private flag to signal that the iterator has finished.
    Int_t             fLevel;                // Current level in the tree
    Int_t             fType;                 // Type of iteration
    Int_t            *fArray;                // Array of node indices for the current path
    TGeoHMatrix      *fMatrix;               // Current global matrix
+   TString           fTopName;              // User name for top
 
    void            IncreaseArray();
 protected:
-   TGeoIterator() : fTop(0), fLevel(0), fType(0), fArray(0), fMatrix(0) { }
+   TGeoIterator() : fTop(0), fMustResume(0), fMustStop(0),
+                    fLevel(0), fType(0), fArray(0), fMatrix(0), fTopName() { }
 
 public:
    TGeoIterator(TGeoVolume *top);
@@ -222,10 +228,13 @@ public:
    Int_t           GetIndex(Int_t i) const {return ((i<=fLevel)?fArray[i]:-1);}
    Int_t           GetLevel() const {return fLevel;}
    TGeoNode       *GetNode(Int_t level) const;
+   void            GetPath(TString &path) const;
    TGeoVolume     *GetTopVolume() const {return fTop;}
    Int_t           GetType() const {return fType;}
    void            Reset(TGeoVolume *top=0);
    void            SetType(Int_t type) {fType = type;}
+   void            SetTopName(const char* name);
+   void            Skip();
    
    ClassDef(TGeoIterator,0)  //Iterator for geometry.
 };
diff --git a/geom/src/TGeoMatrix.cxx b/geom/src/TGeoMatrix.cxx
index 03e32be3954c0dff16fb815594d32ca87b19db9c..5117353f784a33d94a0677350de519e8d86c9d2a 100644
--- a/geom/src/TGeoMatrix.cxx
+++ b/geom/src/TGeoMatrix.cxx
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoMatrix.cxx,v 1.47 2005/11/21 09:31:47 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoMatrix.cxx,v 1.48 2006/01/20 10:35:18 brun Exp $
 // Author: Andrei Gheata   25/10/01
 
 /*************************************************************************
@@ -1054,6 +1054,27 @@ void TGeoRotation::GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2,
    if (phi3<0) phi3+=360.;
 }
 
+//_____________________________________________________________________________
+void TGeoRotation::GetAngles(Double_t &phi, Double_t &theta, Double_t &psi) const
+{
+// Retreive Euler angles.
+   const Double_t *m = fRotationMatrix;
+   // Check if theta is 0 or 180.
+   if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) {      
+      theta = TMath::ACos(m[8])*TMath::RadToDeg();
+      phi = TMath::ATan2(-m[8]*m[1],m[0])*TMath::RadToDeg();
+      psi = 0.; // convention, phi+psi matters
+      return;
+   }
+   // sin(theta) != 0
+   phi = TMath::ATan2(m[2],-m[5]);
+   Double_t sphi = TMath::Sin(phi);
+   if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*TMath::RadToDeg();
+   else theta = TMath::ASin(m[2]/sphi)*TMath::RadToDeg();
+   phi *= TMath::RadToDeg();      
+   psi = TMath::ATan2(m[6],m[7])*TMath::RadToDeg();
+}   
+
 //_____________________________________________________________________________
 Double_t TGeoRotation::Determinant() const
 {
diff --git a/geom/src/TGeoNode.cxx b/geom/src/TGeoNode.cxx
index 7227299af572ad2109bb8d4d60d3eace2c000329..fc7b8054cf01f8ab6726e9119f2eb700fe278f40 100644
--- a/geom/src/TGeoNode.cxx
+++ b/geom/src/TGeoNode.cxx
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoNode.cxx,v 1.30 2006/01/31 14:02:36 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoNode.cxx,v 1.31 2006/02/08 11:03:06 brun Exp $
 // Author: Andrei Gheata   24/10/01
 
 /*************************************************************************
@@ -388,6 +388,16 @@ void TGeoNode::SaveAttributes(ofstream &out)
    }
 }
 
+//_____________________________________________________________________________
+Bool_t TGeoNode::MayOverlap(Int_t iother) const 
+{
+// Check the overlab between the bounding box of the node overlaps with the one
+// the brother with index IOTHER.
+   if (!fOverlaps) return kFALSE;
+   for (Int_t i=0; i<fNovlp; i++) if (fOverlaps[i]==iother) return kTRUE;
+   return kFALSE;
+}   
+
 //_____________________________________________________________________________
 void TGeoNode::MasterToLocal(const Double_t *master, Double_t *local) const
 {
@@ -481,7 +491,7 @@ void TGeoNode::PrintCandidates() const
 void TGeoNode::PrintOverlaps() const
 {
 // print possible overlapping nodes
-   if (!IsOverlapping()) {printf("node %s is ONLY\n", GetName()); return;}
+//   if (!IsOverlapping()) {printf("node %s is ONLY\n", GetName()); return;}
    if (!fOverlaps) {printf("node %s no overlaps\n", GetName()); return;}
    printf("Overlaps for node %s :\n", GetName());
    TGeoNode *node;
@@ -749,9 +759,12 @@ TGeoIterator::TGeoIterator(TGeoVolume *top)
 // Geometry iterator for a branch starting with a TOP node.
    fTop = top;
    fLevel = 0;
+   fMustResume = kFALSE;
+   fMustStop = kFALSE;
    fType = 0;
    fArray = new Int_t[30];
    fMatrix = new TGeoHMatrix();
+   fTopName = fTop->GetName();
 }   
 
 //_____________________________________________________________________________
@@ -760,10 +773,13 @@ TGeoIterator::TGeoIterator(const TGeoIterator &iter)
 // Copy ctor.
    fTop = iter.GetTopVolume();
    fLevel = iter.GetLevel();
+   fMustResume = kFALSE;
+   fMustStop = kFALSE;
    fType = iter.GetType();
    fArray = new Int_t[30+ 30*Int_t(fLevel/30)];
    for (Int_t i=0; i<fLevel+1; i++) fArray[i] = iter.GetIndex(i);
    fMatrix = new TGeoHMatrix(*iter.GetCurrentMatrix());
+   fTopName = fTop->GetName();
 }
 
 //_____________________________________________________________________________
@@ -780,12 +796,15 @@ TGeoIterator &TGeoIterator::operator=(const TGeoIterator &iter)
 // Assignment.
    fTop = iter.GetTopVolume();
    fLevel = iter.GetLevel();
+   fMustResume = kFALSE;
+   fMustStop = kFALSE;
    fType = iter.GetType();
    if (fArray) delete [] fArray;
    fArray = new Int_t[30+ 30*Int_t(fLevel/30)];
    for (Int_t i=0; i<fLevel+1; i++) fArray[i] = iter.GetIndex(i);
    if (!fMatrix) fMatrix = new TGeoHMatrix();
    *fMatrix = *iter.GetCurrentMatrix();
+   fTopName = fTop->GetName();
    return *this;   
 }   
 
@@ -793,11 +812,15 @@ TGeoIterator &TGeoIterator::operator=(const TGeoIterator &iter)
 TGeoNode *TGeoIterator::Next()
 {
 // Returns next node.
+   if (fMustStop) return 0;
    TGeoNode *mother = 0;
    TGeoNode *next = 0;
    Int_t i;
    Int_t nd = fTop->GetNdaughters();
-   if (!nd) return 0;
+   if (!nd) {
+      fMustStop = kTRUE;
+      return 0;
+   }   
    if (!fLevel) {
       fArray[++fLevel] = 0;
       next = fTop->GetNode(0);
@@ -809,6 +832,10 @@ TGeoNode *TGeoIterator::Next()
       mother = next;
       next = mother->GetDaughter(fArray[i]);
    }   
+   if (fMustResume) {
+      fMustResume = kFALSE;
+      return next;
+   }   
    
    switch (fType) {
       case 0:  // default next daughter behavior
@@ -826,6 +853,7 @@ TGeoNode *TGeoIterator::Next()
             if (!next) {
                nd = fTop->GetNdaughters();
                if (fArray[fLevel]<nd-1) return fTop->GetNode(++fArray[fLevel]);
+               fMustStop = kTRUE;
                return 0;
             } else {
                nd = next->GetNdaughters();
@@ -840,9 +868,8 @@ TGeoNode *TGeoIterator::Next()
             if (!mother) return fTop->GetNode(++fArray[fLevel]);
             else return mother->GetDaughter(++fArray[fLevel]);
          }
-      default:
-         return 0;      
    }
+   fMustStop = kTRUE;
    return 0;
 }
    
@@ -878,6 +905,22 @@ TGeoNode *TGeoIterator::GetNode(Int_t level) const
    return node;
 }
 
+//_____________________________________________________________________________
+void TGeoIterator::GetPath(TString &path) const
+{
+// Returns the path for the current node.
+   path = fTopName;
+   if (!fLevel) return;
+   TGeoNode *node = fTop->GetNode(fArray[1]);
+   path += "/";
+   path += node->GetName();
+   for (Int_t i=2; i<fLevel+1; i++) {
+      node = node->GetDaughter(fArray[i]);
+      path += "/";
+      path += node->GetName();
+   }   
+}      
+
 //_____________________________________________________________________________
 void TGeoIterator::IncreaseArray() 
 {
@@ -894,4 +937,51 @@ void TGeoIterator::Reset(TGeoVolume *top)
 // Resets the iterator for volume TOP.
    if (top) fTop = top;
    fLevel = 0;
+   fMustResume = kFALSE;
+   fMustStop = kFALSE;
 }      
+
+//_____________________________________________________________________________
+void TGeoIterator::SetTopName(const char *name)
+{
+// Set the top name for path
+   fTopName = name;
+}   
+
+//_____________________________________________________________________________
+void TGeoIterator::Skip()
+{
+// Stop iterating the current branch. The iteration of the next node will
+// behave as if the branch starting from the current node (included) is not existing.
+   fMustResume = kTRUE;
+   TGeoNode *next = GetNode(fLevel);
+   if (!next) return;
+   Int_t nd;
+   switch (fType) {
+      case 0:  // default next daughter behavior
+         // cd up and pick next
+         while (next) {
+            next = GetNode(fLevel-1);
+            nd = (next==0)?fTop->GetNdaughters():next->GetNdaughters();
+            if (fArray[fLevel]<nd-1) {
+               ++fArray[fLevel];
+               return;
+            }
+            fLevel--;
+            if (!fLevel) {
+               fMustStop = kTRUE;
+               return;
+            }   
+         }     
+         break;
+      case 1:  // one level search
+         next = GetNode(fLevel-1);
+         nd = (next==0)?fTop->GetNdaughters():next->GetNdaughters();
+         if (fArray[fLevel]<nd-1) {
+            ++fArray[fLevel];
+            return;
+         }
+         fMustStop = kTRUE;   
+         break;
+   }
+}         
diff --git a/geom/src/TGeoVoxelFinder.cxx b/geom/src/TGeoVoxelFinder.cxx
index 95605fac13a9c5df76e4a2e6935710770f1efc94..d5cf6b0941ca76c5209d67fb51111ecbb9d44d58 100644
--- a/geom/src/TGeoVoxelFinder.cxx
+++ b/geom/src/TGeoVoxelFinder.cxx
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoVoxelFinder.cxx,v 1.31 2006/02/01 13:30:37 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoVoxelFinder.cxx,v 1.32 2006/02/03 17:07:34 brun Exp $
 // Author: Andrei Gheata   04/02/02
 
 /*************************************************************************
@@ -298,48 +298,34 @@ void TGeoVoxelFinder::FindOverlaps(Int_t inode) const
    Int_t *otmp = new Int_t[nd-1]; 
    Int_t novlp = 0;
    TGeoNode *node = fVolume->GetNode(inode);
-//   printf("Finding overlaps for %s\n", node->GetName());
    xmin = fBoxes[6*inode+3] - fBoxes[6*inode];
    xmax = fBoxes[6*inode+3] + fBoxes[6*inode];
    ymin = fBoxes[6*inode+4] - fBoxes[6*inode+1];
    ymax = fBoxes[6*inode+4] + fBoxes[6*inode+1];
    zmin = fBoxes[6*inode+5] - fBoxes[6*inode+2];
    zmax = fBoxes[6*inode+5] + fBoxes[6*inode+2];
-//   printf("overlaps for MANY node %s\n", node->GetName());
-
-//   printf("xmin=%g  xmax=%g\n", xmin, xmax);
-//   printf("ymin=%g  ymax=%g\n", ymin, ymax);
-//   printf("zmin=%g  zmax=%g\n", zmin, zmax);
-   //TGeoNode *node1;
    // loop on brothers
    for (Int_t ib=0; ib<nd; ib++) {
       if (ib == inode) continue; // everyone overlaps with itself
-      //node1 = fVolume->GetNode(ib);
       xmin1 = fBoxes[6*ib+3] - fBoxes[6*ib];
       xmax1 = fBoxes[6*ib+3] + fBoxes[6*ib];
       ymin1 = fBoxes[6*ib+4] - fBoxes[6*ib+1];
       ymax1 = fBoxes[6*ib+4] + fBoxes[6*ib+1];
       zmin1 = fBoxes[6*ib+5] - fBoxes[6*ib+2];
       zmax1 = fBoxes[6*ib+5] + fBoxes[6*ib+2];
-//      printf(" node %s\n", node1->GetName());
-//      printf("  xmin1=%g  xmax1=%g\n", xmin1, xmax1);
-//      printf("  ymin1=%g  ymax1=%g\n", ymin1, ymax1);
-//      printf("  zmin1=%g  zmax1=%g\n", zmin1, zmax1);
-
 
-      ddx1 = xmin1-xmax;
+      ddx1 = xmax-xmin1;
       ddx2 = xmax1-xmin;
-      if ((ddx1>-1E-10)||(ddx2<1E-10)) continue;
-      ddx1 = ymin1-ymax;
+      if (ddx1*ddx2 <= 0.) continue;
+      ddx1 = ymax-ymin1;
       ddx2 = ymax1-ymin;
-      if ((ddx1>-1E-10)||(ddx2<1E-10)) continue;
-      ddx1 = zmin1-zmax;
+      if (ddx1*ddx2 <= 0.) continue;
+      ddx1 = zmax-zmin1;
       ddx2 = zmax1-zmin;
-      if ((ddx1>-1E-10)||(ddx2<1E-10)) continue;
+      if (ddx1*ddx2 <= 0.) continue;
       otmp[novlp++] = ib;
    }
    if (!novlp) {
-//      printf("---no overlaps for MANY node %s\n", node->GetName());
       delete [] otmp;
       node->SetOverlaps(ovlps, 0);
       return;
@@ -348,8 +334,8 @@ void TGeoVoxelFinder::FindOverlaps(Int_t inode) const
    memcpy(ovlps, otmp, novlp*sizeof(Int_t));
    delete [] otmp;
    node->SetOverlaps(ovlps, novlp);
-//   printf("Overlaps for MANY node %s : %i\n", node->GetName(), novlp);
 }
+
 //-----------------------------------------------------------------------------
 Bool_t TGeoVoxelFinder::GetIndices(Double_t *point)
 {
diff --git a/geompainter/inc/LinkDef.h b/geompainter/inc/LinkDef.h
index 0e7ccd318095ea67943d02bd608dcaaa09fcf493..a3fca0042f4a2161e95beffa8cbcc21213b01e81 100644
--- a/geompainter/inc/LinkDef.h
+++ b/geompainter/inc/LinkDef.h
@@ -16,8 +16,6 @@
 #pragma link C++ class TGeoPainter+;
 #pragma link C++ class TGeoChecker+;
 #pragma link C++ class TGeoOverlap+;
-#pragma link C++ class TGeoNodeOverlap+;
-#pragma link C++ class TGeoExtrusion+;
 #pragma link C++ class TGeoTrack+;
 
 #endif
diff --git a/geompainter/inc/TGeoChecker.h b/geompainter/inc/TGeoChecker.h
index 6dc988d8d6152e5c7f745fc3af168fbd1b02a9b0..f3199be6221c58d743bc6c07d3d30354fddbdf2c 100644
--- a/geompainter/inc/TGeoChecker.h
+++ b/geompainter/inc/TGeoChecker.h
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoChecker.h,v 1.13 2005/04/25 07:53:27 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoChecker.h,v 1.14 2005/11/18 16:07:59 brun Exp $
 // Author: Andrei Gheata   01/11/01
 
 /*************************************************************************
@@ -22,6 +22,9 @@ class TGeoVolume;
 class TGeoVoxelFinder;
 class TGeoNode;
 class TGeoManager;
+class TGeoMatrix;
+class TGeoOverlap;
+class TBuffer3D;
 class TH2F;
 
 /*************************************************************************
@@ -37,6 +40,8 @@ private :
 // data members
    TGeoManager     *fGeoManager;      // pointer to geometry manager
    TGeoVolume      *fVsafe;           // volume to which a safety sphere node was added
+   TBuffer3D       *fBuff1;           // Buffer containing mesh vertices for first volume
+   TBuffer3D       *fBuff2;           // Buffer containing mesh vertices for second volume
 // methods
 
 public:
@@ -57,6 +62,7 @@ public:
    void             PrintOverlaps() const;
    void             RandomPoints(TGeoVolume *vol, Int_t npoints, Option_t *option);
    void             RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz);
+   TGeoOverlap     *MakeCheckOverlap(const char *name, TGeoVolume *vol1, TGeoVolume *vol2, TGeoMatrix *mat1, TGeoMatrix *mat2, Bool_t isovlp, Double_t ovlp);
    TGeoNode        *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path);
    void             ShootRay(Double_t *start, Double_t dirx, Double_t diry, Double_t dirz, Double_t *array, Int_t &nelem, Int_t &dim, Double_t *enpoint=0) const;
    //void             ShowPoints(Option_t *option="");
diff --git a/geompainter/inc/TGeoOverlap.h b/geompainter/inc/TGeoOverlap.h
index 183b21d1d8447bb42c84968429b7140cf9e4b194..b15351feaed682f3a8ad31cdc19c24590a46664d 100644
--- a/geompainter/inc/TGeoOverlap.h
+++ b/geompainter/inc/TGeoOverlap.h
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoOverlap.h,v 1.3 2003/02/13 11:04:18 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoOverlap.h,v 1.4 2005/11/18 16:07:59 brun Exp $
 // Author: Andrei Gheata   09/02/03
 
 /*************************************************************************
@@ -28,6 +28,10 @@
 #include "TAtt3D.h"
 #endif
 
+#ifndef ROOT_TGeoMatrix
+#include "TGeoMatrix.h"
+#endif
+
 class TGeoVolume;
 class TPolyMarker3D;
 class TBrowser;
@@ -44,86 +48,56 @@ class TGeoOverlap : public TNamed,
                     public TAttFill,
                     public TAtt3D
 {
+public:
+enum EOverlapType {
+   kGeoOverlap    = BIT(14),
+   kGeoExtrusion  = BIT(15)
+};
+   
 protected:
-   Double_t         fOverlap;    // overlap distance
-   TGeoVolume      *fVolume;     // volume containing the overlap
+   Double_t         fOverlap;     // overlap distance
+   TGeoVolume      *fVolume1;     // first volume
+   TGeoVolume      *fVolume2;     // second volume
+   TGeoHMatrix     *fMatrix1;     // positioning matrix for first volume
+   TGeoHMatrix     *fMatrix2;     // positioning matrix for second volume
    TPolyMarker3D   *fMarker;     // points in the overlapping region
 
 public:
    TGeoOverlap();
-   TGeoOverlap(const char *name, TGeoVolume *vol, Double_t ovlp);
+   TGeoOverlap(const char *name, TGeoVolume *vol1, TGeoVolume *vol2,
+               const TGeoMatrix *matrix1, const TGeoMatrix *matrix2,
+               Bool_t isovlp=kTRUE,  Double_t ovlp=0.01);
    virtual           ~TGeoOverlap();
    
    void              Browse(TBrowser *b);
    virtual Int_t     Compare(const TObject *obj) const;
    virtual Int_t     DistancetoPrimitive(Int_t px, Int_t py);
-   virtual void      Draw(Option_t *option="")                   = 0;
+   virtual void      Draw(Option_t *option=""); // *MENU*
    virtual void      ExecuteEvent(Int_t event, Int_t px, Int_t py);
    TPolyMarker3D    *GetPolyMarker() const {return fMarker;}
-   virtual TGeoNode *GetNode(Int_t iovlp) const                  = 0;
+   TGeoVolume       *GetFirstVolume() const {return fVolume1;}
+   TGeoVolume       *GetSecondVolume() const {return fVolume2;}
+   TGeoHMatrix      *GetFirstMatrix() const {return fMatrix1;}
+   TGeoHMatrix      *GetSecondMatrix() const {return fMatrix2;}
    Double_t          GetOverlap() const {return fOverlap;}
-   TGeoVolume       *GetVolume() const  {return fVolume;}
-   virtual Bool_t    IsExtrusion() const                         = 0;
+   Bool_t            IsExtrusion() const {return TObject::TestBit(kGeoExtrusion);}
+   Bool_t            IsOverlap() const {return TObject::TestBit(kGeoOverlap);}
    Bool_t            IsFolder() const {return kFALSE;}
    virtual Bool_t    IsSortable() const {return kTRUE;}
    virtual void      Paint(Option_t *option="");
-   virtual void      PrintInfo() const                           = 0;
-   virtual void      Sizeof3D() const                            = 0;
+   virtual void      PrintInfo() const;
+   virtual void      Sizeof3D() const;
+   void              SetIsExtrusion(Bool_t flag=kTRUE) {TObject::SetBit(kGeoExtrusion,flag); TObject::SetBit(kGeoOverlap,!flag);}
+   void              SetIsOverlap(Bool_t flag=kTRUE) {TObject::SetBit(kGeoOverlap,flag); TObject::SetBit(kGeoExtrusion,!flag);}
    void              SetNextPoint(Double_t x, Double_t y, Double_t z);
-   void              SetVolume(TGeoVolume *vol) {fVolume=vol;}
+   void              SetFirstVolume(TGeoVolume *vol) {fVolume1=vol;}
+   void              SetSecondVolume(TGeoVolume *vol) {fVolume2=vol;}
+   void              SetFirstMatrix(TGeoMatrix *matrix) {*fMatrix1 = matrix;}
+   void              SetSecondMatrix(TGeoMatrix *matrix) {*fMatrix2 = matrix;}
    void              SetOverlap(Double_t ovlp)  {fOverlap=ovlp;}
    
    ClassDef(TGeoOverlap, 1)         // base class for geometical overlaps
 };
- 
-/*************************************************************************
- *   TGeoExtrusion - class representing the extrusion of a positioned volume
- *      with respect to its mother.
- ************************************************************************/
- 
-class TGeoExtrusion : public TGeoOverlap
-{
-private:
-   TGeoNode        *fNode;        // extruding daughter
-
-public:
-   TGeoExtrusion();
-   TGeoExtrusion(const char *name, TGeoVolume *vol, Int_t inode, Double_t ovlp);
-   virtual           ~TGeoExtrusion() {;}
-   
-   virtual TGeoNode *GetNode(Int_t iovlp) const;
-   virtual Bool_t    IsExtrusion() const {return kTRUE;}
-   virtual void      Draw(Option_t *option=""); // *MENU*
-   virtual void      PrintInfo() const;         // *MENU*
-   virtual void      Sizeof3D() const;
-   
-   ClassDef(TGeoExtrusion, 1)      // class representing an extruding node 
-};
- 
-/*************************************************************************
- *   TGeoNodeOverlap - class representing the overlap of 2 positioned 
- *      nodes inside a mother volume.
- ************************************************************************/
- 
-class TGeoNodeOverlap : public TGeoOverlap
-{
-private:
-   TGeoNode        *fNode1;       // first node
-   TGeoNode        *fNode2;       // second node
-
-public:
-   TGeoNodeOverlap();
-   TGeoNodeOverlap(const char *name, TGeoVolume *vol, Int_t inode1, Int_t inode2, Double_t ovlp);
-   virtual           ~TGeoNodeOverlap() {;}
-   
-   virtual TGeoNode *GetNode(Int_t iovlp) const;
-   virtual Bool_t    IsExtrusion() const {return kFALSE;}
-   virtual void      Draw(Option_t *option=""); // *MENU*
-   virtual void      PrintInfo() const;         // *MENU*
-   virtual void      Sizeof3D() const;
-   
-   ClassDef(TGeoNodeOverlap, 1)     // class representing 2 overlapping nodes
-};
-     
+      
 #endif
  
diff --git a/geompainter/src/TGeoChecker.cxx b/geompainter/src/TGeoChecker.cxx
index 5b6abbb6a3d39fec684f95dba66a3ca5f9a7b2cf..1252020e871406e90bcaae71cd898e3e24db636c 100644
--- a/geompainter/src/TGeoChecker.cxx
+++ b/geompainter/src/TGeoChecker.cxx
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoChecker.cxx,v 1.40 2006/01/20 10:35:18 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoChecker.cxx,v 1.41 2006/01/31 14:02:36 brun Exp $
 // Author: Andrei Gheata   01/11/01
 // CheckGeometry(), CheckOverlaps() by Mihaela Gheata
 
@@ -93,6 +93,8 @@ TGeoChecker::TGeoChecker()
 // Default constructor
    fGeoManager = 0;
    fVsafe      = 0;
+   fBuff1 = 0;
+   fBuff2 = 0;
 }
 //-----------------------------------------------------------------------------
 TGeoChecker::TGeoChecker(TGeoManager *geom)
@@ -100,6 +102,8 @@ TGeoChecker::TGeoChecker(TGeoManager *geom)
 // Constructor for a given geometry
    fGeoManager = geom;
    fVsafe = 0;
+   fBuff1 = new TBuffer3D(TBuffer3DTypes::kGeneric,500,3,0,0,0,0);
+   fBuff2 = new TBuffer3D(TBuffer3DTypes::kGeneric,500,3,0,0,0,0);   
 }
 //-----------------------------------------------------------------------------
 TGeoChecker::TGeoChecker(const char * /*treename*/, const char * /*filename*/)
@@ -107,11 +111,15 @@ TGeoChecker::TGeoChecker(const char * /*treename*/, const char * /*filename*/)
 // constructor
    fGeoManager = gGeoManager;
    fVsafe = 0;
+   fBuff1 = new TBuffer3D(TBuffer3DTypes::kGeneric,500,3,0,0,0,0);
+   fBuff2 = new TBuffer3D(TBuffer3DTypes::kGeneric,500,3,0,0,0,0);   
 }
 //-----------------------------------------------------------------------------
 TGeoChecker::~TGeoChecker()
 {
 // Destructor
+   delete fBuff1;
+   delete fBuff2;
 }
 //-----------------------------------------------------------------------------
 void TGeoChecker::CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const
@@ -289,6 +297,155 @@ void TGeoChecker::CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, D
    delete [] array2;
 }
 
+//-----------------------------------------------------------------------------
+TGeoOverlap *TGeoChecker::MakeCheckOverlap(const char *name, TGeoVolume *vol1, TGeoVolume *vol2, TGeoMatrix *mat1, TGeoMatrix *mat2, Bool_t isovlp, Double_t ovlp)
+{
+// Check if the 2 non-assembly volume candidates overlap/extrude. Returns overlap object.
+   TGeoOverlap *nodeovlp = 0;
+   Int_t numPoints1 = 0;
+   Int_t numPoints2 = 0;
+   UInt_t ip;
+   Bool_t extrude, isextrusion, isoverlapping;
+   Double_t *points1 = fBuff1->fPnts; 
+   Double_t *points2 = fBuff2->fPnts;
+   Double_t local[3];
+   Double_t point[3];
+   Double_t safety = TGeoShape::Big();
+   if (vol1->IsAssembly() || vol2->IsAssembly()) return nodeovlp;
+   TGeoShape *shape1 = vol1->GetShape();
+   TGeoShape *shape2 = vol2->GetShape();
+   
+   if (!shape1->IsComposite() && 
+       fBuff1->fID != (TObject*)shape1) {
+      // Fill first buffer.
+      numPoints1 = shape1->GetNmeshVertices();
+      fBuff1->SetRawSizes(numPoints1, 3*numPoints1, 0, 0, 0, 0);
+      points1 = fBuff1->fPnts;
+      shape1->SetPoints(points1);
+      fBuff1->fID = shape1;
+   }   
+   if (!shape2->IsComposite() && 
+       fBuff2->fID != (TObject*)shape2) {
+      // Fill first buffer.
+      numPoints2 = shape2->GetNmeshVertices();
+      fBuff2->SetRawSizes(numPoints2, 3*numPoints2, 0, 0, 0, 0);
+      points2 = fBuff2->fPnts;
+      shape2->SetPoints(points2);
+      fBuff2->fID = shape2;
+   }   
+      
+   if (!isovlp) {
+   // Extrusion case. Test vol2 extrude vol1.
+      isextrusion=kFALSE;
+      // loop all points of the daughter
+      if (!shape2->IsComposite()) {
+         for (ip=0; ip<fBuff2->NbPnts(); ip++) {
+            memcpy(local, &points2[3*ip], 3*sizeof(Double_t));
+            mat2->LocalToMaster(local, point);
+            extrude = !shape1->Contains(point);
+            if (extrude) {
+               safety = shape1->Safety(point, kFALSE);
+               if (safety<ovlp) extrude=kFALSE;
+            }    
+            if (extrude) {
+               if (!isextrusion) {
+                  isextrusion = kTRUE;
+                  nodeovlp = new TGeoOverlap(name, vol1, vol2, mat1,mat2,kFALSE,safety);
+                  nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+                  fGeoManager->AddOverlap(nodeovlp);
+               } else {
+                  if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
+                  nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+               }   
+            }
+         }
+      }                
+      // loop all points of the mother
+      if (!shape1->IsComposite()) {
+         for (ip=0; ip<fBuff1->NbPnts(); ip++) {
+            memcpy(point, &points1[3*ip], 3*sizeof(Double_t));
+            mat2->MasterToLocal(point, local);
+            extrude = shape2->Contains(local);
+            if (extrude) {
+               // skip points on mother mesh that have no neghbourhood ouside mother
+               safety = shape1->Safety(point,kTRUE);
+               if (safety>1E-6) {
+                  extrude = kFALSE;
+               } else {   
+                  safety = shape2->Safety(local,kTRUE);
+                  if (safety<ovlp) extrude=kFALSE;
+               }   
+            }   
+            if (extrude) {
+               if (!isextrusion) {
+                  isextrusion = kTRUE;
+                  nodeovlp = new TGeoOverlap(name, vol1,vol2,mat1,mat2,kFALSE,safety);
+                  nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+                  fGeoManager->AddOverlap(nodeovlp);
+               } else {
+                  if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
+                  nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+               }   
+            }
+         }
+      }
+      return nodeovlp;
+   }            
+   // Check overlap
+   Bool_t overlap;
+   overlap = kFALSE;
+   isoverlapping = kFALSE;
+   if (!shape1->IsComposite()) {
+      // loop all points of first candidate
+      for (ip=0; ip<fBuff1->NbPnts(); ip++) {
+         memcpy(local, &points1[3*ip], 3*sizeof(Double_t));
+         mat1->LocalToMaster(local, point);
+         mat2->MasterToLocal(point, local); // now point in local reference of second
+         overlap = shape2->Contains(local);
+         if (overlap) {
+            safety = shape2->Safety(local, kTRUE);
+            if (safety<ovlp) overlap=kFALSE;
+         }    
+         if (overlap) {
+            if (!isoverlapping) {
+               isoverlapping = kTRUE;
+               nodeovlp = new TGeoOverlap(name,vol1,vol2,mat1,mat2,kTRUE,safety);
+               nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+               fGeoManager->AddOverlap(nodeovlp);
+            } else {
+               if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
+               nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+            }     
+         }
+      }
+   }   
+   // loop all points of second candidate
+   if (!shape2->IsComposite()) {
+      for (ip=0; ip<fBuff2->NbPnts(); ip++) {
+         memcpy(local, &points2[3*ip], 3*sizeof(Double_t));
+         mat2->LocalToMaster(local, point);
+         mat1->MasterToLocal(point, local); // now point in local reference of first
+         overlap = shape1->Contains(local);
+         if (overlap) {
+            safety = shape1->Safety(local, kTRUE);
+            if (safety<ovlp) overlap=kFALSE;
+         }    
+         if (overlap) {
+            if (!isoverlapping) {
+               isoverlapping = kTRUE;
+               nodeovlp = new TGeoOverlap(name,vol1,vol2,mat1,mat2,kTRUE,safety);
+               nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+               fGeoManager->AddOverlap(nodeovlp);
+            } else {
+               if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
+               nodeovlp->SetNextPoint(point[0],point[1],point[2]);
+            }     
+         }
+      }
+   }   
+   return nodeovlp;
+}
+
 //-----------------------------------------------------------------------------
 void TGeoChecker::CheckOverlaps(const TGeoVolume *vol, Double_t ovlp, Option_t * /*option*/) const
 {
@@ -297,208 +454,112 @@ void TGeoChecker::CheckOverlaps(const TGeoVolume *vol, Double_t ovlp, Option_t *
    UInt_t nd = vol->GetNdaughters();
    if (!nd) return;
    Bool_t is_assembly = vol->IsAssembly();
+   TGeoIterator next1((TGeoVolume*)vol);
+   TGeoIterator next2((TGeoVolume*)vol);
+   TString path;
    // first, test if daughters extrude their container
-   TGeoShape *shapem = vol->GetShape();
-   TGeoShape *shaped;
    TGeoNode * node;
-   TGeoMatrix *matrix;
+   TGeoChecker *checker = (TGeoChecker*)this;
 
-   TBuffer3D *buff, *buffm;
-   buff = new TBuffer3D(TBuffer3DTypes::kGeneric,500,3,0,0,0,0);
-   buffm = new TBuffer3D(TBuffer3DTypes::kGeneric,500,3,0,0,0,0);
-   Int_t numPoints = 0;
-   Bool_t extrude, isextrusion, isoverlapping;
    TGeoOverlap *nodeovlp = 0;
-   Bool_t ismany;
-   Double_t *points=0, *pointsm=0;
-   char name[20];
-   Double_t local[3];
-   Double_t point[3];
-   Double_t safety = TGeoShape::Big();
-   UInt_t id, ip;
-   // first, test if any of container vertices is inside some daughter
-   // first, test if daughters extrude their container
-   if (!is_assembly) {
-      if (!shapem->IsComposite()) {
-         numPoints = shapem->GetNmeshVertices();
-         buffm->SetRawSizes(numPoints, 3*numPoints, 0, 0, 0, 0);
-         pointsm = buffm->fPnts;
-         shapem->SetPoints(pointsm);
-      }   
-   
-      for (id=0; id<nd; id++) {
-         node = vol->GetNode(id);
-         if (node->GetVolume()->IsAssembly()) continue;
-         shaped = node->GetVolume()->GetShape();
-         if (!shaped->IsComposite()) {
-            numPoints = shaped->GetNmeshVertices();
-            buff->SetRawSizes(numPoints, 3*numPoints, 0, 0, 0, 0);
-            points = buff->fPnts;
-            shaped->SetPoints(points);
+   UInt_t id;
+
+// Check extrusion only for daughters of a non-assembly volume
+   if (!is_assembly) {      
+      while ((node=next1())) {
+         if (node->IsOverlapping()) {
+            next1.Skip();
+            continue;
          }   
-         matrix = node->GetMatrix();
-         ismany = node->IsOverlapping();
-         isextrusion=kFALSE;
-         // loop all points of the daughter
-         if (!shaped->IsComposite()) {
-            for (ip=0; ip<buff->NbPnts(); ip++) {
-               memcpy(local, &points[3*ip], 3*sizeof(Double_t));
-               matrix->LocalToMaster(local, point);
-               extrude = !shapem->Contains(point);
-               if (extrude) {
-                  safety = shapem->Safety(point, kFALSE);
-                  if (safety<ovlp) extrude=kFALSE;
-               }    
-               if (extrude) {
-                  if (!isextrusion) {
-                     isextrusion = kTRUE;
-                     sprintf(name,"%s_x_%i", vol->GetName(),id); 
-                     nodeovlp = new TGeoExtrusion(name, (TGeoVolume*)vol,id,safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                     fGeoManager->AddOverlap(nodeovlp);
-                  } else {
-                     if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                  }   
-               }
-            }
-         }                
-         // loop all points of the mother
-         if (!shapem->IsComposite()) {
-            for (ip=0; ip<buffm->NbPnts(); ip++) {
-               memcpy(point, &pointsm[3*ip], 3*sizeof(Double_t));
-               matrix->MasterToLocal(point, local);
-               extrude = shaped->Contains(local);
-               if (extrude) {
-                  // skip points on mother mesh that have no neghbourhood ouside mother
-                  safety = shapem->Safety(point,kTRUE);
-                  if (safety>1E-6) {
-                     extrude = kFALSE;
-                  } else {   
-                     safety = shaped->Safety(local,kTRUE);
-                     if (safety<ovlp) extrude=kFALSE;
-                  }   
-               }   
-               if (extrude) {
-                  if (!isextrusion) {
-                     isextrusion = kTRUE;
-                     sprintf(name,"%s_mo_%i", vol->GetName(),id); 
-                     nodeovlp = new TGeoExtrusion(name, (TGeoVolume*)vol,id,safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                     fGeoManager->AddOverlap(nodeovlp);
-                  } else {
-                     if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                  }   
-               }
-            }
+         if (!node->GetVolume()->IsAssembly()) {
+            next1.GetPath(path);
+            nodeovlp = checker->MakeCheckOverlap(Form("%s extruded by: %s", vol->GetName(),path.Data()),
+                                 (TGeoVolume*)vol,node->GetVolume(),gGeoIdentity,(TGeoMatrix*)next1.GetCurrentMatrix(),kFALSE,ovlp);
+            next1.Skip();
          }
-      }   
+      }            
    }
 
    // now check if the daughters overlap with each other
-   if (nd<2) {
-      delete buff;
-      delete buffm;
+   if (nd<2) return;
+   TGeoVoxelFinder *vox = vol->GetVoxels();
+   if (!vox) {
+      Warning("CheckOverlaps", "Volume %s with %i daughters but not voxelized", vol->GetName(),nd);
       return;
    }   
-   TGeoVoxelFinder *vox = vol->GetVoxels();
-   TGeoNode *node1;
-   TGeoMatrix *matrix1;
-   Bool_t ismany1, overlap;
+   TGeoNode *node1, *node01, *node02;
+   TGeoHMatrix hmat1, hmat2;
+   TString path1;
    Int_t novlp;
    Int_t *ovlps;
    Int_t ko;
    UInt_t io;
-   for (id=0; id<nd; id++) {  // loop all nodes (node, shapem, matrix, pointsm, buffm)
-      node = vol->GetNode(id);
-      if (node->GetVolume()->IsAssembly()) continue;
-      ismany = node->IsOverlapping();
-      if (ismany) continue;
-      shapem = node->GetVolume()->GetShape();
-      matrix = node->GetMatrix();
-      if (!vox) continue;
+   for (id=0; id<nd; id++) {  
+      node01 = vol->GetNode(id);
+      if (node01->IsOverlapping()) continue;
       vox->FindOverlaps(id);
-      ovlps = node->GetOverlaps(novlp);
+      ovlps = node01->GetOverlaps(novlp);
       if (!ovlps) continue;
-      if (!shapem->IsComposite()) {
-         numPoints = shapem->GetNmeshVertices();
-         buffm->SetRawSizes(numPoints, 3*numPoints, 0, 0, 0, 0);    // node buffer
-         pointsm = buffm->fPnts;
-         shapem->SetPoints(pointsm);
-      }   
+      next1.SetTopName(node01->GetName());
+      path = node01->GetName();
       for (ko=0; ko<novlp; ko++) { // loop all possible overlapping candidates
-         io = ovlps[ko];           // (node1, shaped, matrix1, points, buff)
-         if (io<id) continue;
-         node1 = vol->GetNode(io);
-         if (node1->GetVolume()->IsAssembly()) continue;
-         ismany1 = node1->IsOverlapping();
-         if (ismany1) continue;
-         matrix1 = node1->GetMatrix();
-         shaped = node1->GetVolume()->GetShape();
-         if (!shaped->IsComposite()) {
-            numPoints = shaped->GetNmeshVertices(); // overlapping candidate buffer
-            buff->SetRawSizes(numPoints, 3*numPoints, 0, 0, 0, 0);
-            points = buff->fPnts;
-            shaped->SetPoints(points);
-         }   
-         // loop all points of candidate
-         overlap = kFALSE;
-         isoverlapping = kFALSE;
-         if (!shaped->IsComposite()) {
-            for (ip=0; ip<buff->NbPnts(); ip++) {
-               memcpy(local, &points[3*ip], 3*sizeof(Double_t));
-               matrix1->LocalToMaster(local, point);
-               matrix->MasterToLocal(point, local); // now point in local reference of node
-               overlap = shapem->Contains(local);
-               if (overlap) {
-                  safety = shapem->Safety(local, kTRUE);
-                  if (safety<ovlp) overlap=kFALSE;
-               }    
-               if (overlap) {
-                  if (!isoverlapping) {
-                     isoverlapping = kTRUE;
-                     sprintf(name,"%s_o_%i_%i", vol->GetName(),id,io); 
-                     nodeovlp = new TGeoNodeOverlap(name, (TGeoVolume*)vol,id,io,safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                     fGeoManager->AddOverlap(nodeovlp);
+         io = ovlps[ko];           // (node1, shaped, matrix1, points, fBuff1)
+         if (io<=id) continue;
+         node02 = vol->GetNode(io);
+         if (node02->IsOverlapping()) continue;        
+         next2.SetTopName(node02->GetName());
+         path1 = node02->GetName();
+        
+         // We have to check node against node1, but they may be assemblies
+         if (node01->GetVolume()->IsAssembly()) {
+            next1.Reset(node01->GetVolume());
+            while ((node=next1())) {
+               if (!node->GetVolume()->IsAssembly()) {
+                  next1.GetPath(path);
+                  hmat1 = node01->GetMatrix();
+                  hmat1 *= *next1.GetCurrentMatrix();
+                  if (node02->GetVolume()->IsAssembly()) {
+                     next2.Reset(node02->GetVolume());
+                     while ((node1=next2())) {
+                        if (!node1->GetVolume()->IsAssembly()) {
+                           next2.GetPath(path1);
+                           hmat2 = node02->GetMatrix();
+                           hmat2 *= *next2.GetCurrentMatrix();
+                           nodeovlp = checker->MakeCheckOverlap(Form("%s/%s overlapping %s/%s", vol->GetName(),path.Data(),vol->GetName(),path1.Data()),
+                                              node->GetVolume(),node1->GetVolume(),&hmat1,&hmat2,kTRUE,ovlp);  
+                           next2.Skip();
+                        }
+                     }
                   } else {
-                     if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                  }     
+                     nodeovlp = checker->MakeCheckOverlap(Form("%s/%s overlapping %s/%s", vol->GetName(),path.Data(),vol->GetName(),path1.Data()),
+                                        node->GetVolume(),node02->GetVolume(),&hmat1,node02->GetMatrix(),kTRUE,ovlp);  
+                  }
+                  next1.Skip();
                }
             }
-         }                
-         // loop all points of node
-         if (!shapem->IsComposite()) {
-            for (ip=0; ip<buffm->NbPnts(); ip++) {
-               memcpy(local, &pointsm[3*ip], 3*sizeof(Double_t));
-               matrix->LocalToMaster(local, point);
-               matrix1->MasterToLocal(point, local); // now point in local reference of node
-               overlap = shaped->Contains(local);
-               if (overlap) {
-                  safety = shaped->Safety(local, kTRUE);
-                  if (safety<ovlp) overlap=kFALSE;
-               }    
-               if (overlap) {
-                  if (!isoverlapping) {
-                     isoverlapping = kTRUE;
-                     sprintf(name,"%s_o_%i_%i", vol->GetName(),id,io); 
-                     nodeovlp = new TGeoNodeOverlap(name, (TGeoVolume*)vol,id,io,safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                     fGeoManager->AddOverlap(nodeovlp);
-                  } else {
-                     if (safety>nodeovlp->GetOverlap()) nodeovlp->SetOverlap(safety);
-                     nodeovlp->SetNextPoint(point[0],point[1],point[2]);
-                  }     
+         } else {
+            // node not assembly         
+            if (node02->GetVolume()->IsAssembly()) { 
+               next2.Reset(node02->GetVolume());
+               while ((node1=next2())) {
+                  if (!node1->GetVolume()->IsAssembly()) {
+                     next2.GetPath(path1);
+                     hmat2 = node02->GetMatrix();
+                     hmat2 *= *next2.GetCurrentMatrix();
+                     nodeovlp = checker->MakeCheckOverlap(Form("%s/%s overlapping %s/%s", vol->GetName(),path.Data(),vol->GetName(),path1.Data()),
+                                        node01->GetVolume(),node1->GetVolume(),node01->GetMatrix(),&hmat2,kTRUE,ovlp);  
+                     next2.Skip();
+                  }
                }
+            } else {
+               // node1 also not assembly
+               nodeovlp = checker->MakeCheckOverlap(Form("%s/%s overlapping %s/%s", vol->GetName(),path.Data(),vol->GetName(),path1.Data()),
+                                  node01->GetVolume(),node02->GetVolume(),node01->GetMatrix(),node02->GetMatrix(),kTRUE,ovlp);  
             }
-         }   
+         }                         
       }                
-      node->SetOverlaps(0,0);
+      node01->SetOverlaps(0,0);
    }
-   delete buff;
-   delete buffm;
 }
 
 //-----------------------------------------------------------------------------
diff --git a/geompainter/src/TGeoOverlap.cxx b/geompainter/src/TGeoOverlap.cxx
index ab5ea92517c95647cb9e7729d5c28a7bc24d39a4..d642b3e8330fbd52828bb46e498c7be8ec90bfc6 100644
--- a/geompainter/src/TGeoOverlap.cxx
+++ b/geompainter/src/TGeoOverlap.cxx
@@ -1,4 +1,4 @@
-// @(#)root/geom:$Name:  $:$Id: TGeoOverlap.cxx,v 1.7 2005/04/25 07:53:27 brun Exp $
+// @(#)root/geom:$Name:  $:$Id: TGeoOverlap.cxx,v 1.8 2005/11/18 16:07:59 brun Exp $
 // Author: Andrei Gheata   09-02-03
 
 /*************************************************************************
@@ -32,24 +32,31 @@ TGeoOverlap::TGeoOverlap()
 {
 // Default ctor.
    fOverlap = 0;
-   fVolume  = 0;
+   fVolume1 = 0;
+   fVolume2 = 0;
+   fMatrix1 = 0;
+   fMatrix2 = 0;
    fMarker  = 0;
 }
 
 //______________________________________________________________________________
-TGeoOverlap::TGeoOverlap(const char *name, TGeoVolume *vol, Double_t ovlp)
+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;
-   fVolume  = vol;
-   if (!fVolume) {
-      Error("Ctor", "volume is NULL");
-      return;
-   }   
+   fVolume1  = vol1;
+   fVolume2  = vol2;
+   fMatrix1 = new TGeoHMatrix();
+   *fMatrix1 = matrix1;
+   fMatrix2 = new TGeoHMatrix();
+   *fMatrix2 = matrix2;
    fMarker  = new TPolyMarker3D();
    fMarker->SetMarkerColor(2);
-//   fMarker->SetMarkerStyle(2);
+   SetIsOverlap(isovlp);
+   fMarker->SetMarkerStyle(6);
 //   fMarker->SetMarkerSize(0.5);
 }
 
@@ -58,6 +65,8 @@ TGeoOverlap::~TGeoOverlap()
 {
 // Destructor.
    if (fMarker) delete fMarker;
+   if (fMatrix1) delete fMatrix1;
+   if (fMatrix2) delete fMatrix2;
 }
 
 //______________________________________________________________________________
@@ -94,153 +103,50 @@ Int_t TGeoOverlap::Compare(const TObject *obj) const
 Int_t TGeoOverlap::DistancetoPrimitive(Int_t px, Int_t py)
 {
 // Distance to primitive for an overlap.
-   return fVolume->GetGeoManager()->GetGeomPainter()->DistanceToPrimitiveVol(fVolume, px, py);
+   return fVolume1->GetGeoManager()->GetGeomPainter()->DistanceToPrimitiveVol(fVolume1, px, py);
 }
 
 //______________________________________________________________________________
-void TGeoOverlap::ExecuteEvent(Int_t event, Int_t px, Int_t py)
-{
-// Event interception.
-   fVolume->GetGeoManager()->GetGeomPainter()->ExecuteVolumeEvent(fVolume, event, px, py);
-}
-
-//______________________________________________________________________________
-void TGeoOverlap::Paint(Option_t *option)
-{
-// Paint the overlap.
-   fVolume->GetGeoManager()->GetGeomPainter()->PaintOverlap(this, option);
-}
-
-//______________________________________________________________________________
-void TGeoOverlap::SetNextPoint(Double_t x, Double_t y, Double_t z)
-{
-// Set next overlapping point.
-   fMarker->SetNextPoint(x,y,z);
-}
-
-ClassImp(TGeoExtrusion)
-/*************************************************************************
- *   TGeoExtrusion - class representing the extrusion of a positioned volume
- *      with respect to its mother.
- ************************************************************************/
-
-//______________________________________________________________________________
-TGeoExtrusion::TGeoExtrusion()   
-{
-// Default ctor.
-   fNode = 0;
-}
-
-//______________________________________________________________________________
-TGeoExtrusion::TGeoExtrusion(const char *name, TGeoVolume *vol, Int_t inode, Double_t ovlp)
-              :TGeoOverlap(name, vol, ovlp)
-{
-// Ctor.      
-   if (inode<0 || inode>vol->GetNdaughters()-1) {
-      Error("Ctor", "invalid daughter number %i for volume %s", inode, vol->GetName());
-      return;
-   }
-   fNode = vol->GetNode(inode);   
-}
-
-//______________________________________________________________________________
-TGeoNode *TGeoExtrusion::GetNode(Int_t /*iovlp*/) const
+void TGeoOverlap::Draw(Option_t *option)
 {
-// Get extruding node.
-   return fNode;
-}
-   
-//______________________________________________________________________________
-void TGeoExtrusion::Draw(Option_t *option)
-{
-// Draw the extrusion. Mother volume will be blue, extruding daughter green,
+// Draw the overlap. One daughter will be blue, the other green,
 // extruding points red.
-   fVolume->GetGeoManager()->GetGeomPainter()->DrawOverlap(this, option);
+   fVolume1->GetGeoManager()->GetGeomPainter()->DrawOverlap(this, option);
    PrintInfo();
 }
 
 //______________________________________________________________________________
-void TGeoExtrusion::PrintInfo() const
+void TGeoOverlap::ExecuteEvent(Int_t event, Int_t px, Int_t py)
 {
-// Print some info.
-   printf("* extrusion %s/%s: vol=%s node=%s extr=%g\n", GetName(), GetTitle(), 
-          fVolume->GetName(), fNode->GetName(), fOverlap);
+// Event interception.
+   fVolume1->GetGeoManager()->GetGeomPainter()->ExecuteVolumeEvent(fVolume1, event, px, py);
 }
 
 //______________________________________________________________________________
-void TGeoExtrusion::Sizeof3D() const
+void TGeoOverlap::Paint(Option_t *option)
 {
-// Returns 3D size of this.
-   fVolume->GetShape()->Sizeof3D();
-   fNode->GetVolume()->GetShape()->Sizeof3D();
+// Paint the overlap.
+   fVolume1->GetGeoManager()->GetGeomPainter()->PaintOverlap(this, option);
 }
 
-ClassImp(TGeoNodeOverlap)
-/*************************************************************************
- *   TGeoNodeOverlap - class representing the overlap of 2 positioned 
- *      nodes inside a mother volume.
- ************************************************************************/
-
-//______________________________________________________________________________
-TGeoNodeOverlap::TGeoNodeOverlap()   
-{
-// Default ctor.
-   fNode1 = 0;
-   fNode2 = 0;
-}
-     
 //______________________________________________________________________________
-TGeoNodeOverlap::TGeoNodeOverlap(const char *name, TGeoVolume *vol, Int_t inode1, Int_t inode2, Double_t ovlp)
-              :TGeoOverlap(name, vol, ovlp)
+void TGeoOverlap::PrintInfo() const
 {
-// Ctor.      
-   if (inode1<0 || inode1>vol->GetNdaughters()-1) {
-      Error("Ctor", "invalid daughter number %i for volume %s", inode1, vol->GetName());
-      return;
-   }
-   fNode1 = vol->GetNode(inode1);   
-   if (inode2<0 || inode2>vol->GetNdaughters()-1) {
-      Error("Ctor", "invalid daughter number %i for volume %s", inode2, vol->GetName());
-      return;
-   }
-   fNode2 = vol->GetNode(inode2);   
+// Print some info.
+   printf(" = Overlap %s: %s\n", GetName(), GetTitle());
 }
 
 //______________________________________________________________________________
-TGeoNode *TGeoNodeOverlap::GetNode(Int_t iovlp) const
+void TGeoOverlap::SetNextPoint(Double_t x, Double_t y, Double_t z)
 {
-// Get one of the overlapping nodes.
-   switch (iovlp) {
-      case 0:
-         return fNode1;
-      case 1:
-         return fNode2;
-      default:
-         return 0;
-   }            
+// Set next overlapping point.
+   fMarker->SetNextPoint(x,y,z);
 }
 
 //______________________________________________________________________________
-void TGeoNodeOverlap::Draw(Option_t *option)
-{
-// Draw the overlap. One daughter will be blue, the other green,
-// extruding points red.
-   fVolume->GetGeoManager()->GetGeomPainter()->DrawOverlap(this, option);
-   PrintInfo();
-}
- 
-//______________________________________________________________________________
-void TGeoNodeOverlap::PrintInfo() const
-{
-// Print some info.
-   printf("* overlap %s/%s: vol=%s <%s<->%s> ovlp=%g\n", GetName(), GetTitle(), 
-          fVolume->GetName(), fNode1->GetName(), fNode2->GetName(), fOverlap);
-}
-   
-//______________________________________________________________________________
-void TGeoNodeOverlap::Sizeof3D() const
+void TGeoOverlap::Sizeof3D() const
 {
 // Get 3D size of this.
-   fNode1->GetVolume()->GetShape()->Sizeof3D();
-   fNode2->GetVolume()->GetShape()->Sizeof3D();
+   fVolume1->GetShape()->Sizeof3D();
+   fVolume2->GetShape()->Sizeof3D();
 }
diff --git a/geompainter/src/TGeoPainter.cxx b/geompainter/src/TGeoPainter.cxx
index 5110f9e4d15023e948607dfe682d7378996e15ef..6199b95a90ea74f29c6657c66ccd0c2222d7ceaf 100644
--- a/geompainter/src/TGeoPainter.cxx
+++ b/geompainter/src/TGeoPainter.cxx
@@ -1,4 +1,4 @@
-// @(#)root/geompainter:$Name:  $:$Id: TGeoPainter.cxx,v 1.75 2006/01/19 11:23:08 brun Exp $
+// @(#)root/geompainter:$Name:  $:$Id: TGeoPainter.cxx,v 1.76 2006/01/31 14:02:36 brun Exp $
 // Author: Andrei Gheata   05/03/02
 /*************************************************************************
  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
@@ -280,22 +280,8 @@ Int_t TGeoPainter::DistanceToPrimitiveVol(TGeoVolume *vol, Int_t px, Int_t py)
    
    if (fPaintingOverlaps) {
       TGeoVolume *crt;
-      if (fOverlap->IsExtrusion()) {
-         crt = fOverlap->GetVolume();
-         fMatrix = gGeoIdentity;
-         dist = crt->GetShape()->DistancetoPrimitive(px,py);
-         if (dist<maxdist) {
-            gPad->SetSelected(crt);
-            box = (TGeoBBox*)crt->GetShape();
-            fMatrix->LocalToMaster(box->GetOrigin(), &fCheckedBox[0]);
-            fCheckedBox[3] = box->GetDX();
-            fCheckedBox[4] = box->GetDY();
-            fCheckedBox[5] = box->GetDZ();
-            return 0;
-         }
-      }   
-      crt = fOverlap->GetNode(0)->GetVolume();
-      fMatrix = fOverlap->GetNode(0)->GetMatrix();
+      crt = fOverlap->GetFirstVolume();
+      fMatrix = fOverlap->GetFirstMatrix();
       dist = crt->GetShape()->DistancetoPrimitive(px,py);
       if (dist<maxdist) {
          gPad->SetSelected(crt);
@@ -306,12 +292,8 @@ Int_t TGeoPainter::DistanceToPrimitiveVol(TGeoVolume *vol, Int_t px, Int_t py)
          fCheckedBox[5] = box->GetDZ();
          return 0;
       }
-      if (fOverlap->IsExtrusion()) {
-         gPad->SetSelected(view);
-         return big;
-      }
-      crt = fOverlap->GetNode(1)->GetVolume();
-      fMatrix = fOverlap->GetNode(1)->GetMatrix();
+      crt = fOverlap->GetSecondVolume();
+      fMatrix = fOverlap->GetSecondMatrix();
       dist = crt->GetShape()->DistancetoPrimitive(px,py);
       if (dist<maxdist) {
          gPad->SetSelected(crt);
@@ -734,15 +716,10 @@ char *TGeoPainter::GetVolumeInfo(const TGeoVolume *volume, Int_t /*px*/, Int_t /
          return info;
       }   
       TString ovtype, name;
-      if (fOverlap->IsExtrusion()) {
-         ovtype="EXTRUSION";
-         if (volume==fOverlap->GetVolume()) name=volume->GetName();
-         else name=fOverlap->GetNode(0)->GetName();
-      } else {
-         ovtype = "OVERLAP";
-         if (volume==fOverlap->GetNode(0)->GetVolume()) name=fOverlap->GetNode(0)->GetName();
-         else name=fOverlap->GetNode(1)->GetName();
-      }   
+      if (fOverlap->IsExtrusion()) ovtype="EXTRUSION";
+      else ovtype = "OVERLAP";
+      if (volume==fOverlap->GetFirstVolume()) name=volume->GetName();
+      else name=fOverlap->GetSecondVolume()->GetName();
       sprintf(info, "%s: %s of %g", name.Data(), ovtype.Data(), fOverlap->GetOverlap());
       return info;
    }   
@@ -880,63 +857,39 @@ void TGeoPainter::PaintOverlap(void *ovlp, Option_t *option)
    Int_t color, transparency;
    if (fOverlap != overlap) fOverlap = overlap;
    TGeoHMatrix *hmat = fGeoManager->GetGLMatrix();
-   TGeoVolume *vol = overlap->GetVolume();
-   TGeoNode *node1=0, *node2=0;
+   TGeoVolume *vol;
+   TGeoVolume *vol1 = overlap->GetFirstVolume();
+   TGeoVolume *vol2 = overlap->GetSecondVolume();
+   TGeoHMatrix *matrix1 = overlap->GetFirstMatrix();
+   TGeoHMatrix *matrix2 = overlap->GetSecondMatrix();
    fGeoManager->SetMatrixTransform(kTRUE);
-   if (fOverlap->IsExtrusion()) {
-      if (!fVisLock) fVisVolumes->Add(vol);
-      *hmat = gGeoIdentity;
-      fGeoManager->SetMatrixReflection(kFALSE);
-      fGeoManager->SetPaintVolume(vol);
-      color = vol->GetLineColor();
-      transparency = vol->GetTransparency();
-      vol->SetLineColor(3);
-      vol->SetTransparency(49);
-      if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
-      PaintShape(*(vol->GetShape()),option);
-      vol->SetLineColor(color);
-      vol->SetTransparency(transparency);
-      node1 = overlap->GetNode(0);
-      fGeoManager->SetMatrixReflection(node1->GetMatrix()->IsReflection());
-      *hmat = node1->GetMatrix();
-      vol = node1->GetVolume();
-      if (!fVisLock) fVisVolumes->Add(vol);
-      fGeoManager->SetPaintVolume(vol);
-      color = vol->GetLineColor();
-      vol->SetLineColor(4);
-      if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
-      PaintShape(*(vol->GetShape()),option);
-      vol->SetLineColor(color);
-   } else {
-      node1 = overlap->GetNode(0);
-      vol = node1->GetVolume();
-      *hmat = node1->GetMatrix();
-      fGeoManager->SetMatrixReflection(node1->GetMatrix()->IsReflection());
-      if (!fVisLock) fVisVolumes->Add(vol);
-      fGeoManager->SetPaintVolume(vol);
-      color = vol->GetLineColor();
-      transparency = vol->GetTransparency();
-      vol->SetLineColor(3);
-      vol->SetTransparency(40);
-      if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
-      PaintShape(*(vol->GetShape()),option);
-      vol->SetLineColor(color);
-      vol->SetTransparency(transparency);
-      node2 = overlap->GetNode(1);
-      fGeoManager->SetMatrixReflection(node2->GetMatrix()->IsReflection());
-      vol = node2->GetVolume();
-      *hmat = node2->GetMatrix();
-      if (!fVisLock) fVisVolumes->Add(vol);
-      fGeoManager->SetPaintVolume(vol);
-      color = vol->GetLineColor();
-      transparency = vol->GetTransparency();
-      vol->SetLineColor(4);
-      vol->SetTransparency(40);
-      if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
-      PaintShape(*(vol->GetShape()),option);
-      vol->SetLineColor(color);
-      vol->SetTransparency(transparency);
-   }     
+   //
+   vol = vol1;
+   *hmat = matrix1;
+   fGeoManager->SetMatrixReflection(matrix1->IsReflection());
+   if (!fVisLock) fVisVolumes->Add(vol);
+   fGeoManager->SetPaintVolume(vol);
+   color = vol->GetLineColor();
+   transparency = vol->GetTransparency();
+   vol->SetLineColor(kGreen);
+   vol->SetTransparency(40);
+   if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
+   PaintShape(*(vol->GetShape()),option);
+   vol->SetLineColor(color);
+   vol->SetTransparency(transparency);
+   vol = vol2;
+   *hmat = matrix2;
+   fGeoManager->SetMatrixReflection(matrix2->IsReflection());
+   if (!fVisLock) fVisVolumes->Add(vol);
+   fGeoManager->SetPaintVolume(vol);
+   color = vol->GetLineColor();
+   transparency = vol->GetTransparency();
+   vol->SetLineColor(kBlue);
+   vol->SetTransparency(40);
+   if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
+   PaintShape(*(vol->GetShape()),option);
+   vol->SetLineColor(color);
+   vol->SetTransparency(transparency);
    fGeoManager->SetMatrixTransform(kFALSE);
    fVisLock = kTRUE;
 }