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