1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
// Copyright (c) 2017 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1/Classification/include/CGAL/Classification/Image.h $
// $Id: include/CGAL/Classification/Image.h b26b07a1242 $
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Simon Giraudot
#ifndef CGAL_CLASSIFICATION_IMAGE_H
#define CGAL_CLASSIFICATION_IMAGE_H
#include <CGAL/license/Classification.h>
#include <map>
#include <memory>
#include <CGAL/assertions.h>
#define CGAL_CLASSIFICATION_IMAGE_SIZE_LIMIT 100000000
namespace CGAL {
namespace Classification {
/// \cond SKIP_IN_MANUAL
template <typename Type>
class Image
{
using Vector = std::vector<Type>;
using Map = std::map<std::size_t, Type>;
std::size_t m_width;
std::size_t m_height;
std::size_t m_depth;
std::shared_ptr<Vector> m_raw;
std::shared_ptr<Map> m_sparse;
Type m_default;
public:
// Forbid using copy constructor
// Make it public for a strange VC++ std17 boost-1_82 error
// https://github.com/boostorg/core/issues/148
Image(const Image&)
{
CGAL_assertion(false);
}
Image () : m_width(0), m_height(0), m_depth(0)
{
}
Image (std::size_t width, std::size_t height, std::size_t depth = 1)
: m_width (width)
, m_height (height)
, m_depth (depth)
{
if (m_width * m_height * m_depth > 0)
{
if (m_width * m_height * m_depth < CGAL_CLASSIFICATION_IMAGE_SIZE_LIMIT)
m_raw = std::make_shared<Vector> (m_width * m_height * m_depth);
else
m_sparse = std::make_shared<Map> ();
}
}
~Image ()
{
}
void free BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
m_raw.reset();
m_sparse.reset();
}
Image& operator= (const Image& other)
{
m_raw = other.m_raw;
m_sparse = other.m_sparse;
m_width = other.width();
m_height = other.height();
m_depth = other.depth();
return *this;
}
std::size_t width() const { return m_width; }
std::size_t height() const { return m_height; }
std::size_t depth() const { return m_depth; }
inline std::size_t coord (const std::size_t& x, const std::size_t& y, const std::size_t& z) const
{
return z + (m_depth * y) + (m_depth * m_height * x);
}
Type& operator() (const std::size_t& x, const std::size_t& y, const std::size_t& z = 0)
{
if (!m_raw) // sparse case
{
typename Map::iterator inserted = m_sparse->insert
(std::make_pair (coord(x,y,z), Type())).first;
return inserted->second;
}
return (*m_raw)[coord(x,y,z)];
}
const Type& operator() (const std::size_t& x, const std::size_t& y, const std::size_t& z = 0) const
{
if (!m_raw) // sparse case
{
typename Map::iterator found = m_sparse->find (coord(x,y,z));
if (found != m_sparse->end())
return found->second;
return m_default;
}
return (*m_raw)[coord(x,y,z)];
}
};
/// \endcond
} // namespace Classification
} // namespace CGAL
#endif // CGAL_CLASSIFICATION_IMAGE_H
|