Clean up grid.

This commit is contained in:
jmsgrogan 2023-01-16 08:54:45 +00:00
parent d4bb2b2744
commit 3c6756d7a1
27 changed files with 210 additions and 227 deletions

View file

@ -10,8 +10,6 @@ list(APPEND HEADERS
CommandLineArgs.h
data_structures/RawTree.h
data_structures/List.h
data_structures/ListT.h
data_structures/ListFactory.h
data_structures/Tree.h
encoding/ByteUtils.h
encoding/StringUtils.h
@ -35,7 +33,6 @@ list(APPEND LIB_INCLUDES
CommandLineArgs.cpp
data_structures/RawTree.cpp
data_structures/Tree.cpp
data_structures/ListFactory.cpp
loggers/FileLogger.cpp
file_utilities/Directory.cpp
file_utilities/File.cpp

View file

@ -1,23 +1,69 @@
#pragma once
#include <cstddef>
#include <vector>
#include <string>
#include <stdexcept>
class List
class AbstractList
{
public:
enum class Type
{
UCHAR,
UINT8,
DOUBLE,
COLOR,
LIST,
UNKNOWN
};
~List() = default;
virtual Type getType() const = 0;
virtual ~AbstractList() = default;
virtual std::size_t getLength() const = 0;
};
template<typename T>
class List : public AbstractList
{
public:
List() = default;
void initializeTo(std::size_t size, T value)
{
mData = std::vector<T>(size, value);
}
const T* getDataPtr() const
{
return mData.data();
}
const std::vector<T>& getData() const
{
return mData;
}
T getItem(std::size_t index) const
{
if (index < mData.size())
{
return mData[index];
}
else
{
const auto msg = "Tried to access out of range index: " + std::to_string(index) + " with size " + std::to_string(mData.size());
throw std::out_of_range(msg);
}
}
void setData(const std::vector<T>& data)
{
mData = data;
}
void setItem(std::size_t index, T item)
{
if (index < mData.size())
{
mData[index] = item;
}
}
std::size_t getLength() const override
{
return mData.size();
}
private:
std::vector<T> mData;
};

View file

@ -1,26 +0,0 @@
#include "ListFactory.h"
#include "ListT.h"
#include "Color.h"
std::unique_ptr<List> ListFactory::Create(List::Type type, std::size_t size)
{
std::unique_ptr<List> list;
if (type == List::Type::DOUBLE)
{
list = std::make_unique<ListT<double>>(type, size, 0.0);
}
else if (type == List::Type::UCHAR)
{
list = std::make_unique<ListT<unsigned char> >(type, size, 0);
}
else if (type == List::Type::UINT8)
{
list = std::make_unique<ListT<uint8_t>>(type, size, 0);
}
else if (type == List::Type::COLOR)
{
list = std::make_unique<ListT<Color>>(type, size, Color());
}
return std::move(list);
}

View file

@ -1,11 +0,0 @@
#pragma once
#include "List.h"
#include <memory>
class ListFactory
{
public:
static std::unique_ptr<List> Create(List::Type type, std::size_t size = 0);
};

View file

@ -1,69 +0,0 @@
#pragma once
#include "List.h"
#include <vector>
class ListFactory;
template<typename T>
class ListT : public List
{
public:
ListT() = delete;
ListT(List::Type type, std::size_t size, T value)
: mType(type)
{
if (size > 0)
{
initialize(size, value);
}
}
virtual Type getType() const override
{
return mType;
}
const T* getDataPtr() const
{
return mData.data();
}
const std::vector<T>& getData() const
{
return mData;
}
void setData(const std::vector<T>& data)
{
mData = data;
}
void setDataItem(std::size_t index, T item)
{
if (index < mData.size())
{
mData[index] = item;
}
}
void initialize(std::size_t size, T value)
{
mData.resize(size);
for (std::size_t idx = 0; idx < size; idx++)
{
mData[idx] = value;
}
}
std::size_t getLength() const override
{
return mData.size();
}
private:
List::Type mType{ List::Type::UNKNOWN };
std::vector<T> mData;
};

View file

@ -3,7 +3,8 @@
#include "Bounds.h"
#include "Point.h"
class Grid;
template<typename T>
class SparseGrid;
class AbstractGeometricItem
{
@ -28,7 +29,7 @@ public:
virtual const Point& getLocation() const = 0;
virtual void sample(Grid* grid) const = 0;
virtual void sample(SparseGrid<bool>* grid) const = 0;
virtual Type getType() const { return Type::UNKNOWN; };
};

View file

@ -4,6 +4,7 @@ list(APPEND HEADERS
AbstractGeometricItem.h
Bounds.h
grid/AbstractGrid.h
grid/TypedGrid.h
grid/Grid.h
grid/SparseGrid.h
math/Linalg.h
@ -26,8 +27,6 @@ list(APPEND HEADERS
list(APPEND LIB_INCLUDES
Transform.cpp
grid/AbstractGrid.cpp
grid/Grid.cpp
grid/SparseGrid.cpp
math/Linalg.cpp
math/Matrix.cpp
math/Vector.cpp

View file

@ -1,11 +1,10 @@
#include "AbstractGrid.h"
#include "ListT.h"
AbstractGrid::AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType)
AbstractGrid::AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ)
: mBounds(bounds),
mNumX(numPointsX),
mNumY(numPointsY)
mNumY(numPointsY),
mNumZ(numPointsZ)
{
}
@ -30,10 +29,4 @@ double AbstractGrid::getYSpacing() const
void AbstractGrid::resetBounds(const Bounds& bounds)
{
mBounds = bounds;
initializeData(mData->getType());
}
List::Type AbstractGrid::getDataType()
{
return mData->getType();
}

View file

@ -1,54 +1,28 @@
#pragma once
#include "Bounds.h"
#include "List.h"
#include "ListT.h"
#include <vector>
#include <memory>
#include <stdexcept>
class AbstractGrid
{
public:
AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType = List::Type::DOUBLE);
AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1);
const Bounds& getBounds() const;
virtual std::size_t getDataSize() const = 0;
double getXSpacing() const;
double getYSpacing() const;
List::Type getDataType();
template<typename T>
const std::vector<T> getData() const
{
if (!dynamic_cast<ListT<T>*>(mData.get()))
{
throw std::logic_error("Invalid data type request for Grid data.");
}
return dynamic_cast<ListT<T>*>(mData.get())->getData();
}
template<typename T>
void setData(const std::vector<std::size_t> indices, const std::vector<T>& values)
{
if (auto list_t = dynamic_cast<ListT<T>*>(mData.get()))
{
list_t->setData(indices, values);
}
}
virtual void initializeData(List::Type dataType) = 0;
void resetBounds(const Bounds& bounds);
protected:
Bounds mBounds;
std::unique_ptr<List> mData;
std::size_t mNumX{ 0 };
std::size_t mNumY{ 0 };
std::size_t mNumZ{ 0 };
};

View file

@ -1,14 +0,0 @@
#include "Grid.h"
#include "ListFactory.h"
Grid::Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType)
: AbstractGrid(bounds, numPointsX, numPointsY, dataType)
{
initializeData(dataType);
}
void Grid::initializeData(List::Type dataType)
{
mData = ListFactory::Create(dataType, mNumX * mNumY);
}

