VTK  9.4.20250309
vtkOpenGLContextDevice2DPrivate.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3
21#ifndef vtkOpenGLContextDevice2DPrivate_h
22#define vtkOpenGLContextDevice2DPrivate_h
23
25
26#include "vtkAbstractMapper.h"
27#include "vtkCellIterator.h"
28#include "vtkColor.h"
29#include "vtkFreeTypeTools.h"
30#include "vtkGenericCell.h"
32#include "vtkTextProperty.h"
33#include "vtkTextRenderer.h"
34#include "vtkTexture.h"
36
37#include <algorithm>
38#include <list>
39#include <utility>
40
41// .NAME vtkTextureImageCache - store vtkTexture and vtkImageData identified by
42// a unique key.
43// .SECTION Description
44// Creating and initializing a texture can be time consuming,
45// vtkTextureImageCache offers the ability to reuse them as much as possible.
46VTK_ABI_NAMESPACE_BEGIN
47template <class Key>
49{
50public:
51 struct CacheData
52 {
55 // Use to generate texture coordinates. Computing this is as expensive as
56 // rendering the texture, so we cache it.
58 };
59
61
64 struct CacheElement : public std::pair<Key, CacheData>
65 {
66 // Default constructor
68 : std::pair<Key, CacheData>(Key(), CacheData())
69 {
70 }
71 // Construct a partial CacheElement with no CacheData
72 // This can be used for temporary CacheElement used to search a given
73 // key into the cache list.
74 CacheElement(const Key& key)
75 : std::pair<Key, CacheData>(key, CacheData())
76 {
77 }
78 // Standard constructor of CacheElement
79 CacheElement(const Key& key, const CacheData& cacheData)
80 : std::pair<Key, CacheData>(key, cacheData)
81 {
82 }
83 // Operator tuned to be used when searching into the cache list using
84 // std::find()
85 bool operator==(const CacheElement& other) const
86 {
87 // Here we cheat and make the comparison only on the key, this allows
88 // us to use std::find() to search for a given key.
89 return this->first == other.first;
90 }
91 };
93
97 vtkTextureImageCache() { this->MaxSize = 50; }
98
103 bool IsKeyInCache(const Key& key) const
104 {
105 return std::find(this->Cache.begin(), this->Cache.end(), key) != this->Cache.end();
106 }
107
114 CacheData& GetCacheData(const Key& key);
115
117
122 {
123 typename std::list<CacheElement>::iterator it;
124 for (it = this->Cache.begin(); it != this->Cache.end(); ++it)
125 {
126 it->second.Texture->ReleaseGraphicsResources(window);
127 }
128 }
130
131protected:
133
137 CacheData& AddCacheData(const Key& key, const CacheData& cacheData)
138 {
139 assert(!this->IsKeyInCache(key));
140 if (this->Cache.size() >= this->MaxSize)
141 {
142 this->Cache.pop_back();
143 }
144 this->Cache.push_front(CacheElement(key, cacheData));
145 return this->Cache.begin()->second;
146 }
148
152 std::list<CacheElement> Cache;
154
157 size_t MaxSize;
159};
160
161template <class Key>
163 const Key& key)
164{
165 typename std::list<CacheElement>::iterator it =
166 std::find(this->Cache.begin(), this->Cache.end(), CacheElement(key));
167 if (it != this->Cache.end())
168 {
169 return it->second;
170 }
171 CacheData cacheData;
174 cacheData.Texture->SetInputData(cacheData.ImageData);
175 return this->AddCacheData(key, cacheData);
176}
177
178// .NAME TextPropertyKey - unique key for a vtkTextProperty and text
179// .SECTION Description
180// Uniquely describe a pair of vtkTextProperty and text.
181template <class StringType>
183{
185
188 static vtkTypeUInt32 GetIdFromTextProperty(vtkTextProperty* tprop)
189 {
190 size_t id;
191
193 ftt->MapTextPropertyToId(tprop, &id);
194
195 // The hash is really a uint32 that gets cast to a size_t in
196 // MapTextPropertyToId, so this possible truncation is safe.
197 // Yay legacy APIs.
198 vtkTypeUInt32 hash = static_cast<vtkTypeUInt32>(id);
199
200 // Ensure that the above implementation assumption still holds. If it
201 // doesn't we'll need to rework this cache class a bit.
202 assert("Hash is really a uint32" && static_cast<size_t>(hash) == id);
203
204 // Since we cache the text metrics (which includes orientation and alignment
205 // info), we'll need to store additional options, since MapTextPropertyToId
206 // intentionally ignores them.
207 // These include cell spacing and interior lines for multi cell text, as well
208 // as text justification.
209 int tmp = tprop->GetJustification();
210 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
211 tmp = tprop->GetVerticalJustification();
212 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
213 tmp = tprop->GetCellOffset();
214 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
215 tmp = tprop->GetInteriorLinesVisibility();
216 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
217 tmp = tprop->GetInteriorLinesWidth();
218 hash = vtkFreeTypeTools::HashBuffer(&tmp, sizeof(int), hash);
219 hash = vtkFreeTypeTools::HashBuffer(tprop->GetInteriorLinesColor(), 3 * sizeof(double), hash);
220
221 return hash;
222 }
224
226
229 TextPropertyKey(vtkTextProperty* textProperty, const StringType& text, int dpi)
230 {
231 this->TextPropertyId = GetIdFromTextProperty(textProperty);
232 this->FontSize = textProperty->GetFontSize();
233 double color[3];
234 textProperty->GetColor(color);
235 this->Color.Set(static_cast<unsigned char>(color[0] * 255),
236 static_cast<unsigned char>(color[1] * 255), static_cast<unsigned char>(color[2] * 255),
237 static_cast<unsigned char>(textProperty->GetOpacity() * 255));
238 this->Text = text;
239 this->DPI = dpi;
240 }
242
247 bool operator==(const TextPropertyKey& other) const
248 {
249 return this->TextPropertyId == other.TextPropertyId && this->FontSize == other.FontSize &&
250 this->Text == other.Text && this->Color[0] == other.Color[0] &&
251 this->Color[1] == other.Color[1] && this->Color[2] == other.Color[2] &&
252 this->Color[3] == other.Color[3] && this->DPI == other.DPI;
253 }
254
255 unsigned short FontSize;
257 // States in the function not to use more than 32 bits - int works fine here.
258 vtkTypeUInt32 TextPropertyId;
259 StringType Text;
260 int DPI;
261};
262
264
266{
267public:
269 {
270 this->Texture = nullptr;
272 this->SpriteTexture = nullptr;
273 this->SavedDepthTest = GL_TRUE;
274 this->SavedStencilTest = GL_TRUE;
275 this->SavedBlend = GL_TRUE;
276 this->SavedDrawBuffer = 0;
277 this->SavedClearColor[0] = this->SavedClearColor[1] = this->SavedClearColor[2] =
278 this->SavedClearColor[3] = 0.0f;
279 this->TextCounter = 0;
280 this->GLExtensionsLoaded = true;
281 this->GLSL = true;
282 this->PowerOfTwoTextures = false;
283 }
284
286 {
287 if (this->Texture)
288 {
289 this->Texture->Delete();
290 this->Texture = nullptr;
291 }
292 if (this->SpriteTexture)
293 {
294 this->SpriteTexture->Delete();
295 this->SpriteTexture = nullptr;
296 }
297 }
298
299 void SaveGLState(vtkOpenGLState* ostate, bool colorBuffer = false)
300 {
301 this->SavedDepthTest = ostate->GetEnumState(GL_DEPTH_TEST);
302
303 if (colorBuffer)
304 {
305 this->SavedStencilTest = ostate->GetEnumState(GL_STENCIL_TEST);
306 this->SavedBlend = ostate->GetEnumState(GL_BLEND);
307 ostate->vtkglGetFloatv(GL_COLOR_CLEAR_VALUE, this->SavedClearColor);
308
309#ifdef GL_DRAW_BUFFER
310 ostate->vtkglGetIntegerv(GL_DRAW_BUFFER, &this->SavedDrawBuffer);
311#else
312 this->SavedDrawBuffer = GL_BACK_LEFT;
313#endif
314 }
315 }
316
317 void RestoreGLState(vtkOpenGLState* ostate, bool colorBuffer = false)
318 {
319 ostate->SetEnumState(GL_DEPTH_TEST, this->SavedDepthTest);
320
321 if (colorBuffer)
322 {
323 ostate->SetEnumState(GL_STENCIL_TEST, this->SavedStencilTest);
324 ostate->SetEnumState(GL_BLEND, this->SavedBlend);
325
326 if (this->SavedDrawBuffer != GL_BACK_LEFT)
327 {
328 const GLenum bufs[1] = { static_cast<GLenum>(this->SavedDrawBuffer) };
329 ::glDrawBuffers(1, bufs);
330 }
331
332 ostate->vtkglClearColor(this->SavedClearColor[0], this->SavedClearColor[1],
333 this->SavedClearColor[2], this->SavedClearColor[3]);
334 }
335 }
336
337 float* TexCoords(float* f, int n)
338 {
339 float* texCoord = new float[2 * n];
340 float minX = f[0];
341 float minY = f[1];
342 float maxX = f[0];
343 float maxY = f[1];
344 float* fptr = f;
345 for (int i = 0; i < n; ++i)
346 {
347 minX = fptr[0] < minX ? fptr[0] : minX;
348 maxX = fptr[0] > maxX ? fptr[0] : maxX;
349 minY = fptr[1] < minY ? fptr[1] : minY;
350 maxY = fptr[1] > maxY ? fptr[1] : maxY;
351 fptr += 2;
352 }
353 fptr = f;
355 {
356 const double* textureBounds = this->Texture->GetInput()->GetBounds();
357 float rangeX =
358 (textureBounds[1] - textureBounds[0]) ? textureBounds[1] - textureBounds[0] : 1.;
359 float rangeY =
360 (textureBounds[3] - textureBounds[2]) ? textureBounds[3] - textureBounds[2] : 1.;
361 for (int i = 0; i < n; ++i)
362 {
363 texCoord[i * 2] = (fptr[0] - minX) / rangeX;
364 texCoord[i * 2 + 1] = (fptr[1] - minY) / rangeY;
365 fptr += 2;
366 }
367 }
368 else // this->TextureProperties & vtkContextDevice2D::Stretch
369 {
370 float rangeX = (maxX - minX) ? maxX - minX : 1.f;
371 float rangeY = (maxY - minY) ? maxY - minY : 1.f;
372 for (int i = 0; i < n; ++i)
373 {
374 texCoord[i * 2] = (fptr[0] - minX) / rangeX;
375 texCoord[i * 2 + 1] = (fptr[1] - minY) / rangeY;
376 fptr += 2;
377 }
378 }
379 return texCoord;
380 }
381
383 {
384 vtkVector2i pow2(1, 1);
385 for (int i = 0; i < 2; ++i)
386 {
387 while (pow2[i] < size[i])
388 {
389 pow2[i] *= 2;
390 }
391 }
392 return pow2;
393 }
394
395 GLuint TextureFromImage(vtkImageData* image, vtkVector2f& texCoords)
396 {
397 if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
398 {
399 vtkGenericWarningMacro("Invalid image format: expected unsigned char.");
400 return 0;
401 }
402 int bytesPerPixel = image->GetNumberOfScalarComponents();
403 int size[3];
404 image->GetDimensions(size);
405 vtkVector2i newImg = this->FindPowerOfTwo(vtkVector2i(size[0], size[1]));
406
407 for (int i = 0; i < 2; ++i)
408 {
409 texCoords[i] = size[i] / float(newImg[i]);
410 }
411
412 unsigned char* dataPtr = new unsigned char[newImg[0] * newImg[1] * bytesPerPixel];
413 unsigned char* origPtr = static_cast<unsigned char*>(image->GetScalarPointer());
414
415 for (int i = 0; i < newImg[0]; ++i)
416 {
417 for (int j = 0; j < newImg[1]; ++j)
418 {
419 for (int k = 0; k < bytesPerPixel; ++k)
420 {
421 if (i < size[0] && j < size[1])
422 {
423 dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
424 origPtr[i * bytesPerPixel + j * size[0] * bytesPerPixel + k];
425 }
426 else
427 {
428 dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] = k == 3 ? 0 : 255;
429 }
430 }
431 }
432 }
433
434 GLuint tmpIndex(0);
435 GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
436 GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
437
438 glGenTextures(1, &tmpIndex);
439 glBindTexture(GL_TEXTURE_2D, tmpIndex);
440
441 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
442 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
443 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
444 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
445
446 glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, newImg[0], newImg[1], 0, glFormat,
447 GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(dataPtr));
448 delete[] dataPtr;
449 return tmpIndex;
450 }
451
453 {
454 if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
455 {
456 cout << "Error = not an unsigned char..." << endl;
457 return 0;
458 }
459 int bytesPerPixel = image->GetNumberOfScalarComponents();
460 int size[3];
461 image->GetDimensions(size);
462
463 unsigned char* dataPtr = static_cast<unsigned char*>(image->GetScalarPointer());
464 GLuint tmpIndex(0);
465 GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
466 GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
467
468 glGenTextures(1, &tmpIndex);
469 glBindTexture(GL_TEXTURE_2D, tmpIndex);
470
471 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
472 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
473 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
474 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
475
476 glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, size[0], size[1], 0, glFormat,
477 GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(dataPtr));
478 return tmpIndex;
479 }
480
482 unsigned int TextureProperties;
484 // Store the previous GL state so that we can restore it when complete
489 GLfloat SavedClearColor[4];
490
495 bool GLSL;
497
499
506};
507
509
529{
530
531public:
533 {
534 LINE = 1,
535 POLYGON
536 // TRIANGLE_STRIPS
537 };
538
540 : Device(device)
541 , Points(nullptr)
542 , PointIds(nullptr)
543 , Colors(nullptr)
544 , NumPointsCell(0)
545 {
546 this->cache = new PolyDataCache();
547 }
548
549 ~CellArrayHelper() { delete this->cache; }
550
554 void Draw(int cellType, vtkPolyData* polyData, vtkPoints* points, float x, float y, float scale,
555 int scalarMode, vtkUnsignedCharArray* colors = nullptr)
556 {
557 this->Points = points;
558 this->Colors = colors;
559 this->CellColors->SetNumberOfComponents(colors->GetNumberOfComponents());
560
561 switch (cellType)
562 {
563 case LINE:
564 this->DrawLines(polyData, scalarMode, x, y, scale);
565 break;
566
567 case POLYGON:
568 this->DrawPolygons(polyData, scalarMode, x, y, scale);
569 break;
570 }
571 }
572
573 void HandleEndFrame() { this->cache->SwapCaches(); }
574
575private:
576 CellArrayHelper(const CellArrayHelper&) = delete;
577 void operator=(const CellArrayHelper&) = delete;
578
579 struct PolyDataCacheItem
580 {
581 // Each polydata may have lines as well as polys which must be cached
582 // separately
583 std::vector<float> PolyTri;
585 vtkTimeStamp PolygonsLoadingTime;
586
587 std::vector<float> Lines;
589 vtkTimeStamp LinesLoadingTime;
590 };
591
592 struct PolyDataCache
593 {
594 ~PolyDataCache()
595 {
596 std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev = this->PrevFrameCache.begin();
597 for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
598 {
599 delete itPrev->second;
600 }
601
602 std::map<vtkPolyData*, PolyDataCacheItem*>::iterator it = this->CurrentFrameCache.begin();
603 for (; it != this->CurrentFrameCache.end(); ++it)
604 {
605 delete it->second;
606 }
607 }
608
609 PolyDataCacheItem* GetCacheEntry(vtkPolyData* key)
610 {
611 PolyDataCacheItem* cacheItem = this->CurrentFrameCache[key];
612 if (cacheItem == nullptr)
613 {
614 cacheItem = this->PrevFrameCache[key];
615 if (cacheItem == nullptr)
616 {
617 cacheItem = new PolyDataCacheItem();
618 cacheItem->PolyColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
619 cacheItem->LineColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
620 }
621 else
622 {
623 // Move the item to the current frame, since we were asked for it
624 this->PrevFrameCache.erase(key);
625 }
626
627 // Add the cache item to the current frame's cache
628 this->CurrentFrameCache[key] = cacheItem;
629 }
630
631 return cacheItem;
632 }
633
634 void SwapCaches()
635 {
636 // Delete any objects stored in the previous frame's cache, as
637 // if they had been used in this frame, we would have moved them
638 // into the current frame cache already.
639 std::map<vtkPolyData*, PolyDataCacheItem*>::iterator itPrev = this->PrevFrameCache.begin();
640 for (; itPrev != this->PrevFrameCache.end(); ++itPrev)
641 {
642 delete itPrev->second;
643 }
644
645 // Clear the entries in the previous frame's cache
646 this->PrevFrameCache.clear();
647
648 // Now swap the caches
649 std::swap(this->PrevFrameCache, this->CurrentFrameCache);
650 }
651
652 // Last two frames worth of cached polygon/line primitives for each drawn
653 // polydata.
654 std::map<vtkPolyData*, PolyDataCacheItem*> PrevFrameCache;
655 std::map<vtkPolyData*, PolyDataCacheItem*> CurrentFrameCache;
656 };
657
661 void MapCurrentCell(
662 float const posX, float const posY, float const scale, vtkIdType cellId, int scalarMode)
663 {
664 this->CellPoints.reserve(this->NumPointsCell * 2); /* 2 components */
665 this->CellColors->SetNumberOfTuples(this->NumPointsCell); /* RGBA */
666 for (int i = 0; i < this->NumPointsCell; i++)
667 {
668 double point[3];
669 this->Points->GetPoint(this->PointIds[i], point);
670
671 // Only 2D meshes are supported
672 float const x = static_cast<float>(point[0]) + posX;
673 float const y = static_cast<float>(point[1]) + posY;
674 this->CellPoints.push_back(x * scale);
675 this->CellPoints.push_back(y * scale);
676
677 // Grab specific point / cell colors
679 switch (scalarMode)
680 {
682 mappedColorId = this->PointIds[i];
683 break;
685 mappedColorId = cellId;
686 break;
687 default:
688 std::cerr << "Scalar mode not supported!" << std::endl;
689 break;
690 }
691
692 this->CellColors->SetTuple(i, mappedColorId, this->Colors);
693 }
694 }
695
701 void DrawLines(
702 vtkPolyData* polyData, int scalarMode, float const x, float const y, float const scale)
703 {
704 PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
705
706 if (polyData->GetMTime() > cacheItem->LinesLoadingTime)
707 {
708 vtkNew<vtkGenericCell> genericCell;
709 cacheItem->Lines.clear();
710 cacheItem->LineColors->Reset();
711
712 // Pre-allocate batched array
713 vtkIdType const numVertices = polyData->GetNumberOfCells() * 2; // points/line
714 cacheItem->Lines.reserve(numVertices * 2); // components
715 cacheItem->LineColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
716 cacheItem->LineColors->SetNumberOfTuples(numVertices);
717
718 vtkIdType cellId = 0;
719 vtkIdType vertOffset = 0;
720 vtkCellIterator* cellIter = nullptr;
721
722 for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
723 cellIter->GoToNextCell(), cellId++)
724 {
725 polyData->GetCell(cellIter->GetCellId(), genericCell);
726 if (genericCell->GetCellType() == VTK_LINE || genericCell->GetCellType() == VTK_POLY_LINE)
727 {
728 vtkIdType actualNumPointsCell = genericCell->GetNumberOfPoints();
729
730 for (int i = 0; i < actualNumPointsCell - 1; ++i)
731 {
732 this->NumPointsCell = 2;
733 this->PointIds = genericCell->GetPointIds()->GetPointer(i);
734
735 this->MapCurrentCell(x, y, scale, cellId, scalarMode);
736
737 // Accumulate the current cell in the batched array
738 for (int j = 0; j < this->NumPointsCell; j++)
739 {
740 cacheItem->Lines.push_back(this->CellPoints[2 * j]);
741 cacheItem->Lines.push_back(this->CellPoints[2 * j + 1]);
742
743 double* color4 = this->CellColors->GetTuple(j);
744 cacheItem->LineColors->InsertTuple4(
745 vertOffset + j, color4[0], color4[1], color4[2], color4[3]);
746 }
747
748 vertOffset += this->NumPointsCell;
749 this->CellColors->Reset();
750 this->CellPoints.clear();
751 }
752 }
753 }
754
755 cacheItem->LinesLoadingTime.Modified();
756 cellIter->Delete();
757 }
758
759 if (!cacheItem->Lines.empty())
760 {
761 this->Device->DrawLines(cacheItem->Lines.data(),
762 static_cast<int>(cacheItem->Lines.size() / 2),
763 static_cast<unsigned char*>(cacheItem->LineColors->GetVoidPointer(0)),
764 cacheItem->LineColors->GetNumberOfComponents());
765 }
766 }
767
772 vtkIdType GetCountTriangleVertices(vtkPolyData* polyData)
773 {
774 vtkIdType cellId = 0;
775 vtkIdType numTriVert = 0;
776 vtkNew<vtkGenericCell> genericCell;
777 vtkCellIterator* cellIter = nullptr;
778
779 for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
780 cellIter->GoToNextCell(), cellId++)
781 {
782 polyData->GetCell(cellIter->GetCellId(), genericCell);
783 this->NumPointsCell = genericCell->GetNumberOfPoints();
784 this->PointIds = genericCell->GetPointIds()->GetPointer(0);
785 numTriVert += 3 * (this->NumPointsCell - 2);
786 }
787
788 cellIter->Delete();
789 return numTriVert;
790 }
791
797 void DrawPolygons(
798 vtkPolyData* polyData, int scalarMode, float const x, float const y, float const scale)
799 {
800 PolyDataCacheItem* cacheItem = this->cache->GetCacheEntry(polyData);
801
802 if (polyData->GetMTime() > cacheItem->PolygonsLoadingTime)
803 {
804 cacheItem->PolyTri.clear();
805 cacheItem->PolyColors->Reset();
806
807 // Pre-allocate batched array
808 vtkIdType const totalTriVert = this->GetCountTriangleVertices(polyData);
809 cacheItem->PolyTri.reserve(totalTriVert * 2); // components
810 cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
811 cacheItem->PolyColors->SetNumberOfTuples(totalTriVert);
812
813 // Traverse polygons and convert to triangles
814 vtkIdType cellId = 0;
815 vtkIdType vertOffset = 0;
816 cacheItem->PolyColors->SetNumberOfComponents(this->Colors->GetNumberOfComponents());
817
818 vtkNew<vtkGenericCell> genericCell;
819 vtkCellIterator* cellIter = nullptr;
820
821 for (cellIter = polyData->NewCellIterator(); !cellIter->IsDoneWithTraversal();
822 cellIter->GoToNextCell(), cellId++)
823 {
824 polyData->GetCell(cellIter->GetCellId(), genericCell);
825 if (genericCell->GetCellType() == VTK_TRIANGLE || genericCell->GetCellType() == VTK_QUAD ||
826 genericCell->GetCellType() == VTK_POLYGON)
827 {
828 this->NumPointsCell = genericCell->GetNumberOfPoints();
829 this->PointIds = genericCell->GetPointIds()->GetPointer(0);
830
831 this->MapCurrentCell(x, y, scale, cellId, scalarMode);
832
833 // Convert current cell (polygon) to triangles
834 for (int i = 0; i < this->NumPointsCell - 2; i++)
835 {
836 cacheItem->PolyTri.push_back(this->CellPoints[0]);
837 cacheItem->PolyTri.push_back(this->CellPoints[1]);
838 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 2]);
839 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 3]);
840 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 4]);
841 cacheItem->PolyTri.push_back(this->CellPoints[i * 2 + 5]);
842
843 // Insert triangle vertex color
844 vtkIdType const triangOffset = vertOffset + 3 * i;
845 double* color4 = this->CellColors->GetTuple(0);
846 cacheItem->PolyColors->InsertTuple4(
847 triangOffset, color4[0], color4[1], color4[2], color4[3]);
848
849 color4 = this->CellColors->GetTuple(i + 1);
850 cacheItem->PolyColors->InsertTuple4(
851 triangOffset + 1, color4[0], color4[1], color4[2], color4[3]);
852
853 color4 = this->CellColors->GetTuple(i + 2);
854 cacheItem->PolyColors->InsertTuple4(
855 triangOffset + 2, color4[0], color4[1], color4[2], color4[3]);
856 }
857
858 vertOffset += 3 * (this->NumPointsCell - 2); // Triangle verts current cell
859 this->CellColors->Reset();
860 this->CellPoints.clear();
861 }
862 }
863
864 cacheItem->PolygonsLoadingTime.Modified();
865 cellIter->Delete();
866 }
867
868 if (!cacheItem->PolyTri.empty())
869 {
870 this->Device->CoreDrawTriangles(cacheItem->PolyTri,
871 static_cast<unsigned char*>(cacheItem->PolyColors->GetVoidPointer(0)), 4);
872 }
873 }
874
876
877 vtkPoints* Points;
878 vtkIdType* PointIds;
879 vtkUnsignedCharArray* Colors;
880
882
885 vtkIdType NumPointsCell;
886 std::vector<float> CellPoints;
889
890 PolyDataCache* cache;
891};
892VTK_ABI_NAMESPACE_END
893#endif // VTKOPENGLCONTEXTDEVICE2DPRIVATE_H
894// 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:137
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:167
T * GetPointer() const noexcept
Get a raw pointer to the contained object.
Definition vtkNew.h:256
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)
vtkOpenGLContextDeviceBufferObjectBuilder BufferObjectBuilder
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...
Internal buffer object builder that maintains a cache of VBO groups.
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:139
double * GetPoint(vtkIdType id)
Return a pointer to a double point x[3] for a specific id.
Definition vtkPoints.h:239
concrete dataset represents vertices, lines, polygons, and triangle strips
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:168
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:440
window superclass for vtkRenderWindow
Definition vtkWindow.h:48
@ point
Definition vtkX3D.h:236
@ key
Definition vtkX3D.h:257
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:41
@ VTK_TRIANGLE
Definition vtkCellType.h:42
@ VTK_POLYGON
Definition vtkCellType.h:44
@ VTK_LINE
Definition vtkCellType.h:40
@ VTK_QUAD
Definition vtkCellType.h:46
#define GL_NEAREST
#define GL_UNSIGNED_BYTE
#define GL_CLAMP_TO_EDGE
TextPropertyKey< std::string > UTF8TextPropertyKey
int vtkIdType
Definition vtkType.h:332
#define VTK_UNSIGNED_CHAR
Definition vtkType.h:36