Merging r41246 through r41535 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenkernel / intern / booleanops_mesh.c
1 #if 0
2
3 /*
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
29  */
30
31 /** \file blender/blenkernel/intern/booleanops_mesh.c
32  *  \ingroup bke
33  */
34
35 #include "CSG_BooleanOps.h"
36
37
38
39
40
41 /**
42  * Implementation of boolean ops mesh interface.
43  */
44
45         void
46 CSG_DestroyMeshDescriptor(
47         CSG_MeshDescriptor *mesh
48 ){
49         // Call mesh descriptors destroy function....
50         mesh->m_destroy_func(mesh);
51 }
52         
53 // Destroy function for blender mesh internals.
54
55 static
56         void
57 CSG_DestroyBlenderMeshInternals(
58         CSG_MeshDescriptor *mesh
59 ) {
60         // Free face and vertex iterators.
61         FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));               
62 }
63
64
65 static
66         void
67 CSG_DestroyCSGMeshInternals(
68         CSG_MeshDescriptor *mesh
69 ){
70         CSG_FreeVertexDescriptor(&(mesh->m_vertex_iterator));
71         CSG_FreeFaceDescriptor(&(mesh->m_face_iterator));
72 }
73
74 static
75         int
76 MakeCSGMeshFromBlenderBase(
77         Base * base,
78         CSG_MeshDescriptor * output
79 ) {
80         Mesh *me;
81         if (output == NULL || base == NULL) return 0;
82
83         me = get_mesh(base->object);
84                 
85         output->m_descriptor.user_face_vertex_data_size = 0;
86         output->m_descriptor.user_data_size = sizeof(FaceData);
87
88         output->base = base;
89         
90         BuildMeshDescriptors(
91                 base->object,
92                 &(output->m_face_iterator),
93                 &(output->m_vertex_iterator)
94         );
95
96         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
97
98         return 1;
99 }       
100
101         int
102 CSG_LoadBlenderMesh(
103         Object * obj,
104         CSG_MeshDescriptor *output
105 ){
106
107         Mesh *me;
108         if (output == NULL || obj == NULL) return 0;
109
110         me = get_mesh(obj);
111                 
112         output->m_descriptor.user_face_vertex_data_size = 0;
113         output->m_descriptor.user_data_size = sizeof(FaceData);
114
115         output->base = NULL;
116         
117         BuildMeshDescriptors(
118                 obj,
119                 &(output->m_face_iterator),
120                 &(output->m_vertex_iterator)
121         );
122
123         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
124         output->base = NULL;
125
126         return 1;
127 }
128         
129
130
131
132         int
133 CSG_AddMeshToBlender(
134         CSG_MeshDescriptor *mesh
135 ){
136         Mesh *me_new = NULL;
137         Object *ob_new = NULL;
138         float inv_mat[4][4];
139
140         if (mesh == NULL) return 0;
141         if (mesh->base == NULL) return 0;
142
143         invert_m4_m4(inv_mat,mesh->base->object->obmat);
144
145         // Create a new blender mesh object - using 'base' as 
146         // a template for the new object.
147         ob_new=  AddNewBlenderMesh(mesh->base);
148
149         me_new = ob_new->data;
150
151         // make sure the iterators are reset.
152         mesh->m_face_iterator.Reset(mesh->m_face_iterator.it);
153         mesh->m_vertex_iterator.Reset(mesh->m_vertex_iterator.it);
154
155         // iterate through results of operation and insert into new object
156         // see subsurf.c 
157
158         ConvertCSGDescriptorsToMeshObject(
159                 ob_new,
160                 &(mesh->m_descriptor),
161                 &(mesh->m_face_iterator),
162                 &(mesh->m_vertex_iterator),
163                 inv_mat
164         );
165
166         return 1;
167 }
168
169         int 
170 CSG_PerformOp(
171         CSG_MeshDescriptor *mesh1,
172         CSG_MeshDescriptor *mesh2,
173         int int_op_type,
174         CSG_MeshDescriptor *output
175 ){
176
177         CSG_OperationType op_type;
178         CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
179         int success = 0;
180
181         if (bool_op == NULL) return 0;
182
183         if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) {
184                 return 0;
185         }       
186         if ((int_op_type < 1) || (int_op_type > 3)) return 0;
187
188         switch (int_op_type) {
189                 case 1 : op_type = e_csg_intersection; break;
190                 case 2 : op_type = e_csg_union; break;
191                 case 3 : op_type = e_csg_difference; break;
192                 case 4 : op_type = e_csg_classify; break;
193                 default : op_type = e_csg_intersection;
194         }
195         
196         output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
197         output->base = mesh1->base;
198
199         if (output->m_descriptor.user_face_vertex_data_size) {
200                 // Then use the only interp function supported 
201                 success = 
202                 CSG_PerformBooleanOperation(
203                         bool_op,
204                         op_type,
205                         mesh1->m_face_iterator,
206                         mesh1->m_vertex_iterator,
207                         mesh2->m_face_iterator,
208                         mesh2->m_vertex_iterator,               
209                         InterpFaceVertexData    
210                 );
211         } else {
212                 success = 
213                 CSG_PerformBooleanOperation(
214                         bool_op,
215                         op_type,
216                         mesh1->m_face_iterator,
217                         mesh1->m_vertex_iterator,
218                         mesh2->m_face_iterator,
219                         mesh2->m_vertex_iterator,               
220                         InterpNoUserData        
221                 );
222         }
223
224         if (!success) {
225                 CSG_FreeBooleanOperation(bool_op);
226                 bool_op = NULL;
227                 return 0;
228         }
229                 
230         // get the ouput mesh descriptors.
231
232         CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
233         CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
234         output->m_destroy_func = CSG_DestroyCSGMeshInternals;
235
236         return 1;
237 }
238
239         int
240 NewBooleanMeshTest(
241         struct Base * base,
242         struct Base * base_select,
243         int op_type
244 ){
245
246         CSG_MeshDescriptor m1,m2,output;
247         CSG_MeshDescriptor output2,output3;
248         
249         if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
250                 return 0;
251         }
252         
253         if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
254                 return 0;
255         }
256         
257         CSG_PerformOp(&m1,&m2,1,&output);
258         CSG_PerformOp(&m1,&m2,2,&output2);
259         CSG_PerformOp(&m1,&m2,3,&output3);
260
261         if (!CSG_AddMeshToBlender(&output)) {
262                 return 0;
263         }
264         if (!CSG_AddMeshToBlender(&output2)) {
265                 return 0;
266         }
267         if (!CSG_AddMeshToBlender(&output3)) {
268                 return 0;
269         }
270
271         
272         CSG_DestroyMeshDescriptor(&m1);
273         CSG_DestroyMeshDescriptor(&m2);
274         CSG_DestroyMeshDescriptor(&output);
275         CSG_DestroyMeshDescriptor(&output2);
276         CSG_DestroyMeshDescriptor(&output3);
277
278         return 1;
279 }
280
281 #endif
282