View file

@ -1,12 +1,34 @@
#pragma once
#include "AbstractGrid.h"
#include "TypedGrid.h"
class Grid : public AbstractGrid
template<typename T>
class Grid : public TypedGrid<T>
{
public:
Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType = List::Type::DOUBLE);
Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1)
: TypedGrid<T>(bounds, numPointsX, numPointsY, numPointsZ)
{
this->mData->initializeTo(numPointsX * numPointsY * numPointsZ, T());
}
private:
void initializeData(List::Type dataType) override;
T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const override
{
return this->mData->getItem(getOffset(idx, jdx, kdx));
}
std::size_t getOffset(std::size_t idx, std::size_t jdx, std::size_t kdx) const
{
return idx * this->mNumZ + jdx * this->mNumX * this->mNumZ + kdx;
}
void setItem(std::size_t idx, std::size_t jdx, std::size_t kdx, const T& value) override
{
this->mData->setItem(getOffset(idx, jdx, kdx), value);
}
std::size_t getDataSize() const
{
return this->mData->getLength();
}
};

View file

@ -1,2 +1,15 @@
#pragma once
#include "TypedGrid.h"
template<typename T>
class SparseGrid : public TypedGrid
{
public:
SparseGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY)
: TypedGrid<T>(bounds, numPointsX, numPointsY)
{
}
};

View file

@ -0,0 +1,24 @@
#pragma once
#include "List.h"
#include "AbstractGrid.h"
#include <memory>
template <typename T>
class TypedGrid : public AbstractGrid
{
public:
TypedGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1)
: AbstractGrid(bounds, numPointsX, numPointsY, numPointsZ),
mData(std::make_unique<List<T> >())
{
}
virtual T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const = 0;
virtual void setItem(std::size_t idx, std::size_t jdx, std::size_t kdx, const T& value) = 0;
protected:
std::unique_ptr<List<T> > mData;
};

