VTK  9.1.0
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"
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.
59template <class Key>
61{
62public:
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
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
143protected:
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
173template <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.
193template <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{
271public:
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
394 GLuint TextureFromImage(vtkImageData* image, vtkVector2f& texCoords)
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
530public:
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
574private:
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.empty())
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.empty())
867 {
868 this->Device->CoreDrawTriangles(cacheItem->PolyTri,
869 static_cast<unsigned char*>(cacheItem->PolyColors->GetVoidPointer(0)), 4);
870 }
871 };
872
874
875 vtkPoints* Points;
876 vtkIdType* PointIds;
877 vtkUnsignedCharArray* Colors;
878
880
883 vtkIdType NumPointsCell;
884 std::vector<float> CellPoints;
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
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:238
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
Definition: vtkImageData.h:157
Allocate and hold a VTK object.
Definition: vtkNew.h:165
void Reset()
Deletes reference to instance of T.
Definition: vtkNew.h:230
T * GetPointer() const noexcept
Get a raw pointer to the contained object.
Definition: vtkNew.h:254
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
Cache for text images.
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... 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:143
double * GetPoint(vtkIdType id)
Return a pointer to a double point x[3] for a specific id.
Definition: vtkPoints.h:243
concrete dataset represents vertices, lines, polygons, and triangle strips
Definition: vtkPolyData.h:195
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.
Definition: vtkPolyData.h:858
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
represent text properties.
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 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:175
vtkImageData * GetInput()
Get the input as a vtkImageData object.
record modification and/or execution time
Definition: vtkTimeStamp.h:52
dynamic, self-adjusting array of unsigned char
Some derived classes for the different vectors commonly used.
Definition: vtkVector.h:478
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:89
@ VTK_TRIANGLE
Definition: vtkCellType.h:90
@ VTK_POLYGON
Definition: vtkCellType.h:92
@ VTK_LINE
Definition: vtkCellType.h:88
@ VTK_QUAD
Definition: vtkCellType.h:94
#define GL_NEAREST
#define GL_UNSIGNED_BYTE
#define GL_CLAMP_TO_EDGE
TextPropertyKey< vtkUnicodeString > UTF16TextPropertyKey
TextPropertyKey< vtkStdString > UTF8TextPropertyKey
int vtkIdType
Definition: vtkType.h:332
#define VTK_UNSIGNED_CHAR
Definition: vtkType.h:47