usdrt/gf/rect.h
File members: usdrt/gf/rect.h
// Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include <carb/Defines.h>
#include <usdrt/gf/vec.h>
#include <float.h>
namespace usdrt
{
struct GfRect2i
{
public:
// In order to make GfRect2i a POD type we need to give up on non-default constructor
// pxr::GfRect2i initializes to empty, so we're not 100% compatible here!
GfRect2i() = default;
constexpr GfRect2i(const GfRect2i&) = default;
using MinMaxType = GfVec2i;
static const size_t dimension = MinMaxType::dimension;
using ScalarType = MinMaxType::ScalarType;
constexpr GfRect2i(const GfVec2i& min, const GfVec2i& max) : _min(min), _max(max)
{
}
GfRect2i(const GfVec2i& min, int width, int height) : _min(min), _max(min + GfVec2i(width - 1, height - 1))
{
}
bool IsNull() const
{
return GetWidth() == 0 && GetHeight() == 0;
}
bool IsEmpty() const
{
return GetWidth() <= 0 || GetHeight() <= 0;
}
bool IsValid() const
{
return !IsEmpty();
}
GfRect2i GetNormalized() const
{
GfVec2i min, max;
if (_max[0] < _min[0])
{
min[0] = _max[0];
max[0] = _min[0];
}
else
{
min[0] = _min[0];
max[0] = _max[0];
}
if (_max[1] < _min[1])
{
min[1] = _max[1];
max[1] = _min[1];
}
else
{
min[1] = _min[1];
max[1] = _max[1];
}
return GfRect2i(min, max);
}
const GfVec2i& GetMin() const
{
return _min;
}
const GfVec2i& GetMax() const
{
return _max;
}
int GetMinX() const
{
return _min[0];
}
void SetMinX(int x)
{
_min[0] = x;
}
int GetMaxX() const
{
return _max[0];
}
void SetMaxX(int x)
{
_max[0] = x;
}
int GetMinY() const
{
return _min[1];
}
void SetMinY(int y)
{
_min[1] = y;
}
int GetMaxY() const
{
return _max[1];
}
void SetMaxY(int y)
{
_max[1] = y;
}
void SetMin(const GfVec2i& min)
{
_min = min;
}
void SetMax(const GfVec2i& max)
{
_max = max;
}
GfVec2i GetCenter() const
{
return (_min + _max) / 2;
}
void Translate(const GfVec2i& displacement)
{
_min += displacement;
_max += displacement;
}
unsigned long GetArea() const
{
return (unsigned long)GetWidth() * (unsigned long)GetHeight();
}
GfVec2i GetSize() const
{
return GfVec2i(GetWidth(), GetHeight());
}
int GetWidth() const
{
return (_max[0] - _min[0]) + 1;
}
int GetHeight() const
{
return (_max[1] - _min[1]) + 1;
}
GfRect2i GetIntersection(const GfRect2i& that) const
{
if (IsEmpty())
return *this;
else if (that.IsEmpty())
return that;
else
return GfRect2i(GfVec2i(GfMax(_min[0], that._min[0]), GfMax(_min[1], that._min[1])),
GfVec2i(GfMin(_max[0], that._max[0]), GfMin(_max[1], that._max[1])));
}
GfRect2i Intersect(const GfRect2i& that) const
{
return GetIntersection(that);
}
GfRect2i GetUnion(const GfRect2i& that) const
{
if (IsEmpty())
return that;
else if (that.IsEmpty())
return *this;
else
return GfRect2i(GfVec2i(GfMin(_min[0], that._min[0]), GfMin(_min[1], that._min[1])),
GfVec2i(GfMax(_max[0], that._max[0]), GfMax(_max[1], that._max[1])));
}
GfRect2i Union(const GfRect2i& that) const
{
return GetUnion(that);
}
bool Contains(const GfVec2i& p) const
{
return ((p[0] >= _min[0]) && (p[0] <= _max[0]) && (p[1] >= _min[1]) && (p[1] <= _max[1]));
}
friend bool operator==(const GfRect2i& r1, const GfRect2i& r2)
{
return r1._min == r2._min && r1._max == r2._max;
}
friend bool operator!=(const GfRect2i& r1, const GfRect2i& r2)
{
return !(r1 == r2);
}
GfRect2i operator+=(const GfRect2i& that)
{
*this = GetUnion(that);
return *this;
}
friend GfRect2i operator+(const GfRect2i r1, const GfRect2i& r2)
{
GfRect2i tmp(r1);
tmp += r2;
return tmp;
}
private:
GfVec2i _min = { 0, 0 };
GfVec2i _max = { -1, -1 };
};
}