VTK  9.2.6
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"
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.
58template <class Key>
60{
61public:
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 {
81 }
82 // Construct a partial CacheElement with no CacheData
83 // This can be used for temporary CacheElement used to search a given
84 // key into the cache list.
85 CacheElement(const Key& key)
86 : std::pair<Key, CacheData>(key, CacheData())
87 {
88 }
89 // Standard constructor of CacheElement
90 CacheElement(const Key& key, const CacheData& cacheData)
91 : std::pair<Key, CacheData>(key, cacheData)
92 {
93 }
94 // Operator tuned to be used when searching into the cache list using
95 // std::find()
96 bool operator==(const CacheElement& other) const
97 {
98 // Here we cheat and make the comparison only on the key, this allows
99 // us to use std::find() to search for a given key.
100 return this->first == other.first;
101 }
102 };
104
109
114 bool IsKeyInCache(const Key& key) const
115 {
116 return std::find(this->Cache.begin(), this->Cache.end(), key) != this->Cache.end();
117 }
118
125 CacheData& GetCacheData(const Key& key);
126
128
133 {
134 typename std::list<CacheElement>::iterator it;
135 for (it = this->Cache.begin(); it != this->Cache.end(); ++it)
136 {
137 it->second.Texture->ReleaseGraphicsResources(window);
138 }
139 }
141
142protected:
144
148 CacheData& AddCacheData(const Key& key, const CacheData& cacheData)
149 {
150 assert(!this->IsKeyInCache(key));
151 if (this->Cache.size() >= this->MaxSize)
152 {
153 this->Cache.pop_back();
154 }
155 this->Cache.push_front(CacheElement(key, cacheData));
156 return this->Cache.begin()->second;
157 }
159
163 std::list<CacheElement> Cache;
165
168 size_t MaxSize;
170};
171
172template <class Key>
174 const Key& key)
175{
176 typename std::list<CacheElement>::iterator it =
177 std::find(this->Cache.begin(), this->Cache.end(), CacheElement(key));
178 if (it != this->Cache.end())
179 {
180 return it->second;
181 }
182 CacheData cacheData;
185 cacheData.Texture->SetInputData(cacheData.ImageData);
186 return this->AddCacheData(key, cacheData);
187}
188
189// .NAME TextPropertyKey - unique key for a vtkTextProperty and text
190// .SECTION Description
191// Uniquely describe a pair of vtkTextProperty and text.
192template <class StringType>
194{
196
199 static vtkTypeUInt32 GetIdFromTextProperty(vtkTextProperty* tprop)
200 {
201 size_t id;
202
204 ftt->MapTextPropertyToId(tprop, &id);
205
206 // The hash is really a uint32 that gets cast to a size_t in
207 // MapTextPropertyToId, so this possible truncation is safe.
208 // Yay legacy APIs.
209 vtkTypeUInt32 hash = static_cast<vtkTypeUInt32>(id);
210
211 // Ensure that the above implementation assumption still holds. If it
212 // doesn't we'll need to rework this cache class a bit.
213 assert("Hash is really a uint32" && static_cast<size_t>(hash) == id);
214
215 // Since we cache the text metrics (which includes orientation and alignment
216 // info), we'll need to store additional options, since MapTextPropertyToId
217 // intentionally ignores them.
218 // These include cell spacing and interior lines for multi cell text, as well
219 // as text justification.
220 int tmp = tprop->GetJustification();
221 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
222 tmp = tprop->GetVerticalJustification();
223 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
224 tmp = tprop->GetCellOffset();
225 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
226 tmp = tprop->GetInteriorLinesVisibility();
227 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
228 tmp = tprop->GetInteriorLinesWidth();
229 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
230 hash = vtkFreeTypeTools::HashBuffer(tprop->GetInteriorLinesColor(), 3 * sizeof(double), hash);
231
232 return hash;
233 }
235
237
240 TextPropertyKey(vtkTextProperty* textProperty, const StringType& text, int dpi)
241 {
242 this->TextPropertyId = GetIdFromTextProperty(textProperty);
243 this->FontSize = textProperty->GetFontSize();
244 double color[3];
245 textProperty->GetColor(color);
246 this->Color.Set(static_cast<unsigned char>(color[0] * 255),
247 static_cast<unsigned char>(color[1] * 255), static_cast<unsigned char>(color[2] * 255),
248 static_cast<unsigned char>(textProperty->GetOpacity() * 255));
249 this->Text = text;
250 this->DPI = dpi;
251 }
253
258 bool operator==(const TextPropertyKey& other) const
259 {
260 return this->TextPropertyId == other.TextPropertyId && this->FontSize == other.FontSize &&
261 this->Text == other.Text && this->Color[0] == other.Color[0] &&
262 this->Color[1] == other.Color[1] && this->Color[2] == other.Color[2] &&
263 this->Color[3] == other.Color[3] && this->DPI == other.DPI;
264 }
265
266 unsigned short FontSize;
268 // States in the function not to use more than 32 bits - int works fine here.
269 vtkTypeUInt32 TextPropertyId;
270 StringType Text;
271 int DPI;
272};
273
275
277{
278public:
280 {
281 this->Texture = nullptr;
283 this->SpriteTexture = nullptr;
284 this->SavedDepthTest = GL_TRUE;
285 this->SavedStencilTest = GL_TRUE;
286 this->SavedBlend = GL_TRUE;
287 this->SavedDrawBuffer = 0;
288 this->SavedClearColor[0] = this->SavedClearColor[1] = this->SavedClearColor[2] =
289 this->SavedClearColor[3] = 0.0f;
290 this->TextCounter = 0;
291 this->GLExtensionsLoaded = true;
292 this->GLSL = true;
293 this->PowerOfTwoTextures = false;
294 }
295
297 {
298 if (this->Texture)
299 {
300 this->Texture->Delete();
301 this->Texture = nullptr;
302 }
303 if (this->SpriteTexture)
304 {
305 this->SpriteTexture->Delete();
306 this->SpriteTexture = nullptr;
307 }
308 }
309
310 void SaveGLState(vtkOpenGLState* ostate, bool colorBuffer = false)
311 {
312 this->SavedDepthTest = ostate->GetEnumState(GL_DEPTH_TEST);
313
314 if (colorBuffer)
315 {
316 this->SavedStencilTest = ostate->GetEnumState(GL_STENCIL_TEST);
317 this->SavedBlend = ostate->GetEnumState(GL_BLEND);
318 ostate->vtkglGetFloatv(GL_COLOR_CLEAR_VALUE, this->SavedClearColor);
319 ostate->vtkglGetIntegerv(GL_DRAW_BUFFER, &this->SavedDrawBuffer);
320 }
321 }
322
323 void RestoreGLState(vtkOpenGLState* ostate, bool colorBuffer = false)
324 {
325 ostate->SetEnumState(GL_DEPTH_TEST, this->SavedDepthTest);
326
327 if (colorBuffer)
328 {
329 ostate->SetEnumState(GL_STENCIL_TEST, this->SavedStencilTest);
330 ostate->SetEnumState(GL_BLEND, this->SavedBlend);
331
332 if (this->SavedDrawBuffer != GL_BACK_LEFT)
333 {
334 const GLenum bufs[1] = { static_cast<GLenum>(this->SavedDrawBuffer) };
335 ::glDrawBuffers(1, bufs);
336 }
337
338 ostate->vtkglClearColor(this->SavedClearColor[0], this->SavedClearColor[1],
339 this->SavedClearColor[2], this->SavedClearColor[3]);
340 }
341 }
342
343 float* TexCoords(float* f, int n)
344 {
345 float* texCoord = new float[2 * n];
346 float minX = f[0];
347 float minY = f[1];
348 float maxX = f[0];
349 float maxY = f[1];
350 float* fptr = f;
351 for (int i = 0; i < n; ++i)
352 {
353 minX = fptr[0] < minX ? fptr[0] : minX;
354 maxX = fptr[0] > maxX ? fptr[0] : maxX;
355 minY = fptr[1] < minY ? fptr[1] : minY;
356 maxY = fptr[1] > maxY ? fptr[1] : maxY;
357 fptr += 2;
358 }
359 fptr = f;
361 {
362 const double* textureBounds = this->Texture->GetInput()->GetBounds();
363 float rangeX =
364 (textureBounds[1] - textureBounds[0]) ? textureBounds[1] - textureBounds[0] : 1.;
365 float rangeY =
366 (textureBounds[3] - textureBounds[2]) ? textureBounds[3] - textureBounds[2] : 1.;
367 for (int i = 0; i < n; ++i)
368 {
369 texCoord[i * 2] = (fptr[0] - minX) / rangeX;
370 texCoord[i * 2 + 1] = (fptr[1] - minY) / rangeY;
371 fptr += 2;
372 }
373 }
374 else // this->TextureProperties & vtkContextDevice2D::Stretch
375 {
376 float rangeX = (maxX - minX) ? maxX - minX : 1.f;
377 float rangeY = (maxY - minY) ? maxY - minY : 1.f;
378 for (int i = 0; i < n; ++i)
379 {
380 texCoord[i * 2] = (fptr[0] - minX) / rangeX;
381 texCoord[i * 2 + 1] = (fptr[1] - minY) / rangeY;
382 fptr += 2;
383 }
384 }
385 return texCoord;
386 }
387
389 {
390 vtkVector2i pow2(1, 1);
391 for (int i = 0; i < 2; ++i)
392 {
393 while (pow2[i] < size[i])
394 {
395 pow2[i] *= 2;
396 }
397 }
398 return pow2;
399 }
400
401 GLuint TextureFromImage(vtkImageData* image, vtkVector2f& texCoords)
402 {
403 if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
404 {
405 vtkGenericWarningMacro("Invalid image format: expected unsigned char.");
406 return 0;
407 }
408 int bytesPerPixel = image->GetNumberOfScalarComponents();
409 int size[3];
410 image->GetDimensions(size);
411 vtkVector2i newImg = this->FindPowerOfTwo(vtkVector2i(size[0], size[1]));
412
413 for (int i = 0; i < 2; ++i)
414 {
415 texCoords[i] = size[i] / float(newImg[i]);
416 }
417
418 unsigned char* dataPtr = new unsigned char[newImg[0] * newImg[1] * bytesPerPixel];
419 unsigned char* origPtr = static_cast<unsigned char*>(image->GetScalarPointer());
420
421 for (int i = 0; i < newImg[0]; ++i)
422 {
423 for (int j = 0; j < newImg[1]; ++j)
424 {
425 for (int k = 0; k < bytesPerPixel; ++k)
426 {
427 if (i < size[0] && j < size[1])
428 {
429 dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
430 origPtr[i * bytesPerPixel + j * size[0] * bytesPerPixel + k];
431 }
432 else
433 {
434 dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] = k == 3 ? 0 : 255;
435 }
436 }
437 }
438 }
439
440 GLuint tmpIndex(0);
441 GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
442 GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
443
444 glGenTextures(1, &tmpIndex);
445 glBindTexture(GL_TEXTURE_2D, tmpIndex);
446
447 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
448 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
449 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
450 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
451
452 glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, newImg[0], newImg[1], 0, glFormat,
453 GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(dataPtr));
454 delete[] dataPtr;
455 return tmpIndex;
456 }
457
459 {
460 if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
461 {
462 cout << "Error = not an unsigned char..." << endl;
463 return 0;
464 }
465 int bytesPerPixel = image->GetNumberOfScalarComponents();
466 int size[3];
467 image->GetDimensions(size);
468
469 unsigned char* dataPtr = static_cast<unsigned char*>(image->GetScalarPointer());
470 GLuint tmpIndex(0);
471 GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
472 GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
473
474 glGenTextures(1, &tmpIndex);
475 glBindTexture(GL_TEXTURE_2D, tmpIndex);
476
477 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
478 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
479 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
480 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
481
482 glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, size[0], size[1], 0, glFormat,
483 GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(dataPtr));
484 return tmpIndex;
485 }
486
488 unsigned int TextureProperties;
490 // Store the previous GL state so that we can restore it when complete
495 GLfloat SavedClearColor[4];
496
501 bool GLSL;
503
505
511};
512
514
534{
535
536public:
538 {
539 LINE = 1,
540 POLYGON
541 // TRIANGLE_STRIPS
542 };
543
545 : Device(device)
546 , Points(nullptr)
547 , PointIds(nullptr)
548 , Colors(nullptr)
549 , NumPointsCell(0)
550 {
551 this->cache = new PolyDataCache();
552 };
553
554 ~CellArrayHelper() { delete this->cache; }
555
559 void Draw(int cellType, vtkPolyData* polyData, vtkPoints* points, float x, float y, float scale,
560 int scalarMode, vtkUnsignedCharArray* colors = nullptr)
561 {
562 this->Points = points;
563 this->Colors = colors;
564 this->CellColors->SetNumberOfComponents(colors->GetNumberOfComponents());
565
566 switch (cellType)
567 {
568 case LINE:
569 this->DrawLines(polyData, scalarMode, x, y, scale);
570 break;
571
572 case POLYGON:
573 this->DrawPolygons(polyData, scalarMode, x, y, scale);
574 break;
575 }
576 };
577
578 void HandleEndFrame() { this->cache->SwapCaches(); }
579
580private:
581 CellArrayHelper(const CellArrayHelper&) = delete;
582 void operator=(const CellArrayHelper&) = delete;
583
584 struct PolyDataCacheItem
585 {
586 // Each polydata may have lines as well as polys which must be cached
587 // separately
588 std::vector<float> PolyTri;
590 vtkTimeStamp PolygonsLoadingTime;
591
592 std::vector<float> Lines;
594 vtkTimeStamp LinesLoadingTime;
595 };
596
597 struct PolyDataCache
598 {
599 ~PolyDataCache()
600 {
601 std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev = this->PrevFrameCache.begin();
602 for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
603 {
604 delete itPrev->second;
605 }
606
607 std::map<vtkPolyData*, PolyDataCacheItem*>::iterator it = this->CurrentFrameCache.begin();
608 for (; it != this->CurrentFrameCache.end(); ++it)
609 {
610 delete it->second;
611 }
612 }
613
614 PolyDataCacheItem* GetCacheEntry(vtkPolyData* key)
615 {
616 PolyDataCacheItem* cacheItem = this->CurrentFrameCache[key];
617 if (cacheItem == nullptr)
618 {
619 cacheItem = this->PrevFrameCache[key];
620 if (cacheItem == nullptr)
621 {
622 cacheItem = new PolyDataCacheItem();
623 cacheItem->PolyColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
624 cacheItem->LineColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
625 }
626 else
627 {
628 // Move the item to the current frame, since we were asked for it
629 this->PrevFrameCache.erase(key);
630 }
631
632 // Add the cache item to the current frame's cache
633 this->CurrentFrameCache[key] = cacheItem;
634 }
635
636 return cacheItem;
637 }
638
639 void SwapCaches()
640 {
641 // Delete any objects stored in the previous frame's cache, as
642 // if they had been used in this frame, we would have moved them
643 // into the current frame cache already.
644 std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev = this->PrevFrameCache.begin();
645 for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
646 {
647 delete itPrev->second;
648 }
649
650 // Clear the entries in the previous frame's cache
651 this->PrevFrameCache.clear();
652
653 // Now swap the caches
654 std::swap(this->PrevFrameCache, this->CurrentFrameCache);
655 }
656
657 // Last two frames worth of cached polygon/line primitives for each drawn
658 // polydata.
659 std::map<vtkPolyData*, PolyDataCacheItem*> PrevFrameCache;
660 std::map<vtkPolyData*, PolyDataCacheItem*> CurrentFrameCache;
661 };
662
666 void MapCurrentCell(
667 float const posX, float const posY, float const scale, vtkIdType cellId, int scalarMode)
668 {
669 this->CellPoints.reserve(this->NumPointsCell * 2); /* 2 components */
670 this->CellColors->SetNumberOfTuples(this->NumPointsCell); /* RGBA */
671 for (int i = 0; i < this->NumPointsCell; i++)
672 {
673 double point[3];
674 this->Points->GetPoint(this->PointIds[i], point);
675
676 // Only 2D meshes are supported
677 float const x = static_cast<float>(point[0]) + posX;
678 float const y = static_cast<float>(point[1]) + posY;
679 this->CellPoints.push_back(x * scale);
680 this->CellPoints.push_back(y * scale);
681
682 // Grab specific point / cell colors
684 switch (scalarMode)
685 {
687 mappedColorId = this->PointIds[i];
688 break;
690 mappedColorId = cellId;
691 break;
692 default:
693 std::cerr << "Scalar mode not supported!" << std::endl;
694 break;
695 }
696
697 this->CellColors->SetTuple(i, mappedColorId, this->Colors);
698 }
699 };
700
706 void DrawLines(
707 vtkPolyData* polyData, int scalarMode, float const x, float const y, float const scale)
708 {
709 PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
710
711 if (polyData->GetMTime() > cacheItem->LinesLoadingTime)
712 {
713 vtkNew<vtkGenericCell> genericCell;
714 cacheItem->Lines.clear();
715 cacheItem->LineColors->Reset();
716
717 // Pre-allocate batched array
718 vtkIdType const numVertices = polyData->GetNumberOfCells() * 2; // points/line
719 cacheItem->Lines.reserve(numVertices * 2); // components
720 cacheItem->LineColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
721 cacheItem->LineColors->SetNumberOfTuples(numVertices);
722
723 vtkIdType cellId = 0;
724 vtkIdType vertOffset = 0;
725 vtkCellIterator* cellIter = nullptr;
726
727 for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
728 cellIter->GoToNextCell(), cellId++)
729 {
730 polyData->GetCell(cellIter->GetCellId(), genericCell);
731 if (genericCell->GetCellType() == VTK_LINE || genericCell->GetCellType() == VTK_POLY_LINE)
732 {
733 vtkIdType actualNumPointsCell = genericCell->GetNumberOfPoints();
734
735 for (int i = 0; i < actualNumPointsCell - 1; ++i)
736 {
737 this->NumPointsCell = 2;
738 this->PointIds = genericCell->GetPointIds()->GetPointer(i);
739
740 this->MapCurrentCell(x, y, scale, cellId, scalarMode);
741
742 // Accumulate the current cell in the batched array
743 for (int j = 0; j < this->NumPointsCell; j++)
744 {
745 cacheItem->Lines.push_back(this->CellPoints[2 * j]);
746 cacheItem->Lines.push_back(this->CellPoints[2 * j + 1]);
747
748 double* color4 = this->CellColors->GetTuple(j);
749 cacheItem->LineColors->InsertTuple4(
750 vertOffset + j, color4[0], color4[1], color4[2], color4[3]);
751 }
752
753 vertOffset += this->NumPointsCell;
754 this->CellColors->Reset();
755 this->CellPoints.clear();
756 }
757 }
758 }
759
760 cacheItem->LinesLoadingTime.Modified();
761 cellIter->Delete();
762 }
763
764 if (!cacheItem->Lines.empty())
765 {
766 this->Device->DrawLines(&cacheItem->Lines[0], static_cast<int>(cacheItem->Lines.size() / 2),
767 static_cast<unsigned char*>(cacheItem->LineColors->GetVoidPointer(0)),
768 cacheItem->LineColors->GetNumberOfComponents());
769 }
770 };
771
776 vtkIdType GetCountTriangleVertices(vtkPolyData* polyData)
777 {
778 vtkIdType cellId = 0;
779 vtkIdType numTriVert = 0;
780 vtkNew<vtkGenericCell> genericCell;
781 vtkCellIterator* cellIter = nullptr;
782
783 for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
784 cellIter->GoToNextCell(), cellId++)
785 {
786 polyData->GetCell(cellIter->GetCellId(), genericCell);
787 this->NumPointsCell = genericCell->GetNumberOfPoints();
788 this->PointIds = genericCell->GetPointIds()->GetPointer(0);
789 numTriVert += 3 * (this->NumPointsCell - 2);
790 }
791
792 cellIter->Delete();
793 return numTriVert;
794 };
795
801 void DrawPolygons(
802 vtkPolyData* polyData, int scalarMode, float const x, float const y, float const scale)
803 {
804 PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
805
806 if (polyData->GetMTime() > cacheItem->PolygonsLoadingTime)
807 {
808 cacheItem->PolyTri.clear();
809 cacheItem->PolyColors->Reset();
810
811 // Pre-allocate batched array
812 vtkIdType const totalTriVert = this->GetCountTriangleVertices(polyData);
813 cacheItem->PolyTri.reserve(totalTriVert * 2); // components
814 cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
815 cacheItem->PolyColors->SetNumberOfTuples(totalTriVert);
816
817 // Traverse polygons and convert to triangles
818 vtkIdType cellId = 0;
819 vtkIdType vertOffset = 0;
820 cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
821
822 vtkNew<vtkGenericCell> genericCell;
823 vtkCellIterator* cellIter = nullptr;
824
825 for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
826 cellIter->GoToNextCell(), cellId++)
827 {
828 polyData->GetCell(cellIter->GetCellId(), genericCell);
829 if (genericCell->GetCellType() == VTK_TRIANGLE || genericCell->GetCellType() == VTK_QUAD ||
830 genericCell->GetCellType() == VTK_POLYGON)
831 {
832 this->NumPointsCell = genericCell->GetNumberOfPoints();
833 this->PointIds = genericCell->GetPointIds()->GetPointer(0);
834
835 this->MapCurrentCell(x, y, scale, cellId, scalarMode);
836
837 // Convert current cell (polygon) to triangles
838 for (int i = 0; i < this->NumPointsCell - 2; i++)
839 {
840 cacheItem->PolyTri.push_back(this->CellPoints[0]);
841 cacheItem->PolyTri.push_back(this->CellPoints[1]);
842 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 2]);
843 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 3]);
844 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 4]);
845 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 5]);
846
847 // Insert triangle vertex color
848 vtkIdType const triangOffset = vertOffset + 3 * i;
849 double* color4 = this->CellColors->GetTuple(0);
850 cacheItem->PolyColors->InsertTuple4(
851 triangOffset, color4[0], color4[1], color4[2], color4[3]);
852
853 color4 = this->CellColors->GetTuple(i + 1);
854 cacheItem->PolyColors->InsertTuple4(
855 triangOffset + 1, color4[0], color4[1], color4[2], color4[3]);
856
857 color4 = this->CellColors->GetTuple(i + 2);
858 cacheItem->PolyColors->InsertTuple4(
859 triangOffset + 2, color4[0], color4[1], color4[2], color4[3]);
860 }
861
862 vertOffset += 3 * (this->NumPointsCell - 2); // Triangle verts current cell
863 this->CellColors->Reset();
864 this->CellPoints.clear();
865 }
866 }
867
868 cacheItem->PolygonsLoadingTime.Modified();
869 cellIter->Delete();
870 }
871
872 if (!cacheItem->PolyTri.empty())
873 {
874 this->Device->CoreDrawTriangles(cacheItem->PolyTri,
875 static_cast<unsigned char*>(cacheItem->PolyColors->GetVoidPointer(0)), 4);
876 }
877 };
878
880
881 vtkPoints* Points;
882 vtkIdType* PointIds;
883 vtkUnsignedCharArray* Colors;
884
886
889 vtkIdType NumPointsCell;
890 std::vector<float> CellPoints;
893
894 PolyDataCache* cache;
895};
896#endif // VTKOPENGLCONTEXTDEVICE2DPRIVATE_H
897// 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
Set/Get the dimension (n) of the components.
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.
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 *buffer, size_t n, vtkTypeUInt32 hash=0)
Hash a buffer of a given length.
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.
void SetInputData(vtkDataObject *)
Assign a data object as input.
topologically and geometrically regular array of data
Allocate and hold a VTK object.
Definition vtkNew.h:62
T * GetPointer() const noexcept
Get a raw pointer to the contained object.
Definition vtkNew.h:151
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)
GLuint TextureFromImage(vtkImageData *image, vtkVector2f &texCoords)
vtkTextureImageCache< UTF8TextPropertyKey > TextTextureCache
Cache for text images.
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... The lines will be c...
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:40
double * GetPoint(vtkIdType id)
Return a pointer to a double point x[3] for a specific id.
Definition vtkPoints.h:140
concrete dataset represents vertices, lines, polygons, and triangle strips
Definition vtkPolyData.h:91
vtkCell * GetCell(vtkIdType cellId) override
Standard vtkDataSet interface.
vtkMTimeType GetMTime() override
Get MTime which also considers its cell array MTime.
vtkIdType GetNumberOfCells() override
Standard vtkDataSet interface.
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
represent text properties.
virtual double GetCellOffset()
Set/Get the horizontal offset between cells.
virtual int GetVerticalJustification()
Set/Get the vertical justification to bottom (default), middle, or top.
virtual double GetOpacity()
Set/Get the text's opacity.
virtual int GetFontSize()
Set/Get the font size (in points).
virtual double * GetColor()
Set the color of the text.
virtual double * GetInteriorLinesColor()
Set the color of the interior lines between cells.
virtual bool GetInteriorLinesVisibility()
Set/Get the visibility of the interior lines between cells.
virtual int GetInteriorLinesWidth()
Set the width (in pixels) of the interior lines between cells.
virtual int GetJustification()
Set/Get the horizontal justification to left (default), centered, or right.
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.
CacheData & AddCacheData(const Key &key, const CacheData &cacheData)
Add a new cache entry into the cache list.
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 & GetCacheData(const Key &key)
Return the cache associated to a key.
handles properties associated with a texture map
Definition vtkTexture.h:69
vtkImageData * GetInput()
Get the input as a vtkImageData object.
record modification and/or execution time
dynamic, self-adjusting array of unsigned char
Some derived classes for the different vectors commonly used.
Definition vtkVector.h:422
window superclass for vtkRenderWindow
Definition vtkWindow.h:39
@ point
Definition vtkX3D.h:242
@ key
Definition vtkX3D.h:263
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
#define GL_NEAREST
#define GL_UNSIGNED_BYTE
#define GL_CLAMP_TO_EDGE
TextPropertyKey< vtkStdString > UTF8TextPropertyKey
int vtkIdType
Definition vtkType.h:332
#define VTK_UNSIGNED_CHAR
Definition vtkType.h:47