Subversion Repositories gelsvn

Rev

Rev 443 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 443 Rev 595
-
 
1
/* ----------------------------------------------------------------------- *
-
 
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
-
 
3
 * Copyright (C) the authors and DTU Informatics
-
 
4
 * For license and list of authors, see ../../doc/intro.pdf
-
 
5
 * ----------------------------------------------------------------------- */
-
 
6
 
-
 
7
/**
-
 
8
 * @file Cell.h
-
 
9
 * @brief Cell class for a voxel grid in a 2 level grid.
-
 
10
 */
-
 
11
 
1
#ifndef __GEOMETRY_CELL_H
12
#ifndef __GEOMETRY_CELL_H
2
#define __GEOMETRY_CELL_H
13
#define __GEOMETRY_CELL_H
3
 
14
 
4
#include <vector>
15
#include <vector>
5
#include "CGLA/Vec3i.h"
16
#include "CGLA/Vec3i.h"
6
#include "CGLA/BitMask.h"
17
#include "CGLA/BitMask.h"
7
#include "RGrid.h"
18
#include "RGrid.h"
8
 
19
 
9
namespace Geometry 
20
namespace Geometry 
10
{
21
{
11
	/** \brief Class template for a cell in a hierarchical grid.
22
	/** \brief Class template for a cell in a hierarchical grid.
12
 
23
 
13
			The template arguments are the type and the cell dimension.
24
			The template arguments are the type and the cell dimension.
14
			A Cell is much like an RGrid - except that a Cell may 
25
			A Cell is much like an RGrid - except that a Cell may 
15
			be coalesced into a single value and then split again
26
			be coalesced into a single value and then split again
16
			when a new value is inserted. Also cells are constrained to
27
			when a new value is inserted. Also cells are constrained to
17
			be of size NxNxN where N=2^m for some m. This makes some things
28
			be of size NxNxN where N=2^m for some m. This makes some things
18
			faster.
29
			faster.
19
 
30
 
20
			The reason for making CELL_DIM a template argument rather 
31
			The reason for making CELL_DIM a template argument rather 
21
			than a constructor argument is that we generally have many 
32
			than a constructor argument is that we generally have many 
22
			cells	and do not wish that each cell contains its dimension. 
33
			cells	and do not wish that each cell contains its dimension. 
23
	*/
34
	*/
24
	template<class T, int CELL_DIM, class ChildT>
35
	template<class T, int CELL_DIM, class ChildT>
25
	class Cell
36
	class Cell
26
	{
37
	{
27
	public:
38
	public:
28
		typedef T DataType;
39
		typedef T DataType;
29
 
40
 
30
	private:
41
	private:
31
		bool touched;
42
		bool touched;
32
 
43
 
33
		/// Linear array containing data of this Cell.
44
		/// Linear array containing data of this Cell.
34
		std::vector<T> data;
45
		std::vector<T> data;
35
		
46
		
36
		/** Return a bit mask used to mask indices. 
47
		/** Return a bit mask used to mask indices. 
37
				Some functions in this class are passed a Vec3i 
48
				Some functions in this class are passed a Vec3i 
38
				whose lower bits index into the cell. The mask is
49
				whose lower bits index into the cell. The mask is
39
				used to select these lower bits before the 3D
50
				used to select these lower bits before the 3D
40
				index is converted to	a linear index.
51
				index is converted to	a linear index.
41
				
52
				
42
				If you are wondering about why the static variable 
53
				If you are wondering about why the static variable 
43
				inside the function is not simply a static member of 
54
				inside the function is not simply a static member of 
44
				the class, check out item 47 og "Effective C++" by 
55
				the class, check out item 47 og "Effective C++" by 
45
				Scott Meyers.
56
				Scott Meyers.
46
		*/
57
		*/
47
		static const CGLA::BitMask& get_bit_mask()
58
		static const CGLA::BitMask& get_bit_mask()
48
		{
59
		{
49
			static const CGLA::BitMask bit_mask(CELL_DIM);
60
			static const CGLA::BitMask bit_mask(CELL_DIM);
50
			return bit_mask;
61
			return bit_mask;
51
		}
62
		}
52
 
63
 
53
	public:
64
	public:
54
 
65
 
55
		/** Get dimensions of Cell. Returns only one value since 
66
		/** Get dimensions of Cell. Returns only one value since 
56
				x, y, and z dimensions are the same. */
67
				x, y, and z dimensions are the same. */
57
		static int get_dim() 
68
		static int get_dim() 
58
		{
69
		{
59
			return CELL_DIM;
70
			return CELL_DIM;
60
		}
71
		}
61
 
72
 
62
	private:
73
	private:
63
		
74
		
64
		/** Get index. Computes an index into the linear array representation
75
		/** Get index. Computes an index into the linear array representation
65
				of the voxels in the cell from a 3D grid index. The top bits (which
76
				of the voxels in the cell from a 3D grid index. The top bits (which
66
				have been used to find this Cell) are masked out. */
77
				have been used to find this Cell) are masked out. */
67
 		int get_idx(const CGLA::Vec3i& idx) const
78
 		int get_idx(const CGLA::Vec3i& idx) const
68
		{
79
		{
69
			CGLA::Vec3i bot_idx = get_bit_mask().mask(idx);
80
			CGLA::Vec3i bot_idx = get_bit_mask().mask(idx);
70
 			return (bot_idx[2]*get_dim()+bot_idx[1])*get_dim()+bot_idx[0];
81
 			return (bot_idx[2]*get_dim()+bot_idx[1])*get_dim()+bot_idx[0];
71
		}
82
		}
72
 
83
 
73
	protected:
84
	protected:
74
 
85
 
75
		/** Store a value in the Cell. If the Cell is 
86
		/** Store a value in the Cell. If the Cell is 
76
				coalesced, it is first resized to contain CELL_DIMS 
87
				coalesced, it is first resized to contain CELL_DIMS 
77
				cubed voxels, and then the voxel is inserted. */
88
				cubed voxels, and then the voxel is inserted. */
78
 		void store_priv(const CGLA::Vec3i& p, const T& new_val) 
89
 		void store_priv(const CGLA::Vec3i& p, const T& new_val) 
79
		{
90
		{
80
			if(is_coalesced()) split();
91
			if(is_coalesced()) split();
81
			touched = true;
92
			touched = true;
82
			data[get_idx(p)] = new_val;
93
			data[get_idx(p)] = new_val;
83
		}
94
		}
84
 
95
 
85
		
96
		
86
	public:
97
	public:
87
	
98
	
88
		/** Create empty grid cell. A Cell contains initially a single value.
99
		/** Create empty grid cell. A Cell contains initially a single value.
89
				Reading (using operator[]) any voxel will yield this value. */
100
				Reading (using operator[]) any voxel will yield this value. */
90
		Cell(const T& val): data(1,val), touched(false)
101
		Cell(const T& val): data(1,val), touched(false)
91
		{
102
		{
92
			assert(CELL_DIM==get_dim());
103
			assert(CELL_DIM==get_dim());
93
		}
104
		}
94
 
105
 
95
		/** Clear cell. Removes Cell contents replacing it with a single
106
		/** Clear cell. Removes Cell contents replacing it with a single
96
				specified value. */
107
				specified value. */
97
 		void coalesce(const T& val) 
108
 		void coalesce(const T& val) 
98
		{
109
		{
99
			data=std::vector<T>(1,val);
110
			data=std::vector<T>(1,val);
100
			touched = true;
111
			touched = true;
101
		}
112
		}
102
 
113
 
103
		/// Split cell - causes memory to be reserved for CELL_DIM^3 voxels.
114
		/// Split cell - causes memory to be reserved for CELL_DIM^3 voxels.
104
		void split()
115
		void split()
105
		{
116
		{
106
			T val = data[0];
117
			T val = data[0];
107
			data.resize(CGLA::qbe(CELL_DIM), val);
118
			data.resize(CGLA::qbe(CELL_DIM), val);
108
			touched = true;
119
			touched = true;
109
		}
120
		}
110
 
121
 
111
		/// Check if the cell is coalesced
122
		/// Check if the cell is coalesced
112
		bool is_coalesced() const 
123
		bool is_coalesced() const 
113
		{
124
		{
114
			// We rely on size() being constant time below.
125
			// We rely on size() being constant time below.
115
			// Probably this function should be changed.... it would be bad
126
			// Probably this function should be changed.... it would be bad
116
			// if it was slow ... very bad....
127
			// if it was slow ... very bad....
117
			return data.size()==1;
128
			return data.size()==1;
118
		}
129
		}
119
 
130
 
120
		
131
		
121
		/** Read access to voxel grid. This function is passed
132
		/** Read access to voxel grid. This function is passed
122
				a Vec3i and returns the corresponding voxel. If the
133
				a Vec3i and returns the corresponding voxel. If the
123
				cell is coalesced, the single value stored is returned. */
134
				cell is coalesced, the single value stored is returned. */
124
		const T& operator[](const CGLA::Vec3i& p) const 
135
		const T& operator[](const CGLA::Vec3i& p) const 
125
		{
136
		{
126
			if(is_coalesced()) return data[0];
137
			if(is_coalesced()) return data[0];
127
			return *(&data[get_idx(p)]);
138
			return *(&data[get_idx(p)]);
128
		}
139
		}
129
 
140
 
130
 		void store(const CGLA::Vec3i& p, const T& new_val) 
141
 		void store(const CGLA::Vec3i& p, const T& new_val) 
131
		{
142
		{
132
			return static_cast<ChildT&>(*this).store(p,new_val);
143
			return static_cast<ChildT&>(*this).store(p,new_val);
133
		}
144
		}
134
		
145
		
135
	
146
	
136
		/** Const get a pointer to the first element in the linear
147
		/** Const get a pointer to the first element in the linear
137
				array representation of the grid. */
148
				array representation of the grid. */
138
 		const T* get() const {return &data[0];}
149
 		const T* get() const {return &data[0];}
139
 
150
 
140
		/** Non-const get a pointer to the first element in the linear
151
		/** Non-const get a pointer to the first element in the linear
141
				array representation of the grid. */
152
				array representation of the grid. */
142
		T* get() 
153
		T* get() 
143
		{
154
		{
144
			touched = true;
155
			touched = true;
145
			return &data[0];
156
			return &data[0];
146
		}
157
		}
147
 
158
 
148
		void untouch() {touched=false;}
159
		void untouch() {touched=false;}
149
		void touch() {touched=true;}
160
		void touch() {touched=true;}
150
		bool is_touched() const {return touched;}
161
		bool is_touched() const {return touched;}
151
 
162
 
152
	};
163
	};
153
 
164
 
154
	
165
	
155
	template<class T, int CELL_DIM>
166
	template<class T, int CELL_DIM>
156
	class DefaultCell: public Cell<T,CELL_DIM,DefaultCell<T, CELL_DIM> >
167
	class DefaultCell: public Cell<T,CELL_DIM,DefaultCell<T, CELL_DIM> >
157
	{
168
	{
158
	public:
169
	public:
159
		DefaultCell(const T& val): Cell<T,CELL_DIM,DefaultCell>(val){}
170
		DefaultCell(const T& val): Cell<T,CELL_DIM,DefaultCell>(val){}
160
 		void store(const CGLA::Vec3i& p, const T& new_val) 
171
 		void store(const CGLA::Vec3i& p, const T& new_val) 
161
		{
172
		{
162
			store_priv(p, new_val);
173
			store_priv(p, new_val);
163
		}
174
		}
164
		
175
		
165
	};
176
	};
166
 
177
 
167
 
178
 
168
}
179
}
169
#endif
180
#endif
170
 
181