VTK
vtkOpenGLContextDevice2DPrivate.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkOpenGLContextDevice2DPrivate.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
33 #ifndef vtkOpenGLContextDevice2DPrivate_h
34 #define vtkOpenGLContextDevice2DPrivate_h
35 
37 
38 #include "vtkAbstractMapper.h"
39 #include "vtkCellIterator.h"
40 #include "vtkColor.h"
41 #include "vtkFreeTypeTools.h"
42 #include "vtkGenericCell.h"
43 #include "vtkTextProperty.h"
44 #include "vtkTextRenderer.h"
45 #include "vtkTexture.h"
46 #include "vtkStdString.h"
47 #include "vtkUnicodeString.h"
48 
49 #include <algorithm>
50 #include <list>
51 #include <utility>
52 
53 // .NAME vtkTextureImageCache - store vtkTexture and vtkImageData identified by
54 // a unique key.
55 // .SECTION Description
56 // Creating and initializing a texture can be time consuming,
57 // vtkTextureImageCache offers the ability to reuse them as much as possible.
58 template <class Key>
60 {
61 public:
62  struct CacheData
63  {
66  // Use to generate texture coordinates. Computing this is as expensive as
67  // rendering the texture, so we cache it.
69  };
70 
72 
75  struct CacheElement: public std::pair<Key, CacheData>
76  {
77  // Default constructor
79  : std::pair<Key, CacheData>(Key(), CacheData()){}
80  // Construct a partial CacheElement with no CacheData
81  // This can be used for temporary CacheElement used to search a given
82  // key into the cache list.
83  CacheElement(const Key& key)
84  : std::pair<Key, CacheData>(key, CacheData()){}
85  // Standard constructor of CacheElement
86  CacheElement(const Key& key, const CacheData& cacheData)
87  : std::pair<Key, CacheData>(key, cacheData){}
88  // Operator tuned to be used when searching into the cache list using
89  // std::find()
90  bool operator==(const CacheElement& other)const
91  {
92  // Here we cheat and make the comparison only on the key, this allows
93  // us to use std::find() to search for a given key.
94  return this->first == other.first;
95  }
96  };
98 
103  {
104  this->MaxSize = 50;
105  }
106 
111  bool IsKeyInCache(const Key& key)const
112  {
113  return std::find(this->Cache.begin(), this->Cache.end(), key) != this->Cache.end();
114  }
115 
122  CacheData& GetCacheData(const Key& key);
123 
125 
130  {
131  typename std::list<CacheElement >::iterator it;
132  for (it = this->Cache.begin(); it != this->Cache.end(); ++it)
133  {
134  it->second.Texture->ReleaseGraphicsResources(window);
135  }
136  }
138 
139 protected:
141 
145  CacheData& AddCacheData(const Key& key, const CacheData& cacheData)
146  {
147  assert(!this->IsKeyInCache(key));
148  if (this->Cache.size() >= this->MaxSize)
149  {
150  this->Cache.pop_back();
151  }
152  this->Cache.push_front(CacheElement(key, cacheData));
153  return this->Cache.begin()->second;
154  }
156 
160  std::list<CacheElement > Cache;
162 
165  size_t MaxSize;
166 };
168 
169 template<class Key>
171 ::GetCacheData(const Key& key)
172 {
173  typename std::list<CacheElement>::iterator it =
174  std::find(this->Cache.begin(), this->Cache.end(), CacheElement(key));
175  if (it != this->Cache.end())
176  {
177  return it->second;
178  }
179  CacheData cacheData;
182  cacheData.Texture->SetInputData(cacheData.ImageData);
183  return this->AddCacheData(key, cacheData);
184 }
185 
186 // .NAME TextPropertyKey - unique key for a vtkTextProperty and text
187 // .SECTION Description
188 // Uniquely describe a pair of vtkTextProperty and text.
189 template <class StringType>
191 {
193 
196  static vtkTypeUInt32 GetIdFromTextProperty(vtkTextProperty* tprop)
197  {
198  size_t id;
199 
201  ftt->MapTextPropertyToId(tprop, &id);
202 
203  // The hash is really a uint32 that gets cast to a size_t in
204  // MapTextPropertyToId, so this possible truncation is safe.
205  // Yay legacy APIs.
206  vtkTypeUInt32 hash = static_cast<vtkTypeUInt32>(id);
207 
208  // Ensure that the above implementation assumption still holds. If it
209  // doesn't we'll need to rework this cache class a bit.
210  assert("Hash is really a uint32" && static_cast<size_t>(hash) == id);
211 
212  // Since we cache the text metrics (which includes orientation and alignment
213  // info), we'll need to store the alignment options, since
214  // MapTextPropertyToId intentionally ignores these:
215  int tmp = tprop->GetJustification();
216  hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
217  tmp = tprop->GetVerticalJustification();
218  hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
219 
220  return hash;
221  }
223 
225 
228  TextPropertyKey(vtkTextProperty* textProperty, const StringType& text,
229  int dpi)
230  {
231  this->TextPropertyId = GetIdFromTextProperty(textProperty);
232  this->FontSize = textProperty->GetFontSize();
233  double color[3];
234  textProperty->GetColor(color);
235  this->Color.Set(static_cast<unsigned char>(color[0] * 255),
236  static_cast<unsigned char>(color[1] * 255),
237  static_cast<unsigned char>(color[2] * 255),
238  static_cast<unsigned char>(textProperty->GetOpacity() * 255));
239  this->Text = text;
240  this->DPI = dpi;
241  }
243 
248  bool operator==(const TextPropertyKey& other)const
249  {
250  return this->TextPropertyId == other.TextPropertyId &&
251  this->FontSize == other.FontSize &&
252  this->Text == other.Text &&
253  this->Color[0] == other.Color[0] &&
254  this->Color[1] == other.Color[1] &&
255  this->Color[2] == other.Color[2] &&
256  this->Color[3] == other.Color[3] &&
257  this->DPI == other.DPI;
258  }
259 
260  unsigned short FontSize;
262  // States in the function not to use more than 32 bits - int works fine here.
263  vtkTypeUInt32 TextPropertyId;
264  StringType Text;
265  int DPI;
266 };
267 
270 
272 {
273 public:
275  {
276  this->Texture = nullptr;
277  this->TextureProperties = vtkContextDevice2D::Linear |
279  this->SpriteTexture = nullptr;
280  this->SavedDepthTest = GL_TRUE;
281  this->SavedStencilTest = GL_TRUE;
282  this->SavedBlend = GL_TRUE;
283  this->SavedDrawBuffer = 0;
284  this->SavedClearColor[0] = this->SavedClearColor[1] =
285  this->SavedClearColor[2] =
286  this->SavedClearColor[3] = 0.0f;
287  this->TextCounter = 0;
288  this->GLExtensionsLoaded = true;
289  this->GLSL = true;
290  this->PowerOfTwoTextures = false;
291  }
292 
294  {
295  if (this->Texture)
296  {
297  this->Texture->Delete();
298  this->Texture = nullptr;
299  }
300  if (this->SpriteTexture)
301  {
302  this->SpriteTexture->Delete();
303  this->SpriteTexture = nullptr;
304  }
305  }
306 
307  void SaveGLState(vtkOpenGLState *ostate, bool colorBuffer = false)
308  {
309  this->SavedDepthTest = ostate->GetEnumState(GL_DEPTH_TEST);
310 
311  if (colorBuffer)
312  {
313  this->SavedStencilTest = ostate->GetEnumState(GL_STENCIL_TEST);
314  this->SavedBlend = ostate->GetEnumState(GL_BLEND);
315  ostate->vtkglGetFloatv(GL_COLOR_CLEAR_VALUE, this->SavedClearColor);
316  ostate->vtkglGetIntegerv(GL_DRAW_BUFFER, &this->SavedDrawBuffer);
317  }
318  }
319 
320  void RestoreGLState(vtkOpenGLState *ostate, bool colorBuffer = false)
321  {
322  ostate->SetEnumState(GL_DEPTH_TEST, this->SavedDepthTest);
323 
324  if (colorBuffer)
325  {
326  ostate->SetEnumState(GL_STENCIL_TEST, this->SavedStencilTest);
327  ostate->SetEnumState(GL_BLEND, this->SavedBlend);
328 
329  if(this->SavedDrawBuffer != GL_BACK_LEFT)
330  {
331  glDrawBuffer(this->SavedDrawBuffer);
332  }
333 
334  ostate->vtkglClearColor(this->SavedClearColor[0],
335  this->SavedClearColor[1],
336  this->SavedClearColor[2],
337  this->SavedClearColor[3]);
338  }
339  }
340 
341  float* TexCoords(float* f, int n)
342  {
343  float* texCoord = new float[2*n];
344  float minX = f[0]; float minY = f[1];
345  float maxX = f[0]; float maxY = f[1];
346  float* fptr = f;
347  for(int i = 0; i < n; ++i)
348  {
349  minX = fptr[0] < minX ? fptr[0] : minX;
350  maxX = fptr[0] > maxX ? fptr[0] : maxX;
351  minY = fptr[1] < minY ? fptr[1] : minY;
352  maxY = fptr[1] > maxY ? fptr[1] : maxY;
353  fptr+=2;
354  }
355  fptr = f;
356  if (this->TextureProperties & vtkContextDevice2D::Repeat)
357  {
358  const double* textureBounds = this->Texture->GetInput()->GetBounds();
359  float rangeX = (textureBounds[1] - textureBounds[0]) ?
360  textureBounds[1] - textureBounds[0] : 1.;
361  float rangeY = (textureBounds[3] - textureBounds[2]) ?
362  textureBounds[3] - textureBounds[2] : 1.;
363  for (int i = 0; i < n; ++i)
364  {
365  texCoord[i*2] = (fptr[0]-minX) / rangeX;
366  texCoord[i*2+1] = (fptr[1]-minY) / rangeY;
367  fptr+=2;
368  }
369  }
370  else // this->TextureProperties & vtkContextDevice2D::Stretch
371  {
372  float rangeX = (maxX - minX)? maxX - minX : 1.f;
373  float rangeY = (maxY - minY)? maxY - minY : 1.f;
374  for (int i = 0; i < n; ++i)
375  {
376  texCoord[i*2] = (fptr[0]-minX)/rangeX;
377  texCoord[i*2+1] = (fptr[1]-minY)/rangeY;
378  fptr+=2;
379  }
380  }
381  return texCoord;
382  }
383 
385  {
386  vtkVector2i pow2(1, 1);
387  for (int i = 0; i < 2; ++i)
388  {
389  while (pow2[i] < size[i])
390  {
391  pow2[i] *= 2;
392  }
393  }
394  return pow2;
395  }
396 
398  {
399  if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
400  {
401  vtkGenericWarningMacro("Invalid image format: expected unsigned char.");
402  return 0;
403  }
404  int bytesPerPixel = image->GetNumberOfScalarComponents();
405  int size[3];
406  image->GetDimensions(size);
407  vtkVector2i newImg = this->FindPowerOfTwo(vtkVector2i(size[0], size[1]));
408 
409  for (int i = 0; i < 2; ++i)
410  {
411  texCoords[i] = size[i] / float(newImg[i]);
412  }
413 
414  unsigned char *dataPtr =
415  new unsigned char[newImg[0] * newImg[1] * bytesPerPixel];
416  unsigned char *origPtr =
417  static_cast<unsigned char*>(image->GetScalarPointer());
418 
419  for (int i = 0; i < newImg[0]; ++i)
420  {
421  for (int j = 0; j < newImg[1]; ++j)
422  {
423  for (int k = 0; k < bytesPerPixel; ++k)
424  {
425  if (i < size[0] && j < size[1])
426  {
427  dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
428  origPtr[i * bytesPerPixel + j * size[0] * bytesPerPixel + k];
429  }
430  else
431  {
432  dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
433  k == 3 ? 0 : 255;
434  }
435  }
436  }
437  }
438 
439  GLuint tmpIndex(0);
440  GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
441  GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
442 
443  glGenTextures(1, &tmpIndex);
444  glBindTexture(GL_TEXTURE_2D, tmpIndex);
445 
446  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
447  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
448  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
449  GL_CLAMP_TO_EDGE );
450  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
451  GL_CLAMP_TO_EDGE );
452 
453  glTexImage2D(GL_TEXTURE_2D, 0 , glInternalFormat,
454  newImg[0], newImg[1], 0, glFormat,
455  GL_UNSIGNED_BYTE, static_cast<const GLvoid *>(dataPtr));
456  delete [] dataPtr;
457  return tmpIndex;
458  }
459 
461  {
462  if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
463  {
464  cout << "Error = not an unsigned char..." << endl;
465  return 0;
466  }
467  int bytesPerPixel = image->GetNumberOfScalarComponents();
468  int size[3];
469  image->GetDimensions(size);
470 
471  unsigned char *dataPtr =
472  static_cast<unsigned char*>(image->GetScalarPointer());
473  GLuint tmpIndex(0);
474  GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
475  GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
476 
477  glGenTextures(1, &tmpIndex);
478  glBindTexture(GL_TEXTURE_2D, tmpIndex);
479 
480  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
481  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
482  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
483  GL_CLAMP_TO_EDGE );
484  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
485  GL_CLAMP_TO_EDGE );
486 
487  glTexImage2D(GL_TEXTURE_2D, 0 , glInternalFormat,
488  size[0], size[1], 0, glFormat,
489  GL_UNSIGNED_BYTE, static_cast<const GLvoid *>(dataPtr));
490  return tmpIndex;
491  }
492 
494  unsigned int TextureProperties;
496  // Store the previous GL state so that we can restore it when complete
501  GLfloat SavedClearColor[4];
502 
507  bool GLSL;
509 
511 
517 };
519 
521 
541 {
542 
543 public:
544  enum CellType
545  {
546  LINE = 1,
547  POLYGON
548  //TRIANGLE_STRIPS
549  };
550 
552  : Device(device)
553  , Points(nullptr)
554  , PointIds(nullptr)
555  , Colors(nullptr)
556  , NumPointsCell(0)
557  {
558  this->cache = new PolyDataCache();
559  };
560 
562  {
563  delete this->cache;
564  }
565 
569  void Draw (int cellType, vtkPolyData* polyData, vtkPoints* points, float x,
570  float y, float scale, int scalarMode, vtkUnsignedCharArray* colors = nullptr)
571  {
572  this->Points = points;
573  this->Colors = colors;
574  this->CellColors->SetNumberOfComponents(colors->GetNumberOfComponents());
575 
576  switch (cellType)
577  {
578  case LINE:
579  this->DrawLines(polyData, scalarMode, x, y, scale);
580  break;
581 
582  case POLYGON:
583  this->DrawPolygons(polyData, scalarMode, x, y, scale);
584  break;
585  }
586  };
587 
589  {
590  this->cache->SwapCaches();
591  }
592 
593 private:
594  CellArrayHelper(const CellArrayHelper&) = delete;
595  void operator=(const CellArrayHelper&) = delete;
596 
597  struct PolyDataCacheItem
598  {
599  // Each polydata may have lines as well as polys which must be cached
600  // separately
601  std::vector<float> PolyTri;
603  vtkTimeStamp PolygonsLoadingTime;
604 
605  std::vector<float> Lines;
607  vtkTimeStamp LinesLoadingTime;
608  };
609 
610  struct PolyDataCache
611  {
612  ~PolyDataCache()
613  {
614  std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev =
615  this->PrevFrameCache.begin();
616  for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
617  {
618  delete itPrev->second;
619  }
620 
621  std::map<vtkPolyData*, PolyDataCacheItem*>::iterator it =
622  this->CurrentFrameCache.begin();
623  for (; it != this->CurrentFrameCache.end(); ++it)
624  {
625  delete it->second;
626  }
627  }
628 
629  PolyDataCacheItem* GetCacheEntry(vtkPolyData* key)
630  {
631  PolyDataCacheItem* cacheItem = this->CurrentFrameCache[key];
632  if (cacheItem == nullptr)
633  {
634  cacheItem = this->PrevFrameCache[key];
635  if (cacheItem == nullptr)
636  {
637  cacheItem = new PolyDataCacheItem();
638  cacheItem->PolyColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
639  cacheItem->LineColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
640  }
641  else
642  {
643  // Move the item to the current frame, since we were asked for it
644  this->PrevFrameCache.erase(key);
645  }
646 
647  // Add the cache item to the current frame's cache
648  this->CurrentFrameCache[key] = cacheItem;
649  }
650 
651  return cacheItem;
652  }
653 
654  void SwapCaches()
655  {
656  // Delete any objects stored in the previous frame's cache, as
657  // if they had been used in this frame, we would have moved them
658  // into the current frame cache already.
659  std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev =
660  this->PrevFrameCache.begin();
661  for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
662  {
663  delete itPrev->second;
664  }
665 
666  // Clear the entries in the previous frame's cache
667  this->PrevFrameCache.clear();
668 
669  // Now swap the caches
670  std::swap(this->PrevFrameCache, this->CurrentFrameCache);
671  }
672 
673  // Last two frames worth of cached polygon/line primitives for each drawn
674  // polydata.
675  std::map<vtkPolyData*, PolyDataCacheItem*> PrevFrameCache;
676  std::map<vtkPolyData*, PolyDataCacheItem*> CurrentFrameCache;
677  };
678 
682  void MapCurrentCell (float const posX, float const posY, float const scale,
683  vtkIdType cellId, int scalarMode)
684  {
685  this->CellPoints.reserve(this->NumPointsCell * 2); /* 2 components */
686  this->CellColors->SetNumberOfTuples(this->NumPointsCell); /* RGBA */
687  for (int i = 0; i < this->NumPointsCell; i++)
688  {
689  double point[3];
690  this->Points->GetPoint(this->PointIds[i], point);
691 
692  // Only 2D meshes are supported
693  float const x = static_cast<float>(point[0]) + posX;
694  float const y = static_cast<float>(point[1]) + posY;
695  this->CellPoints.push_back(x * scale);
696  this->CellPoints.push_back(y * scale);
697 
698  // Grab specific point / cell colors
700  switch (scalarMode)
701  {
703  mappedColorId = this->PointIds[i];
704  break;
706  mappedColorId = cellId;
707  break;
708  default:
709  std::cerr << "Scalar mode not supported!" << std::endl;
710  break;
711  }
712 
713  this->CellColors->SetTuple(i, mappedColorId, this->Colors);
714  }
715  };
716 
722  void DrawLines(vtkPolyData* polyData, int scalarMode, float const x,
723  float const y, float const scale)
724  {
725  PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
726 
727  if (polyData->GetMTime() > cacheItem->LinesLoadingTime)
728  {
729  vtkNew<vtkGenericCell> genericCell;
730  cacheItem->Lines.clear();
731  cacheItem->LineColors->Reset();
732 
733  // Pre-allocate batched array
734  vtkIdType const numVertices = polyData->GetNumberOfCells() * 2;// points/line
735  cacheItem->Lines.reserve(numVertices * 2); // components
736  cacheItem->LineColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
737  cacheItem->LineColors->SetNumberOfTuples(numVertices);
738 
739  vtkIdType cellId = 0;
740  vtkIdType vertOffset = 0;
741  vtkCellIterator* cellIter = nullptr;
742 
743  for (cellIter = polyData->NewCellIterator();
744  !cellIter->IsDoneWithTraversal();
745  cellIter->GoToNextCell(), cellId++)
746  {
747  polyData->GetCell(cellIter->GetCellId(), genericCell);
748  if (genericCell->GetCellType() == VTK_LINE ||
749  genericCell->GetCellType() == VTK_POLY_LINE)
750  {
751  vtkIdType actualNumPointsCell = genericCell->GetNumberOfPoints();
752 
753  for (int i = 0; i < actualNumPointsCell - 1; ++i)
754  {
755  this->NumPointsCell = 2;
756  this->PointIds = genericCell->GetPointIds()->GetPointer(i);
757 
758  this->MapCurrentCell(x, y, scale, cellId, scalarMode);
759 
760  // Accumulate the current cell in the batched array
761  for (int j = 0; j < this->NumPointsCell; j++)
762  {
763  cacheItem->Lines.push_back(this->CellPoints[2 * j]);
764  cacheItem->Lines.push_back(this->CellPoints[2 * j + 1]);
765 
766  double* color4 = this->CellColors->GetTuple(j);
767  cacheItem->LineColors->InsertTuple4(vertOffset + j, color4[0], color4[1], color4[2],
768  color4[3]);
769  }
770 
771  vertOffset += this->NumPointsCell;
772  this->CellColors->Reset();
773  this->CellPoints.clear();
774  }
775  }
776  }
777 
778  cacheItem->LinesLoadingTime.Modified();
779  cellIter->Delete();
780  }
781 
782  if (cacheItem->Lines.size() > 0)
783  {
784  this->Device->DrawLines(&cacheItem->Lines[0], cacheItem->Lines.size() / 2,
785  static_cast<unsigned char*>(cacheItem->LineColors->GetVoidPointer(0)),
786  cacheItem->LineColors->GetNumberOfComponents());
787  }
788  };
789 
794  vtkIdType GetCountTriangleVertices(vtkPolyData* polyData)
795  {
796  vtkIdType cellId = 0;
797  vtkIdType numTriVert = 0;
798  vtkNew<vtkGenericCell> genericCell;
799  vtkCellIterator* cellIter = nullptr;
800 
801  for (cellIter = polyData->NewCellIterator();
802  !cellIter->IsDoneWithTraversal();
803  cellIter->GoToNextCell(), cellId++)
804  {
805  polyData->GetCell(cellIter->GetCellId(), genericCell);
806  this->NumPointsCell = genericCell->GetNumberOfPoints();
807  this->PointIds = genericCell->GetPointIds()->GetPointer(0);
808  numTriVert += 3 * (this->NumPointsCell - 2);
809  }
810 
811  cellIter->Delete();
812  return numTriVert;
813  };
814 
820  void DrawPolygons(vtkPolyData* polyData, int scalarMode, float const x,
821  float const y, float const scale)
822  {
823  PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
824 
825  if (polyData->GetMTime() > cacheItem->PolygonsLoadingTime)
826  {
827  cacheItem->PolyTri.clear();
828  cacheItem->PolyColors->Reset();
829 
830  // Pre-allocate batched array
831  vtkIdType const totalTriVert = this->GetCountTriangleVertices(polyData);
832  cacheItem->PolyTri.reserve(totalTriVert * 2); // components
833  cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
834  cacheItem->PolyColors->SetNumberOfTuples(totalTriVert);
835 
836  // Traverse polygons and convert to triangles
837  vtkIdType cellId = 0;
838  vtkIdType vertOffset = 0;
839  cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
840 
841  vtkNew<vtkGenericCell> genericCell;
842  vtkCellIterator* cellIter = nullptr;
843 
844  for (cellIter = polyData->NewCellIterator();
845  !cellIter->IsDoneWithTraversal();
846  cellIter->GoToNextCell(), cellId++)
847  {
848  polyData->GetCell(cellIter->GetCellId(), genericCell);
849  if (genericCell->GetCellType() == VTK_TRIANGLE ||
850  genericCell->GetCellType() == VTK_QUAD ||
851  genericCell->GetCellType() == VTK_POLYGON)
852  {
853  this->NumPointsCell = genericCell->GetNumberOfPoints();
854  this->PointIds = genericCell->GetPointIds()->GetPointer(0);
855 
856  this->MapCurrentCell(x, y, scale, cellId, scalarMode);
857 
858  // Convert current cell (polygon) to triangles
859  for (int i = 0; i < this->NumPointsCell - 2; i++)
860  {
861  cacheItem->PolyTri.push_back(this->CellPoints[0]);
862  cacheItem->PolyTri.push_back(this->CellPoints[1]);
863  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 2]);
864  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 3]);
865  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 4]);
866  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 5]);
867 
868  // Insert triangle vertex color
869  vtkIdType const triangOffset = vertOffset + 3 * i;
870  double* color4 = this->CellColors->GetTuple(0);
871  cacheItem->PolyColors->InsertTuple4(triangOffset, color4[0], color4[1],
872  color4[2], color4[3]);
873 
874  color4 = this->CellColors->GetTuple(i + 1);
875  cacheItem->PolyColors->InsertTuple4(triangOffset + 1, color4[0], color4[1],
876  color4[2], color4[3]);
877 
878  color4 = this->CellColors->GetTuple(i + 2);
879  cacheItem->PolyColors->InsertTuple4(triangOffset + 2, color4[0], color4[1],
880  color4[2], color4[3]);
881  }
882 
883  vertOffset += 3 * (this->NumPointsCell - 2); // Triangle verts current cell
884  this->CellColors->Reset();
885  this->CellPoints.clear();
886  }
887  }
888 
889  cacheItem->PolygonsLoadingTime.Modified();
890  cellIter->Delete();
891  }
892 
893  if (cacheItem->PolyTri.size() > 0)
894  {
895  this->Device->CoreDrawTriangles(cacheItem->PolyTri,
896  static_cast<unsigned char*>(cacheItem->PolyColors->GetVoidPointer(0)), 4);
897  }
898  };
899 
900  vtkOpenGLContextDevice2D* Device;
901 
902  vtkPoints* Points;
903  vtkIdType* PointIds;
904  vtkUnsignedCharArray* Colors;
905 
907 
910  vtkIdType NumPointsCell;
911  std::vector<float> CellPoints;
912  vtkNew<vtkUnsignedCharArray> CellColors;
914 
915  PolyDataCache* cache;
916 };
917 #endif // VTKOPENGLCONTEXTDEVICE2DPRIVATE_H
918 // VTK-HeaderTest-Exclude: vtkOpenGLContextDevice2DPrivate.h
bool operator==(const CacheElement &other) const
vtkIdType GetNumberOfPoints()
Return the number of points in the cell.
Definition: vtkCell.h:140
virtual int GetJustification()
Set/Get the horizontal justification to left (default), centered, or right.
double * GetBounds()
Return a pointer to the geometry bounding box in the form (xmin,xmax, ymin,ymax, zmin,zmax).
void SetEnumState(unsigned int name, bool value)
record modification and/or execution time
Definition: vtkTimeStamp.h:35
Class for drawing 2D primitives using OpenGL 1.1+.
void Draw(int cellType, vtkPolyData *polyData, vtkPoints *points, float x, float y, float scale, int scalarMode, vtkUnsignedCharArray *colors=nullptr)
Draw primitives as specified by cellType.
void vtkglGetIntegerv(unsigned int pname, int *params)
static int GetNumberOfScalarComponents(vtkInformation *meta_data)
Set/Get the number of scalar components for points.
GLuint TextureFromImage(vtkImageData *image, vtkVector2f &texCoords)
bool IsKeyInCache(const Key &key) const
Search the cache list to see if a given key already exists.
void SaveGLState(vtkOpenGLState *ostate, bool colorBuffer=false)
int vtkIdType
Definition: vtkType.h:347
TextPropertyKey(vtkTextProperty *textProperty, const StringType &text, int dpi)
Creates a TextPropertyKey.
concrete dataset represents vertices, lines, polygons, and triangle strips
Definition: vtkPolyData.h:85
std::list< CacheElement > Cache
List of a pair of key and cache data.
bool GetEnumState(unsigned int name)
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
CacheElement(const Key &key, const CacheData &cacheData)
void SetInputData(vtkDataObject *)
Assign a data object as input.
void ReleaseGraphicsResources(vtkWindow *window)
Release all the OpenGL Pixel Buffer Object(PBO) associated with the textures of the cache list...
bool operator==(const TextPropertyKey &other) const
Compares two TextPropertyKeys with each other.
TextPropertyKey< vtkStdString > UTF8TextPropertyKey
window superclass for vtkRenderWindow
Definition: vtkWindow.h:37
size_t MaxSize
Maximum size the cache list can be.
virtual vtkIdType GetCellId()=0
Get the id of the current cell.
void vtkglGetFloatv(unsigned int pname, float *params)
void GoToNextCell()
Increment to next cell.
OpenGL state storage.
vtkCell * GetCell(vtkIdType cellId) override
Standard vtkDataSet interface.
#define VTK_SCALAR_MODE_USE_POINT_DATA
virtual int * GetDimensions()
Get dimensions of this structured points dataset.
static int GetScalarType(vtkInformation *meta_data)
vtkTextureImageCache< UTF16TextPropertyKey > TextTextureCache
Cache for text images.
vtkTextureImageCache< UTF8TextPropertyKey > MathTextTextureCache
Cache for text images.
topologically and geometrically regular array of data
Definition: vtkImageData.h:45
vtkImageData * GetInput()
Get the input as a vtkImageData object.
Some derived classes for the different vectors commonly used.
Definition: vtkVector.h:408
int GetCellType() override
See the vtkCell API for descriptions of these methods.
virtual int GetVerticalJustification()
Set/Get the vertical justification to bottom (default), middle, or top.
CacheData & GetCacheData(const Key &key)
Return the cache associated to a key.
vtkIdType GetNumberOfCells() override
Standard vtkDataSet interface.
handles properties associated with a texture map
Definition: vtkTexture.h:71
vtkTextureImageCache()
Construct a texture image cache with a maximum number of texture of 50.
virtual double GetOpacity()
Set/Get the text&#39;s opacity.
vtkMTimeType GetMTime() override
Get MTime which also considers its cell array MTime.
represent text properties.
static vtkFreeTypeTools * GetInstance()
Return the singleton instance with no reference counting.
dynamic, self-adjusting array of unsigned char
virtual double * GetColor()
Set the color of the text.
#define VTK_UNSIGNED_CHAR
Definition: vtkType.h:51
vtkCellIterator * NewCellIterator() override
Return an iterator that traverses the cells in this data set.
virtual void * GetScalarPointer(int coordinates[3])
Access the native pointer for the scalar data.
void MapTextPropertyToId(vtkTextProperty *tprop, size_t *tprop_cache_id)
Given a text property &#39;tprop&#39;, get its unique ID in our cache framework.
void RestoreGLState(vtkOpenGLState *ostate, bool colorBuffer=false)
void vtkglClearColor(float red, float green, float blue, float alpha)
Efficient cell iterator for vtkDataSet topologies.
vtkIdList * GetPointIds()
Return the list of point ids defining the cell.
Definition: vtkCell.h:155
CacheElement associates a unique key to some cache.
vtkVector2i FindPowerOfTwo(const vtkVector2i &size)
virtual int GetFontSize()
Set/Get the font size (in points).
TextPropertyKey< vtkUnicodeString > UTF16TextPropertyKey
static vtkTypeUInt32 GetIdFromTextProperty(vtkTextProperty *tprop)
Transform a text property into an unsigned long.
static vtkTypeUInt32 HashBuffer(const void *str, size_t n, vtkTypeUInt32 hash=0)
Hash a string of a given length.
#define VTK_SCALAR_MODE_USE_CELL_DATA
FreeType library support.
CacheData & AddCacheData(const Key &key, const CacheData &cacheData)
Add a new cache entry into the cache list.
virtual bool IsDoneWithTraversal()=0
Returns false while the iterator is valid.
vtkSmartPointer< vtkImageData > ImageData
vtkIdType * GetPointer(const vtkIdType i)
Get a pointer to a particular data index.
Definition: vtkIdList.h:114
represent and manipulate 3D points
Definition: vtkPoints.h:39
virtual void Delete()
Delete a VTK object.