Saturday morning first cup of coffee hack (yeah, its a late
[blender.git] / source / blender / src / booleanops_mesh.c
1 #if 0
2
3 /**
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34 #include "CSG_BooleanOps.h"
35
36 #include "BKE_booleanops.h"
37 #include "BKE_booleanops_mesh.h"
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_material_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_scene_types.h"
44
45 #include "BKE_global.h"
46 #include "BKE_mesh.h"
47 #include "BKE_displist.h"
48 #include "BKE_object.h"
49 #include "BKE_utildefines.h"
50 #include "BKE_library.h"
51 #include "BKE_material.h"
52
53 #include "BLI_arithb.h"
54
55 #ifdef HAVE_CONFIG_H
56 #include <config.h>
57 #endif
58
59 /**
60  * Implementation of boolean ops mesh interface.
61  */
62
63         void
64 CSG_DestroyMeshDescriptor(
65         CSG_MeshDescriptor *mesh
66 ){
67         // Call mesh descriptors destroy function....
68         mesh->m_destroy_func(mesh);
69 }
70         
71 // Destroy function for blender mesh internals.
72
73 static
74         void
75 CSG_DestroyBlenderMeshInternals(
76         CSG_MeshDescriptor *mesh
77 ) {
78         // Free face and vertex iterators.
79         FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));               
80 }
81
82
83 static
84         void
85 CSG_DestroyCSGMeshInternals(
86         CSG_MeshDescriptor *mesh
87 ){
88         CSG_FreeVertexDescriptor(&(mesh->m_vertex_iterator));
89         CSG_FreeFaceDescriptor(&(mesh->m_face_iterator));
90 }
91
92 static
93         int
94 MakeCSGMeshFromBlenderBase(
95         Base * base,
96         CSG_MeshDescriptor * output
97 ) {
98         Mesh *me;
99         if (output == NULL || base == NULL) return 0;
100
101         me = get_mesh(base->object);
102                 
103         output->m_descriptor.user_face_vertex_data_size = 0;
104         output->m_descriptor.user_data_size = sizeof(FaceData);
105
106         if (me->tface) {
107                 output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData);
108         }
109
110         output->base = base;
111         
112         BuildMeshDescriptors(
113                 base->object,
114                 &(output->m_face_iterator),
115                 &(output->m_vertex_iterator)
116         );
117
118         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
119
120         return 1;
121 }       
122
123         int
124 CSG_LoadBlenderMesh(
125         Object * obj,
126         CSG_MeshDescriptor *output
127 ){
128
129         Mesh *me;
130         if (output == NULL || obj == NULL) return 0;
131
132         me = get_mesh(obj);
133                 
134         output->m_descriptor.user_face_vertex_data_size = 0;
135         output->m_descriptor.user_data_size = sizeof(FaceData);
136
137         if (me->tface) {
138                 output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData);
139         }
140
141         output->base = NULL;
142         
143         BuildMeshDescriptors(
144                 obj,
145                 &(output->m_face_iterator),
146                 &(output->m_vertex_iterator)
147         );
148
149         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
150         output->base = NULL;
151
152         return 1;
153 }
154         
155
156
157
158         int
159 CSG_AddMeshToBlender(
160         CSG_MeshDescriptor *mesh
161 ){
162         Mesh *me_new = NULL;
163         Object *ob_new = NULL;
164         float inv_mat[4][4];
165
166         if (mesh == NULL) return 0;
167         if (mesh->base == NULL) return 0;
168
169         Mat4Invert(inv_mat,mesh->base->object->obmat);
170
171         // Create a new blender mesh object - using 'base' as 
172         // a template for the new object.
173         ob_new=  AddNewBlenderMesh(mesh->base);
174
175         me_new = ob_new->data;
176
177         // make sure the iterators are reset.
178         mesh->m_face_iterator.Reset(mesh->m_face_iterator.it);
179         mesh->m_vertex_iterator.Reset(mesh->m_vertex_iterator.it);
180
181         // iterate through results of operation and insert into new object
182         // see subsurf.c 
183
184         ConvertCSGDescriptorsToMeshObject(
185                 ob_new,
186                 &(mesh->m_descriptor),
187                 &(mesh->m_face_iterator),
188                 &(mesh->m_vertex_iterator),
189                 inv_mat
190         );
191
192         return 1;
193 }
194
195         int 
196 CSG_PerformOp(
197         CSG_MeshDescriptor *mesh1,
198         CSG_MeshDescriptor *mesh2,
199         int int_op_type,
200         CSG_MeshDescriptor *output
201 ){
202
203         CSG_OperationType op_type;
204         CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
205         int success = 0;
206
207         if (bool_op == NULL) return 0;
208
209         if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) {
210                 return 0;
211         }       
212         if ((int_op_type < 1) || (int_op_type > 3)) return 0;
213
214         switch (int_op_type) {
215                 case 1 : op_type = e_csg_intersection; break;
216                 case 2 : op_type = e_csg_union; break;
217                 case 3 : op_type = e_csg_difference; break;
218                 case 4 : op_type = e_csg_classify; break;
219                 default : op_type = e_csg_intersection;
220         }
221         
222         output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
223         output->base = mesh1->base;
224
225         if (output->m_descriptor.user_face_vertex_data_size) {
226                 // Then use the only interp function supported 
227                 success = 
228                 CSG_PerformBooleanOperation(
229                         bool_op,
230                         op_type,
231                         mesh1->m_face_iterator,
232                         mesh1->m_vertex_iterator,
233                         mesh2->m_face_iterator,
234                         mesh2->m_vertex_iterator,               
235                         InterpFaceVertexData    
236                 );
237         } else {
238                 success = 
239                 CSG_PerformBooleanOperation(
240                         bool_op,
241                         op_type,
242                         mesh1->m_face_iterator,
243                         mesh1->m_vertex_iterator,
244                         mesh2->m_face_iterator,
245                         mesh2->m_vertex_iterator,               
246                         InterpNoUserData        
247                 );
248         }
249
250         if (!success) {
251                 CSG_FreeBooleanOperation(bool_op);
252                 bool_op = NULL;
253                 return 0;
254         }
255                 
256         // get the ouput mesh descriptors.
257
258         CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
259         CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
260         output->m_destroy_func = CSG_DestroyCSGMeshInternals;
261
262         return 1;
263 }
264
265         int
266 NewBooleanMeshTest(
267         struct Base * base,
268         struct Base * base_select,
269         int op_type
270 ){
271
272         CSG_MeshDescriptor m1,m2,output;
273         CSG_MeshDescriptor output2,output3;
274         
275         if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
276                 return 0;
277         }
278         
279         if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
280                 return 0;
281         }
282         
283         CSG_PerformOp(&m1,&m2,1,&output);
284         CSG_PerformOp(&m1,&m2,2,&output2);
285         CSG_PerformOp(&m1,&m2,3,&output3);
286
287         if (!CSG_AddMeshToBlender(&output)) {
288                 return 0;
289         }
290         if (!CSG_AddMeshToBlender(&output2)) {
291                 return 0;
292         }
293         if (!CSG_AddMeshToBlender(&output3)) {
294                 return 0;
295         }
296
297         
298         CSG_DestroyMeshDescriptor(&m1);
299         CSG_DestroyMeshDescriptor(&m2);
300         CSG_DestroyMeshDescriptor(&output);
301         CSG_DestroyMeshDescriptor(&output2);
302         CSG_DestroyMeshDescriptor(&output3);
303
304         return 1;
305 }
306
307
308 #endif