OpenVolumeMeshProperty.hh 15.6 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 35 36 37 38 39 40 41 42 43 44 45 46 47 48
/*===========================================================================*\
 *                                                                           *
 *                            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/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Date$                    *
 *   $LastChangedBy$                                                *
 *                                                                           *
\*===========================================================================*/

#ifndef OPENVOLUMEMESHPROPERTY_HH
#define OPENVOLUMEMESHPROPERTY_HH

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

#include <cassert>
49 50 51 52 53
#include <istream>
#include <ostream>
#include <numeric>
#include <string>
#include <vector>
54 55 56

#include "OpenVolumeMeshBaseProperty.hh"

57 58
#include "Serializers.hh"

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
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:

74 75
    template <class PropT, class HandleT> friend class PropertyPtr;

76 77 78 79 80 81 82 83 84
	typedef T 										Value;
	typedef std::vector<T> 				            vector_type;
	typedef T 										value_type;
	typedef typename vector_type::reference 		reference;
	typedef typename vector_type::const_reference 	const_reference;

public:

	/// Default constructor
85 86 87
	OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const T _def = T()) :
		OpenVolumeMeshBaseProperty(_name),
		def_(_def) {
88 89 90 91
	}

	/// Copy constructor
	OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) :
92 93 94
		OpenVolumeMeshBaseProperty(_rhs),
		data_(_rhs.data_),
		def_(_rhs.def_) {
95 96 97 98 99 100 101 102
	}

public:
	// inherited from OpenVolumeMeshBaseProperty
	virtual void reserve(size_t _n) {
		data_.reserve(_n);
	}
	virtual void resize(size_t _n) {
103
                data_.resize(_n, def_);
104 105 106 107 108 109
	}
	virtual void clear() {
		data_.clear();
		vector_type().swap(data_);
	}
	virtual void push_back() {
110
		data_.push_back(def_);
111 112 113 114
	}
	virtual void swap(size_t _i0, size_t _i1) {
		std::swap(data_[_i0], data_[_i1]);
	}
115 116 117 118 119 120
	virtual void copy(size_t _src_idx, size_t _dst_idx) {
		data_[_dst_idx] = data_[_src_idx];
	}
	void delete_element(size_t _idx) {
		data_.erase(data_.begin() + _idx);
	}
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

public:

	virtual size_t n_elements() const {
		return data_.size();
	}
	virtual size_t element_size() const {
		return sizeof(T);
	}

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

	virtual size_t size_of() const {
		if (element_size() != OpenVolumeMeshBaseProperty::UnknownSize)
			return this->OpenVolumeMeshBaseProperty::size_of(n_elements());
Max Lyon's avatar
Max Lyon committed
142
    return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
143 144 145 146 147 148 149
	}

	virtual size_t size_of(size_t _n_elem) const {
		return this->OpenVolumeMeshBaseProperty::size_of(_n_elem);
	}

	// Function to serialize a property
150
    virtual void serialize(std::ostream& _ostr) const {
151 152
        for(typename vector_type::const_iterator it = data_.begin();
                it != data_.end(); ++it) {
153
            OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
154 155 156
        }
    }

Mike Kremer's avatar
Mike Kremer committed
157
    // Function to deserialize a property
158
    virtual void deserialize(std::istream& _istr) {
Mike Kremer's avatar
Mike Kremer committed
159
        for(unsigned int i = 0; i < n_elements(); ++i) {
160
            OpenVolumeMesh::deserialize(_istr, data_[i]);
Mike Kremer's avatar
Mike Kremer committed
161 162 163
        }
    }

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
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
183 184
  reference operator[](size_t _idx) {
    assert(_idx < data_.size());
185 186 187 188
		return data_[_idx];
	}

	/// Const access to the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
189 190
  const_reference operator[](size_t _idx) const {
    assert(_idx < data_.size());
191 192 193 194 195
		return data_[_idx];
	}

	/// Make a copy of self.
	OpenVolumeMeshPropertyT<T>* clone() const {
196
		OpenVolumeMeshPropertyT<T>* p = new OpenVolumeMeshPropertyT<T>(*this);
197 198 199
		return p;
	}

