Subversion Repositories gelsvn

Rev

Rev 595 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 595 Rev 601
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
5
 * ----------------------------------------------------------------------- */
6
 
6
 
7
/**
7
/**
8
 * @file AncestorGrid.h
8
 * @file AncestorGrid.h
9
 * @brief Abstract class for voxel grids.
9
 * @brief Abstract class for voxel grids.
10
 */
10
 */
11
 
11
 
12
#ifndef __GEOMETRY_ANCESTORGRID_H
12
#ifndef __GEOMETRY_ANCESTORGRID_H
13
#define __GEOMETRY_ANCESTORGRID_H
13
#define __GEOMETRY_ANCESTORGRID_H
14
 
14
 
15
#include "CGLA/Vec3i.h"
15
#include "../CGLA/Vec3i.h"
16
 
16
 
17
namespace Geometry 
17
namespace Geometry 
18
{
18
{
19
 
19
 
20
	/** \brief Class template is used as abstract ancestor of 
20
	/** \brief Class template is used as abstract ancestor of 
21
			voxel grids. 
21
			voxel grids. 
22
 
22
 
23
			Strictly speaking, this class is not 
23
			Strictly speaking, this class is not 
24
			abstract, since it does not have any virtual functions.
24
			abstract, since it does not have any virtual functions.
25
			However, operator[]() and store() simply call 
25
			However, operator[]() and store() simply call 
26
			functions in derived classes. To do so, you must pass
26
			functions in derived classes. To do so, you must pass
27
			the derived class as a template argument to this class
27
			the derived class as a template argument to this class
28
			when you define the derived class. This is called the
28
			when you define the derived class. This is called the
29
			Barton and Nackman trick. See Todd Veldhuizen, 
29
			Barton and Nackman trick. See Todd Veldhuizen, 
30
			"Techniques for Scientific C++" 1.3.3.
30
			"Techniques for Scientific C++" 1.3.3.
31
	*/
31
	*/
32
 	template<typename T, class ChildT>
32
 	template<typename T, class ChildT>
33
	class AncestorGrid
33
	class AncestorGrid
34
	{
34
	{
35
	public:
35
	public:
36
		typedef T DataType;
36
		typedef T DataType;
37
 
37
 
38
	private:
38
	private:
39
		/// xyz dimensions of grid.
39
		/// xyz dimensions of grid.
40
		CGLA::Vec3i dims;
40
		CGLA::Vec3i dims;
41
  
41
  
42
	public:
42
	public:
43
  
43
  
44
		/// Construct a grid of specified xyz dimensions.
44
		/// Construct a grid of specified xyz dimensions.
45
		AncestorGrid(int _x_dim, int _y_dim, int _z_dim): 
45
		AncestorGrid(int _x_dim, int _y_dim, int _z_dim): 
46
			dims(_x_dim,_y_dim,_z_dim) {}
46
			dims(_x_dim,_y_dim,_z_dim) {}
47
  
47
  
48
		/// Construct a grid of specified xyz dimensions.
48
		/// Construct a grid of specified xyz dimensions.
49
		AncestorGrid(const CGLA::Vec3i& _dims): dims(_dims) {}
49
		AncestorGrid(const CGLA::Vec3i& _dims): dims(_dims) {}
50
		
50
		
51
		/** Check if voxel is within grid bounds.
51
		/** Check if voxel is within grid bounds.
52
				This function is passed a Vec3i, p, and returns true
52
				This function is passed a Vec3i, p, and returns true
53
				if p is within the voxel grid. */
53
				if p is within the voxel grid. */
54
 		bool in_domain(const CGLA::Vec3i& p) const
54
 		bool in_domain(const CGLA::Vec3i& p) const
55
		{
55
		{
56
			for(int i=0; i<3; i++)
56
			for(int i=0; i<3; i++)
57
				if (p[i]<0 || p[i] >= dims[i])
57
				if (p[i]<0 || p[i] >= dims[i])
58
					return false;
58
					return false;
59
			return true;
59
			return true;
60
		}
60
		}
61
  
61
  
62
		/** Get dimensions of grid.
62
		/** Get dimensions of grid.
63
 
63
 
64
				This function returns a Vec3i with the dimensions
64
				This function returns a Vec3i with the dimensions
65
				of the grid. */
65
				of the grid. */
66
 		const CGLA::Vec3i& get_dims() const {return dims;}
66
 		const CGLA::Vec3i& get_dims() const {return dims;}
67
 
67
 
68
		/// Get the corner having smallest coordinates.
68
		/// Get the corner having smallest coordinates.
69
 		const CGLA::Vec3i get_lo_corner() const {return CGLA::Vec3i(0);}
69
 		const CGLA::Vec3i get_lo_corner() const {return CGLA::Vec3i(0);}
70
 
70
 
71
		/// Get the corner having greatest coordinates. 
71
		/// Get the corner having greatest coordinates. 
72
 		const CGLA::Vec3i& get_hi_corner() const {return dims;}
72
 		const CGLA::Vec3i& get_hi_corner() const {return dims;}
73
 
73
 
74
		/** Access (read only) a voxel in a grid. 
74
		/** Access (read only) a voxel in a grid. 
75
 
75
 
76
				This is the operator[] which is passed a Vec3i 
76
				This is the operator[] which is passed a Vec3i 
77
				and returns a const reference to a voxel.
77
				and returns a const reference to a voxel.
78
				This function is "statically virtual", i.e.
78
				This function is "statically virtual", i.e.
79
				it simply calls the store function of a derived 
79
				it simply calls the store function of a derived 
80
				class.
80
				class.
81
				See below why there is no non-const operator[] 
81
				See below why there is no non-const operator[] 
82
		*/
82
		*/
83
		const T& operator[](const CGLA::Vec3i& p) const 
83
		const T& operator[](const CGLA::Vec3i& p) const 
84
		{
84
		{
85
			return static_cast<const ChildT&>(*this)[p];
85
			return static_cast<const ChildT&>(*this)[p];
86
		}
86
		}
87
 
87
 
88
 
88
 
89
		/** Store a voxel in grid. 
89
		/** Store a voxel in grid. 
90
 
90
 
91
				This function returns nothing but is passed a 
91
				This function returns nothing but is passed a 
92
				Vec3i p and T value t and stores t at p in the 
92
				Vec3i p and T value t and stores t at p in the 
93
				grid. This function is "statically virtual", i.e.
93
				grid. This function is "statically virtual", i.e.
94
				it simply calls the store function of a derived 
94
				it simply calls the store function of a derived 
95
				class. 
95
				class. 
96
				
96
				
97
				Yes, it would be simpler to provide a non-const
97
				Yes, it would be simpler to provide a non-const
98
				operator[], however, a non-const operator[] will
98
				operator[], however, a non-const operator[] will
99
				often be called even when no writing takes place.
99
				often be called even when no writing takes place.
100
				(Scott Meyers, "More Effective C++, p. 218)
100
				(Scott Meyers, "More Effective C++, p. 218)
101
				If a grid implementation allocates memory when 
101
				If a grid implementation allocates memory when 
102
				a voxel is accessed for writing, then it is a problem
102
				a voxel is accessed for writing, then it is a problem
103
				that we cannot be sure a non-const operator[] is 
103
				that we cannot be sure a non-const operator[] is 
104
				called only if we are writing. We might then allocate
104
				called only if we are writing. We might then allocate
105
				memory even if we just want to read. 
105
				memory even if we just want to read. 
106
		*/
106
		*/
107
 		void store(const CGLA::Vec3i& p, const T& t)
107
 		void store(const CGLA::Vec3i& p, const T& t)
108
		{
108
		{
109
			return static_cast<ChildT&>(*this).store(p,t);
109
			return static_cast<ChildT&>(*this).store(p,t);
110
		}
110
		}
111
	};
111
	};
112
}
112
}
113
 
113
 
114
#endif
114
#endif
115
 
115