Salome HOME
updated copyright message
[modules/gui.git] / src / VTKViewer / VTKViewer_PolyDataMapper.cxx
index 019350a173c7c91d33ae4fc6946134ebdf04df75..d98944141878f194bd83d22005a662f631d8b13b 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,6 +16,9 @@
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+#ifdef VTK_OPENGL2
+#define GL_GLEXT_PROTOTYPES
+#endif
 
 #include "VTKViewer_PolyDataMapper.h"
 #include "VTKViewer_MarkerUtils.h"
@@ -25,6 +28,7 @@
 #include <QString>
 
 #include <vtkCellArray.h>
+#include <vtkXMLImageDataReader.h>
 #include <vtkImageData.h>
 #include <vtkObjectFactory.h>
 #include <vtkPointData.h>
 #include <vtkSmartPointer.h>
 #include <vtkTimerLog.h>
 #include <vtkWindow.h>
+#include <vtkRenderWindow.h>
+#include <vtkCommand.h>
+#include <vtkCellData.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkIdTypeArray.h>
+
+#include <Basics_Utils.hxx>
 
-#ifndef WNT
+#ifndef WIN32
 # ifndef GLX_GLXEXT_LEGACY
 #  define GLX_GLXEXT_LEGACY
 # endif
+#ifdef __APPLE__
+#import <mach-o/dyld.h>
+#import <stdlib.h>
+#import <string.h>
+void * glXGetProcAddressARB (const GLubyte *name)
+
+{
+    NSSymbol symbol;
+    char *symbolName;
+    symbolName = (char *)malloc (strlen ((const char *)name) + 2); // 1
+    strcpy(symbolName + 1, (const char *)name); // 2
+    symbolName[0] = '_'; // 3
+    symbol = NULL;
+    if (NSIsSymbolNameDefined (symbolName)) // 4
+        symbol = NSLookupAndBindSymbol (symbolName);
+    free (symbolName); // 5
+    return symbol ? NSAddressOfSymbol (symbol) : NULL; // 6
+}
+#else
 # include <GL/glx.h>
+#endif
 # include <dlfcn.h>
 #else
 # include <wingdi.h>
 #endif
 
 #ifndef VTK_IMPLEMENT_MESA_CXX
-vtkCxxRevisionMacro(VTKViewer_PolyDataMapper, "Revision$");
-vtkStandardNewMacro(VTKViewer_PolyDataMapper);
+vtkStandardNewMacro(VTKViewer_PolyDataMapper)
 #endif
 
 // some definitions for what the polydata has in it
@@ -59,67 +89,33 @@ vtkStandardNewMacro(VTKViewer_PolyDataMapper);
 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
 #define VTK_PDPSM_OPAQUE_COLORS      0x0040
 
-#ifndef APIENTRY
-#define APIENTRY
-#endif
-#ifndef APIENTRYP
-#define APIENTRYP APIENTRY *
-#endif
-
-#ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
-#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB  0x8642
-#endif
-
-#ifndef GL_ARB_point_sprite
-#define GL_POINT_SPRITE_ARB               0x8861
-#define GL_COORD_REPLACE_ARB              0x8862
-#endif
-
-#ifndef GL_ARB_vertex_buffer_object
-typedef ptrdiff_t GLsizeiptrARB;
+typedef GLfloat TBall;
 
-#define GL_ARRAY_BUFFER_ARB               0x8892
-#define GL_STATIC_DRAW_ARB                0x88E4
+#ifdef WIN32
+  #ifdef max
+    #undef max
+  #endif
 #endif
 
-typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
-typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
-typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
-typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+// ----------------------------------------------- Special Textures -----------------------------------
+// texture id for balls drawing
+#define BallTextureId 0 
 
-static PFNGLGENBUFFERSARBPROC               vglGenBuffersARB              = NULL;
-static PFNGLBINDBUFFERARBPROC               vglBindBufferARB              = NULL;
-static PFNGLBUFFERDATAARBPROC               vglBufferDataARB              = NULL;
-static PFNGLDELETEBUFFERSARBPROC            vglDeleteBuffersARB           = NULL;
 
