New files from new booleans
[blender.git] / intern / boolop / intern / BOP_Segment.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_Segment.h"
32
33 #define UNDEFINED 0
34
35 /**
36  * Constructs a new segment.
37  */
38 BOP_Segment::BOP_Segment(){
39         m_cfg1  = UNDEFINED;
40         m_cfg2  = UNDEFINED;  
41 }
42
43 /**
44  * Returns the relative edge index between two relative vertex indices.
45  * @param v1 relative vertex index
46  * @param v2 relative vertex index
47  * @return relative edge index between two relative vertex indices, -1 otherwise
48  */
49 int BOP_Segment::getEdgeBetween(unsigned int v1, unsigned int v2) 
50 {
51         if ((v1 == 1 && v2 == 2) || (v1 == 2 && v2 == 1)) return 1;
52         if ((v1 == 3 && v2 == 2) || (v1 == 2 && v2 == 3)) return 2;
53         if ((v1 == 1 && v2 == 3) || (v1 == 3 && v2 == 1)) return 3;
54         return -1;
55 }
56
57 /** 
58  * Returns if a relative vertex index is on a relative edge index.
59  * @param v relative vertex index
60  * @param e relative edge index
61  * @return true if the relative vertex index is on the relative edge index, 
62  * false otherwise.
63  */
64 bool BOP_Segment::isOnEdge(unsigned int v, unsigned int e)
65 {
66         if (v == 1 && (e == 1 || e == 3)) return true;
67         if (v == 2 && (e == 1 || e == 2)) return true;
68         if (v == 3 && (e == 2 || e == 3)) return true;
69         return false;
70 }
71
72 /**
73  * Inverts the segment, swapping ends data.
74  */
75 void BOP_Segment::invert()
76 {
77         BOP_Index aux = m_v1;
78         m_v1    = m_v2;
79         m_v2    = aux;
80         aux     = m_cfg1;
81         m_cfg1  = m_cfg2;
82         m_cfg2  = aux;
83 }
84
85 /**
86  * Sorts the segment according to ends configuration.
87  * The criterion to sort is ...
88  *
89  *   UNDEFINED < VERTEX < EDGE < IN
90  *   cfg1 > cfg2
91  *
92  * so ... 
93  *
94  *   VERTEX(cfg1) => UNDEFINED(cfg2) || VERTEX(cfg2)
95  *   EDGE(cfg1) =>   UNDEFINED(cfg2) || VERTEX(cfg2) || EDGE(cfg2)
96  *   IN(cfg1) =>     UNDEFINED(cfg2) || VERTEX(cfg2) || EDGE(cfg2) || IN(cfg2)
97  */
98 void BOP_Segment::sort()
99 {
100         if (m_cfg1 < m_cfg2) invert();
101 }
102
103 /**
104  * Returns if the specified end segment configuration is IN.
105  * @return true if the specified end segment configuration is IN, false otherwise
106  */
107 bool BOP_Segment::isIn(unsigned int cfg)
108 {
109         return (cfg == 20);
110 }
111
112 /**
113  * Returns if the specified end segment configuration is EDGE.
114  * @return true if the specified end segment configuration is EDGE, false otherwise
115  */
116 bool BOP_Segment::isEdge(unsigned int cfg)
117 {
118         return (cfg > 10) && (cfg < 20);
119 }
120
121 /**
122  * Returns if the specified end segment configuration is VERTEX.
123  * @return true if the specified end segment configuration is VERTEX, false otherwise
124  */
125 bool BOP_Segment::isVertex(unsigned int cfg)
126 {
127         return (cfg!=UNDEFINED) && (cfg < 10);
128 }
129
130 /**
131  * Returns if the specified end segment configuration is DEFINED (not UNDEFINED).
132  * @return true if the specified end segment configuration is DEFINED, false otherwise
133  */
134 bool BOP_Segment::isDefined(unsigned int cfg)
135 {
136         return (cfg != UNDEFINED);
137 }   
138
139 /**
140  * Returns if the specified end segment configuration is UNDEFINED.
141  * @return true if the specified end segment configuration is UNDEFINED, false otherwise
142  */
143 bool BOP_Segment::isUndefined(unsigned int cfg)
144 {
145         return (cfg == UNDEFINED);
146 }   
147
148 /**
149  * Returns the relative edge index from the specified end segment configuration.
150  * @return relative edge index from the specified end segment configuration
151  */
152 unsigned int BOP_Segment::getEdge(unsigned int cfg)
153 {
154         return cfg-10;
155 }   
156
157 /**
158  * Returns the relative vertex index from the specified end segment configuration.
159  * @return relative vertex index from the specified end segment configuration
160  */
161 BOP_Index BOP_Segment::getVertex(unsigned int cfg)
162 {
163         return cfg;
164 }   
165
166 /**
167  * Returns the end segment configuration for the specified relative edge index.
168  * @return end segment configuration for the specified relative edge index
169  */
170 unsigned int BOP_Segment::createEdgeCfg(unsigned int edge)
171 {
172         return 10+edge;
173 }
174
175 /**
176  * Returns the end segment configuration for the specified relative vertex index.
177  * @return end segment configuration for the specified relative vertex index
178  */
179 unsigned int BOP_Segment::createVertexCfg(BOP_Index vertex)
180 {
181         return vertex;
182 }
183
184 /**
185  * Returns the end segment IN configuration.
186  * @return end segment IN configuration
187  */
188 unsigned int BOP_Segment::createInCfg()
189 {
190         return 20;
191 }
192
193 /**
194  * Returns the end segment UNDEFINED configuration.
195  * @return end segment UNDEFINED configuration
196  */
197 unsigned int BOP_Segment::createUndefinedCfg()
198 {
199         return UNDEFINED;
200 }
201
202 /**
203  * Returns the inner segment configuration.
204  * @return inner segment configuration
205  */
206 unsigned int BOP_Segment::getConfig() 
207 {
208         if (isUndefined(m_cfg1)) return m_cfg2;
209         else if (isUndefined(m_cfg2)) return m_cfg1;
210         else if (isVertex(m_cfg1)) {
211                 // v1 is vertex
212                 if (isVertex(m_cfg2)) {
213                         // v2 is vertex
214                         return createEdgeCfg(getEdgeBetween(getVertex(m_cfg1),getVertex(m_cfg2)));
215                 }
216                 else if (isEdge(m_cfg2)) {
217                         // v2 is edge
218                         if (isOnEdge(m_cfg1,getEdge(m_cfg2))) return m_cfg2;
219                         else return createInCfg(); //IN
220                 } 
221                 else return createInCfg(); //IN
222         }
223         else if (isEdge(m_cfg1)) {
224                 // v1 is edge
225                 if (isVertex(m_cfg2)) {
226                         // v2 is vertex
227                         if (isOnEdge(m_cfg2,getEdge(m_cfg1))) return m_cfg1;
228                         else return createInCfg(); //IN
229                 }
230                 else if (isEdge(m_cfg2)) {
231                         // v2 is edge
232                         if (m_cfg1 == m_cfg2) return m_cfg1;
233                         else return createInCfg(); // IN
234                 }
235                 else return createInCfg(); // IN
236         }
237         else return createInCfg(); // IN
238 }
239
240 /**
241  * Implements operator <<
242  */
243 ostream &operator<<(ostream &stream, const BOP_Segment &c)
244 {
245         cout << "m_v1: " << c.m_v1 << "(" << c.m_cfg1 << ") m_v2: " << c.m_v2 << "(" << c.m_cfg2 << ")";
246         return stream;
247 }