VTK  9.3.20240424
vtkPixelExtent.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
18#ifndef vtkPixelExtent_h
19#define vtkPixelExtent_h
20
21#include "vtkCommonDataModelModule.h" // for export
22#include "vtkSystemIncludes.h" // for VTK's system header config
23
24#include <algorithm> // for inline impl
25#include <climits> // for inline impl
26#include <deque> // for inline impl
27#include <iostream> // for inline impl
28
29VTK_ABI_NAMESPACE_BEGIN
30class VTKCOMMONDATAMODEL_EXPORT vtkPixelExtent
31{
32public:
34
35 template <typename T>
36 vtkPixelExtent(const T* ext);
37
38 template <typename T>
39 vtkPixelExtent(T ilo, T ihi, T jlo, T jhi);
40
41 template <typename T>
42 vtkPixelExtent(T width, T height)
43 {
44 this->SetData(T(0), width - T(1), T(0), height - T(1));
45 }
46
47 vtkPixelExtent(const vtkPixelExtent& other);
48
49 vtkPixelExtent& operator=(const vtkPixelExtent& other);
50
54 int& operator[](int i) { return this->Data[i]; }
55 const int& operator[](int i) const { return this->Data[i]; }
56
60 void SetData(const vtkPixelExtent& ext);
61
62 template <typename T>
63 void SetData(const T* ext);
64
65 template <typename T>
66 void SetData(T ilo, T ihi, T jlo, T jhi);
67 void Clear();
68
72 int* GetData() { return this->Data; }
73 const int* GetData() const { return this->Data; }
74
75 template <typename T>
76 void GetData(T data[4]) const;
77
78 unsigned int* GetDataU() { return reinterpret_cast<unsigned int*>(this->Data); }
79
80 const unsigned int* GetDataU() const { return reinterpret_cast<const unsigned int*>(this->Data); }
81
83
86 void GetStartIndex(int first[2]) const;
87 void GetStartIndex(int first[2], const int origin[2]) const;
88 void GetEndIndex(int last[2]) const;
90
94 int Empty() const;
95
99 bool operator==(const vtkPixelExtent& other) const;
100
102
105 int Contains(const vtkPixelExtent& other) const;
106 int Contains(int i, int j) const;
108
112 int Disjoint(vtkPixelExtent other) const;
113
117 template <typename T>
118 void Size(T nCells[2]) const;
119
123 size_t Size() const;
124
128 void operator&=(const vtkPixelExtent& other);
129
133 void operator|=(const vtkPixelExtent& other);
134
136
139 void Grow(int n);
140 void Grow(int q, int n);
141 void GrowLow(int q, int n);
142 void GrowHigh(int q, int n);
144
146
149 void Shrink(int n);
150 void Shrink(int q, int n);
152
156 void Shift();
157
161 void Shift(const vtkPixelExtent& ext);
162
166 void Shift(int* n);
167
171 void Shift(int q, int n);
172
179 vtkPixelExtent Split(int dir);
180
182
185 void CellToNode();
186 void NodeToCell();
188
192 template <typename T>
193 static void Size(const vtkPixelExtent& ext, T nCells[2]);
194
198 static size_t Size(const vtkPixelExtent& ext);
199
205 static vtkPixelExtent Grow(const vtkPixelExtent& inputExt, int n);
206
208 const vtkPixelExtent& inputExt, const vtkPixelExtent& problemDomain, int n);
209
210 static vtkPixelExtent GrowLow(const vtkPixelExtent& ext, int q, int n);
211
212 static vtkPixelExtent GrowHigh(const vtkPixelExtent& ext, int q, int n);
213
219 const vtkPixelExtent& inputExt, const vtkPixelExtent& problemDomain, int n);
220
221 static vtkPixelExtent Shrink(const vtkPixelExtent& inputExt, int n);
222
227 static vtkPixelExtent NodeToCell(const vtkPixelExtent& inputExt);
228
233 static vtkPixelExtent CellToNode(const vtkPixelExtent& inputExt);
234
236
239 static void Shift(int* ij, int n);
240 static void Shift(int* ij, int* n);
242
248 static void Split(int i, int j, const vtkPixelExtent& ext, std::deque<vtkPixelExtent>& newExts);
249
256 static void Subtract(
257 const vtkPixelExtent& A, const vtkPixelExtent& B, std::deque<vtkPixelExtent>& C);
258
264 static void Merge(std::deque<vtkPixelExtent>& exts);
265
266private:
267 int Data[4];
268};
269
273VTKCOMMONDATAMODEL_EXPORT
274std::ostream& operator<<(std::ostream& os, const vtkPixelExtent& ext);
275
276//-----------------------------------------------------------------------------
277template <typename T>
278void vtkPixelExtent::SetData(const T* ext)
279{
280 Data[0] = static_cast<int>(ext[0]);
281 Data[1] = static_cast<int>(ext[1]);
282 Data[2] = static_cast<int>(ext[2]);
283 Data[3] = static_cast<int>(ext[3]);
284}
285
286//-----------------------------------------------------------------------------
287template <typename T>
288void vtkPixelExtent::SetData(T ilo, T ihi, T jlo, T jhi)
289{
290 T ext[4] = { ilo, ihi, jlo, jhi };
291 this->SetData(ext);
292}
293
294//-----------------------------------------------------------------------------
296{
297 this->SetData(other.GetData());
298}
299
300//-----------------------------------------------------------------------------
301template <typename T>
302void vtkPixelExtent::GetData(T data[4]) const
303{
304 data[0] = static_cast<T>(this->Data[0]);
305 data[1] = static_cast<T>(this->Data[1]);
306 data[2] = static_cast<T>(this->Data[2]);
307 data[3] = static_cast<T>(this->Data[3]);
308}
309
310//-----------------------------------------------------------------------------
312{
313 this->SetData<int>(INT_MAX, INT_MIN, INT_MAX, INT_MIN);
314}
315
316//-----------------------------------------------------------------------------
318{
319 this->Clear();
320}
321
322//-----------------------------------------------------------------------------
323template <typename T>
325{
326 this->SetData(ext);
327}
328
329//-----------------------------------------------------------------------------
330template <typename T>
331vtkPixelExtent::vtkPixelExtent(T ilo, T ihi, T jlo, T jhi)
332{
333 this->SetData(ilo, ihi, jlo, jhi);
334}
335
336//-----------------------------------------------------------------------------
338{
339 if (&other != this)
340 {
341 this->Data[0] = other.Data[0];
342 this->Data[1] = other.Data[1];
343 this->Data[2] = other.Data[2];
344 this->Data[3] = other.Data[3];
345 }
346 return *this;
347}
348
349//-----------------------------------------------------------------------------
351{
352 *this = other;
353}
354
355//-----------------------------------------------------------------------------
356template <typename T>
357void vtkPixelExtent::Size(const vtkPixelExtent& ext, T nCells[2])
358{
359 nCells[0] = ext[1] - ext[0] + 1;
360 nCells[1] = ext[3] - ext[2] + 1;
361}
362
363//-----------------------------------------------------------------------------
364inline size_t vtkPixelExtent::Size(const vtkPixelExtent& ext)
365{
366 return (ext[1] - ext[0] + 1) * (ext[3] - ext[2] + 1);
367}
368
369//-----------------------------------------------------------------------------
370template <typename T>
371void vtkPixelExtent::Size(T nCells[2]) const
372{
373 vtkPixelExtent::Size(*this, nCells);
374}
375
376//-----------------------------------------------------------------------------
377inline size_t vtkPixelExtent::Size() const
378{
379 return vtkPixelExtent::Size(*this);
380}
381
382//-----------------------------------------------------------------------------
383inline void vtkPixelExtent::GetStartIndex(int first[2]) const
384{
385 first[0] = this->Data[0];
386 first[1] = this->Data[2];
387}
388
389//-----------------------------------------------------------------------------
390inline void vtkPixelExtent::GetStartIndex(int first[2], const int origin[2]) const
391{
392 first[0] = this->Data[0] - origin[0];
393 first[1] = this->Data[2] - origin[1];
394}
395
396//-----------------------------------------------------------------------------
397inline void vtkPixelExtent::GetEndIndex(int last[2]) const
398{
399 last[0] = this->Data[1];
400 last[1] = this->Data[3];
401}
402
403//-----------------------------------------------------------------------------
404inline int vtkPixelExtent::Empty() const
405{
406 if (this->Data[0] > this->Data[1] || this->Data[2] > this->Data[3])
407 {
408 return 1;
409 }
410 return 0;
411}
412
413//-----------------------------------------------------------------------------
414inline bool vtkPixelExtent::operator==(const vtkPixelExtent& other) const
415{
416 if ((this->Data[0] == other.Data[0]) && (this->Data[1] == other.Data[1]) &&
417 (this->Data[2] == other.Data[2]) && (this->Data[3] == other.Data[3]))
418 {
419 return true;
420 }
421 return false;
422}
423
424//-----------------------------------------------------------------------------
425inline int vtkPixelExtent::Contains(const vtkPixelExtent& other) const
426{
427 if ((this->Data[0] <= other.Data[0]) && (this->Data[1] >= other.Data[1]) &&
428 (this->Data[2] <= other.Data[2]) && (this->Data[3] >= other.Data[3]))
429 {
430 return 1;
431 }
432 return 0;
433}
434
435//-----------------------------------------------------------------------------
436inline int vtkPixelExtent::Contains(int i, int j) const
437{
438 if ((this->Data[0] <= i) && (this->Data[1] >= i) && (this->Data[2] <= j) && (this->Data[3] >= j))
439 {
440 return 1;
441 }
442 return 0;
443}
444
445//-----------------------------------------------------------------------------
447{
448 if (this->Empty())
449 {
450 return;
451 }
452
453 if (other.Empty())
454 {
455 this->Clear();
456 return;
457 }
458
459 this->Data[0] = (std::max)(this->Data[0], other.Data[0]);
460 this->Data[1] = (std::min)(this->Data[1], other.Data[1]);
461 this->Data[2] = (std::max)(this->Data[2], other.Data[2]);
462 this->Data[3] = (std::min)(this->Data[3], other.Data[3]);
463
464 if (this->Empty())
465 {
466 this->Clear();
467 }
468}
469
470//-----------------------------------------------------------------------------
472{
473 if (other.Empty())
474 {
475 return;
476 }
477
478 if (this->Empty())
479 {
480 this->SetData(other.GetData());
481 return;
482 }
483
484 this->Data[0] = (std::min)(this->Data[0], other.Data[0]);
485 this->Data[1] = (std::max)(this->Data[1], other.Data[1]);
486 this->Data[2] = (std::min)(this->Data[2], other.Data[2]);
487 this->Data[3] = (std::max)(this->Data[3], other.Data[3]);
488}
489
490//-----------------------------------------------------------------------------
492{
493 other &= *this;
494 return other.Empty();
495}
496
497//-----------------------------------------------------------------------------
498inline void vtkPixelExtent::Grow(int n)
499{
500 this->Data[0] -= n;
501 this->Data[1] += n;
502 this->Data[2] -= n;
503 this->Data[3] += n;
504}
505
506//-----------------------------------------------------------------------------
507inline void vtkPixelExtent::Grow(int q, int n)
508{
509 q *= 2;
510
511 this->Data[q] -= n;
512 this->Data[q + 1] += n;
513}
514
515//-----------------------------------------------------------------------------
516inline void vtkPixelExtent::GrowLow(int q, int n)
517{
518 this->Data[2 * q] -= n;
519}
520
521//-----------------------------------------------------------------------------
522inline void vtkPixelExtent::GrowHigh(int q, int n)
523{
524 this->Data[2 * q + 1] += n;
525}
526
527//-----------------------------------------------------------------------------
528inline void vtkPixelExtent::Shrink(int n)
529{
530 this->Data[0] += n;
531 this->Data[1] -= n;
532 this->Data[2] += n;
533 this->Data[3] -= n;
534}
535
536//-----------------------------------------------------------------------------
537inline void vtkPixelExtent::Shrink(int q, int n)
538{
539 q *= 2;
540 this->Data[q] += n;
541 this->Data[q + 1] -= n;
542}
543
544//-----------------------------------------------------------------------------
545inline void vtkPixelExtent::Shift(int* n)
546{
547 this->Data[0] += n[0];
548 this->Data[1] += n[0];
549 this->Data[2] += n[1];
550 this->Data[3] += n[1];
551}
552
553//-----------------------------------------------------------------------------
554inline void vtkPixelExtent::Shift(int q, int n)
555{
556 q *= 2;
557 this->Data[q] += n;
558 this->Data[q + 1] += n;
559}
560
561//-----------------------------------------------------------------------------
562inline void vtkPixelExtent::Shift(const vtkPixelExtent& other)
563{
564 for (int q = 0; q < 2; ++q)
565 {
566 int qq = q * 2;
567 int n = -other[qq];
568
569 this->Data[qq] += n;
570 this->Data[qq + 1] += n;
571 }
572}
573
574//-----------------------------------------------------------------------------
576{
577 for (int q = 0; q < 2; ++q)
578 {
579 int qq = q * 2;
580 int n = -this->Data[qq];
581
582 this->Data[qq] += n;
583 this->Data[qq + 1] += n;
584 }
585}
586
587//-----------------------------------------------------------------------------
589{
590 vtkPixelExtent half;
591
592 int q = 2 * dir;
593 int l = this->Data[q + 1] - this->Data[q] + 1;
594 int s = l / 2;
595
596 if (s)
597 {
598 s += this->Data[q];
599 half = *this;
600 half.Data[q] = s;
601 this->Data[q + 1] = s - 1;
602 }
603
604 return half;
605}
606
607//-----------------------------------------------------------------------------
609{
610 ++this->Data[1];
611 ++this->Data[3];
612}
613
614//-----------------------------------------------------------------------------
616{
617 --this->Data[1];
618 --this->Data[3];
619}
620
621//-----------------------------------------------------------------------------
622inline bool operator<(const vtkPixelExtent& l, const vtkPixelExtent& r)
623{
624 return l.Size() < r.Size();
625}
626
627VTK_ABI_NAMESPACE_END
628#endif
629// VTK-HeaderTest-Exclude: vtkPixelExtent.h
Representation of a cartesian pixel plane and common operations on it.
void CellToNode()
In-place conversion from cell based to node based extent, and vise-versa.
static vtkPixelExtent Grow(const vtkPixelExtent &inputExt, const vtkPixelExtent &problemDomain, int n)
static vtkPixelExtent GrowLow(const vtkPixelExtent &ext, int q, int n)
vtkPixelExtent & operator=(const vtkPixelExtent &other)
const int * GetData() const
vtkPixelExtent Split(int dir)
Divide the extent in half in the given direction.
bool operator==(const vtkPixelExtent &other) const
Test for equivalence.
vtkPixelExtent(T width, T height)
static vtkPixelExtent Grow(const vtkPixelExtent &inputExt, int n)
Add or remove ghost cells.
void SetData(const vtkPixelExtent &ext)
Set the extent.
static void Merge(std::deque< vtkPixelExtent > &exts)
Merge compatible extents in the list.
size_t Size() const
Get the total number.
void operator&=(const vtkPixelExtent &other)
In place intersection.
static vtkPixelExtent Shrink(const vtkPixelExtent &inputExt, const vtkPixelExtent &problemDomain, int n)
Remove ghost cells.
static vtkPixelExtent GrowHigh(const vtkPixelExtent &ext, int q, int n)
void NodeToCell()
In-place conversion from cell based to node based extent, and vise-versa.
const unsigned int * GetDataU() const
int Disjoint(vtkPixelExtent other) const
Return non-zero if the extent is disjoint from the other.
static vtkPixelExtent Shrink(const vtkPixelExtent &inputExt, int n)
int & operator[](int i)
Element access.
void GetStartIndex(int first[2]) const
Get the start/end index.
void Shrink(int n)
Shrink the extent by n.
void Shift()
Shifts by low corner of this, moving to the origin.
int * GetData()
Direct access to internal data.
static void Shift(int *ij, int n)
Shift by the given amount while respecting mode.
int Contains(const vtkPixelExtent &other) const
Return non-zero if this extent contains the other.
static vtkPixelExtent NodeToCell(const vtkPixelExtent &inputExt)
Convert from point extent to cell extent while respecting the dimensionality of the data.
unsigned int * GetDataU()
void GetEndIndex(int last[2]) const
Get the start/end index.
void Size(T nCells[2]) const
Get the number in each direction.
int Empty() const
Return true if empty.
const int & operator[](int i) const
static void Split(int i, int j, const vtkPixelExtent &ext, std::deque< vtkPixelExtent > &newExts)
Split ext at i,j, resulting extents (up to 4) are appended to newExts.
static void Subtract(const vtkPixelExtent &A, const vtkPixelExtent &B, std::deque< vtkPixelExtent > &C)
A - B = C C is a set of disjoint extents such that the intersection of B and C is empty and the inter...
static void Shift(int *ij, int *n)
Shift by the given amount while respecting mode.
void GrowLow(int q, int n)
Expand the extents by n.
void operator|=(const vtkPixelExtent &other)
In place union.
void Grow(int n)
Expand the extents by n.
static vtkPixelExtent CellToNode(const vtkPixelExtent &inputExt)
Convert from cell extent to point extent while respecting the dimensionality of the data.
void GrowHigh(int q, int n)
Expand the extents by n.
bool operator<(const vtkPixelExtent &l, const vtkPixelExtent &r)
VTKCOMMONDATAMODEL_EXPORT std::ostream & operator<<(std::ostream &os, const vtkPixelExtent &ext)
Stream insertion operator for formatted output of pixel extents.
bool VTKCOMMONCORE_EXPORT operator==(const std::string &a, const vtkStringToken &b)