-#ifndef WNT
-#define GL_GetProcAddress( x )   glXGetProcAddressARB( (const GLubyte*)x )
-#else
-#define GL_GetProcAddress( x )   wglGetProcAddress( (const LPCSTR)x )
-#endif
 
-bool InitializeBufferExtensions()
+void MessageCallback( GLenum /*source*/,
+                      GLenum type,
+                      GLuint /*id*/,
+                      GLenum severity,
+                      GLsizei /*length*/,
+                      const GLcharARB* message,
+                      const void* /*userParam*/ )
 {
-  vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
-  if( !vglGenBuffersARB )
-    return false;
-
-  vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
-  if( !vglBindBufferARB )
-    return false;
-
-  vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
-  if( !vglBufferDataARB )
-    return false;
-
-  vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
-  if( !vglDeleteBuffersARB )
-    return false;
-
-  return true;
-};
+  fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
+           ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
+            type, severity, message );
+}
 
-static bool IsBufferExtensionsInitialized = InitializeBufferExtensions();
 
 //-----------------------------------------------------------------------------
 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
@@ -134,6 +130,20 @@ VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
   this->MarkerType                = VTK::MT_NONE;
   this->MarkerScale               = VTK::MS_NONE;
   this->MarkerId                  = 0;
+  this->BallEnabled               = false;
+  this->BallScale                 = 1.0;
+  this->PointProgram              = 0;
+#ifdef VTK_OPENGL2
+  this->VertexShader              = 0;
+  this->FragmentShader            = 0;
+#endif
+
+  this->OpenGLHelper.Init();
+
+  // For debug purposes only
+  // glEnable              ( GL_DEBUG_OUTPUT );
+  // glDebugMessageCallback( (GLDEBUGPROC) MessageCallback, 0 );
+
 }
 
 //-----------------------------------------------------------------------------
@@ -141,8 +151,64 @@ VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
 {
   if( PointSpriteTexture > 0 )
     glDeleteTextures( 1, &PointSpriteTexture );
+
+#ifdef VTK_OPENGL2
+  this->OpenGLHelper.DestroyShaderProgram( this->PointProgram, this->VertexShader, this->FragmentShader);
+#endif
 }
 
+//-----------------------------------------------------------------------------
+int VTKViewer_PolyDataMapper::InitShader()
+{
+#ifdef VTK_OPENGL2
+#if defined(WIN32) && defined(UNICODE)
+       std::wstring wFilePath = std::wstring(_wgetenv(L"GUI_ROOT_DIR")) + L"/share/salome/resources/gui/Point";
+       std::string filePath = Kernel_Utils::utf8_encode_s(wFilePath.c_str());
+#else
+  std::string filePath = std::string( getenv( "GUI_ROOT_DIR") ) + "/share/salome/resources/gui/Point";
+#endif
+  if( !this->OpenGLHelper.CreateShaderProgram(filePath, this->PointProgram, this->VertexShader, this->FragmentShader) )
+    return false;
+
+  // Get uniform locations.
+  GLint current_program;
+  glGetIntegerv( GL_CURRENT_PROGRAM, &current_program );
+  this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
+
+  this->myLocations.ModelViewProjection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uModelViewProjectionMatrix" );
+  this->myLocations.Projection          = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uProjectionMatrix" );
+  this->myLocations.GeneralPointSize    = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uGeneralPointSize" );
+  this->myLocations.PointSprite         = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uPointSprite" );
+
+  this->OpenGLHelper.vglUseProgramObjectARB( current_program );
+
+  this->OpenGLHelper.vglGenVertexArraysARB(1, &this->VertexArrayObject);
+#else
+#if defined(WIN32) && defined(UNICODE)
+       std::wstring wFilePath = std::wstring(_wgetenv( L"GUI_ROOT_DIR" ) ) + L"/share/salome/resources/gui/Vertex_Program_ARB.txt";
+       std::string fileName = Kernel_Utils::utf8_encode( wFilePath.c_str() );
+#else
+  std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
+                         "/share/salome/resources/gui/Vertex_Program_ARB.txt";
+#endif
+
+  char* shader = GUI_OPENGL::readFromFile( fileName );
+
+  GLhandleARB VertexShader = this->OpenGLHelper.vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
+  this->OpenGLHelper.vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
+  this->OpenGLHelper.vglCompileShaderARB( VertexShader );
+
+  this->PointProgram = this->OpenGLHelper.vglCreateProgramObjectARB();
+  this->OpenGLHelper.vglAttachObjectARB( this->PointProgram, VertexShader );
+
+  this->OpenGLHelper.vglLinkProgramARB( this->PointProgram );
+  free( shader );
+#endif
+
+  return ES_Ok;
+}
+
+
 //-----------------------------------------------------------------------------
 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
 {
@@ -153,6 +219,109 @@ void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
   this->Modified();
 }
 
