Index: trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc
===================================================================
--- trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc	(revision 529)
+++ trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc	(revision 593)
@@ -25,6 +25,6 @@
 //
 //
-// $Id: G4OpenGLStoredSceneHandler.cc,v 1.31 2006/08/30 11:43:57 allison Exp $
-// GEANT4 tag $Name: geant4-08-02-patch-01 $
+// $Id: G4OpenGLStoredSceneHandler.cc,v 1.34 2007/04/04 16:50:27 allison Exp $
+// GEANT4 tag $Name: geant4-09-00-ref-01 $
 //
 // 
@@ -46,8 +46,12 @@
 #include "G4PhysicalVolumeModel.hh"
 #include "G4VPhysicalVolume.hh"
+#include "G4LogicalVolume.hh"
 #include "G4Polyline.hh"
 #include "G4Polymarker.hh"
+#include "G4Text.hh"
 #include "G4Circle.hh"
 #include "G4Square.hh"
+#include "G4Polyhedron.hh"
+#include "G4AttHolder.hh"
 
 G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler (G4VGraphicsSystem& system,
@@ -56,5 +60,6 @@
 fMemoryForDisplayLists (true),
 fAddPrimitivePreambleNestingDepth (0),
-fTopPODL (0)
+fTopPODL (0),
+fProcessing2D (false)
 {}
 
@@ -69,78 +74,23 @@
   if (fAddPrimitivePreambleNestingDepth > 1) return;
 
+  // Because of our need to control colour of transients (display by
+  // time fading), display lists may only cover a single primitive.
+  // So display list setup is here.
+
+  if (fpViewer->GetViewParameters().IsPicking()) {
+    fPickMap[++fPickName] = 0;
+  }
+
   const G4Colour& c = GetColour (visible);
-
-  if (fMemoryForDisplayLists && fReadyForTransients) {
-
-    TO& to = fTOList.back();  // Transient object information.
-
-    // Get vis attributes - pick up defaults if none.
-    const G4VisAttributes* pVA =
-      fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
-
-    // Get time information from vis attributes.
-    to.fStartTime = pVA->GetStartTime();
-    to.fEndTime = pVA->GetEndTime();
-
-    // Keep colour out of (already started) display list so that it
-    // can be applied independently.
-    glEndList();
-    glDeleteLists(fDisplayListId, 1);
-    to.fColour = c;
-    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
-    glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
-      
-  } else {
-
-    // Make sure colour is set in other cases.
-    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
-  }
-}
-
-void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
-{
-  fAddPrimitivePreambleNestingDepth--;
-}
-
-void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
-{
-  AddPrimitivePreamble(polyline);
-  G4OpenGLSceneHandler::AddPrimitive(polyline);
-  AddPrimitivePostamble();
-}
-
-void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
-{
-  AddPrimitivePreamble(circle);
-  G4OpenGLSceneHandler::AddPrimitive(circle);
-  AddPrimitivePostamble();
-}
-
-void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
-{
-  AddPrimitivePreamble(square);
-  G4OpenGLSceneHandler::AddPrimitive(square);
-  AddPrimitivePostamble();
-}
-
-void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
-{
-  AddPrimitivePreamble(polymarker);
-  G4OpenGLSceneHandler::AddPrimitive(polymarker);
-  AddPrimitivePostamble();
-}
-
-void G4OpenGLStoredSceneHandler::BeginPrimitives
-(const G4Transform3D& objectTransformation) {
-  
-  G4VSceneHandler::BeginPrimitives (objectTransformation);
 
   if (fMemoryForDisplayLists) {
     fDisplayListId = glGenLists (1);
     if (!fDisplayListId) {  // Could pre-allocate?
-      G4cout << "********************* WARNING! ********************\n"
-	   <<"Unable to allocate any more display lists in OpenGL.\n "
-	   << "      Continuing drawing in IMMEDIATE MODE.\n"
-	   << "***************************************************" << G4endl;
+      G4cout <<
+	"********************* WARNING! ********************"
+	"\nUnable to allocate any more display lists in OpenGL."
+	"\n     Continuing drawing in IMMEDIATE MODE."
+	"\n***************************************************"
+	     << G4endl;
       fMemoryForDisplayLists = false;
     }
@@ -148,25 +98,57 @@
   if (fMemoryForDisplayLists) {
     if (fReadyForTransients) {
-      TO to(fDisplayListId, objectTransformation);
+      TO to(fDisplayListId, *fpObjectTransformation);
+      to.fPickName = fPickName;
+      to.fColour = c;
+      const G4VisAttributes* pVA =
+	fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
+      to.fStartTime = pVA->GetStartTime();
+      to.fEndTime = pVA->GetEndTime();
       fTOList.push_back(to);
       glDrawBuffer (GL_FRONT);
       glPushMatrix();
-      G4OpenGLTransform3D oglt (objectTransformation);
+      G4OpenGLTransform3D oglt (*fpObjectTransformation);
       glMultMatrixd (oglt.GetGLMatrix ());
+      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
       glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
     }
     else {
-      fPOList.push_back(PO(fDisplayListId, objectTransformation));
+      PO po(fDisplayListId, *fpObjectTransformation);
+      po.fPickName = fPickName;
+      fPOList.push_back(po);
       glNewList (fDisplayListId, GL_COMPILE);
+      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
     }
   } else {
     glDrawBuffer (GL_FRONT);
     glPushMatrix();
-    G4OpenGLTransform3D oglt (objectTransformation);
+    G4OpenGLTransform3D oglt (*fpObjectTransformation);
     glMultMatrixd (oglt.GetGLMatrix ());
-  }
-}
-
-void G4OpenGLStoredSceneHandler::EndPrimitives () {
+    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
+  }
+
+  if (fProcessing2D) {
+    // Push current 3D world matrices and load identity to define screen
+    // coordinates...
+    glMatrixMode (GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho (-1., 1., -1., 1., -G4OPENGL_DBL_MAX, G4OPENGL_DBL_MAX);
+    glMatrixMode (GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+  }
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
+{
+  if (fProcessing2D) {
+    // Pop current 3D world matrices back again...
+    glMatrixMode (GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode (GL_MODELVIEW);
+    glPopMatrix();
+  }
+
   if (fMemoryForDisplayLists) {
     glEndList();
@@ -177,61 +159,94 @@
     glDrawBuffer (GL_BACK);
   }
-  G4VSceneHandler::EndPrimitives ();
+  fAddPrimitivePreambleNestingDepth--;
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
+{
+  AddPrimitivePreamble(polyline);
+  G4OpenGLSceneHandler::AddPrimitive(polyline);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
+{
+  AddPrimitivePreamble(polymarker);
+  G4OpenGLSceneHandler::AddPrimitive(polymarker);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
+{
+  // Note: colour is still handled in
+  // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
+  // gets into the display list
+  AddPrimitivePreamble(text);
+  G4OpenGLSceneHandler::AddPrimitive(text);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
+{
+  AddPrimitivePreamble(circle);
+  G4OpenGLSceneHandler::AddPrimitive(circle);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
+{
+  AddPrimitivePreamble(square);
+  G4OpenGLSceneHandler::AddPrimitive(square);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale)
+{
+  // Let base class split into primitives.
+  G4OpenGLSceneHandler::AddPrimitive(scale);
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
+{
+  // Note: colour is still handled in
+  // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
+  // gets into the display list
+  AddPrimitivePreamble(polyhedron);
+  G4OpenGLSceneHandler::AddPrimitive(polyhedron);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs)
+{
+  // Note: colour is still handled in
+  // G4OpenGLSceneHandler::AddPrimitive(const G4NURBS&), so it still
+  // gets into the display list
+  AddPrimitivePreamble(nurbs);
+  G4OpenGLSceneHandler::AddPrimitive(nurbs);
+  AddPrimitivePostamble();
+}
+
+void G4OpenGLStoredSceneHandler::BeginPrimitives
+(const G4Transform3D& objectTransformation)
+{  
+  G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
+
+  // Display list setup moved to AddPrimitivePreamble.  See notes there.
+}
+
+void G4OpenGLStoredSceneHandler::EndPrimitives ()
+{
+  G4OpenGLSceneHandler::EndPrimitives ();
 }
 
 void G4OpenGLStoredSceneHandler::BeginPrimitives2D()
 {
-  G4VSceneHandler::BeginPrimitives2D();
-
-  if (fMemoryForDisplayLists) {
-    fDisplayListId = glGenLists (1);
-    if (!fDisplayListId) {  // Could pre-allocate?
-      G4cout << "********************* WARNING! ********************\n"
-	   <<"Unable to allocate any more display lists in OpenGL.\n "
-	   << "      Continuing drawing in IMMEDIATE MODE.\n"
-	   << "***************************************************" << G4endl;
-      fMemoryForDisplayLists = false;
-    }
-  }
-  if (fMemoryForDisplayLists) {
-    if (fReadyForTransients) {
-      fTOList.push_back(TO(fDisplayListId));
-      glDrawBuffer (GL_FRONT);
-      glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
-    }
-    else {
-      fPOList.push_back(PO(fDisplayListId));
-      glNewList (fDisplayListId, GL_COMPILE);
-    }
-  } else {
-    glDrawBuffer (GL_FRONT);
-  }
-  // Push current 3D world matrices and load identity to define screen
-  // coordinates...
-  glMatrixMode (GL_PROJECTION);
-  glPushMatrix();
-  glLoadIdentity();
-  glOrtho (-1., 1., -1., 1., -DBL_MAX, DBL_MAX);
-  glMatrixMode (GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
+  G4OpenGLSceneHandler::BeginPrimitives2D();
+  fProcessing2D = true;
 }
 
 void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
 {
-  // Pop current 3D world matrices back again...
-  glMatrixMode (GL_PROJECTION);
-  glPopMatrix();
-  glMatrixMode (GL_MODELVIEW);
-  glPopMatrix();
-
-  if (fMemoryForDisplayLists) {
-    glEndList();
-  }
-  if (fReadyForTransients || !fMemoryForDisplayLists) {
-    glFlush ();
-    glDrawBuffer (GL_BACK);
-  }
-  G4VSceneHandler::EndPrimitives2D ();
+  fProcessing2D = false;
+  G4OpenGLSceneHandler::EndPrimitives2D ();
 }
 
@@ -253,6 +268,5 @@
       "  display List for fTopPODL - try OpenGL Immediated mode."
 	   << G4endl;
-  }
-  else {
+  } else {
     glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); {
       for (size_t i = 0; i < fPOList.size (); i++) {
@@ -260,4 +274,6 @@
 	G4OpenGLTransform3D oglt (fPOList[i].fTransform);
 	glMultMatrixd (oglt.GetGLMatrix ());
+	if (fpViewer->GetViewParameters().IsPicking())
+	  glLoadName(fPOList[i].fPickName);
 	glCallList (fPOList[i].fDisplayListId);
 	glPopMatrix();
@@ -288,4 +304,5 @@
   fPOList.clear ();
   fSolidMap.clear ();
+  ClearAndDestroyAtts();
 
   // ...and clear transient store...
@@ -375,5 +392,20 @@
 	(fSolidMap.find (pSolid) != fSolidMap.end ())) {
       fDisplayListId = fSolidMap [pSolid];
-      fPOList.push_back(PO(fDisplayListId,*fpObjectTransformation));
+      PO po(fDisplayListId,*fpObjectTransformation);
+      if (fpViewer->GetViewParameters().IsPicking()) {
+	G4AttHolder* holder = new G4AttHolder;
+	// Load G4Atts from G4VisAttributes, if any...
+	const G4VisAttributes* va = pPVModel->GetCurrentLV()->GetVisAttributes();
+	if (va) {
+	  const std::map<G4String,G4AttDef>* vaDefs = va->GetAttDefs();
+	  if (vaDefs) holder->AddAtts(va->CreateAttValues(), vaDefs);
+	}
+	// Load G4Atts from G4PhysicalVolumeModel...
+	const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs();
+	if (defs) holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs);
+	fPickMap[++fPickName] = holder;
+	po.fPickName = fPickName;
+      }
+      fPOList.push_back(po);
     }
     else {