View file

@ -18,7 +18,7 @@ public:
Bounds getBounds() const override;
void sample(Grid* grid) const override {};
void sample(SparseGrid<bool>* grid) const override {};
private:
Point mStartPoint;

View file

@ -27,7 +27,7 @@ const Point& LineSegment::getPoint1() const
return mP1;
}
void LineSegment::sample(Grid* grid) const
void LineSegment::sample(SparseGrid<bool>* grid) const
{
}

View file

@ -15,7 +15,7 @@ public:
const Point& getPoint1() const;
void sample(Grid* grid) const override;
void sample(SparseGrid<bool>* grid) const override;
Bounds getBounds() const override;

View file

@ -27,7 +27,7 @@ void Circle::setMinorRadius(double radius)
mMinorRadius = radius;
}
void Circle::sample(Grid* grid) const
void Circle::sample(SparseGrid<bool>* grid) const
{
}

View file

@ -22,7 +22,7 @@ public:
void setMinorRadius(double radius);
void sample(Grid* grid) const override;
void sample(SparseGrid<bool>* grid) const override;
private:
double mMinorRadius{ 0.5 };

View file

@ -31,7 +31,7 @@ namespace ntk {
return { minX , maxX , minY , maxY };
}
void Rectangle::sample(Grid* grid) const
void Rectangle::sample(SparseGrid<bool>* grid) const
{
}

View file

@ -19,7 +19,7 @@ public:
Type getType() const override;
void sample(Grid* grid) const override;
void sample(SparseGrid<bool>* grid) const override;
private:
Point mBottomLeft;

View file

@ -5,10 +5,12 @@
#include "Grid.h"
RasterPainter::RasterPainter(DrawingContext* context)
: AbstractPainter(context),
mGrid(std::make_unique<Grid>(Bounds{0.0, 0.0, 100.0, 100.0}))
: AbstractPainter(context)
{
const auto width = context->getSurface()->getWidth();
const auto height = context->getSurface()->getHeight();
mGrid = std::make_unique<Grid<unsigned char> >(Bounds{ 0.0, 0.0, 100.0, 100.0 }, width, height);
}
void RasterPainter::paint()

View file

@ -5,6 +5,8 @@
#include <memory>
class DrawingContext;
template<typename T>
class Grid;
class RasterPainter : public AbstractPainter
@ -15,5 +17,5 @@ public:
void paint() override;
private:
std::unique_ptr<Grid> mGrid;
std::unique_ptr<Grid<unsigned char> > mGrid;
};

View file

@ -31,7 +31,7 @@ list(APPEND platform_LIB_INCLUDES
)
endif()
list(APPEND image_LIBS core compression)
list(APPEND image_LIBS core compression geometry)
list(APPEND image_DEFINES "")
add_library(image SHARED ${image_LIB_INCLUDES} ${platform_LIB_INCLUDES} ${image_HEADERS})

View file

@ -1,12 +1,13 @@
#include "Image.h"
#include "Color.h"
#include "Grid.h"
#ifdef _WIN32
#include "Win32WicImage.h"
#endif
Image::Image(unsigned width, unsigned height, ImageData::Type dataType)
Image::Image(unsigned width, unsigned height, DataType dataType)
: mWidth(width),
mHeight(height),
mDataType(dataType)
@ -19,38 +20,43 @@ Image::~Image()
}
std::unique_ptr<Image> Image::Create(unsigned width, unsigned height, ImageData::Type dataType)
std::unique_ptr<Image> Image::Create(unsigned width, unsigned height, DataType dataType)
{
return std::make_unique<Image>(width, height, dataType);
}
void Image::initialize()
{
if (mDataType == ImageData::Type::UCHAR || mDataType == ImageData::Type::UNKNOWN)
Bounds bounds(0.0, mWidth, 0.0, mHeight);
if (mDataType == DataType::UCHAR)
{
auto data = std::unique_ptr<ImageDataT<unsigned char> >();
data->initialize(getBytesPerRow() * mHeight, 0);
mData = std::move(data);
mData = std::make_unique<Grid<unsigned char> >(bounds, mWidth, mHeight, mNumChannels);
}
else
{
auto data = std::unique_ptr<ImageDataT<uint8_t> >();
data->initialize(getBytesPerRow() * mHeight, 0);
mData = std::move(data);
mData = std::make_unique<Grid<uint8_t> >(bounds, mWidth, mHeight, mNumChannels);
}
}
void Image::setPixelValue(unsigned idx, unsigned jdx, const Color& color)
void Image::setPixelValues(const Indices& indices, const std::vector<Color>& colors)
{
if (!mData)
{
initialize();
}
const auto offset = jdx * getBytesPerRow() + idx * 3;
mData->setDataItem(offset, color.getR());
mData->setDataItem(offset + 1, color.getG());
mData->setDataItem(offset + 2, color.getB());
if (mDataType == DataType::UCHAR)
{
auto data_t = getDataT<unsigned char>();
for (std::size_t idx=0; idx< indices.size(); idx++)
{
auto id = indices[idx];
auto color = colors[idx];
data_t->setItem(id.first, id.second, 0, color.getR());
data_t->setItem(id.first, id.second, 1, color.getG());
data_t->setItem(id.first, id.second, 2, color.getB());
}
}
}
unsigned Image::getBytesPerRow() const
@ -83,14 +89,20 @@ PlatformImage* Image::getPlatformImage()
return mPlatformImage.get();
}
ImageData* Image::getData()
AbstractGrid* Image::getData() const
{
return mData.get();
}
unsigned char Image::getAsUnsignedChar(unsigned idx, unsigned jdx) const
template<typename T>
Grid<T>* Image::getDataT() const
{
return mData->getAsUnsignedChar(jdx * getBytesPerRow() + idx);
return dynamic_cast<Grid<T>*>(this->mData.get());
}
Image::DataType Image::getType() const
{
return mDataType;
}
unsigned Image::getNumChannels() const

