New files from new booleans
[blender.git] / intern / boolop / intern / BOP_Face.cpp
1 /**
2  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. The Blender
8  * Foundation also sells licenses for use in proprietary software under
9  * the Blender License.  See http://www.blender.org/BL/ for information
10  * about this.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30  
31 #include "BOP_Face.h"
32
33 /******************************************************************************/
34 /*** BOP_Face                                                               ***/
35 /******************************************************************************/
36
37 /**
38  * Constructs a new face.
39  * @param plane face plane
40  * @param originalFace index of the original face
41  */
42 BOP_Face::BOP_Face(MT_Plane3 plane, BOP_Index originalFace)
43 {
44         m_plane        = plane;
45         m_tag          = UNCLASSIFIED;
46         m_originalFace = originalFace;
47 }
48
49 /**
50  * Inverts this face.
51  */
52 void BOP_Face::invert()
53 {
54         getPlane().Invert();
55         BOP_Index aux = m_indexs[0];
56         m_indexs[0] = m_indexs[2];
57         m_indexs[2] = aux;
58 }
59
60 /******************************************************************************/
61 /*** BOP_Face                                                              ***/
62 /******************************************************************************/
63
64 /**
65  * Constructs a new triangle face.
66  * @param v1 vertex index
67  * @param v2 vertex index
68  * @param v3 vertex index
69  * @param plane face plane
70  * @param originalFace index of the original face
71  */
72 BOP_Face3::BOP_Face3(BOP_Index v1, BOP_Index v2, BOP_Index v3, MT_Plane3 plane, BOP_Index originalFace): BOP_Face(plane,originalFace) 
73 {
74         m_indexs[0] = v1;
75         m_indexs[1] = v2;
76         m_indexs[2] = v3;       
77         m_size = 3;
78 }
79
80 /**
81  * Returns the relative edge index (1,2,3) for the specified vertex indexs.
82  * @param v1 vertex index
83  * @param v2 vertex index
84  * @param e relative edge index (1,2,3)
85  * @return true if (v1,v2) is an edge of this face, false otherwise
86  */
87 bool BOP_Face3::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e)
88 {
89         if (m_indexs[0] == v1) {
90                 if (m_indexs[1] == v2) {
91                         e = 1;
92                 }
93                 else if (m_indexs[2] == v2) {
94                         e = 3;
95                 }
96                 else
97                   return false;
98         }
99         else if (m_indexs[1] == v1) {
100                 if (m_indexs[0] == v2) {
101                         e = 1;
102                 }
103                 else if (m_indexs[2] == v2) {
104                         e = 2;
105                 }
106                 else
107                   return false;
108         }
109         else if (m_indexs[2] == v1) {
110                 if (m_indexs[0] == v2) {
111                         e = 3;
112                 }
113                 else if (m_indexs[1] == v2) {
114                         e = 2;
115                 }
116                 else
117                   return false;
118         }else {
119           return false;
120         }
121         
122         return  true;
123
124
125 /**
126  * Returns if this face contains the specified vertex index.
127  * @param v vertex index
128  * @return true if this face contains the specified vertex index, false otherwise
129  */
130 bool BOP_Face3::containsVertex(BOP_Index v) 
131 {
132         return (m_indexs[0] == v || m_indexs[1] == v || m_indexs[2] == v);
133 }
134
135 /**
136  * Returns the neighbours of the specified vertex index.
137  * @param v vertex index
138  * @param prev previous vertex index
139  * @param next next vertex index
140  * @return true if this face contains the vertex index v, false otherwise
141  */
142 bool BOP_Face3::getNeighbours(BOP_Index v, BOP_Index &prev, BOP_Index &next) 
143 {
144         if (m_indexs[0] == v) {
145           prev = m_indexs[2];
146           next = m_indexs[1];
147         }
148         else if (m_indexs[1] == v) {
149           prev = m_indexs[0];
150           next = m_indexs[2];
151         }
152         else if (m_indexs[2] == v) {
153           prev = m_indexs[1];
154           next = m_indexs[0];
155         }
156         else return false;
157         
158         return true;
159 }
160
161 /**
162  * Returns the previous neighbour of the specified vertex index.
163  * @param v vertex index
164  * @param w previous vertex index
165  * @return true if this face contains the specified vertex index, false otherwise
166  */
167 bool BOP_Face3::getPreviousVertex(BOP_Index v, BOP_Index &w) 
168 {
169         if (m_indexs[0] == v) w = m_indexs[2];
170         else if (m_indexs[1] == v) w = m_indexs[0];
171         else if (m_indexs[2] == v) w = m_indexs[1];
172         else return false;
173         
174         return true;
175 }
176
177 /**
178  * Returns the next neighbour of the specified vertex index.
179  * @param v vertex index
180  * @param w vertex index
181  * @return true if this face contains the specified vertex index, false otherwise
182  */
183 bool BOP_Face3::getNextVertex(BOP_Index v, BOP_Index &w) 
184 {
185         if (m_indexs[0] == v) w = m_indexs[1];
186         else if (m_indexs[1] == v) w = m_indexs[2];
187         else if (m_indexs[2] == v) w = m_indexs[0];
188         else return false;
189         
190         return true;
191
192
193 /**
194  * Replaces a face vertex index.
195  * @param oldIndex old vertex index
196  * @param newIndex new vertex index
197  */
198 void BOP_Face3::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
199 {
200         if (m_indexs[0] == oldIndex) m_indexs[0] = newIndex;
201         else if (m_indexs[1] == oldIndex) m_indexs[1] = newIndex;
202         else if (m_indexs[2] == oldIndex) m_indexs[2] = newIndex;
203 }
204
205 /******************************************************************************/
206 /*** BOP_Face4                                                              ***/
207 /******************************************************************************/
208
209 /**
210  * Constructs a new quad face.
211  * @param v1 vertex index
212  * @param v2 vertex index
213  * @param v3 vertex index
214  * @param v4 vertex index
215  * @param plane face plane
216  * @param originalFace index of the original face
217  */
218 BOP_Face4::BOP_Face4(BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, MT_Plane3 plane, 
219                                          BOP_Index originalFace): 
220                                          BOP_Face(plane,originalFace) 
221 {
222         m_indexs[0] = v1;
223         m_indexs[1] = v2;
224         m_indexs[2] = v3;
225         m_indexs[3] = v4;
226         
227         m_size = 4;
228 }
229
230 /**
231  * Returns if this face contains the specified vertex index.
232  * @param v vertex index
233  * @return true if this face contains the specified vertex index, false otherwise
234  */
235 bool BOP_Face4::containsVertex(BOP_Index v) 
236 {
237         return (m_indexs[0] == v || m_indexs[1] == v || m_indexs[2] == v || m_indexs[3]==v);
238 }
239
240 /**
241  * Returns the neighbours of the specified vertex index.
242  * @param v vertex index
243  * @param prev previous vertex index
244  * @param next next vertex index
245  * @param opp opposite vertex index
246  * @return true if this face contains the vertex index v, false otherwise
247  */
248 bool BOP_Face4::getNeighbours(BOP_Index v, BOP_Index &prev, BOP_Index &next, BOP_Index &opp) 
249 {
250         if (m_indexs[0] == v) {
251           prev = m_indexs[3];
252           next = m_indexs[1];
253           opp = m_indexs[2];
254         }
255         else if (m_indexs[1] == v) {
256           prev = m_indexs[0];
257           next = m_indexs[2];
258           opp = m_indexs[3];
259         }
260         else if (m_indexs[2] == v) {
261           prev = m_indexs[1];
262           next = m_indexs[3];
263           opp = m_indexs[0];
264         }
265         else if (m_indexs[3] == v) {
266           prev = m_indexs[2];
267           next = m_indexs[0];
268           opp = m_indexs[1];
269         }
270         else return false;
271
272         return true;
273 }
274
275 /**
276  * Returns the previous neighbour of the specified vertex index.
277  * @param v vertex index
278  * @param w previous vertex index
279  * @return true if this face contains the specified vertex index, false otherwise
280  */
281 bool BOP_Face4::getPreviousVertex(BOP_Index v, BOP_Index &w) 
282 {
283         if (m_indexs[0] == v) w = m_indexs[3];
284         else if (m_indexs[1] == v) w = m_indexs[0];
285         else if (m_indexs[2] == v) w = m_indexs[1];
286         else if (m_indexs[3] == v) w = m_indexs[2];
287         else return false;
288
289         return true;
290 }
291
292 /**
293  * Returns the next neighbour of the specified vertex index.
294  * @param v vertex index
295  * @param w next vertex index
296  * @return true if this face contains the specified vertex index, false otherwise
297  */
298 bool BOP_Face4::getNextVertex(BOP_Index v, BOP_Index &w) 
299 {
300         if (m_indexs[0] == v) w = m_indexs[1];
301         else if (m_indexs[1] == v) w = m_indexs[2];
302         else if (m_indexs[2] == v) w = m_indexs[3];
303         else if (m_indexs[3] == v) w = m_indexs[0];
304         else return false;
305
306         return true;
307
308
309 /**
310  * Returns the opposite  neighbour of the specified vertex index.
311  * @param v vertex index
312  * @param w opposite vertex index
313  * @return true if this face contains the specified vertex index, false otherwise
314  */
315 bool BOP_Face4::getOppositeVertex(BOP_Index v, BOP_Index &w)
316 {
317         if (m_indexs[0] == v) 
318                 w = m_indexs[2];
319         else if (m_indexs[1] == v) 
320                 w = m_indexs[3];
321         else if (m_indexs[2] == v) 
322                 w = m_indexs[0];
323         else if (m_indexs[3] == v) 
324                 w = m_indexs[1];
325         else
326           return false;
327
328         return true;
329 }
330
331 /**
332  * Replaces a face vertex index.
333  * @param oldIndex old vertex index
334  * @param newIndex new vertex index
335  */
336 void BOP_Face4::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
337 {
338         if (m_indexs[0] == oldIndex) m_indexs[0] = newIndex;
339         else if (m_indexs[1] == oldIndex) m_indexs[1] = newIndex;
340         else if (m_indexs[2] == oldIndex) m_indexs[2] = newIndex;
341         else if (m_indexs[3] == oldIndex) m_indexs[3] = newIndex;
342 }
343
344 /**
345  * Returns the relative edge index (1,2,3,4) for the specified vertex indexs.
346  * @param v1 vertex index
347  * @param v2 vertex index
348  * @param e relative edge index (1,2,3,4)
349  * @return true if (v1,v2) is an edge of this face, false otherwise
350  */
351 bool BOP_Face4::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e)
352 {
353         if (m_indexs[0] == v1) {
354                 if (m_indexs[1] == v2) {
355                         e = 1;
356                 }
357                 else if (m_indexs[3] == v2) {
358                         e = 4;
359                 }
360                 else
361                   return false;
362         }
363         else if (m_indexs[1] == v1) {
364                 if (m_indexs[0] == v2) {
365                         e = 1;
366                 }
367                 else if (m_indexs[2] == v2) {
368                         e = 2;
369                 }
370                 else
371                   return false;
372         }
373         else if (m_indexs[2] == v1) {
374                 if (m_indexs[1] == v2) {
375                         e = 2;
376                 }
377                 else if (m_indexs[3] == v2) {
378                         e = 3;
379                 }
380                 else
381                   return false;
382         }
383         else if (m_indexs[3] == v1) {
384                 if (m_indexs[2] == v2) {
385                         e = 3;
386                 }
387                 else if (m_indexs[0] == v2) {
388                         e = 4;
389                 }
390                 else
391                   return false;
392         }
393         else return false;
394         
395         return  true;
396 }  
397
398 /**
399  * Implements operator <<.
400  */
401 ostream &operator<<(ostream &stream, BOP_Face *f)
402 {
403         char aux[20];
404         BOP_stringTAG(f->m_tag,aux);
405         if (f->size()==3) {
406                 stream << "Face[" << f->getVertex(0) << "," << f->getVertex(1) << ",";
407                 stream << f->getVertex(2) << "] ("  <<  aux  <<  ") <-- " << f->m_originalFace;
408         }
409         else {
410                 stream << "Face[" << f->getVertex(0) << "," << f->getVertex(1) << ",";
411                 stream << f->getVertex(2) << "," << f->getVertex(3) << "] ("  <<  aux;
412                 stream <<  ") <-- " << f->m_originalFace;
413         }
414
415         return stream;
416 }