+//-----------------------------------------------------------------------------
+// Definition of structures and fuctions used in SetBallEnabled() method
+namespace VTK
+{
+  //----------------------------------------------------------------------------
+  vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
+    if( !theMainTexture || !theAlphaTexture )
+      return 0;
+    
+    vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
+    vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
+    
+    aMainReader->SetFileName( theMainTexture );
+    anAlphaReader->SetFileName( theAlphaTexture );
+
+    aMainReader->Update();
+    anAlphaReader->Update();
+    
+    vtkImageData* aMainImageData = aMainReader->GetOutput();
+    vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
+    
+    int* aMainImageSize = aMainImageData->GetDimensions();
+    int* anAlphaImageSize = anAlphaImageData->GetDimensions();
+    if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
+      return NULL;
+
+    vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
+    aCompositeImageData->Delete();
+    
+    int aNbCompositeComponents = 4;
+    aCompositeImageData->SetDimensions(aMainImageSize);
+    aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
+    
+    unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
+    unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
+    unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
+
+    int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
+    int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
+    int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
+
+    int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
+    for(; aCompositeId < aCompositeSize;) {
+      aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
+      aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
+      aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
+      aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
+
+      aMainId += aNbMainComponents;
+      anAlphaId += aNbAlphaComponents;
+      aCompositeId += aNbCompositeComponents;
+    }
+    aMainReader->Delete();
+    anAlphaReader->Delete();
+    return aCompositeImageData;
+  }  
+}
+
+//-----------------------------------------------------------------------------
+bool VTKViewer_PolyDataMapper::GetBallEnabled()
+{
+  return this->BallEnabled;
+}
+//-----------------------------------------------------------------------------
+void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
+{ 
+  if( this->BallEnabled == theBallEnabled )
+    return;
+  else 
+    this->BallEnabled = theBallEnabled;
+
+  if(!this->BallEnabled) {
+    this->ImageData = NULL;
+  }
+
+  if(this->BallEnabled) {
+    if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
+      QString aMainTexture  = getenv( "GUI_ROOT_DIR" );
+      aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
+      
+      QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
+      anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
+      vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toUtf8().constData(), anAlphaTexture.toUtf8().constData() );
+      this->SpecialTextures[BallTextureId] = aTextureValue;
+    }
+    this->ImageData = this->SpecialTextures[BallTextureId];
+  }
+  this->Modified();
+}
+
+//-----------------------------------------------------------------------------
+double VTKViewer_PolyDataMapper::GetBallScale()
+{
+  return this->BallScale;
+}
+//-----------------------------------------------------------------------------
+void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
+{
+  if( this->BallScale == theBallScale )
+    return;
+  this->BallScale = theBallScale;
+}
+
 //-----------------------------------------------------------------------------
 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
 {
@@ -222,16 +391,30 @@ int VTKViewer_PolyDataMapper::GetMarkerTexture()
 //-----------------------------------------------------------------------------
 int VTKViewer_PolyDataMapper::InitExtensions()
 {
-  char* ext = (char*)glGetString( GL_EXTENSIONS );
-  if( !IsBufferExtensionsInitialized ||
+#ifdef VTK_OPENGL2
+  int n = 0;
+  std::ostringstream strm;
+  glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+  for (int i = 0; i < n; i++)
+    {
+      const char *exti = (const char *)this->OpenGLHelper.vglGetStringiARB(GL_EXTENSIONS, i);
+      strm<< exti <<" ";
+    }
+  std::string s = strm.str();
+  const char* ext = s.c_str();
+#else  
+  const char* ext = (const char*)glGetString( GL_EXTENSIONS );
+#endif
+  if( !this->OpenGLHelper.IsInitialized() || !ext ||
       strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
-      strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL )
+      strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
+      strstr( ext, "GL_ARB_shader_objects") == NULL )
   {
     MESSAGE("Initializing ARB extensions failed");
     return ES_Error;
   }
 
-  return ES_Ok;
+  return this->InitShader();
 }
 
 //-----------------------------------------------------------------------------
@@ -246,7 +429,12 @@ void VTKViewer_PolyDataMapper::InitPointSprites()
   glEnable( GL_DEPTH_TEST );
 
   glEnable( GL_ALPHA_TEST );
-  glAlphaFunc( GL_GREATER, 0.0 );
+  if(!this->BallEnabled) {
+    glAlphaFunc( GL_GREATER, 0.0 );
+  }
+  else { 
+    glAlphaFunc( GL_GREATER, 0.5 );
+  }
 
   glDisable( GL_LIGHTING );
 
@@ -268,38 +456,174 @@ void VTKViewer_PolyDataMapper::InitTextures()
   if( !this->ImageData.GetPointer() )
     return;
 
+  glEnable( GL_TEXTURE_2D );
+  if( this->PointSpriteTexture == 0 ) {
+    glGenTextures( 1, &this->PointSpriteTexture );
+  }
+#ifdef VTK_OPENGL2
+  this->OpenGLHelper.vglActiveTextureARB( GL_TEXTURE0 );
+#endif
+  glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
+  glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
-  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+  
+  if(this->BallEnabled) {
+    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+  } else {
+    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+  }
 
   int* aSize = this->ImageData->GetDimensions();
   unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
 
-  //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-  glEnable( GL_TEXTURE_2D );
-  glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
-  glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
+#ifdef VTK_OPENGL2
+  // Set sampler.
+  this->OpenGLHelper.vglUniform1iARB( this->myLocations.PointSprite, GL_TEXTURE0 );
+#endif
 }
 
 //-----------------------------------------------------------------------------
 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
 {
-  bool isUsePointSprites = this->MarkerEnabled && this->MarkerType != VTK::MT_NONE;
+  bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) || 
+    this->BallEnabled;
   if( isUsePointSprites )
   {
-    if( this->ExtensionsInitialized == ES_None )
+    if( this->ExtensionsInitialized != ES_Ok )
       this->ExtensionsInitialized = this->InitExtensions();
     this->InitPointSprites();
     this->InitTextures();
   }
 