View file

@ -1,19 +1,30 @@
#pragma once
#include "PlatformImage.h"
#include "ImageData.h"
#include <memory>
#include <vector>
class Color;
class AbstractGrid;
template<typename T>
class Grid;
class Image
{
public:
Image(unsigned width, unsigned height, ImageData::Type dataType = ImageData::Type::UCHAR);
enum class DataType
{
UCHAR
};
using Index = std::pair<std::size_t, std::size_t>;
using Indices = std::vector<Index>;
Image(unsigned width, unsigned height, DataType dataType = DataType::UCHAR);
~Image();
static std::unique_ptr<Image> Create(unsigned width, unsigned height, ImageData::Type dataType = ImageData::Type::UCHAR);
static std::unique_ptr<Image> Create(unsigned width, unsigned height, DataType dataType = DataType::UCHAR);
unsigned getBytesPerRow() const;
unsigned getWidth() const;
@ -21,11 +32,15 @@ public:
unsigned getBitDepth() const;
unsigned getNumChannels() const;
ImageData* getData();
unsigned char getAsUnsignedChar(unsigned idx, unsigned jdx) const;
AbstractGrid* getData() const;
template<typename T>
Grid<T>* getDataT() const;
DataType getType() const;
PlatformImage* getPlatformImage();
void setPixelValue(unsigned idx, unsigned jdx, const Color& color);
void setPixelValues(const Indices& indices, const std::vector<Color>& colors);
void setWidth(unsigned width);
void setHeight(unsigned height);
void setBitDepth(unsigned bitDepth);
@ -39,7 +54,7 @@ private:
unsigned mBitDepth{8};
unsigned mNumChannels{4};
ImageData::Type mDataType;
std::unique_ptr<ImageData> mData;
DataType mDataType;
std::unique_ptr<AbstractGrid> mData;
std::unique_ptr<PlatformImage> mPlatformImage;
};

View file

@ -1,5 +1,7 @@
#include "ImageBitStream.h"
#include "AbstractGrid.h"
ImageBitStream::ImageBitStream(Image* image)
: BitStream(),
mImage(image)
@ -9,7 +11,7 @@ ImageBitStream::ImageBitStream(Image* image)
bool ImageBitStream::isFinished() const
{
return mByteOffset == mImage->getData()->getLength();
return mByteOffset == mImage->getData()->getDataSize();
}
std::vector<unsigned char> ImageBitStream::peekNextNBytes(unsigned n) const
@ -25,8 +27,9 @@ std::optional<unsigned char> ImageBitStream::readNextByte()
{
return std::nullopt;
}
const auto val = mImage->getData()->getAsUnsignedChar(mByteOffset);
return val;
//const auto val = mImage->getData()->getAsUnsignedChar(mByteOffset);
//return val;
return {};
}
void ImageBitStream::writeByte(unsigned char data, bool checkOverflow )
@ -37,6 +40,6 @@ void ImageBitStream::writeByte(unsigned char data, bool checkOverflow )
{
return;
}
mImage->getData()->setDataItem(mByteOffset, data);
//mImage->getData()->setDataItem(mByteOffset, data);
}