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  const GLenum bufs[1] = { static_cast<GLenum>(this->SavedDrawBuffer) };
328  ::glDrawBuffers(1, bufs);
329  }
330 
331  ostate->vtkglClearColor(this->SavedClearColor[0], this->SavedClearColor[1],
332  this->SavedClearColor[2], this->SavedClearColor[3]);
333  }
334  }
335 
336  float* TexCoords(float* f, int n)
337  {
338  float* texCoord = new float[2 * n];
339  float minX = f[0];
340  float minY = f[1];
341  float maxX = f[0];
342  float maxY = f[1];
343  float* fptr = f;
344  for (int i = 0; i < n; ++i)
345  {
346  minX = fptr[0] < minX ? fptr[0] : minX;
347  maxX = fptr[0] > maxX ? fptr[0] : maxX;
348  minY = fptr[1] < minY ? fptr[1] : minY;
349  maxY = fptr[1] > maxY ? fptr[1] : maxY;
350  fptr += 2;
351  }
352  fptr = f;
354  {
355  const double* textureBounds = this->Texture->GetInput()->GetBounds();
356  float rangeX =
357  (textureBounds[1] - textureBounds[0]) ? textureBounds[1] - textureBounds[0] : 1.;
358  float rangeY =
359  (textureBounds[3] - textureBounds[2]) ? textureBounds[3] - textureBounds[2] : 1.;
360  for (int i = 0; i < n; ++i)
361  {
362  texCoord[i * 2] = (fptr[0] - minX) / rangeX;
363  texCoord[i * 2 + 1] = (fptr[1] - minY) / rangeY;
364  fptr += 2;
365  }
366  }
367  else // this->TextureProperties & vtkContextDevice2D::Stretch
368  {
369  float rangeX = (maxX - minX) ? maxX - minX : 1.f;
370  float rangeY = (maxY - minY) ? maxY - minY : 1.f;
371  for (int i = 0; i < n; ++i)
372  {
373  texCoord[i * 2] = (fptr[0] - minX) / rangeX;
374  texCoord[i * 2 + 1] = (fptr[1] - minY) / rangeY;
375  fptr += 2;
376  }
377  }
378  return texCoord;
379  }
380 
382  {
383  vtkVector2i pow2(1, 1);
384  for (int i = 0; i < 2; ++i)
385  {
386  while (pow2[i] < size[i])
387  {
388  pow2[i] *= 2;
389  }
390  }
391  return pow2;
392  }
393 
395  {
396  if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
397  {
398  vtkGenericWarningMacro("Invalid image format: expected unsigned char.");
399  return 0;
400  }
401  int bytesPerPixel = image->GetNumberOfScalarComponents();
402  int size[3];
403  image->GetDimensions(size);
404  vtkVector2i newImg = this->FindPowerOfTwo(vtkVector2i(size[0], size[1]));
405 
406  for (int i = 0; i < 2; ++i)
407  {
408  texCoords[i] = size[i] / float(newImg[i]);
409  }
410 
411  unsigned char* dataPtr = new unsigned char[newImg[0] * newImg[1] * bytesPerPixel];
412  unsigned char* origPtr = static_cast<unsigned char*>(image->GetScalarPointer());
413 
414  for (int i = 0; i < newImg[0]; ++i)
415  {
416  for (int j = 0; j < newImg[1]; ++j)
417  {
418  for (int k = 0; k < bytesPerPixel; ++k)
419  {
420  if (i < size[0] && j < size[1])
421  {
422  dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
423  origPtr[i * bytesPerPixel + j * size[0] * bytesPerPixel + k];
424  }
425  else
426  {
427  dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] = k == 3 ? 0 : 255;
428  }
429  }
430  }
431  }
432 
433  GLuint tmpIndex(0);
434  GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
435  GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
436 
437  glGenTextures(1, &tmpIndex);
438  glBindTexture(GL_TEXTURE_2D, tmpIndex);
439 
440  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
441  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
442  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
443  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
444 
445  glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, newImg[0], newImg[1], 0, glFormat,
446  GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(dataPtr));
447  delete[] dataPtr;
448  return tmpIndex;
449  }
450 
452  {
453  if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
454  {
455  cout << "Error = not an unsigned char..." << endl;
456  return 0;
457  }
458  int bytesPerPixel = image->GetNumberOfScalarComponents();
459  int size[3];
460  image->GetDimensions(size);
461 
462  unsigned char* dataPtr = static_cast<unsigned char*>(image->GetScalarPointer());
463  GLuint tmpIndex(0);
464  GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
465  GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
466 
467  glGenTextures(1, &tmpIndex);
468  glBindTexture(GL_TEXTURE_2D, tmpIndex);
469 
470  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
471  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
472  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
473  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
474 
475  glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, size[0], size[1], 0, glFormat,
476  GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(dataPtr));
477  return tmpIndex;
478  }
479 
481  unsigned int TextureProperties;
483  // Store the previous GL state so that we can restore it when complete
488  GLfloat SavedClearColor[4];
489 
494  bool GLSL;
496 
498 
505 };
506 
508 
528 {
529 
530 public:
531  enum CellType
532  {
533  LINE = 1,
534  POLYGON
535  // TRIANGLE_STRIPS
536  };
537 
539  : Device(device)
540  , Points(nullptr)
541  , PointIds(nullptr)
542  , Colors(nullptr)
543  , NumPointsCell(0)
544  {
545  this->cache = new PolyDataCache();
546  };
547 
548  ~CellArrayHelper() { delete this->cache; }
549 
553  void Draw(int cellType, vtkPolyData* polyData, vtkPoints* points, float x, float y, float scale,
554  int scalarMode, vtkUnsignedCharArray* colors = nullptr)
555  {
556  this->Points = points;
557  this->Colors = colors;
558  this->CellColors->SetNumberOfComponents(colors->GetNumberOfComponents());
559 
560  switch (cellType)
561  {
562  case LINE:
563  this->DrawLines(polyData, scalarMode, x, y, scale);
564  break;
565 
566  case POLYGON:
567  this->DrawPolygons(polyData, scalarMode, x, y, scale);
568  break;
569  }
570  };
571 
572  void HandleEndFrame() { this->cache->SwapCaches(); }
573 
574 private:
575  CellArrayHelper(const CellArrayHelper&) = delete;
576  void operator=(const CellArrayHelper&) = delete;
577 
578  struct PolyDataCacheItem
579  {
580  // Each polydata may have lines as well as polys which must be cached
581  // separately
582  std::vector<float> PolyTri;
584  vtkTimeStamp PolygonsLoadingTime;
585 
586  std::vector<float> Lines;
588  vtkTimeStamp LinesLoadingTime;
589  };
590 
591  struct PolyDataCache
592  {
593  ~PolyDataCache()
594  {
595  std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev = this->PrevFrameCache.begin();
596  for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
597  {
598  delete itPrev->second;
599  }
600 
601  std::map<vtkPolyData*, PolyDataCacheItem*>::iterator it = this->CurrentFrameCache.begin();
602  for (; it != this->CurrentFrameCache.end(); ++it)
603  {
604  delete it->second;
605  }
606  }
607 
608  PolyDataCacheItem* GetCacheEntry(vtkPolyData* key)
609  {
610  PolyDataCacheItem* cacheItem = this->CurrentFrameCache[key];
611  if (cacheItem == nullptr)
612  {
613  cacheItem = this->PrevFrameCache[key];
614  if (cacheItem == nullptr)
615  {
616  cacheItem = new PolyDataCacheItem();
617  cacheItem->PolyColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
618  cacheItem->LineColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
619  }
620  else
621  {
622  // Move the item to the current frame, since we were asked for it
623  this->PrevFrameCache.erase(key);
624  }
625 
626  // Add the cache item to the current frame's cache
627  this->CurrentFrameCache[key] = cacheItem;
628  }
629 
630  return cacheItem;
631  }
632 
633  void SwapCaches()
634  {
635  // Delete any objects stored in the previous frame's cache, as
636  // if they had been used in this frame, we would have moved them
637  // into the current frame cache already.
638  std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev = this->PrevFrameCache.begin();
639  for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
640  {
641  delete itPrev->second;
642  }
643 
644  // Clear the entries in the previous frame's cache
645  this->PrevFrameCache.clear();
646 
647  // Now swap the caches
648  std::swap(this->PrevFrameCache, this->CurrentFrameCache);
649  }
650 
651  // Last two frames worth of cached polygon/line primitives for each drawn
652  // polydata.
653  std::map<vtkPolyData*, PolyDataCacheItem*> PrevFrameCache;
654  std::map<vtkPolyData*, PolyDataCacheItem*> CurrentFrameCache;
655  };
656 
660  void MapCurrentCell(
661  float const posX, float const posY, float const scale, vtkIdType cellId, int scalarMode)
662  {
663  this->CellPoints.reserve(this->NumPointsCell * 2); /* 2 components */
664  this->CellColors->SetNumberOfTuples(this->NumPointsCell); /* RGBA */
665  for (int i = 0; i < this->NumPointsCell; i++)
666  {
667  double point[3];
668  this->Points->GetPoint(this->PointIds[i], point);
669 
670  // Only 2D meshes are supported
671  float const x = static_cast<float>(point[0]) + posX;
672  float const y = static_cast<float>(point[1]) + posY;
673  this->CellPoints.push_back(x * scale);
674  this->CellPoints.push_back(y * scale);
675 
676  // Grab specific point / cell colors
678  switch (scalarMode)
679  {
681  mappedColorId = this->PointIds[i];
682  break;
684  mappedColorId = cellId;
685  break;
686  default:
687  std::cerr << "Scalar mode not supported!" << std::endl;
688  break;
689  }
690 
691  this->CellColors->SetTuple(i, mappedColorId, this->Colors);
692  }
693  };
694 
700  void DrawLines(
701  vtkPolyData* polyData, int scalarMode, float const x, float const y, float const scale)
702  {
703  PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
704 
705  if (polyData->GetMTime() > cacheItem->LinesLoadingTime)
706  {
707  vtkNew<vtkGenericCell> genericCell;
708  cacheItem->Lines.clear();
709  cacheItem->LineColors->Reset();
710 
711  // Pre-allocate batched array
712  vtkIdType const numVertices = polyData->GetNumberOfCells() * 2; // points/line
713  cacheItem->Lines.reserve(numVertices * 2); // components
714  cacheItem->LineColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
715  cacheItem->LineColors->SetNumberOfTuples(numVertices);
716 
717  vtkIdType cellId = 0;
718  vtkIdType vertOffset = 0;
719  vtkCellIterator* cellIter = nullptr;
720 
721  for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
722  cellIter->GoToNextCell(), cellId++)
723  {
724  polyData->GetCell(cellIter->GetCellId(), genericCell);
725  if (genericCell->GetCellType() == VTK_LINE || genericCell->GetCellType() == VTK_POLY_LINE)
726  {
727  vtkIdType actualNumPointsCell = genericCell->GetNumberOfPoints();
728 
729  for (int i = 0; i < actualNumPointsCell - 1; ++i)
730  {
731  this->NumPointsCell = 2;
732  this->PointIds = genericCell->GetPointIds()->GetPointer(i);
733 
734  this->MapCurrentCell(x, y, scale, cellId, scalarMode);
735 
736  // Accumulate the current cell in the batched array
737  for (int j = 0; j < this->NumPointsCell; j++)
738  {
739  cacheItem->Lines.push_back(this->CellPoints[2 * j]);
740  cacheItem->Lines.push_back(this->CellPoints[2 * j + 1]);
741 
742  double* color4 = this->CellColors->GetTuple(j);
743  cacheItem->LineColors->InsertTuple4(
744  vertOffset + j, color4[0], color4[1], color4[2], color4[3]);
745  }
746 
747  vertOffset += this->NumPointsCell;
748  this->CellColors->Reset();
749  this->CellPoints.clear();
750  }
751  }
752  }
753 
754  cacheItem->LinesLoadingTime.Modified();
755  cellIter->Delete();
756  }
757 
758  if (cacheItem->Lines.size() > 0)
759  {
760  this->Device->DrawLines(&cacheItem->Lines[0], static_cast<int>(cacheItem->Lines.size() / 2),
761  static_cast<unsigned char*>(cacheItem->LineColors->GetVoidPointer(0)),
762  cacheItem->LineColors->GetNumberOfComponents());
763  }
764  };
765 
770  vtkIdType GetCountTriangleVertices(vtkPolyData* polyData)
771  {
772  vtkIdType cellId = 0;
773  vtkIdType numTriVert = 0;
774  vtkNew<vtkGenericCell> genericCell;
775  vtkCellIterator* cellIter = nullptr;
776 
777  for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
778  cellIter->GoToNextCell(), cellId++)
779  {
780  polyData->GetCell(cellIter->GetCellId(), genericCell);
781  this->NumPointsCell = genericCell->GetNumberOfPoints();
782  this->PointIds = genericCell->GetPointIds()->GetPointer(0);
783  numTriVert += 3 * (this->NumPointsCell - 2);
784  }
785 
786  cellIter->Delete();
787  return numTriVert;
788  };
789 
795  void DrawPolygons(
796  vtkPolyData* polyData, int scalarMode, float const x, float const y, float const scale)
797  {
798  PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
799 
800  if (polyData->GetMTime() > cacheItem->PolygonsLoadingTime)
801  {
802  cacheItem->PolyTri.clear();
803  cacheItem->PolyColors->Reset();
804 
805  // Pre-allocate batched array
806  vtkIdType const totalTriVert = this->GetCountTriangleVertices(polyData);
807  cacheItem->PolyTri.reserve(totalTriVert * 2); // components
808  cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
809  cacheItem->PolyColors->SetNumberOfTuples(totalTriVert);
810 
811  // Traverse polygons and convert to triangles
812  vtkIdType cellId = 0;
813  vtkIdType vertOffset = 0;
814  cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
815 
816  vtkNew<vtkGenericCell> genericCell;
817  vtkCellIterator* cellIter = nullptr;
818 
819  for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
820  cellIter->GoToNextCell(), cellId++)
821  {
822  polyData->GetCell(cellIter->GetCellId(), genericCell);
823  if (genericCell->GetCellType() == VTK_TRIANGLE || genericCell->GetCellType() == VTK_QUAD ||
824  genericCell->GetCellType() == VTK_POLYGON)
825  {
826  this->NumPointsCell = genericCell->GetNumberOfPoints();
827  this->PointIds = genericCell->GetPointIds()->GetPointer(0);
828 
829  this->MapCurrentCell(x, y, scale, cellId, scalarMode);
830 
831  // Convert current cell (polygon) to triangles
832  for (int i = 0; i < this->NumPointsCell - 2; i++)
833  {
834  cacheItem->PolyTri.push_back(this->CellPoints[0]);
835  cacheItem->PolyTri.push_back(this->CellPoints[1]);
836  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 2]);
837  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 3]);
838  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 4]);
839  cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 5]);
840 
841  // Insert triangle vertex color
842  vtkIdType const triangOffset = vertOffset + 3 * i;
843  double* color4 = this->CellColors->GetTuple(0);
844  cacheItem->PolyColors->InsertTuple4(
845  triangOffset, color4[0], color4[1], color4[2], color4[3]);
846 
847  color4 = this->CellColors->GetTuple(i + 1);
848  cacheItem->PolyColors->InsertTuple4(
849  triangOffset + 1, color4[0], color4[1], color4[2], color4[3]);
850 
851  color4 = this->CellColors->GetTuple(i + 2);
852  cacheItem->PolyColors->InsertTuple4(
853  triangOffset + 2, color4[0], color4[1], color4[2], color4[3]);
854  }
855 
856  vertOffset += 3 * (this->NumPointsCell - 2); // Triangle verts current cell
857  this->CellColors->Reset();
858  this->CellPoints.clear();
859  }
860  }
861 
862  cacheItem->PolygonsLoadingTime.Modified();
863  cellIter->Delete();
864  }
865 
866  if (cacheItem->PolyTri.size() > 0)
867  {
868  this->Device->CoreDrawTriangles(cacheItem->PolyTri,
869  static_cast<unsigned char*>(cacheItem->PolyColors->GetVoidPointer(0)), 4);
870  }
871  };
872 
873  vtkOpenGLContextDevice2D* Device;
874 
875  vtkPoints* Points;
876  vtkIdType* PointIds;
877  vtkUnsignedCharArray* Colors;
878 
880 
883  vtkIdType NumPointsCell;
884  std::vector<float> CellPoints;
885  vtkNew<vtkUnsignedCharArray> CellColors;
887 
888  PolyDataCache* cache;
889 };
890 #endif // VTKOPENGLCONTEXTDEVICE2DPRIVATE_H
891 // 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:35
@ 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