-  MAPPER_SUPERCLASS::RenderPiece( ren, act );
+  if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
+    MAPPER_SUPERCLASS::RenderPiece( ren, act );
+    if( isUsePointSprites )
+      this->CleanupPointSprites();
+    glBindTexture( GL_TEXTURE_2D, 0 );
+  } else {
+    vtkIdType numPts;
+    vtkPolyData *input= this->GetInput();
+
+    //
+    // make sure that we've been properly initialized
+    //
+    if (ren->GetRenderWindow()->CheckAbortStatus())
+      return;
+
+    if ( input == NULL )
+    {
+      vtkErrorMacro(<< "No input!");
+      return;
+    }
+    else
+    {
+      this->InvokeEvent(vtkCommand::StartEvent,NULL);
+      this->Update();
+      this->InvokeEvent(vtkCommand::EndEvent,NULL);
+      numPts = input->GetNumberOfPoints();
+    }
 
-  if( isUsePointSprites )
+    if (numPts == 0)
+    {
+      vtkDebugMacro(<< "No points!");
+      return;
+    }
+
+    // make sure our window is current
+    ren->GetRenderWindow()->MakeCurrent();
+
+    GLint current_program;
+    glGetIntegerv( GL_CURRENT_PROGRAM, &current_program );
+    this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
+
+#ifndef VTK_OPENGL2
+    //
+    // if something has changed regenerate colors and display lists
+    // if required
+    //
+    int noAbort=1;
+    if ( this->GetMTime() > this->BuildTime ||
+        input->GetMTime() > this->BuildTime ||
+        act->GetProperty()->GetMTime() > this->BuildTime ||
+        ren->GetRenderWindow() != this->LastWindow)
+    {
+      // sets this->Colors as side effect
+      this->MapScalars( act->GetProperty()->GetOpacity() );
+
+      if (!this->ImmediateModeRendering &&
+         !this->GetGlobalImmediateModeRendering())
+      {
+       this->ReleaseGraphicsResources(ren->GetRenderWindow());
+       this->LastWindow = ren->GetRenderWindow();
+
+       // get a unique display list id
+       this->ListId = glGenLists(1);
+       glNewList(this->ListId,GL_COMPILE);
+
+       noAbort = this->Draw(ren,act);
+       glEndList();
+
+       // Time the actual drawing
+       this->Timer->StartTimer();
+       glCallList(this->ListId);
+       this->Timer->StopTimer();
+      }
+      else
+      {
+       this->ReleaseGraphicsResources(ren->GetRenderWindow());
+       this->LastWindow = ren->GetRenderWindow();
+      }
+      if (noAbort)
+       this->BuildTime.Modified();
+    }
+    // if nothing changed but we are using display lists, draw it
+    else
+    {
+      if (!this->ImmediateModeRendering &&
+         !this->GetGlobalImmediateModeRendering())
+      {
+       // Time the actual drawing
+       this->Timer->StartTimer();
+       glCallList(this->ListId);
+       this->Timer->StopTimer();
+      }
+    }
+
+    // if we are in immediate mode rendering we always
+    // want to draw the primitives here
+    if (this->ImmediateModeRendering ||
+       this->GetGlobalImmediateModeRendering())
+    {
+      // sets this->Colors as side effect
+      this->MapScalars( act->GetProperty()->GetOpacity() );
+
+      // Time the actual drawing
+      this->Timer->StartTimer();
+      this->Draw(ren,act);
+      this->Timer->StopTimer();
+    }
+
+    this->TimeToDraw = (float)this->Timer->GetElapsedTime();
+
+    // If the timer is not accurate enough, set it to a small
+    // time so that it is not zero
+    if ( this->TimeToDraw == 0.0 )
+      this->TimeToDraw = 0.0001;
+#else
+    //this->RenderPieceStart(ren, act);
+    this->RenderPieceDraw(ren, act);
+    //    this->RenderEdges(ren,act);
+    //this->RenderPieceFinish(ren, act);
+#endif    
+    this->OpenGLHelper.vglUseProgramObjectARB( current_program );
     this->CleanupPointSprites();
+    glBindTexture( GL_TEXTURE_2D, 0 );
+  }  
 }
 
 //-----------------------------------------------------------------------------
