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