New files from new booleans
[blender.git] / intern / boolop / intern / BOP_Splitter.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_Splitter.h"
32 #include "BOP_Tag.h"
33
34 #include <iostream>
35 using namespace std;
36
37 /**
38  * Returns the split point resulting from intersect a plane and a mesh face  
39  * according to its specified relative edge.
40  * @param plane split plane
41  * @param m mesh
42  * @param f face
43  * @param e relative edge index
44  * @return intersection point
45  */
46 MT_Point3 BOP_splitEdge(MT_Plane3 plane, BOP_Mesh *m, BOP_Face *f, unsigned int e)
47 {
48         int v1 = -1, v2 = -1;
49   
50         switch(e) {
51         case 1:
52                 v1 = f->getVertex(0);
53                 v2 = f->getVertex(1);
54                 break;
55         case 2:
56                 v1 = f->getVertex(1);
57                 v2 = f->getVertex(2);
58                 break;
59         case 3:
60                 v1 = f->getVertex(2);
61                 v2 = f->getVertex(0);
62                 break;
63         default:
64                 // wrong relative edge index!
65                 break;
66         }
67   
68         MT_Point3 p1 = m->getVertex(v1)->getPoint();
69         MT_Point3 p2 = m->getVertex(v2)->getPoint();
70         return BOP_intersectPlane(plane,p1,p2);
71 }
72
73 /**
74  * Returns the segment resulting from intersect a plane and a mesh face.
75  * @param plane split plane
76  * @param m mesh
77  * @param f face
78  * @return segment if there is intersection, NULL otherwise
79  */
80 BOP_Segment BOP_splitFace(MT_Plane3 plane, BOP_Mesh *m, BOP_Face *f)
81 {    
82         BOP_Vertex *v1 = m->getVertex(f->getVertex(0));
83         BOP_Vertex *v2 = m->getVertex(f->getVertex(1));
84         BOP_Vertex *v3 = m->getVertex(f->getVertex(2));
85
86         // Classify face vertices
87         BOP_TAG tag1 = BOP_createTAG(BOP_classify(v1->getPoint(),plane));
88         BOP_TAG tag2 = BOP_createTAG(BOP_classify(v2->getPoint(),plane));
89         BOP_TAG tag3 = BOP_createTAG(BOP_classify(v3->getPoint(),plane));
90   
91         // Classify face according to its vertices classification
92         BOP_TAG tag = BOP_createTAG(tag1,tag2,tag3);
93   
94         BOP_Segment s;
95
96         switch(tag) {
97         case IN_IN_IN : 
98         case OUT_OUT_OUT :
99         case ON_ON_ON :
100                 s.m_cfg1 = s.m_cfg2 = BOP_Segment::createUndefinedCfg();        
101                 break;
102     
103         case ON_OUT_OUT :
104         case ON_IN_IN :
105                 s.m_v1 = f->getVertex(0);
106                 s.m_cfg1 = BOP_Segment::createVertexCfg(1);
107                 s.m_cfg2 = BOP_Segment::createUndefinedCfg();
108                 break;
109     
110         case OUT_ON_OUT :
111         case IN_ON_IN :
112                 s.m_v1 = f->getVertex(1); 
113                 s.m_cfg1 = BOP_Segment::createVertexCfg(2);
114                 s.m_cfg2 = BOP_Segment::createUndefinedCfg();
115                 break;
116     
117         case OUT_OUT_ON :      
118         case IN_IN_ON :
119                 s.m_v1 = f->getVertex(2); 
120                 s.m_cfg1 = BOP_Segment::createVertexCfg(3);
121                 s.m_cfg2 = BOP_Segment::createUndefinedCfg();
122                 break;
123     
124         case ON_ON_IN :
125         case ON_ON_OUT :
126                 s.m_v1 = f->getVertex(0); 
127                 s.m_v2 = f->getVertex(1);
128                 s.m_cfg1 = BOP_Segment::createVertexCfg(1);
129                 s.m_cfg2 = BOP_Segment::createVertexCfg(2);
130                 break;
131     
132         case ON_OUT_ON :        
133         case ON_IN_ON :
134                 s.m_v1 = f->getVertex(0); 
135                 s.m_v2 = f->getVertex(2);
136                 s.m_cfg1 = BOP_Segment::createVertexCfg(1);
137                 s.m_cfg2 = BOP_Segment::createVertexCfg(3);
138                 break;
139     
140         case OUT_ON_ON :
141         case IN_ON_ON :
142                 s.m_v1 = f->getVertex(1); 
143                 s.m_v2 = f->getVertex(2);
144                 s.m_cfg1 = BOP_Segment::createVertexCfg(2);
145                 s.m_cfg2 = BOP_Segment::createVertexCfg(3);
146                 break;
147     
148         case IN_OUT_ON :
149         case OUT_IN_ON :
150                 s.m_v2 = f->getVertex(2);
151                 s.m_cfg1 = BOP_Segment::createEdgeCfg(1);
152                 s.m_cfg2 = BOP_Segment::createVertexCfg(3);
153             break;
154     
155         case IN_ON_OUT :
156         case OUT_ON_IN :
157                 s.m_v1 = f->getVertex(1);
158                 s.m_cfg1 = BOP_Segment::createVertexCfg(2);
159                 s.m_cfg2 = BOP_Segment::createEdgeCfg(3);
160                 break;
161     
162         case ON_IN_OUT :
163         case ON_OUT_IN :
164                 s.m_v1 = f->getVertex(0);
165                 s.m_cfg1 = BOP_Segment::createVertexCfg(1);
166                 s.m_cfg2 = BOP_Segment::createEdgeCfg(2);
167                 break;
168     
169         case OUT_IN_IN :
170         case IN_OUT_OUT :
171                 s.m_cfg1 = BOP_Segment::createEdgeCfg(1);
172                 s.m_cfg2 = BOP_Segment::createEdgeCfg(3);
173                 break;
174     
175         case OUT_IN_OUT :
176         case IN_OUT_IN :
177                 s.m_cfg1 = BOP_Segment::createEdgeCfg(1);
178                 s.m_cfg2 = BOP_Segment::createEdgeCfg(2);
179                 break;
180     
181         case OUT_OUT_IN :
182         case IN_IN_OUT :
183                 s.m_cfg1 = BOP_Segment::createEdgeCfg(2);
184                 s.m_cfg2 = BOP_Segment::createEdgeCfg(3);
185                 break;
186     
187         default:
188                 // wrong TAG!
189                 break;
190         }
191
192         return s;
193 }