@@ -316,7 +640,7 @@ namespace VTK
   //-----------------------------------------------------------------------------
   struct TColorFunctorBase
   {
-    vtkFloatingPointType myAlpha;
+    double myAlpha;
 
     TColorFunctorBase( vtkProperty* theProperty )
     {
@@ -326,12 +650,14 @@ namespace VTK
     virtual
     void
     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
+
+    virtual ~TColorFunctorBase() {}
   };
 
   //-----------------------------------------------------------------------------
   struct TPropertyColor : TColorFunctorBase
   {
-    vtkFloatingPointType myColor[3];
+    double myColor[3];
 
     TPropertyColor( vtkProperty* theProperty ):
       TColorFunctorBase( theProperty )
@@ -341,7 +667,7 @@ namespace VTK
 
     virtual
     void
-    get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
+    get( TVertex& theVertex, vtkIdType /*thePointId*/, vtkIdType /*theCellId*/ )
     {
       theVertex.r = myColor[0];
       theVertex.g = myColor[1];
@@ -389,7 +715,7 @@ namespace VTK
 
     virtual
     vtkIdType
-    GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
+    GetTupleId( vtkIdType thePointId, vtkIdType /*theCellId*/ )
     {
       return thePointId;
     }
@@ -405,7 +731,7 @@ namespace VTK
 
     virtual
     vtkIdType
-    GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
+    GetTupleId( vtkIdType /*thePointId*/, vtkIdType theCellId )
     {
       return theCellId;
     }
@@ -418,11 +744,19 @@ namespace VTK
                    TColorFunctorBase* theColorFunctor,
                    TVertex* theVertexArr,
                    vtkIdType &theCellId,
-                   vtkIdType &theVertexId )
+                   vtkIdType &theVertexId,
+                   TBall* theBallArr,
+                   vtkDataArray* theDiamArray,
+                   double theBallScale )
   {
-    vtkIdType* ptIds = theCells->GetPointer();
+    vtkIdType* ptIds = theCells->GetData()->GetPointer(0);
     vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
 
+    bool mapBalls = false; 
+    if(theBallArr && theDiamArray) {
+      mapBalls = true;
+    }
+
     while ( ptIds < endPtIds ) {
       vtkIdType nPts = *ptIds;
       ++ptIds;
@@ -442,6 +776,10 @@ namespace VTK
         ++ptIds; 
         --nPts; 
       }
+      
+      if(mapBalls){
+        theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
+      }
 
       ++theCellId;
     }
@@ -452,36 +790,63 @@ namespace VTK
   void DrawCellsPoints( vtkPolyData* theInput,
                         vtkPoints* thePoints,
                         TColorFunctorBase* theColorFunctor,
-                        TVertex* theVertexArr )
+                        TVertex* theVertexArr,
+                        TBall* theBallArr,
+                        double theBallScale )
   {
     vtkIdType aCellId = 0, aVertexId = 0;
 
     TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
+    vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;    
 
-    if ( vtkCellArray* aCellArray = theInput->GetVerts() )
-      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
+    if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
+      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
+    }
   
     if ( vtkCellArray* aCellArray = theInput->GetLines() )
