Merging r46096 through r46110 from trunk into soc-2011-tomato
[blender-staging.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         }
212         else {
213                 success = 
214                 CSG_PerformBooleanOperation(
215                         bool_op,
216                         op_type,
217                         mesh1->m_face_iterator,
218                         mesh1->m_vertex_iterator,
219                         mesh2->m_face_iterator,
220                         mesh2->m_vertex_iterator,               
221                         InterpNoUserData        
222                 );
223         }
224
225         if (!success) {
226                 CSG_FreeBooleanOperation(bool_op);
227                 bool_op = NULL;
228                 return 0;
229         }
230                 
231         // get the ouput mesh descriptors.
232
233         CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
234         CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
235         output->m_destroy_func = CSG_DestroyCSGMeshInternals;
236
237         return 1;
238 }
239
240         int
241 NewBooleanMeshTest(
242         struct Base * base,
243         struct Base * base_select,
244         int op_type
245 ) {
246
247         CSG_MeshDescriptor m1,m2,output;
248         CSG_MeshDescriptor output2,output3;
249         
250         if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
251                 return 0;
252         }
253         
254         if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
255                 return 0;
256         }
257         
258         CSG_PerformOp(&m1,&m2,1,&output);
259         CSG_PerformOp(&m1,&m2,2,&output2);
260         CSG_PerformOp(&m1,&m2,3,&output3);
261
262         if (!CSG_AddMeshToBlender(&output)) {
263                 return 0;
264         }
265         if (!CSG_AddMeshToBlender(&output2)) {
266                 return 0;
267         }
268         if (!CSG_AddMeshToBlender(&output3)) {
269                 return 0;
270         }
271
272         
273         CSG_DestroyMeshDescriptor(&m1);
274         CSG_DestroyMeshDescriptor(&m2);
275         CSG_DestroyMeshDescriptor(&output);
276         CSG_DestroyMeshDescriptor(&output2);
277         CSG_DestroyMeshDescriptor(&output3);
278
279         return 1;
280 }
281
282 #endif
283