1 // Copyright (C) 2007-2023 CEA, EDF, 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, or (at your option) any later version.
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 #define GL_GLEXT_PROTOTYPES
23 #include "VTKViewer_PolyDataMapper.h"
24 #include "VTKViewer_MarkerUtils.h"
26 #include <utilities.h>
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 #include <vtkUnsignedCharArray.h>
45 #include <vtkIdTypeArray.h>
47 #include <Basics_Utils.hxx>
50 # ifndef GLX_GLXEXT_LEGACY
51 # define GLX_GLXEXT_LEGACY
54 #import <mach-o/dyld.h>
57 void * glXGetProcAddressARB (const GLubyte *name)
62 symbolName = (char *)malloc (strlen ((const char *)name) + 2); // 1
63 strcpy(symbolName + 1, (const char *)name); // 2
64 symbolName[0] = '_'; // 3
66 if (NSIsSymbolNameDefined (symbolName)) // 4
67 symbol = NSLookupAndBindSymbol (symbolName);
68 free (symbolName); // 5
69 return symbol ? NSAddressOfSymbol (symbol) : NULL; // 6
79 #ifndef VTK_IMPLEMENT_MESA_CXX
80 vtkStandardNewMacro(VTKViewer_PolyDataMapper)
83 // some definitions for what the polydata has in it
84 #define VTK_PDPSM_COLORS 0x0001
85 #define VTK_PDPSM_CELL_COLORS 0x0002
86 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
87 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
88 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
89 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
90 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
92 typedef GLfloat TBall;
100 // ----------------------------------------------- Special Textures -----------------------------------
101 // texture id for balls drawing
102 #define BallTextureId 0
106 void MessageCallback( GLenum /*source*/,
111 const GLcharARB* message,
112 const void* /*userParam*/ )
114 fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
115 ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
116 type, severity, message );
120 //-----------------------------------------------------------------------------
121 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
123 Q_INIT_RESOURCE( VTKViewer );
125 this->ExtensionsInitialized = ES_None;
127 this->PointSpriteTexture = 0;
129 this->MarkerEnabled = false;
130 this->MarkerType = VTK::MT_NONE;
131 this->MarkerScale = VTK::MS_NONE;
133 this->BallEnabled = false;
134 this->BallScale = 1.0;
135 this->PointProgram = 0;
137 this->VertexShader = 0;
138 this->FragmentShader = 0;
141 this->OpenGLHelper.Init();
143 // For debug purposes only
144 // glEnable ( GL_DEBUG_OUTPUT );
145 // glDebugMessageCallback( (GLDEBUGPROC) MessageCallback, 0 );
149 //-----------------------------------------------------------------------------
150 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
152 if( PointSpriteTexture > 0 )
153 glDeleteTextures( 1, &PointSpriteTexture );
156 this->OpenGLHelper.DestroyShaderProgram( this->PointProgram, this->VertexShader, this->FragmentShader);
160 //-----------------------------------------------------------------------------
161 int VTKViewer_PolyDataMapper::InitShader()
164 #if defined(WIN32) && defined(UNICODE)
165 std::wstring wFilePath = std::wstring(_wgetenv(L"GUI_ROOT_DIR")) + L"/share/salome/resources/gui/Point";
166 std::string filePath = Kernel_Utils::utf8_encode_s(wFilePath.c_str());
168 std::string filePath = std::string( getenv( "GUI_ROOT_DIR") ) + "/share/salome/resources/gui/Point";
170 if( !this->OpenGLHelper.CreateShaderProgram(filePath, this->PointProgram, this->VertexShader, this->FragmentShader) )
173 // Get uniform locations.
174 GLint current_program;
175 glGetIntegerv( GL_CURRENT_PROGRAM, ¤t_program );
176 this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
178 this->myLocations.ModelViewProjection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uModelViewProjectionMatrix" );
179 this->myLocations.Projection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uProjectionMatrix" );
180 this->myLocations.GeneralPointSize = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uGeneralPointSize" );
181 this->myLocations.PointSprite = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uPointSprite" );
183 this->OpenGLHelper.vglUseProgramObjectARB( current_program );
185 this->OpenGLHelper.vglGenVertexArraysARB(1, &this->VertexArrayObject);
187 #if defined(WIN32) && defined(UNICODE)
188 std::wstring wFilePath = std::wstring(_wgetenv( L"GUI_ROOT_DIR" ) ) + L"/share/salome/resources/gui/Vertex_Program_ARB.txt";
189 std::string fileName = Kernel_Utils::utf8_encode( wFilePath.c_str() );
191 std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
192 "/share/salome/resources/gui/Vertex_Program_ARB.txt";
195 char* shader = GUI_OPENGL::readFromFile( fileName );
197 GLhandleARB VertexShader = this->OpenGLHelper.vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
198 this->OpenGLHelper.vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
199 this->OpenGLHelper.vglCompileShaderARB( VertexShader );
201 this->PointProgram = this->OpenGLHelper.vglCreateProgramObjectARB();
202 this->OpenGLHelper.vglAttachObjectARB( this->PointProgram, VertexShader );
204 this->OpenGLHelper.vglLinkProgramARB( this->PointProgram );
212 //-----------------------------------------------------------------------------
213 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
215 if( this->MarkerEnabled == theMarkerEnabled )
218 this->MarkerEnabled = theMarkerEnabled;
222 //-----------------------------------------------------------------------------
223 // Definition of structures and fuctions used in SetBallEnabled() method
226 //----------------------------------------------------------------------------
227 vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
228 if( !theMainTexture || !theAlphaTexture )
231 vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
232 vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
234 aMainReader->SetFileName( theMainTexture );
235 anAlphaReader->SetFileName( theAlphaTexture );
237 aMainReader->Update();
238 anAlphaReader->Update();
240 vtkImageData* aMainImageData = aMainReader->GetOutput();
241 vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
243 int* aMainImageSize = aMainImageData->GetDimensions();
244 int* anAlphaImageSize = anAlphaImageData->GetDimensions();
245 if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
248 vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
249 aCompositeImageData->Delete();
251 int aNbCompositeComponents = 4;
252 aCompositeImageData->SetDimensions(aMainImageSize);
253 aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
255 unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
256 unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
257 unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
259 int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
260 int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
261 int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
263 int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
264 for(; aCompositeId < aCompositeSize;) {
265 aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
266 aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
267 aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
268 aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
270 aMainId += aNbMainComponents;
271 anAlphaId += aNbAlphaComponents;
272 aCompositeId += aNbCompositeComponents;
274 aMainReader->Delete();
275 anAlphaReader->Delete();
276 return aCompositeImageData;
280 //-----------------------------------------------------------------------------
281 bool VTKViewer_PolyDataMapper::GetBallEnabled()
283 return this->BallEnabled;
285 //-----------------------------------------------------------------------------
286 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
288 if( this->BallEnabled == theBallEnabled )
291 this->BallEnabled = theBallEnabled;
293 if(!this->BallEnabled) {
294 this->ImageData = NULL;
297 if(this->BallEnabled) {
298 if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
299 QString aMainTexture = getenv( "GUI_ROOT_DIR" );
300 aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
302 QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
303 anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
304 vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toUtf8().constData(), anAlphaTexture.toUtf8().constData() );
305 this->SpecialTextures[BallTextureId] = aTextureValue;
307 this->ImageData = this->SpecialTextures[BallTextureId];
312 //-----------------------------------------------------------------------------
313 double VTKViewer_PolyDataMapper::GetBallScale()
315 return this->BallScale;
317 //-----------------------------------------------------------------------------
318 void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
320 if( this->BallScale == theBallScale )
322 this->BallScale = theBallScale;
325 //-----------------------------------------------------------------------------
326 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
328 if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
331 this->MarkerType = theMarkerType;
332 this->MarkerScale = theMarkerScale;
334 if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
335 this->ImageData = NULL;
340 int aMarkerType = (int)this->MarkerType;
341 int aMarkerScale = (int)this->MarkerScale;
343 int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
345 if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
347 QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
348 VTK::MarkerTexture aMarkerTexture;
349 if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
350 this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
353 this->ImageData = this->StandardTextures[ anId ];
357 //-----------------------------------------------------------------------------
358 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
360 if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
363 this->MarkerType = VTK::MT_USER;
364 this->MarkerId = theMarkerId;
366 if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
367 this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
369 this->ImageData = this->CustomTextures[ theMarkerId ];
373 //-----------------------------------------------------------------------------
374 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
376 return this->MarkerType;
379 //-----------------------------------------------------------------------------
380 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
382 return this->MarkerScale;
385 //-----------------------------------------------------------------------------
386 int VTKViewer_PolyDataMapper::GetMarkerTexture()
388 return this->MarkerId;
391 //-----------------------------------------------------------------------------
392 int VTKViewer_PolyDataMapper::InitExtensions()
396 std::ostringstream strm;
397 glGetIntegerv(GL_NUM_EXTENSIONS, &n);
398 for (int i = 0; i < n; i++)
400 const char *exti = (const char *)this->OpenGLHelper.vglGetStringiARB(GL_EXTENSIONS, i);
403 std::string s = strm.str();
404 const char* ext = s.c_str();
406 const char* ext = (const char*)glGetString( GL_EXTENSIONS );
408 if( !this->OpenGLHelper.IsInitialized() || !ext ||
409 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
410 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
411 strstr( ext, "GL_ARB_shader_objects") == NULL )
413 MESSAGE("Initializing ARB extensions failed");
417 return this->InitShader();
420 //-----------------------------------------------------------------------------
421 void VTKViewer_PolyDataMapper::InitPointSprites()
423 glEnable( GL_POINT_SPRITE_ARB );
424 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
426 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
428 glDepthFunc( GL_LEQUAL );
429 glEnable( GL_DEPTH_TEST );
431 glEnable( GL_ALPHA_TEST );
432 if(!this->BallEnabled) {
433 glAlphaFunc( GL_GREATER, 0.0 );
436 glAlphaFunc( GL_GREATER, 0.5 );
439 glDisable( GL_LIGHTING );
441 glDisable( GL_COLOR_MATERIAL );
444 //-----------------------------------------------------------------------------
445 void VTKViewer_PolyDataMapper::CleanupPointSprites()
449 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
450 glDisable( GL_POINT_SPRITE_ARB );
453 //-----------------------------------------------------------------------------
454 void VTKViewer_PolyDataMapper::InitTextures()
456 if( !this->ImageData.GetPointer() )
459 glEnable( GL_TEXTURE_2D );
460 if( this->PointSpriteTexture == 0 ) {
461 glGenTextures( 1, &this->PointSpriteTexture );
464 this->OpenGLHelper.vglActiveTextureARB( GL_TEXTURE0 );
466 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
467 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
468 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
469 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
471 if(this->BallEnabled) {
472 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
473 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
475 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
476 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
479 int* aSize = this->ImageData->GetDimensions();
480 unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
481 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
482 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
486 this->OpenGLHelper.vglUniform1iARB( this->myLocations.PointSprite, GL_TEXTURE0 );
490 //-----------------------------------------------------------------------------
491 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
493 bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) ||
495 if( isUsePointSprites )
497 if( this->ExtensionsInitialized != ES_Ok )
498 this->ExtensionsInitialized = this->InitExtensions();
499 this->InitPointSprites();
500 this->InitTextures();
503 if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
504 MAPPER_SUPERCLASS::RenderPiece( ren, act );
505 if( isUsePointSprites )
506 this->CleanupPointSprites();
507 glBindTexture( GL_TEXTURE_2D, 0 );
510 vtkPolyData *input= this->GetInput();
513 // make sure that we've been properly initialized
515 if (ren->GetRenderWindow()->CheckAbortStatus())
520 vtkErrorMacro(<< "No input!");
525 this->InvokeEvent(vtkCommand::StartEvent,NULL);
527 this->InvokeEvent(vtkCommand::EndEvent,NULL);
528 numPts = input->GetNumberOfPoints();
533 vtkDebugMacro(<< "No points!");
537 // make sure our window is current
538 ren->GetRenderWindow()->MakeCurrent();
540 GLint current_program;
541 glGetIntegerv( GL_CURRENT_PROGRAM, ¤t_program );
542 this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
546 // if something has changed regenerate colors and display lists
550 if ( this->GetMTime() > this->BuildTime ||
551 input->GetMTime() > this->BuildTime ||
552 act->GetProperty()->GetMTime() > this->BuildTime ||
553 ren->GetRenderWindow() != this->LastWindow)
555 // sets this->Colors as side effect
556 this->MapScalars( act->GetProperty()->GetOpacity() );
558 if (!this->ImmediateModeRendering &&
559 !this->GetGlobalImmediateModeRendering())
561 this->ReleaseGraphicsResources(ren->GetRenderWindow());
562 this->LastWindow = ren->GetRenderWindow();
564 // get a unique display list id
565 this->ListId = glGenLists(1);
566 glNewList(this->ListId,GL_COMPILE);
568 noAbort = this->Draw(ren,act);
571 // Time the actual drawing
572 this->Timer->StartTimer();
573 glCallList(this->ListId);
574 this->Timer->StopTimer();
578 this->ReleaseGraphicsResources(ren->GetRenderWindow());
579 this->LastWindow = ren->GetRenderWindow();
582 this->BuildTime.Modified();
584 // if nothing changed but we are using display lists, draw it
587 if (!this->ImmediateModeRendering &&
588 !this->GetGlobalImmediateModeRendering())
590 // Time the actual drawing
591 this->Timer->StartTimer();
592 glCallList(this->ListId);
593 this->Timer->StopTimer();
597 // if we are in immediate mode rendering we always
598 // want to draw the primitives here
599 if (this->ImmediateModeRendering ||
600 this->GetGlobalImmediateModeRendering())
602 // sets this->Colors as side effect
603 this->MapScalars( act->GetProperty()->GetOpacity() );
605 // Time the actual drawing
606 this->Timer->StartTimer();
608 this->Timer->StopTimer();
611 this->TimeToDraw = (float)this->Timer->GetElapsedTime();
613 // If the timer is not accurate enough, set it to a small
614 // time so that it is not zero
615 if ( this->TimeToDraw == 0.0 )
616 this->TimeToDraw = 0.0001;
618 //this->RenderPieceStart(ren, act);
619 this->RenderPieceDraw(ren, act);
620 // this->RenderEdges(ren,act);
621 //this->RenderPieceFinish(ren, act);
623 this->OpenGLHelper.vglUseProgramObjectARB( current_program );
624 this->CleanupPointSprites();
625 glBindTexture( GL_TEXTURE_2D, 0 );
629 //-----------------------------------------------------------------------------
630 // Definition of structures and fuctions used in Draw() method
633 //-----------------------------------------------------------------------------
640 //-----------------------------------------------------------------------------
641 struct TColorFunctorBase
645 TColorFunctorBase( vtkProperty* theProperty )
647 myAlpha = theProperty->GetOpacity();
652 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
654 virtual ~TColorFunctorBase() {}
657 //-----------------------------------------------------------------------------
658 struct TPropertyColor : TColorFunctorBase
662 TPropertyColor( vtkProperty* theProperty ):
663 TColorFunctorBase( theProperty )
665 theProperty->GetColor( myColor );
670 get( TVertex& theVertex, vtkIdType /*thePointId*/, vtkIdType /*theCellId*/ )
672 theVertex.r = myColor[0];
673 theVertex.g = myColor[1];
674 theVertex.b = myColor[2];
675 theVertex.a = myAlpha;
679 //-----------------------------------------------------------------------------
680 struct TColors2Color : TColorFunctorBase
682 vtkUnsignedCharArray* myColors;
684 TColors2Color( vtkProperty* theProperty,
685 vtkUnsignedCharArray* theColors ):
686 TColorFunctorBase( theProperty ),
687 myColors( theColors )
692 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
694 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
695 unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
697 theVertex.r = int( aColor[0] ) / 255.0;
698 theVertex.g = int( aColor[1] ) / 255.0;
699 theVertex.b = int( aColor[2] ) / 255.0;
700 theVertex.a = myAlpha;
705 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
708 //-----------------------------------------------------------------------------
709 struct TPointColors2Color : TColors2Color
711 TPointColors2Color( vtkProperty* theProperty,
712 vtkUnsignedCharArray* theColors ):
713 TColors2Color( theProperty, theColors )
718 GetTupleId( vtkIdType thePointId, vtkIdType /*theCellId*/ )
724 //-----------------------------------------------------------------------------
725 struct TCellColors2Color : TColors2Color
727 TCellColors2Color( vtkProperty* theProperty,
728 vtkUnsignedCharArray* theColors ):
729 TColors2Color( theProperty, theColors )
734 GetTupleId( vtkIdType /*thePointId*/, vtkIdType theCellId )
740 //-----------------------------------------------------------------------------
741 template < class TCoordinates >
742 void DrawPoints( TCoordinates* theStartPoints,
743 vtkCellArray* theCells,
744 TColorFunctorBase* theColorFunctor,
745 TVertex* theVertexArr,
746 vtkIdType &theCellId,
747 vtkIdType &theVertexId,
749 vtkDataArray* theDiamArray,
750 double theBallScale )
752 vtkIdType* ptIds = theCells->GetData()->GetPointer(0);
753 vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
755 bool mapBalls = false;
756 if(theBallArr && theDiamArray) {
760 while ( ptIds < endPtIds ) {
761 vtkIdType nPts = *ptIds;
765 TVertex& aVertex = theVertexArr[ theVertexId ];
766 vtkIdType aPointId = *ptIds;
768 TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
769 aVertex.vx = anOffsetPoints[0];
770 aVertex.vy = anOffsetPoints[1];
771 aVertex.vz = anOffsetPoints[2];
773 theColorFunctor->get( aVertex, aPointId, theCellId );
781 theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
788 //-----------------------------------------------------------------------------
789 template < class TCoordinates >
790 void DrawCellsPoints( vtkPolyData* theInput,
791 vtkPoints* thePoints,
792 TColorFunctorBase* theColorFunctor,
793 TVertex* theVertexArr,
795 double theBallScale )
797 vtkIdType aCellId = 0, aVertexId = 0;
799 TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
800 vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;
802 if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
803 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
806 if ( vtkCellArray* aCellArray = theInput->GetLines() )
807 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
809 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
810 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
812 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
813 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
818 //-----------------------------------------------------------------------------
819 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
822 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
823 return MAPPER_SUPERCLASS::Draw( ren, act );
825 InternalDraw( ren, act );
830 //-----------------------------------------------------------------------------
831 void VTKViewer_PolyDataMapper::RenderPieceDraw( vtkRenderer* ren, vtkActor* act ) {
832 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled) {
833 MAPPER_SUPERCLASS::RenderPieceDraw( ren, act );
836 InternalDraw( ren, act );
841 #include <vtkCamera.h>
842 #include <vtkOpenGLCamera.h>
843 #include <vtkOpenGLActor.h>
846 void VTKViewer_PolyDataMapper::InternalDraw(vtkRenderer* ren, vtkActor* act ) {
847 vtkUnsignedCharArray* colors = NULL;
848 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();
902 int aMode = 0; // to remove
904 VTK::TColorFunctorBase* aColorFunctor = NULL;
905 if( colors && aMode != 1 ) {
907 aColorFunctor = new VTK::TCellColors2Color( prop, colors );
909 aColorFunctor = new VTK::TPointColors2Color( prop, colors );
911 aColorFunctor = new VTK::TPropertyColor( prop );
913 if ( points->GetDataType() == VTK_FLOAT )
914 VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
916 VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
918 delete aColorFunctor;
921 if( this->ExtensionsInitialized == ES_Ok ) {
923 GLint current_program;
924 glGetIntegerv( GL_CURRENT_PROGRAM, ¤t_program );
925 this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
927 vtkOpenGLCamera *cam = (vtkOpenGLCamera *)(ren->GetActiveCamera());
932 cam->GetKeyMatrices(ren,wcvc,norms,vcdc,wcdc);
933 if (!act->GetIsIdentity())
936 vtkMatrix3x3 *anorms;
937 ((vtkOpenGLActor *)act)->GetKeyMatrices( mcwc, anorms );
938 vtkMatrix4x4::Multiply4x4( mcwc, wcdc, this->TempMatrix4 );
940 this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, this->TempMatrix4 );
944 this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, wcdc );
946 this->OpenGLHelper.SetUniformMatrix( this->myLocations.Projection, vcdc );
948 this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, std::max( aSize[0], aSize[1] ) );
950 GLuint aBufferObjectID, aDiamsID = 0;
952 this->OpenGLHelper.vglBindVertexArrayARB( this->VertexArrayObject );
953 this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
954 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
956 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
957 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
959 delete [] aVertexArr;
962 GLint colorAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Color" );
963 GLint vertexAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Vertex" );
964 GLint diamAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Diameter" );
966 GLsizei vertexSize = sizeof(VTK::TVertex);
968 this->OpenGLHelper.vglVertexAttribPointerARB( colorAttrib, 4, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0 );
969 this->OpenGLHelper.vglEnableVertexAttribArrayARB( colorAttrib );
971 this->OpenGLHelper.vglVertexAttribPointerARB( vertexAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 4) );
972 this->OpenGLHelper.vglEnableVertexAttribArrayARB( vertexAttrib );
974 if(this->BallEnabled) {
975 // Don't use uniform variable.
976 this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, -1 );
977 this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
978 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
980 int aDiamsSize = sizeof(TBall)*aNbCells;
981 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
983 delete [] aBallArray;
985 this->OpenGLHelper.vglVertexAttribPointerARB( diamAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0 );
986 this->OpenGLHelper.vglEnableVertexAttribArrayARB( diamAttrib );
989 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
991 if( this->BallEnabled ) {
992 this->OpenGLHelper.vglDisableVertexAttribArrayARB( diamAttrib );
993 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
994 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
997 this->OpenGLHelper.vglDisableVertexAttribArrayARB( colorAttrib );
998 this->OpenGLHelper.vglDisableVertexAttribArrayARB( vertexAttrib );
999 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1000 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
1001 this->OpenGLHelper.vglBindVertexArrayARB( 0 );
1003 this->OpenGLHelper.vglUseProgramObjectARB( current_program );
1005 GLuint aBufferObjectID, aDiamsID = 0;
1006 GLint attribute_diams = -1;
1007 glPointSize( std::max( aSize[0], aSize[1] ) );
1008 this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
1009 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1011 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
1012 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
1014 delete [] aVertexArr;
1016 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1017 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1019 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
1020 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
1022 glEnableClientState( GL_VERTEX_ARRAY );
1023 glEnableClientState( GL_COLOR_ARRAY );
1025 if(this->BallEnabled) {
1026 this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
1027 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
1029 int aDiamsSize = sizeof(TBall)*aNbCells;
1030 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
1032 delete [] aBallArray;
1033 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1034 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
1036 attribute_diams = this->OpenGLHelper.vglGetAttribLocationARB(this->PointProgram, "diameter");
1037 this->OpenGLHelper.vglEnableVertexAttribArrayARB(attribute_diams);
1038 this->OpenGLHelper.vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
1039 this->OpenGLHelper.vglVertexAttribPointerARB(
1040 attribute_diams, // attribute
1041 1, // number of elements per vertex, here (diameter)
1042 GL_FLOAT, // the type of each element
1043 GL_FALSE, // take our values as-is
1044 0, // no extra data between each position
1045 0 // offset of first element
1049 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1051 glDisableClientState( GL_COLOR_ARRAY );
1052 glDisableClientState( GL_VERTEX_ARRAY );
1053 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
1055 if(this->BallEnabled) {
1056 this->OpenGLHelper.vglDisableVertexAttribArrayARB(attribute_diams);
1057 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
1061 } else { // there are no extensions
1062 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
1063 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex),
1064 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1066 glEnableClientState( GL_VERTEX_ARRAY );
1067 glEnableClientState( GL_COLOR_ARRAY );
1069 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1071 glDisableClientState( GL_COLOR_ARRAY );
1072 glDisableClientState( GL_VERTEX_ARRAY );
1074 delete [] aVertexArr;
1079 this->UpdateProgress(1.0);