-      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
+      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
   
     if ( vtkCellArray* aCellArray = theInput->GetPolys() )
-      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
+      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
   
     if ( vtkCellArray* aCellArray = theInput->GetStrips() )
-      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId ); 
+      DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale ); 
   }
 } // namespace VTK
 
+#ifndef VTK_OPENGL2
 //-----------------------------------------------------------------------------
 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
 {
-  if( !this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer() )
+  int noAbort = 1;
+  if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
     return MAPPER_SUPERCLASS::Draw( ren, act );
 
+  InternalDraw( ren, act );
+
+  return noAbort;
+}
+#else
+//-----------------------------------------------------------------------------
+void VTKViewer_PolyDataMapper::RenderPieceDraw( vtkRenderer* ren, vtkActor* act ) {
+  if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled) {
+    MAPPER_SUPERCLASS::RenderPieceDraw( ren, act );
+    return;
+  }
+  InternalDraw( ren, act );
+}
+#endif
+
+#ifdef VTK_OPENGL2
+#include <vtkCamera.h>
+#include <vtkOpenGLCamera.h>
+#include <vtkOpenGLActor.h>
+#endif
+
+void VTKViewer_PolyDataMapper::InternalDraw(vtkRenderer* ren, vtkActor* act ) {
   vtkUnsignedCharArray* colors = NULL;
   vtkPolyData* input  = this->GetInput();
   vtkPoints* points;
-  int noAbort = 1;
   int cellScalars = 0;
   vtkProperty* prop = act->GetProperty();
 
@@ -489,34 +854,50 @@ int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
 
   if ( this->Colors )
   {
-    colors = this->Colors;
-    if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
-          this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
-          !input->GetPointData()->GetScalars() )
-         && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA)
-      cellScalars = 1;
+    if(!this->BallEnabled) {
+      colors = this->Colors;
+      if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
+           this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
+           !input->GetPointData()->GetScalars() )
+          && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
+       cellScalars = 1;
+    }
   }
 
   {
     vtkIdType aTotalConnectivitySize = 0;
+    vtkIdType aNbCells = 0;
 
-    if ( vtkCellArray* aCellArray = input->GetVerts() )
+    if ( vtkCellArray* aCellArray = input->GetVerts() ) {
       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+      aNbCells += aCellArray->GetNumberOfCells();
+    }
 
-    if ( vtkCellArray* aCellArray = input->GetLines() )
+    if ( vtkCellArray* aCellArray = input->GetLines() ) {
       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+      aNbCells += aCellArray->GetNumberOfCells();
+    }
 
-    if ( vtkCellArray* aCellArray = input->GetPolys() )
+    if ( vtkCellArray* aCellArray = input->GetPolys() ) {
       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+      aNbCells += aCellArray->GetNumberOfCells();
+    }
 
-    if ( vtkCellArray* aCellArray = input->GetStrips() )
+    if ( vtkCellArray* aCellArray = input->GetStrips() ) {
       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+      aNbCells += aCellArray->GetNumberOfCells();
+    }
 
     if ( aTotalConnectivitySize > 0 ) {
       VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
+      
+      TBall* aBallArray = 0;
+
+      if(this->BallEnabled) {
+       aBallArray = new TBall[aNbCells];
+      }
 
       int* aSize = this->ImageData->GetDimensions();
-      glPointSize( std::max( aSize[0], aSize[1] ) );
 
       int aMode = 0; // to remove
       {
@@ -530,39 +911,154 @@ int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
           aColorFunctor = new VTK::TPropertyColor( prop );
         }
         if ( points->GetDataType() == VTK_FLOAT )
-          VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr );
+          VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
         else
-          VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr );
+          VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
 
         delete aColorFunctor;
       }
 
       if( this->ExtensionsInitialized == ES_Ok ) {
-        GLuint aBufferObjectID = 0;
-        vglGenBuffersARB( 1, &aBufferObjectID );
-        vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+#ifdef VTK_OPENGL2
+       GLint current_program;
+       glGetIntegerv( GL_CURRENT_PROGRAM, &current_program );
+        this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
+
+        vtkOpenGLCamera *cam = (vtkOpenGLCamera *)(ren->GetActiveCamera());
+        vtkMatrix4x4 *wcdc;
+        vtkMatrix4x4 *wcvc;
+        vtkMatrix3x3 *norms;
+        vtkMatrix4x4 *vcdc;
+        cam->GetKeyMatrices(ren,wcvc,norms,vcdc,wcdc);
+        if (!act->GetIsIdentity())
+        {
+          vtkMatrix4x4 *mcwc;
+          vtkMatrix3x3 *anorms;
+          ((vtkOpenGLActor *)act)->GetKeyMatrices( mcwc, anorms );
+          vtkMatrix4x4::Multiply4x4( mcwc, wcdc, this->TempMatrix4 );
+
+          this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, this->TempMatrix4 );
+        }
+        else
+        {
+               this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, wcdc );
+        }
+        this->OpenGLHelper.SetUniformMatrix( this->myLocations.Projection, vcdc );
+
+        this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, std::max( aSize[0], aSize[1] ) );
+
+        GLuint aBufferObjectID, aDiamsID = 0;
+
+        this->OpenGLHelper.vglBindVertexArrayARB( this->VertexArrayObject );
+        this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
+        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
         
         int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
