OpenVolumeMeshProperty.hh 9.21 KB
Newer Older
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
/*===========================================================================*\
 *                                                                           *
 *                            OpenVolumeMesh                                 *
 *        Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen         *
 *                        www.openvolumemesh.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenVolumeMesh.                                     *
 *                                                                           *
 *  OpenVolumeMesh is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenVolumeMesh is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenVolumeMesh.  If not,                              *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

35
#pragma once
36 37 38 39

//== INCLUDES =================================================================

#include <cassert>
40 41 42 43 44
#include <istream>
#include <ostream>
#include <numeric>
#include <string>
#include <vector>
45 46 47

#include "OpenVolumeMeshBaseProperty.hh"

48 49
#include "Serializers.hh"

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
namespace OpenVolumeMesh {

//== CLASS DEFINITION =========================================================

/** \class OpenVolumeMeshPropertyT
 *
 *  \brief Default property class for any type T.
 *
 *  The default property class for any type T.
 */

template<class T>
class OpenVolumeMeshPropertyT: public OpenVolumeMeshBaseProperty {
public:

65
    template <class PropT, class Entity> friend class PropertyPtr;
66

67 68 69 70 71
    typedef T                                         Value;
    typedef typename std::vector<T>                   vector_type;
    typedef T                                         value_type;
    typedef typename vector_type::reference           reference;
    typedef typename vector_type::const_reference     const_reference;
72 73 74

public:

75
	explicit OpenVolumeMeshPropertyT(
76 77
            const std::string& _name,
            const std::string& _internal_type_name,
78 79 80 81
            const T &_def = T())
        : OpenVolumeMeshBaseProperty(_name, _internal_type_name),
          def_(_def)
    {}
82

83 84

	OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default;
85 86 87

public:
	// inherited from OpenVolumeMeshBaseProperty
88
	void reserve(size_t _n) override{
89 90
		data_.reserve(_n);
	}
91
	void resize(size_t _n) override {
92
                data_.resize(_n, def_);
93
	}
94
	size_t size() const override {
95 96
		return data_.size();
	}
97
	void clear() override {
98 99 100
		data_.clear();
		vector_type().swap(data_);
	}
101
	void push_back() override {
102
		data_.push_back(def_);
103
	}
104
	void swap(size_t _i0, size_t _i1) override {
105 106 107
        std::swap(data_[_i0], data_[_i1]);
    }

108 109 110
	virtual void copy(size_t _src_idx, size_t _dst_idx) {
		data_[_dst_idx] = data_[_src_idx];
	}
111
	void delete_element(size_t _idx) override {
Martin Heistermann's avatar
Martin Heistermann committed
112
		data_.erase(data_.begin() + static_cast<long>(_idx));
113
	}
114 115 116

public:

117
	size_t n_elements() const override {
118 119
		return data_.size();
	}
120
	size_t element_size() const override {
121 122 123
        return sizeof(T);
    }

124 125 126 127 128 129 130 131 132

#ifndef DOXY_IGNORE_THIS
	struct plus {
		size_t operator ()(size_t _b, const T& /*_v*/) {
			return _b + sizeof(T);
		}
	};
#endif

133
    size_t size_of() const override {
134 135 136 137
        if (element_size() != OpenVolumeMeshBaseProperty::UnknownSize)
            return this->OpenVolumeMeshBaseProperty::size_of(n_elements());
        return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
    }
138

139
	size_t size_of(size_t _n_elem) const override {
140 141 142 143
		return this->OpenVolumeMeshBaseProperty::size_of(_n_elem);
	}

	// Function to serialize a property
144
    void serialize(std::ostream& _ostr) const override {
145 146
        for(typename vector_type::const_iterator it = data_.begin();
                it != data_.end(); ++it) {
147
            OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
148 149 150
        }
    }

Mike Kremer's avatar
Mike Kremer committed
151
    // Function to deserialize a property
152
    void deserialize(std::istream& _istr) override {
Mike Kremer's avatar
Mike Kremer committed
153
        for(unsigned int i = 0; i < n_elements(); ++i) {
154
            OpenVolumeMesh::deserialize(_istr, data_[i]);
Mike Kremer's avatar
Mike Kremer committed
155 156 157
        }
    }

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
public:
	// data access interface

