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