-        vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
+        this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
         
         delete [] aVertexArr;
         
-        vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
-        vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+
+        GLint colorAttrib  = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Color" );
+        GLint vertexAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Vertex" );
+        GLint diamAttrib   = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Diameter" );
+
+        GLsizei vertexSize = sizeof(VTK::TVertex);
+
+        this->OpenGLHelper.vglVertexAttribPointerARB( colorAttrib, 4, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0 );
+        this->OpenGLHelper.vglEnableVertexAttribArrayARB( colorAttrib );
+
+        this->OpenGLHelper.vglVertexAttribPointerARB( vertexAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 4) );
+        this->OpenGLHelper.vglEnableVertexAttribArrayARB( vertexAttrib );
+
+       if(this->BallEnabled) {
+         // Don't use uniform variable.
+         this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, -1 );
+         this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
+         this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
+
+         int aDiamsSize = sizeof(TBall)*aNbCells;
+         this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
+
+         delete [] aBallArray;
+
+         this->OpenGLHelper.vglVertexAttribPointerARB( diamAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0 );
+         this->OpenGLHelper.vglEnableVertexAttribArrayARB( diamAttrib );
+       }
+
+       glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
+
+       if( this->BallEnabled ) {
+         this->OpenGLHelper.vglDisableVertexAttribArrayARB( diamAttrib );
+         this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+         this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
+       }
+
+       this->OpenGLHelper.vglDisableVertexAttribArrayARB( colorAttrib );
+       this->OpenGLHelper.vglDisableVertexAttribArrayARB( vertexAttrib );
+       this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+       this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
+       this->OpenGLHelper.vglBindVertexArrayARB( 0 );
+
+       this->OpenGLHelper.vglUseProgramObjectARB( current_program );
+#else
+       GLuint aBufferObjectID, aDiamsID = 0;
+       GLint attribute_diams = -1;
+       glPointSize( std::max( aSize[0], aSize[1] ) );
+       this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
+       this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+
+       int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
+       this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
+
+       delete [] aVertexArr;
+
+       this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+       this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
         
         glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
         glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
         
         glEnableClientState( GL_VERTEX_ARRAY );
         glEnableClientState( GL_COLOR_ARRAY );