	/// Get pointer to array (does not work for T==bool)
	const T* data() const {

		if (data_.empty())
			return 0;

		return &data_[0];
	}

	/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash)
	vector_type& data_vector() {

		return data_;
	}

	/// Access the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
177 178
  reference operator[](size_t _idx) {
    assert(_idx < data_.size());
179 180 181 182
		return data_[_idx];
	}

	/// Const access to the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
183 184
  const_reference operator[](size_t _idx) const {
    assert(_idx < data_.size());
185 186 187 188
		return data_[_idx];
	}

	/// Make a copy of self.
189
	OpenVolumeMeshPropertyT<T>* clone() const override {
190
		OpenVolumeMeshPropertyT<T>* p = new OpenVolumeMeshPropertyT<T>(*this);
191 192 193
		return p;
	}

194 195 196 197 198 199 200 201
	typename vector_type::const_iterator begin() const { return data_.begin(); }

	typename vector_type::iterator begin() { return data_.begin(); }

	typename vector_type::const_iterator end() const { return data_.end(); }

    typename vector_type::iterator end() { return data_.end(); }

202 203 204
protected:

    /// Delete multiple entries in list
205
    void delete_multiple_entries(const std::vector<bool>& _tags) override {
206 207 208 209 210 211 212 213 214 215 216 217 218 219

        assert(_tags.size() == data_.size());
        vector_type new_data;
        typename vector_type::iterator d_it = data_.begin();
        std::vector<bool>::const_iterator t_it = _tags.begin();
        std::vector<bool>::const_iterator t_end = _tags.end();
        for(; t_it != t_end; ++t_it, ++d_it) {
            if(!*t_it) {
                new_data.push_back(*d_it);
            }
        }
        data_.swap(new_data);
    }

220 221 222
private:

	vector_type data_;
223 224

	const T def_;
225 226 227
};


228 229 230
//-----------------------------------------------------------------------------
// Property specialization for bool type.
//-----------------------------------------------------------------------------
231 232

template<>
233 234
inline void OpenVolumeMeshPropertyT<bool>::swap(size_t _i0, size_t _i1)
{
235 236 237 238 239 240
    // std::vector<bool>::swap(reference x, reference y) exists, but
    // on libstdc++ with _GLIBCXX_DEBUG it doesn't compile
    // (2018-02-26, libstdc++ 8.2.0)

    auto tmp = data_[_i0];
    data_[_i0] = data_[_i1];
241
    data_[_i1] = tmp;
242
}
243

244 245 246 247 248
template<>
inline size_t OpenVolumeMeshPropertyT<bool>::size_of(size_t _n_elem) const
{
    return _n_elem / 8 + ((_n_elem % 8) != 0);
}
249

250 251 252 253 254
template<>
inline size_t OpenVolumeMeshPropertyT<bool>::size_of() const
{
    return size_of(n_elements());
}
255

256 257 258 259 260
template<>
inline size_t OpenVolumeMeshPropertyT<bool>::element_size() const
{
    return OpenVolumeMeshBaseProperty::UnknownSize;
}
261

262 263 264 265 266 267 268
template<>
inline void OpenVolumeMeshPropertyT<bool>::deserialize(std::istream& _istr)
{
    for(unsigned int i = 0; i < n_elements(); ++i) {
        value_type val;
        OpenVolumeMesh::deserialize(_istr, val);
        data_[i] = val;
269
    }
270
}
271

272 273

//-----------------------------------------------------------------------------
274 275
// Property specialization for std::string type.
//-----------------------------------------------------------------------------
276
template<>
277 278 279 280
inline size_t OpenVolumeMeshPropertyT<std::string>::size_of(size_t) const
{
    return OpenVolumeMeshBaseProperty::UnknownSize;
}
281

282 283 284 285 286
template<>
inline size_t OpenVolumeMeshPropertyT<std::string>::size_of() const
{
    return sizeof(data_);
}
287

288 289 290 291 292
template<>
inline size_t OpenVolumeMeshPropertyT<std::string>::element_size() const
{
    return OpenVolumeMeshBaseProperty::UnknownSize;
}
293 294


295
//-----------------------------------------------------------------------------
296 297 298

} // Namespace OpenVolumeMesh