200 201 202 203 204 205 206 207
	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(); }

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
protected:

    /// Delete multiple entries in list
    virtual void delete_multiple_entries(const std::vector<bool>& _tags) {

        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);
    }

226 227 228
private:

	vector_type data_;
229 230

	const T def_;
231 232 233 234 235
};

//-----------------------------------------------------------------------------


Mike Kremer's avatar
Mike Kremer committed
236 237
/**
 * Property specialization for bool type.
238 239 240 241 242
 */
template<>
class OpenVolumeMeshPropertyT<bool> : public OpenVolumeMeshBaseProperty {
public:

243 244
    template <class PropT, class HandleT> friend class PropertyPtr;

245 246 247 248
    typedef std::vector<bool> 				vector_type;
    typedef bool 							value_type;
    typedef vector_type::reference 			reference;
    typedef vector_type::const_reference 	const_reference;
249 250 251

public:

252 253 254 255
    OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const bool _def = bool()) :
        OpenVolumeMeshBaseProperty(_name),
        def_(_def) {
    }
256 257

public:
258
    // inherited from OpenVolumeMeshBaseProperty
259

260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    virtual void reserve(size_t _n) {
        data_.reserve(_n);
    }
    virtual void resize(size_t _n) {
        data_.resize(_n, def_);
    }
    virtual void clear() {
        data_.clear();
        vector_type().swap(data_);
    }
    virtual void push_back() {
        data_.push_back(def_);
    }
    virtual void swap(size_t _i0, size_t _i1) {
        bool t(data_[_i0]);
        data_[_i0] = data_[_i1];
        data_[_i1] = t;
    }
278 279 280
    virtual void copy(size_t _src_idx, size_t _dst_idx) {
        data_[_dst_idx] = data_[_src_idx];
    }
281

282
    void delete_element(size_t _idx) {
283 284 285 286 287
        data_.erase(data_.begin() + _idx);
    }

public:

288 289 290 291 292 293 294 295 296 297 298 299
    virtual size_t n_elements() const {
        return data_.size();
    }
    virtual size_t element_size() const {
        return OpenVolumeMeshBaseProperty::UnknownSize;
    }
    virtual size_t size_of() const {
        return size_of(n_elements());
    }
    virtual size_t size_of(size_t _n_elem) const {
        return _n_elem / 8 + ((_n_elem % 8) != 0);
    }
300

301 302 303 304 305
    // Function to serialize a property
    virtual void serialize(std::ostream& _ostr) const {
        for(vector_type::const_iterator it = data_.begin();
                it != data_.end(); ++it) {
            OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
306
        }
307
    }
308

309 310 311 312 313 314
    // Function to deserialize a property
    virtual void deserialize(std::istream& _istr) {
        for(unsigned int i = 0; i < n_elements(); ++i) {
            value_type val;
            OpenVolumeMesh::deserialize(_istr, val);
            data_[i] = val;
315
        }
316
    }
317

318 319
public:

320
    /// Access the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
321 322
    reference operator[](size_t _idx) {
        assert(_idx < data_.size());
323 324
        return data_[_idx];
    }
325

326
    /// Const access to the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
327 328
    const_reference operator[](size_t _idx) const {
        assert(_idx < data_.size());
329 330
        return data_[_idx];
    }
331

332 333 334 335 336 337
    /// Make a copy of self.
    OpenVolumeMeshPropertyT<bool>* clone() const {
        OpenVolumeMeshPropertyT<bool>* p = new OpenVolumeMeshPropertyT<bool> (
                *this);
        return p;
    }
338

339
    vector_type::const_iterator begin() const { return data_.begin(); }
340 341 342 343 344 345 346

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

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

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

347 348 349 350 351 352 353
protected:

    /// Delete multiple entries in list
    virtual void delete_multiple_entries(const std::vector<bool>& _tags) {

        assert(_tags.size() == data_.size());
        vector_type new_data;
Mike Kremer's avatar
Mike Kremer committed
354
        vector_type::iterator d_it = data_.begin();
355 356 357 358 359 360 361 362 363 364
        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);
    }

365 366
private:

367
    vector_type data_;
368

369
    const bool def_;
370 371 372 373 374
};

//-----------------------------------------------------------------------------


Mike Kremer's avatar
Mike Kremer committed
375 376
/**
 * Property specialization for std::string type.
377 378 379 380 381
 */