-        
+
+       if(this->BallEnabled) {
+               this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
+               this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
+
+         int aDiamsSize = sizeof(TBall)*aNbCells;
+         this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
+
+         delete [] aBallArray;
+         this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+         this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
+
+         attribute_diams = this->OpenGLHelper.vglGetAttribLocationARB(this->PointProgram, "diameter");
+         this->OpenGLHelper.vglEnableVertexAttribArrayARB(attribute_diams);
+         this->OpenGLHelper.vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
+         this->OpenGLHelper.vglVertexAttribPointerARB(
+                                   attribute_diams,   // attribute
+                                   1,                 // number of elements per vertex, here (diameter)
+                                   GL_FLOAT,          // the type of each element
+                                   GL_FALSE,          // take our values as-is
+                                   0,                 // no extra data between each position
+                                   0                  // offset of first element
+                                   );
+       }
+
         glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
         
         glDisableClientState( GL_COLOR_ARRAY );
-        glDisableClientState( GL_VERTEX_ARRAY );
-        
-        vglDeleteBuffersARB( 1, &aBufferObjectID );
-      } else { // there are no extensions
+        glDisableClientState( GL_VERTEX_ARRAY );       
+        this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
+
+       if(this->BallEnabled) {
+               this->OpenGLHelper.vglDisableVertexAttribArrayARB(attribute_diams);
+               this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
+       }
+
+#endif
+         } else { // there are no extensions
         glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
         glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), 
                          (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
@@ -581,5 +1077,4 @@ int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
   }
 
   this->UpdateProgress(1.0);
-  return noAbort;
 }