Initial revision
[blender.git] / intern / bsp / intern / BSP_CSGMesh_CFIterator.h
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 #ifndef BSP_CSGMesh_CFIterator_h
33
34 #define BSP_CSGMesh_CFIterator_h
35
36 #include "BSP_CSGMesh.h"
37 #include "../extern/CSG_BooleanOps.h"
38 /**
39  * This class defines 2 C style iterators over a CSG mesh, one for
40  * vertices and 1 for faces. They conform to the iterator interface
41  * defined in CSG_BooleanOps.h
42  */
43
44 struct BSP_CSGMesh_VertexIt {
45         MEM_RefCountPtr<BSP_CSGMesh> mesh;
46         BSP_MVertex * pos;
47 };
48
49
50 static
51         void
52 BSP_CSGMesh_VertexIt_Destruct(
53         CSG_VertexIteratorDescriptor * iterator
54 ) {
55         delete ((BSP_CSGMesh_VertexIt *)(iterator->it));
56         iterator->it = NULL;
57         iterator->Done = NULL;
58         iterator->Fill = NULL;
59         iterator->Reset = NULL;
60         iterator->Step = NULL;
61         iterator->num_elements = 0;
62 };
63
64
65 static
66         int
67 BSP_CSGMesh_VertexIt_Done(
68         CSG_IteratorPtr it
69 ) {
70         // assume CSG_IteratorPtr is of the correct type.
71         BSP_CSGMesh_VertexIt * vertex_it = (BSP_CSGMesh_VertexIt *)it;
72
73         if (vertex_it->pos < vertex_it->mesh->VertexSet().end()) return 0;
74         return 1;
75 };
76
77 static
78         void
79 BSP_CSGMesh_VertexIt_Fill(
80         CSG_IteratorPtr it,
81         CSG_IVertex *vert
82 ) {
83         // assume CSG_IteratorPtr is of the correct type.
84         BSP_CSGMesh_VertexIt * vertex_it = (BSP_CSGMesh_VertexIt *)it;
85                         
86         vertex_it->pos->m_pos.getValue(vert->position);
87 };
88
89 static
90         void
91 BSP_CSGMesh_VertexIt_Step(
92         CSG_IteratorPtr it
93 ) {
94         // assume CSG_IteratorPtr is of the correct type.
95         BSP_CSGMesh_VertexIt * vertex_it = (BSP_CSGMesh_VertexIt *)it;
96
97         ++(vertex_it->pos);
98 };
99
100 static
101         void
102 BSP_CSGMesh_VertexIt_Reset(
103         CSG_IteratorPtr it
104 ) {
105         // assume CSG_IteratorPtr is of the correct type.
106         BSP_CSGMesh_VertexIt * vertex_it = (BSP_CSGMesh_VertexIt *)it;
107         vertex_it->pos = vertex_it->mesh->VertexSet().begin();
108 };      
109
110 static
111         void
112 BSP_CSGMeshVertexIt_Construct(
113         BSP_CSGMesh *mesh,
114         CSG_VertexIteratorDescriptor *output
115 ){
116         // user should have insured mesh is not equal to NULL.
117         
118         output->Done = BSP_CSGMesh_VertexIt_Done;
119         output->Fill = BSP_CSGMesh_VertexIt_Fill;
120         output->Step = BSP_CSGMesh_VertexIt_Step;
121         output->Reset = BSP_CSGMesh_VertexIt_Reset;
122         output->num_elements = mesh->VertexSet().size();
123         
124         BSP_CSGMesh_VertexIt * v_it = new BSP_CSGMesh_VertexIt;
125         v_it->mesh = mesh;
126         v_it->pos = mesh->VertexSet().begin();
127         output->it = v_it;
128 };                      
129
130
131 /**
132  * Face iterator.
133  */
134
135 struct BSP_CSGMesh_FaceIt {
136         MEM_RefCountPtr<BSP_CSGMesh> mesh;
137         BSP_MFace *pos;
138         int face_triangle;
139 };
140
141
142 static
143         void
144 BSP_CSGMesh_FaceIt_Destruct(
145         CSG_FaceIteratorDescriptor *iterator
146 ) {
147         delete ((BSP_CSGMesh_FaceIt *)(iterator->it));
148         iterator->it = NULL;
149         iterator->Done = NULL;
150         iterator->Fill = NULL;
151         iterator->Reset = NULL;
152         iterator->Step = NULL;
153         iterator->num_elements = 0;
154 };
155
156
157 static
158         int
159 BSP_CSGMesh_FaceIt_Done(
160         CSG_IteratorPtr it
161 ) {
162         // assume CSG_IteratorPtr is of the correct type.
163         BSP_CSGMesh_FaceIt * face_it = (BSP_CSGMesh_FaceIt *)it;
164
165         if (face_it->pos < face_it->mesh->FaceSet().end()) {
166                 if (face_it->face_triangle + 3 <= face_it->pos->m_verts.size()) {
167                         return 0;
168                 }
169         }
170         return 1;
171 };
172
173 static
174         void
175 BSP_CSGMesh_FaceIt_Fill(
176         CSG_IteratorPtr it,
177         CSG_IFace *face
178 ){
179         // assume CSG_IteratorPtr is of the correct type.
180         BSP_CSGMesh_FaceIt * face_it = (BSP_CSGMesh_FaceIt *)it;                
181         // essentially iterating through a triangle fan here.
182         const int tri_index = face_it->face_triangle;
183
184         face->vertex_index[0] = int(face_it->pos->m_verts[0]);
185         face->vertex_index[1] = int(face_it->pos->m_verts[tri_index + 1]);
186         face->vertex_index[2] = int(face_it->pos->m_verts[tri_index + 2]);
187
188         // Copy the user face data across - this does nothing
189         // if there was no mesh user data.
190
191         // time to change the iterator type to an integer...
192         face_it->mesh->FaceData().Copy(
193                 face->user_face_data,
194                 int(face_it->pos - face_it->mesh->FaceSet().begin())
195         );
196         
197         // Copy face vertex data across...
198
199         face_it->mesh->FaceVertexData().Copy(
200                 face->user_face_vertex_data[0],
201                 face_it->pos->m_fv_data[0]
202         );
203
204         face_it->mesh->FaceVertexData().Copy(
205                 face->user_face_vertex_data[1],
206                 face_it->pos->m_fv_data[tri_index + 1]
207         );
208
209         face_it->mesh->FaceVertexData().Copy(
210                 face->user_face_vertex_data[2],
211                 face_it->pos->m_fv_data[tri_index + 2]
212         );
213
214         face->vertex_number = 3;
215 };
216
217 static
218         void
219 BSP_CSGMesh_FaceIt_Step(
220         CSG_IteratorPtr it
221 ) {
222         // assume CSG_IteratorPtr is of the correct type.
223         BSP_CSGMesh_FaceIt * face_it = (BSP_CSGMesh_FaceIt *)it;                
224
225         // safety guard
226         if (face_it->pos < face_it->mesh->FaceSet().end()) {
227
228                 if (face_it->face_triangle + 3 < face_it->pos->m_verts.size()) {
229                         (face_it->face_triangle)++;
230                 } else {
231                         face_it->face_triangle = 0;
232                         (face_it->pos) ++;
233                 }
234         }
235 };
236
237 static
238         void
239 BSP_CSGMesh_FaceIt_Reset(
240         CSG_IteratorPtr it
241 ) {
242         // assume CSG_IteratorPtr is of the correct type.
243         BSP_CSGMesh_FaceIt * f_it = (BSP_CSGMesh_FaceIt *)it;           
244         f_it->pos = f_it->mesh->FaceSet().begin();
245         f_it->face_triangle = 0;
246 };
247
248 static
249         void
250 BSP_CSGMesh_FaceIt_Construct(
251         BSP_CSGMesh * mesh,
252         CSG_FaceIteratorDescriptor *output
253 ) {
254
255         output->Done = BSP_CSGMesh_FaceIt_Done;
256         output->Fill = BSP_CSGMesh_FaceIt_Fill;
257         output->Step = BSP_CSGMesh_FaceIt_Step;
258         output->Reset = BSP_CSGMesh_FaceIt_Reset;
259
260         output->num_elements = mesh->CountTriangles();
261         
262         BSP_CSGMesh_FaceIt * f_it = new BSP_CSGMesh_FaceIt;
263         f_it->mesh = mesh;
264         f_it->pos = mesh->FaceSet().begin();
265         f_it->face_triangle = 0;
266
267         output->it = f_it;
268
269 };
270
271
272 #endif