1 // Copyright (C) 2007-2012 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 <vtkImageData.h>
29 #include <vtkObjectFactory.h>
30 #include <vtkPointData.h>
31 #include <vtkPolyData.h>
32 #include <vtkProperty.h>
33 #include <vtkRenderer.h>
34 #include <vtkSmartPointer.h>
35 #include <vtkTimerLog.h>
36 #include <vtkWindow.h>
39 # ifndef GLX_GLXEXT_LEGACY
40 # define GLX_GLXEXT_LEGACY
48 #ifndef VTK_IMPLEMENT_MESA_CXX
49 vtkCxxRevisionMacro(VTKViewer_PolyDataMapper, "Revision$");
50 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
53 // some definitions for what the polydata has in it
54 #define VTK_PDPSM_COLORS 0x0001
55 #define VTK_PDPSM_CELL_COLORS 0x0002
56 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
57 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
58 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
59 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
60 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
66 #define APIENTRYP APIENTRY *
69 #ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
70 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
73 #ifndef GL_ARB_point_sprite
74 #define GL_POINT_SPRITE_ARB 0x8861
75 #define GL_COORD_REPLACE_ARB 0x8862
78 #ifndef GL_ARB_vertex_buffer_object
79 typedef ptrdiff_t GLsizeiptrARB;
81 #define GL_ARRAY_BUFFER_ARB 0x8892
82 #define GL_STATIC_DRAW_ARB 0x88E4
85 typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
86 typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
87 typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
88 typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
90 static PFNGLGENBUFFERSARBPROC vglGenBuffersARB = NULL;
91 static PFNGLBINDBUFFERARBPROC vglBindBufferARB = NULL;
92 static PFNGLBUFFERDATAARBPROC vglBufferDataARB = NULL;
93 static PFNGLDELETEBUFFERSARBPROC vglDeleteBuffersARB = NULL;
96 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
98 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
101 bool InitializeBufferExtensions()
103 vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
104 if( !vglGenBuffersARB )
107 vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
108 if( !vglBindBufferARB )
111 vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
112 if( !vglBufferDataARB )
115 vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
116 if( !vglDeleteBuffersARB )
122 static bool IsBufferExtensionsInitialized = InitializeBufferExtensions();
124 //-----------------------------------------------------------------------------
125 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
127 Q_INIT_RESOURCE( VTKViewer );
129 this->ExtensionsInitialized = ES_None;
131 this->PointSpriteTexture = 0;
133 this->MarkerEnabled = false;
134 this->MarkerType = VTK::MT_NONE;
135 this->MarkerScale = VTK::MS_NONE;
139 //-----------------------------------------------------------------------------
140 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
142 if( PointSpriteTexture > 0 )
143 glDeleteTextures( 1, &PointSpriteTexture );
146 //-----------------------------------------------------------------------------
147 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
149 if( this->MarkerEnabled == theMarkerEnabled )
152 this->MarkerEnabled = theMarkerEnabled;
156 //-----------------------------------------------------------------------------
157 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
159 if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
162 this->MarkerType = theMarkerType;
163 this->MarkerScale = theMarkerScale;
165 if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
166 this->ImageData = NULL;
171 int aMarkerType = (int)this->MarkerType;
172 int aMarkerScale = (int)this->MarkerScale;
174 int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
176 if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
178 QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
179 VTK::MarkerTexture aMarkerTexture;
180 if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
181 this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
184 this->ImageData = this->StandardTextures[ anId ];
188 //-----------------------------------------------------------------------------
189 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
191 if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
194 this->MarkerType = VTK::MT_USER;
195 this->MarkerId = theMarkerId;
197 if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
198 this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
200 this->ImageData = this->CustomTextures[ theMarkerId ];
204 //-----------------------------------------------------------------------------
205 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
207 return this->MarkerType;
210 //-----------------------------------------------------------------------------
211 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
213 return this->MarkerScale;
216 //-----------------------------------------------------------------------------
217 int VTKViewer_PolyDataMapper::GetMarkerTexture()
219 return this->MarkerId;
222 //-----------------------------------------------------------------------------
223 int VTKViewer_PolyDataMapper::InitExtensions()
225 char* ext = (char*)glGetString( GL_EXTENSIONS );
226 if( !IsBufferExtensionsInitialized ||
227 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
228 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL )
230 MESSAGE("Initializing ARB extensions failed");
237 //-----------------------------------------------------------------------------
238 void VTKViewer_PolyDataMapper::InitPointSprites()
240 glEnable( GL_POINT_SPRITE_ARB );
241 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
243 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
245 glDepthFunc( GL_LEQUAL );
246 glEnable( GL_DEPTH_TEST );
248 glEnable( GL_ALPHA_TEST );
249 glAlphaFunc( GL_GREATER, 0.0 );
251 glDisable( GL_LIGHTING );
253 glDisable( GL_COLOR_MATERIAL );
256 //-----------------------------------------------------------------------------
257 void VTKViewer_PolyDataMapper::CleanupPointSprites()
261 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
262 glDisable( GL_POINT_SPRITE_ARB );
265 //-----------------------------------------------------------------------------
266 void VTKViewer_PolyDataMapper::InitTextures()
268 if( !this->ImageData.GetPointer() )
271 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
272 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
273 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
274 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
276 int* aSize = this->ImageData->GetDimensions();
277 unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
278 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
279 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
281 //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
282 glEnable( GL_TEXTURE_2D );
283 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
284 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
287 //-----------------------------------------------------------------------------
288 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
290 bool isUsePointSprites = this->MarkerEnabled && this->MarkerType != VTK::MT_NONE;
291 if( isUsePointSprites )
293 if( this->ExtensionsInitialized == ES_None )
294 this->ExtensionsInitialized = this->InitExtensions();
295 this->InitPointSprites();
296 this->InitTextures();
299 MAPPER_SUPERCLASS::RenderPiece( ren, act );
301 if( isUsePointSprites )
302 this->CleanupPointSprites();
305 //-----------------------------------------------------------------------------
306 // Definition of structures and fuctions used in Draw() method
309 //-----------------------------------------------------------------------------
316 //-----------------------------------------------------------------------------
317 struct TColorFunctorBase
319 vtkFloatingPointType myAlpha;
321 TColorFunctorBase( vtkProperty* theProperty )
323 myAlpha = theProperty->GetOpacity();
328 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
331 //-----------------------------------------------------------------------------
332 struct TPropertyColor : TColorFunctorBase
334 vtkFloatingPointType myColor[3];
336 TPropertyColor( vtkProperty* theProperty ):
337 TColorFunctorBase( theProperty )
339 theProperty->GetColor( myColor );
344 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
346 theVertex.r = myColor[0];
347 theVertex.g = myColor[1];
348 theVertex.b = myColor[2];
349 theVertex.a = myAlpha;
353 //-----------------------------------------------------------------------------
354 struct TColors2Color : TColorFunctorBase
356 vtkUnsignedCharArray* myColors;
358 TColors2Color( vtkProperty* theProperty,
359 vtkUnsignedCharArray* theColors ):
360 TColorFunctorBase( theProperty ),
361 myColors( theColors )
366 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
368 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
369 unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
371 theVertex.r = int( aColor[0] ) / 255.0;
372 theVertex.g = int( aColor[1] ) / 255.0;
373 theVertex.b = int( aColor[2] ) / 255.0;
374 theVertex.a = myAlpha;
379 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
382 //-----------------------------------------------------------------------------
383 struct TPointColors2Color : TColors2Color
385 TPointColors2Color( vtkProperty* theProperty,
386 vtkUnsignedCharArray* theColors ):
387 TColors2Color( theProperty, theColors )
392 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
398 //-----------------------------------------------------------------------------
399 struct TCellColors2Color : TColors2Color
401 TCellColors2Color( vtkProperty* theProperty,
402 vtkUnsignedCharArray* theColors ):
403 TColors2Color( theProperty, theColors )
408 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
414 //-----------------------------------------------------------------------------
415 template < class TCoordinates >
416 void DrawPoints( TCoordinates* theStartPoints,
417 vtkCellArray* theCells,
418 TColorFunctorBase* theColorFunctor,
419 TVertex* theVertexArr,
420 vtkIdType &theCellId,
421 vtkIdType &theVertexId )
423 vtkIdType* ptIds = theCells->GetPointer();
424 vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
426 while ( ptIds < endPtIds ) {
427 vtkIdType nPts = *ptIds;
431 TVertex& aVertex = theVertexArr[ theVertexId ];
432 vtkIdType aPointId = *ptIds;
434 TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
435 aVertex.vx = anOffsetPoints[0];
436 aVertex.vy = anOffsetPoints[1];
437 aVertex.vz = anOffsetPoints[2];
439 theColorFunctor->get( aVertex, aPointId, theCellId );
450 //-----------------------------------------------------------------------------
451 template < class TCoordinates >
452 void DrawCellsPoints( vtkPolyData* theInput,
453 vtkPoints* thePoints,
454 TColorFunctorBase* theColorFunctor,
455 TVertex* theVertexArr )
457 vtkIdType aCellId = 0, aVertexId = 0;
459 TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
461 if ( vtkCellArray* aCellArray = theInput->GetVerts() )
462 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
464 if ( vtkCellArray* aCellArray = theInput->GetLines() )
465 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
467 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
468 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
470 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
471 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
475 //-----------------------------------------------------------------------------
476 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
478 if( !this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer() )
479 return MAPPER_SUPERCLASS::Draw( ren, act );
481 vtkUnsignedCharArray* colors = NULL;
482 vtkPolyData* input = this->GetInput();
486 vtkProperty* prop = act->GetProperty();
488 points = input->GetPoints();
492 colors = this->Colors;
493 if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
494 this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
495 !input->GetPointData()->GetScalars() )
496 && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA)
501 vtkIdType aTotalConnectivitySize = 0;
503 if ( vtkCellArray* aCellArray = input->GetVerts() )
504 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
506 if ( vtkCellArray* aCellArray = input->GetLines() )
507 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
509 if ( vtkCellArray* aCellArray = input->GetPolys() )
510 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
512 if ( vtkCellArray* aCellArray = input->GetStrips() )
513 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
515 if ( aTotalConnectivitySize > 0 ) {
516 VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
518 int* aSize = this->ImageData->GetDimensions();
519 glPointSize( std::max( aSize[0], aSize[1] ) );
521 int aMode = 0; // to remove
523 VTK::TColorFunctorBase* aColorFunctor = NULL;
524 if( colors && aMode != 1 ) {
526 aColorFunctor = new VTK::TCellColors2Color( prop, colors );
528 aColorFunctor = new VTK::TPointColors2Color( prop, colors );
530 aColorFunctor = new VTK::TPropertyColor( prop );
532 if ( points->GetDataType() == VTK_FLOAT )
533 VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr );
535 VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr );
537 delete aColorFunctor;
540 if( this->ExtensionsInitialized == ES_Ok ) {
541 GLuint aBufferObjectID = 0;
542 vglGenBuffersARB( 1, &aBufferObjectID );
543 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
545 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
546 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
548 delete [] aVertexArr;
550 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
551 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
553 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
554 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
556 glEnableClientState( GL_VERTEX_ARRAY );
557 glEnableClientState( GL_COLOR_ARRAY );
559 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
561 glDisableClientState( GL_COLOR_ARRAY );
562 glDisableClientState( GL_VERTEX_ARRAY );
564 vglDeleteBuffersARB( 1, &aBufferObjectID );
565 } else { // there are no extensions
566 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
567 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex),
568 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
570 glEnableClientState( GL_VERTEX_ARRAY );
571 glEnableClientState( GL_COLOR_ARRAY );
573 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
575 glDisableClientState( GL_COLOR_ARRAY );
576 glDisableClientState( GL_VERTEX_ARRAY );
578 delete [] aVertexArr;
583 this->UpdateProgress(1.0);