Subversion Repositories gelsvn

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
39 bj 1
#ifndef __IMESH_TRIMESHBUILDER_H__
2
#define __IMESH_TRIMESHBUILDER_H__
3
 
4
#include "TriMesh.h"
5
 
6
namespace IMesh
7
{
8
 
9
	/** The TriMeshBuilder constructs a TriMesh. The reason to have this
10
			class is that indexed face sets are very "undynamic" to begin with.
11
			Typically, we store all data in vectors for efficiency, and it is
12
			difficult to add and especially remove data from these vectors.
13
			By having a builder class, we can separate concerns so that the 
14
			content adding is taken care of before the mesh is used. */
15
	class TriMeshBuilder: public TriMeshData
16
	{
17
		// A TriMeshBuilder is only constructed using the default constructor.
18
		TriMeshBuilder(const TriMeshBuilder&);
19
		bool did_call_get_trimesh;
20
	public:
21
 
22
 
23
		/** The constructor begins by registering the basic data
24
				types, i.e. the */
25
		TriMeshBuilder();
26
 
27
		~TriMeshBuilder();
28
 
29
		void clear();
30
 
31
		//----------------------------------------------------------------------
32
		// Register face sets and attributes
33
		//----------------------------------------------------------------------
34
 
35
		/** Register a new face set. If this is not the first face set, the 
36
				first face set is copied into the presently registered face set. */
37
		int register_face_set();
38
 
39
		/** Register a face attribute of type ATTR. If there is an existing 
40
				attribute of the same name, then the handle passed as second
41
				argument is made to point to this attribute and no new attribute
42
				is created. */
43
		template<class ATTR>
44
		void register_face_attribute(const std::string& attr_name,
45
																 AttrHandle<ATTR>& handle)
46
		{
47
			assert(!did_call_get_trimesh);
48
			if(!get_fattr_handle(attr_name, handle))
49
				{
50
					handle.idx = face_attr.size();
51
					face_attr.push_back(new AttrVec<ATTR>(attr_name));
52
				}
53
		}
54
 
55
		/// Utility function, register face colours.
56
		void register_face_colors();
57
 
58
		/// Utility function that registers the use of face normals.
59
		void register_face_normals();
60
 
61
		/** Register a vertex attribute of type ATTR, indexed via FACESET.
62
		If there is an existing attribute of the same name, then the
63
		handle passed as second argument is made to point to this
64
		attribute and no new attribute is created. */
65
		template<class ATTR>
66
		void register_vertex_attribute(const std::string& attr_name,
67
																	 AttrHandle<ATTR>& handle, int face_set=0)
68
		{
69
			assert(!did_call_get_trimesh);
70
			assert(face_set < face_sets.size());
71
			if(!get_vattr_handle(attr_name, handle))
72
				{
73
					handle.idx = vert_attr.size();
74
					vert_attr.push_back(new AttrVec<ATTR>(attr_name));
75
					face_set_mapping.push_back(face_set);
76
				}
77
		}
78
 
79
		// ----------------------------------------------------------------------
80
		// utility functions. These are used to register standard resources.
81
		// ----------------------------------------------------------------------
82
 
83
		/// Register vertex normals (of type Vec3f)
84
		void register_vertex_normals(int face_set = 0);
85
 
86
		/// Register vertex normals (of type Vec4f)
87
		void register_vertex_colors(int face_set = 0);
88
 
89
		/// Register vertex texture coords (of type Vec4f)
90
		void register_vertex_texcoords(int face_set = 0);
91
 
92
		/** Functions to add a face. When a face is added, the same face
93
				is added to all facesets. Afterwards, use set_face to alter a face
94
				in a given face_set. */
95
		void add_face(const CGLA::Vec3i& face);
96
 
97
		/// Add a vertex attribute
98
		template<class ATTR>
99
		int add_vattr(AttrHandle<ATTR> handle, const ATTR& val)
100
		{
101
			int n = vert_attr[handle.idx]->size();
102
			push_back_attr(*vert_attr[handle.idx],val);
103
			return n;
104
		}
105
 
106
		/// Add a face attribute
107
		template<class ATTR>
108
		int add_fattr(AttrHandle<ATTR> handle, const ATTR& val)
109
		{
110
			int n = face_attr[handle.idx]->size();
111
			push_back_attr(*face_attr[handle.idx],val);
112
			return n;
113
		}
114
 
115
		/// Add a face normal
116
		int add_fnorm(const CGLA::Vec3f& norm)
117
		{
118
			return add_fattr(FA_NORM, norm);
119
		}
120
 
121
		/// Add a face colour
122
		int add_fcol(const CGLA::Vec4f& col)
123
		{
124
			return add_fattr(FA_COL, col);
125
		}
126
 
127
		/// Add a vertex position to the mesh.
128
		int add_vpos(const CGLA::Vec3f& pos)
129
		{
130
			return add_vattr(VA_POS, pos);
131
		}
132
 
133
		/// Add a vertex normal to the mesh.
134
		int add_vnorm(const CGLA::Vec3f& norm)
135
		{
136
			return add_vattr(VA_NORM, norm);
137
		}
138
 
139
		/// Add a vertex colour to the mesh.
140
		int add_vcol(const CGLA::Vec4f& col)
141
		{
142
			return add_vattr(VA_COL, col);
143
		}
144
 
145
		/// Add a vertex texture coordinate to the mesh.
146
		int add_vtex(const CGLA::Vec4f& tex)
147
		{
148
			return add_vattr(VA_TEX, tex);
149
		}
150
 
151
		/** Build and return a resource ptr to the trimesh. After this function
152
				has been called, the destructor is the only function which it is
153
				allowed to call - unless the clear function is called.  */
154
		TriMesh* get_trimesh();
155
	};
156
 
157
	/** Register and compute face normals. if do_flip is true, the normals 
158
			point opposite the ccw direction. */
159
	void compute_face_normals(TriMeshBuilder& bldr, bool do_flip=false);
160
 
161
 
162
	/** This function computes vertex normals for a mesh. If no vertex normals
163
			have been registered, compute_vertex_normals will first register and
164
			add vertex normals. The normals are registered to the default face set
165
			meaning that there is a one to one relationship between vertices and
166
			vertex normals. If vertex_normals are already registered, it is assumed
167
			that the correct number of vertex normals have also been added.
168
 
169
			Vertex normals are then computed by adding the face normal weighted by
170
			angle to the normal corresponding to each vertex of the face. Finally,
171
			all vertex normals are normalized. */
172
	void compute_vertex_normals(TriMeshBuilder& bldr);
173
 
174
	/** This function is passed a builder and the handle of the smoothing group
175
			attribute. vertex_normals are registered to a new face set, and the 
176
			normal faces are computed using the smoothing group information. 
177
			Finally, compute_vertex_normals(bldr) is called to generated the actual
178
			normals. */
179
	void compute_vertex_normals(TriMeshBuilder& bldr, 
180
															AttrHandle<int> smooth_group_attr);
181
 
182
	/** This function is passed a builder and the cosine of a crease angle.
183
			vertex_normals are registered to a new face set, and the 
184
			normal faces are computed using the smoothing group information. 
185
			Finally, compute_vertex_normals(bldr) is called to generated the actual
186
			normals. */
187
	void compute_vertex_normals(TriMeshBuilder& bldr, float);
188
 
189
}
190
 
191
#endif