1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "VTKViewer_PolyDataMapper.h"
21 #include "VTKViewer_MarkerUtils.h"
23 #include <utilities.h>
27 #include <vtkCellArray.h>
28 #include <vtkXMLImageDataReader.h>
29 #include <vtkImageData.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkPointData.h>
32 #include <vtkPolyData.h>
33 #include <vtkProperty.h>
34 #include <vtkRenderer.h>
35 #include <vtkSmartPointer.h>
36 #include <vtkTimerLog.h>
37 #include <vtkWindow.h>
38 #include <vtkRenderWindow.h>
39 #include <vtkCommand.h>
40 #include <vtkCellData.h>
43 # ifndef GLX_GLXEXT_LEGACY
44 # define GLX_GLXEXT_LEGACY
52 #ifndef VTK_IMPLEMENT_MESA_CXX
53 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
56 // some definitions for what the polydata has in it
57 #define VTK_PDPSM_COLORS 0x0001
58 #define VTK_PDPSM_CELL_COLORS 0x0002
59 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
60 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
61 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
62 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
63 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
69 #define APIENTRYP APIENTRY *
72 #ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
73 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
76 #ifndef GL_ARB_point_sprite
77 #define GL_POINT_SPRITE_ARB 0x8861
78 #define GL_COORD_REPLACE_ARB 0x8862
81 #ifndef GL_ARB_vertex_buffer_object
82 typedef ptrdiff_t GLsizeiptrARB;
84 #define GL_ARRAY_BUFFER_ARB 0x8892
85 #define GL_STATIC_DRAW_ARB 0x88E4
87 typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
88 typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
89 typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
90 typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
91 typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
92 typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
93 typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
94 typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
95 typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
96 typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
97 typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
98 typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
99 typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
100 typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
101 typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
103 typedef GLfloat TBall;
106 static PFNGLSHADERSOURCEARBPROC vglShaderSourceARB = NULL;
107 static PFNGLCREATESHADEROBJECTARBPROC vglCreateShaderObjectARB = NULL;
108 static PFNGLCOMPILESHADERARBPROC vglCompileShaderARB = NULL;
109 static PFNGLCREATEPROGRAMOBJECTARBPROC vglCreateProgramObjectARB = NULL;
110 static PFNGLATTACHOBJECTARBPROC vglAttachObjectARB = NULL;
111 static PFNGLLINKPROGRAMARBPROC vglLinkProgramARB = NULL;
112 static PFNGLUSEPROGRAMOBJECTARBPROC vglUseProgramObjectARB = NULL;
114 static PFNGLGENBUFFERSARBPROC vglGenBuffersARB = NULL;
115 static PFNGLBINDBUFFERARBPROC vglBindBufferARB = NULL;
116 static PFNGLBUFFERDATAARBPROC vglBufferDataARB = NULL;
117 static PFNGLDELETEBUFFERSARBPROC vglDeleteBuffersARB = NULL;
118 static PFNGLGETATTRIBLOCATIONARBPROC vglGetAttribLocationARB = NULL;
119 static PFNGLVERTEXATTRIBPOINTERPROC vglVertexAttribPointerARB = NULL;
120 static PFNGLENABLEVERTEXATTRIBARRAYARBPROC vglEnableVertexAttribArrayARB = NULL;
121 static PFNGLDISABLEVERTEXATTRIBARRAYARBPROC vglDisableVertexAttribArrayARB = NULL;
125 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
127 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
136 // ----------------------------------------------- Special Textures -----------------------------------
137 // texture id for balls drawing
138 #define BallTextureId 0
140 bool InitializeBufferExtensions()
143 vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)GL_GetProcAddress( "glShaderSourceARB" );
144 if( !vglShaderSourceARB )
147 vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)GL_GetProcAddress( "glCreateShaderObjectARB" );
148 if( !vglCreateShaderObjectARB )
151 vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)GL_GetProcAddress( "glCompileShaderARB" );
152 if( !vglCompileShaderARB )
155 vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glCreateProgramObjectARB" );
156 if( !vglCreateProgramObjectARB )
159 vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)GL_GetProcAddress( "glAttachObjectARB" );
160 if( !vglAttachObjectARB )
163 vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)GL_GetProcAddress( "glLinkProgramARB" );
164 if( !vglLinkProgramARB )
167 vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glUseProgramObjectARB" );
168 if( !vglUseProgramObjectARB )
171 vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
172 if( !vglGenBuffersARB )
175 vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
176 if( !vglBindBufferARB )
179 vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
180 if( !vglBufferDataARB )
183 vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
184 if( !vglDeleteBuffersARB )
187 vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocation" );
188 if( !vglGetAttribLocationARB )
191 vglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERPROC)GL_GetProcAddress( "glVertexAttribPointer" );
192 if( !vglVertexAttribPointerARB )
195 vglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glEnableVertexAttribArray" );
196 if(!vglEnableVertexAttribArrayARB)
199 vglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glDisableVertexAttribArray" );
201 if(!vglDisableVertexAttribArrayARB)
208 //-----------------------------------------------------------------------------
209 char* readFromFile( std::string fileName )
211 FILE* file = fopen( fileName.c_str(), "r" );
213 char* content = NULL;
218 fseek( file, 0, SEEK_END );
219 count = ftell( file );
224 content = ( char* )malloc( sizeof( char ) * ( count + 1 ) );
225 count = fread( content, sizeof( char ), count, file );
226 content[ count ] = '\0';
234 static bool IsBufferExtensionsInitialized = InitializeBufferExtensions();
236 //-----------------------------------------------------------------------------
237 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
239 Q_INIT_RESOURCE( VTKViewer );
241 this->ExtensionsInitialized = ES_None;
243 this->PointSpriteTexture = 0;
245 this->MarkerEnabled = false;
246 this->MarkerType = VTK::MT_NONE;
247 this->MarkerScale = VTK::MS_NONE;
249 this->BallEnabled = false;
252 //-----------------------------------------------------------------------------
253 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
255 if( PointSpriteTexture > 0 )
256 glDeleteTextures( 1, &PointSpriteTexture );
259 //-----------------------------------------------------------------------------
260 void VTKViewer_PolyDataMapper::InitShader()
262 std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
263 "/share/salome/resources/gui/Vertex_Program_ARB.txt";
265 char* shader = readFromFile( fileName );
267 GLhandleARB VertexShader = vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
268 vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
269 vglCompileShaderARB( VertexShader );
271 this->VertexProgram = vglCreateProgramObjectARB();
272 vglAttachObjectARB( this->VertexProgram, VertexShader );
274 vglLinkProgramARB( this->VertexProgram );
279 //-----------------------------------------------------------------------------
280 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
282 if( this->MarkerEnabled == theMarkerEnabled )
285 this->MarkerEnabled = theMarkerEnabled;
289 //-----------------------------------------------------------------------------
290 // Definition of structures and fuctions used in SetBallEnabled() method
293 //----------------------------------------------------------------------------
294 vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
295 if( !theMainTexture || !theAlphaTexture )
298 vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
299 vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
301 aMainReader->SetFileName( theMainTexture );
302 anAlphaReader->SetFileName( theAlphaTexture );
304 aMainReader->Update();
305 anAlphaReader->Update();
307 vtkImageData* aMainImageData = aMainReader->GetOutput();
308 vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
310 int* aMainImageSize = aMainImageData->GetDimensions();
311 int* anAlphaImageSize = anAlphaImageData->GetDimensions();
312 if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
315 vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
316 aCompositeImageData->Delete();
318 int aNbCompositeComponents = 4;
319 aCompositeImageData->SetDimensions(aMainImageSize);
320 aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
322 unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
323 unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
324 unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
326 int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
327 int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
328 int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
330 int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
331 for(; aCompositeId < aCompositeSize;) {
332 aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
333 aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
334 aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
335 aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
337 aMainId += aNbMainComponents;
338 anAlphaId += aNbAlphaComponents;
339 aCompositeId += aNbCompositeComponents;
341 aMainReader->Delete();
342 anAlphaReader->Delete();
343 return aCompositeImageData;
347 //-----------------------------------------------------------------------------
348 bool VTKViewer_PolyDataMapper::GetBallEnabled()
350 return this->BallEnabled;
352 //-----------------------------------------------------------------------------
353 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
355 if( this->BallEnabled == theBallEnabled )
358 this->BallEnabled = theBallEnabled;
360 if(!this->BallEnabled) {
361 this->ImageData = NULL;
364 if(this->BallEnabled) {
365 if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
366 QString aMainTexture = getenv( "GUI_ROOT_DIR" );
367 aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
369 QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
370 anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
371 vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toLatin1().constData(), anAlphaTexture.toLatin1().constData() );
372 this->SpecialTextures[BallTextureId] = aTextureValue;
374 this->ImageData = this->SpecialTextures[BallTextureId];
379 //-----------------------------------------------------------------------------
380 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
382 if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
385 this->MarkerType = theMarkerType;
386 this->MarkerScale = theMarkerScale;
388 if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
389 this->ImageData = NULL;
394 int aMarkerType = (int)this->MarkerType;
395 int aMarkerScale = (int)this->MarkerScale;
397 int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
399 if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
401 QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
402 VTK::MarkerTexture aMarkerTexture;
403 if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
404 this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
407 this->ImageData = this->StandardTextures[ anId ];
411 //-----------------------------------------------------------------------------
412 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
414 if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
417 this->MarkerType = VTK::MT_USER;
418 this->MarkerId = theMarkerId;
420 if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
421 this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
423 this->ImageData = this->CustomTextures[ theMarkerId ];
427 //-----------------------------------------------------------------------------
428 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
430 return this->MarkerType;
433 //-----------------------------------------------------------------------------
434 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
436 return this->MarkerScale;
439 //-----------------------------------------------------------------------------
440 int VTKViewer_PolyDataMapper::GetMarkerTexture()
442 return this->MarkerId;
445 //-----------------------------------------------------------------------------
446 int VTKViewer_PolyDataMapper::InitExtensions()
448 char* ext = (char*)glGetString( GL_EXTENSIONS );
449 if( !IsBufferExtensionsInitialized ||
450 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
451 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
452 strstr( ext, "GL_ARB_shader_objects") == NULL )
454 MESSAGE("Initializing ARB extensions failed");
458 if( this->BallEnabled )
464 //-----------------------------------------------------------------------------
465 void VTKViewer_PolyDataMapper::InitPointSprites()
467 glEnable( GL_POINT_SPRITE_ARB );
468 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
470 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
472 glDepthFunc( GL_LEQUAL );
473 glEnable( GL_DEPTH_TEST );
475 glEnable( GL_ALPHA_TEST );
476 if(!this->BallEnabled) {
477 glAlphaFunc( GL_GREATER, 0.0 );
480 glAlphaFunc( GL_GREATER, 0.5 );
483 glDisable( GL_LIGHTING );
485 glDisable( GL_COLOR_MATERIAL );
488 //-----------------------------------------------------------------------------
489 void VTKViewer_PolyDataMapper::CleanupPointSprites()
493 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
494 glDisable( GL_POINT_SPRITE_ARB );
497 //-----------------------------------------------------------------------------
498 void VTKViewer_PolyDataMapper::InitTextures()
500 if( !this->ImageData.GetPointer() )
503 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
504 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
506 if(this->BallEnabled) {
507 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
508 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
510 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
511 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
514 int* aSize = this->ImageData->GetDimensions();
515 unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
516 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
517 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
519 //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
520 glEnable( GL_TEXTURE_2D );
521 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
522 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
525 //-----------------------------------------------------------------------------
526 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
528 bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) ||
530 if( isUsePointSprites )
532 if( this->ExtensionsInitialized == ES_None )
533 this->ExtensionsInitialized = this->InitExtensions();
534 this->InitPointSprites();
535 this->InitTextures();
538 if(!this->BallEnabled) {
539 MAPPER_SUPERCLASS::RenderPiece( ren, act );
540 if( isUsePointSprites )
541 this->CleanupPointSprites();
544 vtkPolyData *input= this->GetInput();
547 // make sure that we've been properly initialized
549 if (ren->GetRenderWindow()->CheckAbortStatus())
554 vtkErrorMacro(<< "No input!");
559 this->InvokeEvent(vtkCommand::StartEvent,NULL);
561 this->InvokeEvent(vtkCommand::EndEvent,NULL);
562 numPts = input->GetNumberOfPoints();
567 vtkDebugMacro(<< "No points!");
571 // make sure our window is current
572 ren->GetRenderWindow()->MakeCurrent();
575 vglUseProgramObjectARB( this->VertexProgram );
578 // if something has changed regenerate colors and display lists
582 if ( this->GetMTime() > this->BuildTime ||
583 input->GetMTime() > this->BuildTime ||
584 act->GetProperty()->GetMTime() > this->BuildTime ||
585 ren->GetRenderWindow() != this->LastWindow)
587 // sets this->Colors as side effect
588 this->MapScalars( act->GetProperty()->GetOpacity() );
590 if (!this->ImmediateModeRendering &&
591 !this->GetGlobalImmediateModeRendering())
593 this->ReleaseGraphicsResources(ren->GetRenderWindow());
594 this->LastWindow = ren->GetRenderWindow();
596 // get a unique display list id
597 this->ListId = glGenLists(1);
598 glNewList(this->ListId,GL_COMPILE);
600 noAbort = this->Draw(ren,act);
603 // Time the actual drawing
604 this->Timer->StartTimer();
605 glCallList(this->ListId);
606 this->Timer->StopTimer();
610 this->ReleaseGraphicsResources(ren->GetRenderWindow());
611 this->LastWindow = ren->GetRenderWindow();
614 this->BuildTime.Modified();
616 // if nothing changed but we are using display lists, draw it
619 if (!this->ImmediateModeRendering &&
620 !this->GetGlobalImmediateModeRendering())
622 // Time the actual drawing
623 this->Timer->StartTimer();
624 glCallList(this->ListId);
625 this->Timer->StopTimer();
629 // if we are in immediate mode rendering we always
630 // want to draw the primitives here
631 if (this->ImmediateModeRendering ||
632 this->GetGlobalImmediateModeRendering())
634 // sets this->Colors as side effect
635 this->MapScalars( act->GetProperty()->GetOpacity() );
637 // Time the actual drawing
638 this->Timer->StartTimer();
640 this->Timer->StopTimer();
643 this->TimeToDraw = (float)this->Timer->GetElapsedTime();
645 // If the timer is not accurate enough, set it to a small
646 // time so that it is not zero
647 if ( this->TimeToDraw == 0.0 )
648 this->TimeToDraw = 0.0001;
650 vglUseProgramObjectARB( 0 );
652 this->CleanupPointSprites();
656 //-----------------------------------------------------------------------------
657 // Definition of structures and fuctions used in Draw() method
660 //-----------------------------------------------------------------------------
667 //-----------------------------------------------------------------------------
668 struct TColorFunctorBase
672 TColorFunctorBase( vtkProperty* theProperty )
674 myAlpha = theProperty->GetOpacity();
679 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
682 //-----------------------------------------------------------------------------
683 struct TPropertyColor : TColorFunctorBase
687 TPropertyColor( vtkProperty* theProperty ):
688 TColorFunctorBase( theProperty )
690 theProperty->GetColor( myColor );
695 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
697 theVertex.r = myColor[0];
698 theVertex.g = myColor[1];
699 theVertex.b = myColor[2];
700 theVertex.a = myAlpha;
704 //-----------------------------------------------------------------------------
705 struct TColors2Color : TColorFunctorBase
707 vtkUnsignedCharArray* myColors;
709 TColors2Color( vtkProperty* theProperty,
710 vtkUnsignedCharArray* theColors ):
711 TColorFunctorBase( theProperty ),
712 myColors( theColors )
717 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
719 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
720 unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
722 theVertex.r = int( aColor[0] ) / 255.0;
723 theVertex.g = int( aColor[1] ) / 255.0;
724 theVertex.b = int( aColor[2] ) / 255.0;
725 theVertex.a = myAlpha;
730 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
733 //-----------------------------------------------------------------------------
734 struct TPointColors2Color : TColors2Color
736 TPointColors2Color( vtkProperty* theProperty,
737 vtkUnsignedCharArray* theColors ):
738 TColors2Color( theProperty, theColors )
743 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
749 //-----------------------------------------------------------------------------
750 struct TCellColors2Color : TColors2Color
752 TCellColors2Color( vtkProperty* theProperty,
753 vtkUnsignedCharArray* theColors ):
754 TColors2Color( theProperty, theColors )
759 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
765 //-----------------------------------------------------------------------------
766 template < class TCoordinates >
767 void DrawPoints( TCoordinates* theStartPoints,
768 vtkCellArray* theCells,
769 TColorFunctorBase* theColorFunctor,
770 TVertex* theVertexArr,
771 vtkIdType &theCellId,
772 vtkIdType &theVertexId,
774 vtkDataArray* theDiamArray)
776 vtkIdType* ptIds = theCells->GetPointer();
777 vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
779 bool mapBalls = false;
780 if(theBallArr && theDiamArray) {
784 while ( ptIds < endPtIds ) {
785 vtkIdType nPts = *ptIds;
789 TVertex& aVertex = theVertexArr[ theVertexId ];
790 vtkIdType aPointId = *ptIds;
792 TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
793 aVertex.vx = anOffsetPoints[0];
794 aVertex.vy = anOffsetPoints[1];
795 aVertex.vz = anOffsetPoints[2];
797 theColorFunctor->get( aVertex, aPointId, theCellId );
805 theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0];
812 //-----------------------------------------------------------------------------
813 template < class TCoordinates >
814 void DrawCellsPoints( vtkPolyData* theInput,
815 vtkPoints* thePoints,
816 TColorFunctorBase* theColorFunctor,
817 TVertex* theVertexArr,
820 vtkIdType aCellId = 0, aVertexId = 0;
822 TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
823 vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;
825 if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
826 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams);
829 if ( vtkCellArray* aCellArray = theInput->GetLines() )
830 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams);
832 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
833 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams);
835 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
836 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams);
840 //-----------------------------------------------------------------------------
841 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
843 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
844 return MAPPER_SUPERCLASS::Draw( ren, act );
846 vtkUnsignedCharArray* colors = NULL;
847 vtkPolyData* input = this->GetInput();
851 vtkProperty* prop = act->GetProperty();
853 points = input->GetPoints();
857 if(!this->BallEnabled) {
858 colors = this->Colors;
859 if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
860 this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
861 !input->GetPointData()->GetScalars() )
862 && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
868 vtkIdType aTotalConnectivitySize = 0;
869 vtkIdType aNbCells = 0;
871 if ( vtkCellArray* aCellArray = input->GetVerts() ) {
872 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
873 aNbCells += aCellArray->GetNumberOfCells();
876 if ( vtkCellArray* aCellArray = input->GetLines() ) {
877 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
878 aNbCells += aCellArray->GetNumberOfCells();
881 if ( vtkCellArray* aCellArray = input->GetPolys() ) {
882 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
883 aNbCells += aCellArray->GetNumberOfCells();
886 if ( vtkCellArray* aCellArray = input->GetStrips() ) {
887 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
888 aNbCells += aCellArray->GetNumberOfCells();
891 if ( aTotalConnectivitySize > 0 ) {
892 VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
894 TBall* aBallArray = 0;
896 if(this->BallEnabled) {
897 aBallArray = new TBall[aNbCells];
900 int* aSize = this->ImageData->GetDimensions();
901 glPointSize( std::max( aSize[0], aSize[1] ) );
903 int aMode = 0; // to remove
905 VTK::TColorFunctorBase* aColorFunctor = NULL;
906 if( colors && aMode != 1 ) {
908 aColorFunctor = new VTK::TCellColors2Color( prop, colors );
910 aColorFunctor = new VTK::TPointColors2Color( prop, colors );
912 aColorFunctor = new VTK::TPropertyColor( prop );
914 if ( points->GetDataType() == VTK_FLOAT )
915 VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray );
917 VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray );
919 delete aColorFunctor;
922 if( this->ExtensionsInitialized == ES_Ok ) {
923 GLuint aBufferObjectID, aDiamsID = 0;
924 GLint attribute_diams = -1;
925 vglGenBuffersARB( 1, &aBufferObjectID );
926 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
928 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
929 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
931 delete [] aVertexArr;
933 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
934 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
936 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
937 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
939 glEnableClientState( GL_VERTEX_ARRAY );
940 glEnableClientState( GL_COLOR_ARRAY );
942 if(this->BallEnabled) {
943 vglGenBuffersARB( 2, &aDiamsID);
944 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
946 int aDiamsSize = sizeof(TBall)*aNbCells;
947 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
949 delete [] aBallArray;
950 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
951 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
953 attribute_diams = vglGetAttribLocationARB(this->VertexProgram, "diameter");
954 vglEnableVertexAttribArrayARB(attribute_diams);
955 vglBindBufferARB(GL_ARRAY_BUFFER, aDiamsID);
956 vglVertexAttribPointerARB(
957 attribute_diams, // attribute
958 1, // number of elements per vertex, here (diameter)
959 GL_FLOAT, // the type of each element
960 GL_FALSE, // take our values as-is
961 0, // no extra data between each position
962 0 // offset of first element
966 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
968 glDisableClientState( GL_COLOR_ARRAY );
969 glDisableClientState( GL_VERTEX_ARRAY );
970 vglDeleteBuffersARB( 1, &aBufferObjectID );
972 if(this->BallEnabled) {
973 vglDisableVertexAttribArrayARB(attribute_diams);
974 vglDeleteBuffersARB( 2, &aDiamsID );
977 } else { // there are no extensions
978 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
979 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex),
980 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
982 glEnableClientState( GL_VERTEX_ARRAY );
983 glEnableClientState( GL_COLOR_ARRAY );
985 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
987 glDisableClientState( GL_COLOR_ARRAY );
988 glDisableClientState( GL_VERTEX_ARRAY );
990 delete [] aVertexArr;
995 this->UpdateProgress(1.0);