template<>
class OpenVolumeMeshPropertyT<std::string> : public OpenVolumeMeshBaseProperty {
public:

382 383
    template <class PropT, class HandleT> friend class PropertyPtr;

384 385 386 387 388
    typedef std::string 					Value;
    typedef std::vector<std::string> 		vector_type;
    typedef std::string 					value_type;
    typedef vector_type::reference 			reference;
    typedef vector_type::const_reference 	const_reference;
389 390 391

public:

392 393 394 395
    OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const std::string& _def = "") :
        OpenVolumeMeshBaseProperty(_name),
        def_(_def) {
    }
396 397

public:
398
    // inherited from OpenVolumeMeshBaseProperty
399

400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
    virtual void reserve(size_t _n) {
        data_.reserve(_n);
    }
    virtual void resize(size_t _n) {
        data_.resize(_n, def_);
    }
    virtual void clear() {
        data_.clear();
        vector_type().swap(data_);
    }
    virtual void push_back() {
        data_.push_back(def_);
    }
    virtual void swap(size_t _i0, size_t _i1) {
        std::swap(data_[_i0], data_[_i1]);
    }
416 417 418
    virtual void copy(size_t _src_idx, size_t _dst_idx) {
        data_[_dst_idx] = data_[_src_idx];
    }
419
    virtual void delete_element(size_t _idx) {
420 421 422 423 424
        data_.erase(data_.begin() + _idx);
    }

public:

425 426 427 428 429 430 431 432 433
    virtual size_t n_elements() const {
        return data_.size();
    }
    virtual size_t element_size() const {
        return OpenVolumeMeshBaseProperty::UnknownSize;
    }
    virtual size_t size_of() const {
        return sizeof(data_);
    }
434

435 436 437
    virtual size_t size_of(size_t /* _n_elem */) const {
        return OpenVolumeMeshBaseProperty::UnknownSize;
    }
438

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
    virtual void stats(std::ostream& _ostr) const {
        for(vector_type::const_iterator it = data_.begin();
            it != data_.end(); ++it) {
                _ostr << *it << " ";
        }
    }

    // Function to serialize a property
    virtual void serialize(std::ostream& _ostr) const {
        for(vector_type::const_iterator it = data_.begin();
                it != data_.end(); ++it) {
            OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
        }
    }

    // Function to deserialize a property
    virtual void deserialize(std::istream& _istr) {
        for(unsigned int i = 0; i < n_elements(); ++i) {
            OpenVolumeMesh::deserialize(_istr, data_[i]);
        }
    }
460 461 462

public:

463 464 465
    const value_type* data() const {
        if (data_.empty())
            return 0;
466

467 468
        return (value_type*) &data_[0];
    }
469

470
    /// Access the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
471 472
    reference operator[](size_t _idx) {
        assert(_idx < data_.size());
473 474
        return ((value_type*) &data_[0])[_idx];
    }
475

476
    /// Const access the i'th element. No range check is performed!
Max Lyon's avatar
Max Lyon committed
477 478
    const_reference operator[](size_t _idx) const {
        assert(_idx < data_.size());
479 480
        return ((value_type*) &data_[0])[_idx];
    }
481

482 483 484 485 486
    OpenVolumeMeshPropertyT<value_type>* clone() const {
        OpenVolumeMeshPropertyT<value_type>* p = new OpenVolumeMeshPropertyT<
                value_type> (*this);
        return p;
    }
487

488
    vector_type::const_iterator begin() const { return data_.begin(); }
489 490 491 492 493 494 495

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

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

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

496 497 498 499 500 501 502
protected:

    /// Delete multiple entries in list
    virtual void delete_multiple_entries(const std::vector<bool>& _tags) {

        assert(_tags.size() == data_.size());
        vector_type new_data;
Mike Kremer's avatar
Mike Kremer committed
503
        vector_type::iterator d_it = data_.begin();
504 505 506 507 508 509 510 511 512 513
        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);
    }

514 515
private:

516
    vector_type data_;
517

518
    const std::string def_;
519 520 521 522 523 524 525
};

} // Namespace OpenVolumeMesh

//=============================================================================
#endif // OPENVOLUMEMESHPROPERTY_HH defined
//=============================================================================