]> SALOME platform Git repositories - modules/gui.git/blob - src/VTKViewer/VTKViewer_PolyDataMapper.cxx
Salome HOME
f61d2af2165adb49115956402d39580767249308
[modules/gui.git] / src / VTKViewer / VTKViewer_PolyDataMapper.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #ifdef VTK_OPENGL2
20 #define GL_GLEXT_PROTOTYPES
21 #endif
22
23 #include "VTKViewer_PolyDataMapper.h"
24 #include "VTKViewer_MarkerUtils.h"
25
26 #include <utilities.h>
27
28 #include <QString>
29
30 #include <vtkCellArray.h>
31 #include <vtkXMLImageDataReader.h>
32 #include <vtkImageData.h>
33 #include <vtkObjectFactory.h>
34 #include <vtkPointData.h>
35 #include <vtkPolyData.h>
36 #include <vtkProperty.h>
37 #include <vtkRenderer.h>
38 #include <vtkSmartPointer.h>
39 #include <vtkTimerLog.h>
40 #include <vtkWindow.h>
41 #include <vtkRenderWindow.h>
42 #include <vtkCommand.h>
43 #include <vtkCellData.h>
44
45 #ifndef WIN32
46 # ifndef GLX_GLXEXT_LEGACY
47 #  define GLX_GLXEXT_LEGACY
48 # endif
49 # include <GL/glx.h>
50 # include <dlfcn.h>
51 #else
52 # include <wingdi.h>
53 #endif
54
55 #ifndef VTK_IMPLEMENT_MESA_CXX
56 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
57 #endif
58
59 // some definitions for what the polydata has in it
60 #define VTK_PDPSM_COLORS             0x0001
61 #define VTK_PDPSM_CELL_COLORS        0x0002
62 #define VTK_PDPSM_POINT_TYPE_FLOAT   0x0004
63 #define VTK_PDPSM_POINT_TYPE_DOUBLE  0x0008
64 #define VTK_PDPSM_NORMAL_TYPE_FLOAT  0x0010
65 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
66 #define VTK_PDPSM_OPAQUE_COLORS      0x0040
67
68 typedef GLfloat TBall;
69
70 #ifdef WIN32
71   #ifdef max
72     #undef max
73   #endif
74 #endif
75
76 // ----------------------------------------------- Special Textures -----------------------------------
77 // texture id for balls drawing
78 #define BallTextureId 0 
79
80
81 //-----------------------------------------------------------------------------
82 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
83 {
84   Q_INIT_RESOURCE( VTKViewer );
85
86   this->ExtensionsInitialized     = ES_None;
87
88   this->PointSpriteTexture        = 0;
89
90   this->MarkerEnabled             = false;
91   this->MarkerType                = VTK::MT_NONE;
92   this->MarkerScale               = VTK::MS_NONE;
93   this->MarkerId                  = 0;
94   this->BallEnabled               = false;
95   this->BallScale                 = 1.0;
96   this->PointProgram              = 0;
97 #ifdef VTK_OPENGL2
98   this->VertexShader              = 0;
99   this->FragmentShader            = 0;
100 #endif
101
102   this->OpenGLHelper.Init();
103 }
104
105 //-----------------------------------------------------------------------------
106 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
107 {
108   if( PointSpriteTexture > 0 )
109     glDeleteTextures( 1, &PointSpriteTexture );
110
111 #ifdef VTK_OPENGL2
112   this->OpenGLHelper.DestroyShaderProgram( this->PointProgram, this->VertexShader, this->FragmentShader);
113 #endif
114 }
115
116 //-----------------------------------------------------------------------------
117 int VTKViewer_PolyDataMapper::InitShader()
118 {
119 #ifdef VTK_OPENGL2
120   std::string filePath = std::string( getenv( "GUI_ROOT_DIR") ) + "/share/salome/resources/gui/Point";
121   if( !this->OpenGLHelper.CreateShaderProgram(filePath, this->PointProgram, this->VertexShader, this->FragmentShader) )
122     return false;
123
124   // Get uniform locations.
125   this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
126
127   this->myLocations.ModelViewProjection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uModelViewProjectionMatrix" );
128   this->myLocations.GeneralPointSize    = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uGeneralPointSize" );
129   this->myLocations.PointSprite         = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uPointSprite" );
130
131   this->OpenGLHelper.vglUseProgramObjectARB( 0 );
132
133   this->OpenGLHelper.vglGenVertexArraysARB(1, &this->VertexArrayObject);
134 #else
135   std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
136                          "/share/salome/resources/gui/Vertex_Program_ARB.txt";
137
138   char* shader = readFromFile( fileName );
139
140   GLhandleARB VertexShader = this->OpenGLHelper.vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
141   this->OpenGLHelper.vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
142   this->OpenGLHelper.vglCompileShaderARB( VertexShader );
143
144   this->PointProgram = this->OpenGLHelper.vglCreateProgramObjectARB();
145   this->OpenGLHelper.vglAttachObjectARB( this->PointProgram, VertexShader );
146
147   this->OpenGLHelper.vglLinkProgramARB( this->PointProgram );
148   free( shader );
149 #endif
150
151   return ES_Ok;
152 }
153
154
155 //-----------------------------------------------------------------------------
156 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
157 {
158   if( this->MarkerEnabled == theMarkerEnabled )
159     return;
160
161   this->MarkerEnabled = theMarkerEnabled;
162   this->Modified();
163 }
164
165 //-----------------------------------------------------------------------------
166 // Definition of structures and fuctions used in SetBallEnabled() method
167 namespace VTK
168 {
169   //----------------------------------------------------------------------------
170   vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
171     if( !theMainTexture || !theAlphaTexture )
172       return 0;
173     
174     vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
175     vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
176     
177     aMainReader->SetFileName( theMainTexture );
178     anAlphaReader->SetFileName( theAlphaTexture );
179
180     aMainReader->Update();
181     anAlphaReader->Update();
182     
183     vtkImageData* aMainImageData = aMainReader->GetOutput();
184     vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
185     
186     int* aMainImageSize = aMainImageData->GetDimensions();
187     int* anAlphaImageSize = anAlphaImageData->GetDimensions();
188     if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
189       return NULL;
190
191     vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
192     aCompositeImageData->Delete();
193     
194     int aNbCompositeComponents = 4;
195     aCompositeImageData->SetDimensions(aMainImageSize);
196     aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
197     
198     unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
199     unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
200     unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
201
202     int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
203     int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
204     int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
205
206     int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
207     for(; aCompositeId < aCompositeSize;) {
208       aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
209       aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
210       aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
211       aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
212
213       aMainId += aNbMainComponents;
214       anAlphaId += aNbAlphaComponents;
215       aCompositeId += aNbCompositeComponents;
216     }
217     aMainReader->Delete();
218     anAlphaReader->Delete();
219     return aCompositeImageData;
220   }  
221 }
222
223 //-----------------------------------------------------------------------------
224 bool VTKViewer_PolyDataMapper::GetBallEnabled()
225 {
226   return this->BallEnabled;
227 }
228 //-----------------------------------------------------------------------------
229 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
230
231   if( this->BallEnabled == theBallEnabled )
232     return;
233   else 
234     this->BallEnabled = theBallEnabled;
235
236   if(!this->BallEnabled) {
237     this->ImageData = NULL;
238   }
239
240   if(this->BallEnabled) {
241     if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
242       QString aMainTexture  = getenv( "GUI_ROOT_DIR" );
243       aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
244       
245       QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
246       anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
247       vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toLatin1().constData(), anAlphaTexture.toLatin1().constData() );
248       this->SpecialTextures[BallTextureId] = aTextureValue;
249     }
250     this->ImageData = this->SpecialTextures[BallTextureId];
251   }
252   this->Modified();
253 }
254
255 //-----------------------------------------------------------------------------
256 double VTKViewer_PolyDataMapper::GetBallScale()
257 {
258   return this->BallScale;
259 }
260 //-----------------------------------------------------------------------------
261 void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
262 {
263   if( this->BallScale == theBallScale )
264     return;
265   this->BallScale = theBallScale;
266 }
267
268 //-----------------------------------------------------------------------------
269 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
270 {
271   if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
272     return;
273
274   this->MarkerType = theMarkerType;
275   this->MarkerScale = theMarkerScale;
276
277   if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
278     this->ImageData = NULL;
279     this->Modified();
280     return;
281   }
282
283   int aMarkerType = (int)this->MarkerType;
284   int aMarkerScale = (int)this->MarkerScale;
285
286   int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
287
288   if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
289   {
290     QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
291     VTK::MarkerTexture aMarkerTexture;
292     if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
293       this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
294   }
295
296   this->ImageData = this->StandardTextures[ anId ];
297   this->Modified();
298 }
299
300 //-----------------------------------------------------------------------------
301 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
302 {
303   if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
304     return;
305
306   this->MarkerType = VTK::MT_USER;
307   this->MarkerId = theMarkerId;
308
309   if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
310     this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
311
312   this->ImageData = this->CustomTextures[ theMarkerId ];
313   this->Modified();
314 }
315
316 //-----------------------------------------------------------------------------
317 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
318 {
319   return this->MarkerType;
320 }
321
322 //-----------------------------------------------------------------------------
323 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
324 {
325   return this->MarkerScale;
326 }
327
328 //-----------------------------------------------------------------------------
329 int VTKViewer_PolyDataMapper::GetMarkerTexture()
330 {
331   return this->MarkerId;
332 }
333
334 //-----------------------------------------------------------------------------
335 int VTKViewer_PolyDataMapper::InitExtensions()
336 {
337 #ifdef VTK_OPENGL2
338   int n = 0;
339   std::ostringstream strm;
340   glGetIntegerv(GL_NUM_EXTENSIONS, &n);
341   for (int i = 0; i < n; i++)
342     {
343       const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, i);
344       strm<< exti <<" ";
345     }
346   std::string s = strm.str();
347   const char* ext = s.c_str();
348 #else  
349   const char* ext = (const char*)glGetString( GL_EXTENSIONS );
350 #endif
351   if( !this->OpenGLHelper.IsInitialized() || !ext ||
352       strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
353       strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
354       strstr( ext, "GL_ARB_shader_objects") == NULL )
355   {
356     MESSAGE("Initializing ARB extensions failed");
357     return ES_Error;
358   }
359
360   return this->InitShader();
361 }
362
363 //-----------------------------------------------------------------------------
364 void VTKViewer_PolyDataMapper::InitPointSprites()
365 {
366   glEnable( GL_POINT_SPRITE_ARB );
367   glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
368
369   glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
370
371   glDepthFunc( GL_LEQUAL );
372   glEnable( GL_DEPTH_TEST );
373
374   glEnable( GL_ALPHA_TEST );
375   if(!this->BallEnabled) {
376     glAlphaFunc( GL_GREATER, 0.0 );
377   }
378   else { 
379     glAlphaFunc( GL_GREATER, 0.5 );
380   }
381
382   glDisable( GL_LIGHTING );
383
384   glDisable( GL_COLOR_MATERIAL );
385 }
386
387 //-----------------------------------------------------------------------------
388 void VTKViewer_PolyDataMapper::CleanupPointSprites()
389 {
390   glPopAttrib();
391
392   glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
393   glDisable( GL_POINT_SPRITE_ARB );
394 }
395
396 //-----------------------------------------------------------------------------
397 void VTKViewer_PolyDataMapper::InitTextures()
398 {
399   if( !this->ImageData.GetPointer() )
400     return;
401
402   glEnable( GL_TEXTURE_2D );
403   if( this->PointSpriteTexture == 0 ) {
404     glGenTextures( 1, &this->PointSpriteTexture );
405   }
406 #ifdef VTK_OPENGL2
407   glActiveTexture( GL_TEXTURE0 );
408 #endif
409   glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
410   glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
411   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
412   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
413   
414   if(this->BallEnabled) {
415     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
416     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
417   } else {
418     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
419     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
420   }
421
422   int* aSize = this->ImageData->GetDimensions();
423   unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
424   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
425                 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
426
427 #ifdef VTK_OPENGL2
428   // Set sampler.
429   this->OpenGLHelper.vglUniform1iARB( this->myLocations.PointSprite, GL_TEXTURE0 );
430 #endif
431 }
432
433 //-----------------------------------------------------------------------------
434 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
435 {
436   bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) || 
437     this->BallEnabled;
438   if( isUsePointSprites )
439   {
440     if( this->ExtensionsInitialized != ES_Ok )
441       this->ExtensionsInitialized = this->InitExtensions();
442     this->InitPointSprites();
443     this->InitTextures();
444   }
445
446   if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
447     MAPPER_SUPERCLASS::RenderPiece( ren, act );
448     if( isUsePointSprites )
449       this->CleanupPointSprites();
450     glBindTexture( GL_TEXTURE_2D, 0 );
451   } else {
452     vtkIdType numPts;
453     vtkPolyData *input= this->GetInput();
454
455     //
456     // make sure that we've been properly initialized
457     //
458     if (ren->GetRenderWindow()->CheckAbortStatus())
459       return;
460
461     if ( input == NULL )
462     {
463       vtkErrorMacro(<< "No input!");
464       return;
465     }
466     else
467     {
468       this->InvokeEvent(vtkCommand::StartEvent,NULL);
469       this->Update();
470       this->InvokeEvent(vtkCommand::EndEvent,NULL);
471       numPts = input->GetNumberOfPoints();
472     }
473
474     if (numPts == 0)
475     {
476       vtkDebugMacro(<< "No points!");
477       return;
478     }
479
480     // make sure our window is current
481     ren->GetRenderWindow()->MakeCurrent();
482
483
484     this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
485
486 #ifndef VTK_OPENGL2
487     //
488     // if something has changed regenerate colors and display lists
489     // if required
490     //
491     int noAbort=1;
492     if ( this->GetMTime() > this->BuildTime ||
493          input->GetMTime() > this->BuildTime ||
494          act->GetProperty()->GetMTime() > this->BuildTime ||
495          ren->GetRenderWindow() != this->LastWindow)
496     {
497       // sets this->Colors as side effect
498       this->MapScalars( act->GetProperty()->GetOpacity() );
499
500       if (!this->ImmediateModeRendering &&
501           !this->GetGlobalImmediateModeRendering())
502       {
503         this->ReleaseGraphicsResources(ren->GetRenderWindow());
504         this->LastWindow = ren->GetRenderWindow();
505
506         // get a unique display list id
507         this->ListId = glGenLists(1);
508         glNewList(this->ListId,GL_COMPILE);
509
510         noAbort = this->Draw(ren,act);
511         glEndList();
512
513         // Time the actual drawing
514         this->Timer->StartTimer();
515         glCallList(this->ListId);
516         this->Timer->StopTimer();
517       }
518       else
519       {
520         this->ReleaseGraphicsResources(ren->GetRenderWindow());
521         this->LastWindow = ren->GetRenderWindow();
522       }
523       if (noAbort)
524         this->BuildTime.Modified();
525     }
526     // if nothing changed but we are using display lists, draw it
527     else
528     {
529       if (!this->ImmediateModeRendering &&
530           !this->GetGlobalImmediateModeRendering())
531       {
532         // Time the actual drawing
533         this->Timer->StartTimer();
534         glCallList(this->ListId);
535         this->Timer->StopTimer();
536       }
537     }
538
539     // if we are in immediate mode rendering we always
540     // want to draw the primitives here
541     if (this->ImmediateModeRendering ||
542         this->GetGlobalImmediateModeRendering())
543     {
544       // sets this->Colors as side effect
545       this->MapScalars( act->GetProperty()->GetOpacity() );
546
547       // Time the actual drawing
548       this->Timer->StartTimer();
549       this->Draw(ren,act);
550       this->Timer->StopTimer();
551     }
552
553     this->TimeToDraw = (float)this->Timer->GetElapsedTime();
554
555     // If the timer is not accurate enough, set it to a small
556     // time so that it is not zero
557     if ( this->TimeToDraw == 0.0 )
558       this->TimeToDraw = 0.0001;
559 #else
560     //this->RenderPieceStart(ren, act);
561     this->RenderPieceDraw(ren, act);
562     //    this->RenderEdges(ren,act);
563     //this->RenderPieceFinish(ren, act);
564 #endif    
565     this->OpenGLHelper.vglUseProgramObjectARB( 0 );
566     this->CleanupPointSprites();
567     glBindTexture( GL_TEXTURE_2D, 0 );
568   }  
569 }
570
571 //-----------------------------------------------------------------------------
572 // Definition of structures and fuctions used in Draw() method
573 namespace VTK
574 {
575   //-----------------------------------------------------------------------------
576   struct TVertex
577   {
578     GLfloat r, g, b, a;
579     GLfloat vx, vy, vz;
580   };
581
582   //-----------------------------------------------------------------------------
583   struct TColorFunctorBase
584   {
585     double myAlpha;
586
587     TColorFunctorBase( vtkProperty* theProperty )
588     {
589       myAlpha = theProperty->GetOpacity();
590     }
591
592     virtual
593     void
594     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
595   };
596
597   //-----------------------------------------------------------------------------
598   struct TPropertyColor : TColorFunctorBase
599   {
600     double myColor[3];
601
602     TPropertyColor( vtkProperty* theProperty ):
603       TColorFunctorBase( theProperty )
604     {
605       theProperty->GetColor( myColor );
606     }
607
608     virtual
609     void
610     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
611     {
612       theVertex.r = myColor[0];
613       theVertex.g = myColor[1];
614       theVertex.b = myColor[2];
615       theVertex.a = myAlpha;
616     }
617   };
618
619   //-----------------------------------------------------------------------------
620   struct TColors2Color : TColorFunctorBase
621   {
622     vtkUnsignedCharArray* myColors;
623
624     TColors2Color( vtkProperty* theProperty,
625                    vtkUnsignedCharArray* theColors ):
626       TColorFunctorBase( theProperty ),
627       myColors( theColors )
628     {}
629
630     virtual
631     void
632     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
633     {
634       vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
635       unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
636
637       theVertex.r = int( aColor[0] ) / 255.0;
638       theVertex.g = int( aColor[1] ) / 255.0;
639       theVertex.b = int( aColor[2] ) / 255.0;
640       theVertex.a = myAlpha;
641     }
642
643     virtual
644     vtkIdType
645     GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
646   };
647
648   //-----------------------------------------------------------------------------
649   struct TPointColors2Color : TColors2Color
650   {
651     TPointColors2Color( vtkProperty* theProperty,
652                         vtkUnsignedCharArray* theColors ):
653       TColors2Color( theProperty, theColors )
654     {}
655
656     virtual
657     vtkIdType
658     GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
659     {
660       return thePointId;
661     }
662   };
663
664   //-----------------------------------------------------------------------------
665   struct TCellColors2Color : TColors2Color
666   {
667     TCellColors2Color( vtkProperty* theProperty,
668                        vtkUnsignedCharArray* theColors ):
669       TColors2Color( theProperty, theColors )
670     {}
671
672     virtual
673     vtkIdType
674     GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
675     {
676       return theCellId;
677     }
678   };
679
680   //-----------------------------------------------------------------------------
681   template < class TCoordinates >
682   void DrawPoints( TCoordinates* theStartPoints,
683                    vtkCellArray* theCells,
684                    TColorFunctorBase* theColorFunctor,
685                    TVertex* theVertexArr,
686                    vtkIdType &theCellId,
687                    vtkIdType &theVertexId,
688                    TBall* theBallArr,
689                    vtkDataArray* theDiamArray,
690                    double theBallScale )
691   {
692     vtkIdType* ptIds = theCells->GetPointer();
693     vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
694
695     bool mapBalls = false; 
696     if(theBallArr && theDiamArray) {
697       mapBalls = true;
698     }
699
700     while ( ptIds < endPtIds ) {
701       vtkIdType nPts = *ptIds;
702       ++ptIds;
703
704       while ( nPts > 0 ) {
705         TVertex& aVertex = theVertexArr[ theVertexId ];
706         vtkIdType aPointId = *ptIds;
707
708         TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
709         aVertex.vx = anOffsetPoints[0];
710         aVertex.vy = anOffsetPoints[1];
711         aVertex.vz = anOffsetPoints[2];
712
713         theColorFunctor->get( aVertex, aPointId, theCellId );
714
715         ++theVertexId;
716         ++ptIds; 
717         --nPts; 
718       }
719       
720       if(mapBalls){
721         theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
722       }
723
724       ++theCellId;
725     }
726   }
727
728   //-----------------------------------------------------------------------------
729   template < class TCoordinates >
730   void DrawCellsPoints( vtkPolyData* theInput,
731                         vtkPoints* thePoints,
732                         TColorFunctorBase* theColorFunctor,
733                         TVertex* theVertexArr,
734                         TBall* theBallArr,
735                         double theBallScale )
736   {
737     vtkIdType aCellId = 0, aVertexId = 0;
738
739     TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
740     vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;    
741
742     if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
743       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
744     }
745   
746     if ( vtkCellArray* aCellArray = theInput->GetLines() )
747       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
748   
749     if ( vtkCellArray* aCellArray = theInput->GetPolys() )
750       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
751   
752     if ( vtkCellArray* aCellArray = theInput->GetStrips() )
753       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale ); 
754   }
755 } // namespace VTK
756
757 #ifndef VTK_OPENGL2
758 //-----------------------------------------------------------------------------
759 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
760 {
761   int noAbort = 1;
762   if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
763     return MAPPER_SUPERCLASS::Draw( ren, act );
764
765   InternalDraw( ren, act );
766
767   return noAbort;
768 }
769 #else
770 //-----------------------------------------------------------------------------
771 void VTKViewer_PolyDataMapper::RenderPieceDraw( vtkRenderer* ren, vtkActor* act ) {
772   int noAbort = 1;
773   if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled) {
774     MAPPER_SUPERCLASS::RenderPieceDraw( ren, act );
775     return;
776   }
777   InternalDraw( ren, act );
778 }
779 #endif
780
781 #ifdef VTK_OPENGL2
782 #include <vtkCamera.h>
783 #include <vtkOpenGLCamera.h>
784 #include <vtkOpenGLActor.h>
785 #endif
786
787 void VTKViewer_PolyDataMapper::InternalDraw(vtkRenderer* ren, vtkActor* act ) {
788   vtkUnsignedCharArray* colors = NULL;
789   vtkPolyData* input  = this->GetInput();
790   vtkPoints* points;
791   int cellScalars = 0;
792   vtkProperty* prop = act->GetProperty();
793
794   points = input->GetPoints();
795
796   if ( this->Colors )
797   {
798     if(!this->BallEnabled) {
799       colors = this->Colors;
800       if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
801             this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
802             !input->GetPointData()->GetScalars() )
803            && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
804         cellScalars = 1;
805     }
806   }
807
808   {
809     vtkIdType aTotalConnectivitySize = 0;
810     vtkIdType aNbCells = 0;
811
812     if ( vtkCellArray* aCellArray = input->GetVerts() ) {
813       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
814       aNbCells += aCellArray->GetNumberOfCells();
815     }
816
817     if ( vtkCellArray* aCellArray = input->GetLines() ) {
818       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
819       aNbCells += aCellArray->GetNumberOfCells();
820     }
821
822     if ( vtkCellArray* aCellArray = input->GetPolys() ) {
823       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
824       aNbCells += aCellArray->GetNumberOfCells();
825     }
826
827     if ( vtkCellArray* aCellArray = input->GetStrips() ) {
828       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
829       aNbCells += aCellArray->GetNumberOfCells();
830     }
831
832     if ( aTotalConnectivitySize > 0 ) {
833       VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
834       
835       TBall* aBallArray = 0;
836
837       if(this->BallEnabled) {
838         aBallArray = new TBall[aNbCells];
839       }
840
841       int* aSize = this->ImageData->GetDimensions();
842       //glPointSize( std::max( aSize[0], aSize[1] ) );
843
844       int aMode = 0; // to remove
845       {
846         VTK::TColorFunctorBase* aColorFunctor = NULL;
847         if( colors && aMode != 1 ) {
848           if ( cellScalars )
849             aColorFunctor = new VTK::TCellColors2Color( prop, colors );
850           else
851             aColorFunctor = new VTK::TPointColors2Color( prop, colors );
852         } else {
853           aColorFunctor = new VTK::TPropertyColor( prop );
854         }
855         if ( points->GetDataType() == VTK_FLOAT )
856           VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
857         else
858           VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
859
860         delete aColorFunctor;
861       }
862
863       if( this->ExtensionsInitialized == ES_Ok ) {
864 #ifdef VTK_OPENGL2
865         this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
866
867         vtkOpenGLCamera *cam = (vtkOpenGLCamera *)(ren->GetActiveCamera());
868         vtkMatrix4x4 *wcdc;
869         vtkMatrix4x4 *wcvc;
870         vtkMatrix3x3 *norms;
871         vtkMatrix4x4 *vcdc;
872         cam->GetKeyMatrices(ren,wcvc,norms,vcdc,wcdc);
873         if (!act->GetIsIdentity())
874         {
875           vtkMatrix4x4 *mcwc;
876           vtkMatrix3x3 *anorms;
877           ((vtkOpenGLActor *)act)->GetKeyMatrices( mcwc, anorms );
878           vtkMatrix4x4::Multiply4x4( mcwc, wcdc, this->TempMatrix4 );
879
880           this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, this->TempMatrix4 );
881         }
882         else
883         {
884                 this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, wcdc );
885         }
886
887         this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, std::max( aSize[0], aSize[1] ) );
888
889         GLuint aBufferObjectID, aDiamsID = 0;
890
891         this->OpenGLHelper.vglBindVertexArrayARB( this->VertexArrayObject );
892         this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
893         this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
894         
895         int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
896         this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
897         
898         delete [] aVertexArr;
899         
900
901         GLint colorAttrib  = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Color" );
902         GLint vertexAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Vertex" );
903         GLint diamAttrib   = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Diameter" );
904
905         GLsizei vertexSize = sizeof(VTK::TVertex);
906
907         this->OpenGLHelper.vglVertexAttribPointerARB( colorAttrib, 4, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0 );
908         this->OpenGLHelper.vglEnableVertexAttribArrayARB( colorAttrib );
909
910         this->OpenGLHelper.vglVertexAttribPointerARB( vertexAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 4) );
911         this->OpenGLHelper.vglEnableVertexAttribArrayARB( vertexAttrib );
912
913        if(this->BallEnabled) {
914          // Don't use uniform variable.
915          this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, -1 );
916          this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
917          this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
918
919          int aDiamsSize = sizeof(TBall)*aNbCells;
920          this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
921
922          delete [] aBallArray;
923
924          this->OpenGLHelper.vglVertexAttribPointerARB( diamAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0 );
925          this->OpenGLHelper.vglEnableVertexAttribArrayARB( diamAttrib );
926        }
927
928        glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
929
930        if( this->BallEnabled ) {
931          this->OpenGLHelper.vglDisableVertexAttribArrayARB( diamAttrib );
932          this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
933          this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
934        }
935
936        this->OpenGLHelper.vglDisableVertexAttribArrayARB( colorAttrib );
937        this->OpenGLHelper.vglDisableVertexAttribArrayARB( vertexAttrib );
938        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
939        this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
940        this->OpenGLHelper.vglBindVertexArrayARB( 0 );
941
942        this->OpenGLHelper.vglUseProgramObjectARB( 0 );
943 #else
944        GLuint aBufferObjectID, aDiamsID = 0;
945        GLint attribute_diams = -1;
946
947        this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
948        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
949
950        int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
951        this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
952
953        delete [] aVertexArr;
954
955        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
956        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
957         
958         glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
959         glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
960         
961         glEnableClientState( GL_VERTEX_ARRAY );
962         glEnableClientState( GL_COLOR_ARRAY );
963
964         if(this->BallEnabled) {
965                 this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
966                 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
967
968           int aDiamsSize = sizeof(TBall)*aNbCells;
969           this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
970
971           delete [] aBallArray;
972           this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
973           this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
974
975           attribute_diams = vglGetAttribLocationARB(this->PointProgram, "diameter");
976           this->OpenGLHelper.vglEnableVertexAttribArrayARB(attribute_diams);
977           this->OpenGLHelper.vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
978           this->OpenGLHelper.vglVertexAttribPointerARB(
979                                     attribute_diams,   // attribute
980                                     1,                 // number of elements per vertex, here (diameter)
981                                     GL_FLOAT,          // the type of each element
982                                     GL_FALSE,          // take our values as-is
983                                     0,                 // no extra data between each position
984                                     0                  // offset of first element
985                                     );
986         }
987
988         glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
989         
990         glDisableClientState( GL_COLOR_ARRAY );
991         glDisableClientState( GL_VERTEX_ARRAY );       
992         this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
993
994         if(this->BallEnabled) {
995                 this->OpenGLHelper.vglDisableVertexAttribArrayARB(attribute_diams);
996                 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
997         }
998
999 #endif
1000           } else { // there are no extensions
1001         glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
1002         glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), 
1003                          (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1004
1005         glEnableClientState( GL_VERTEX_ARRAY );
1006         glEnableClientState( GL_COLOR_ARRAY );
1007         
1008         glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1009         
1010         glDisableClientState( GL_COLOR_ARRAY );
1011         glDisableClientState( GL_VERTEX_ARRAY );
1012
1013         delete [] aVertexArr;
1014       }
1015     }
1016   }
1017
1018   this->UpdateProgress(1.0);
1019 }