=== Custom Transform Orientation ===
[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 /**
56  * Implementation of boolean ops mesh interface.
57  */
58
59         void
60 CSG_DestroyMeshDescriptor(
61         CSG_MeshDescriptor *mesh
62 ){
63         // Call mesh descriptors destroy function....
64         mesh->m_destroy_func(mesh);
65 }
66         
67 // Destroy function for blender mesh internals.
68
69 static
70         void
71 CSG_DestroyBlenderMeshInternals(
72         CSG_MeshDescriptor *mesh
73 ) {
74         // Free face and vertex iterators.
75         FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));               
76 }
77
78
79 static
80         void
81 CSG_DestroyCSGMeshInternals(
82         CSG_MeshDescriptor *mesh
83 ){
84         CSG_FreeVertexDescriptor(&(mesh->m_vertex_iterator));
85         CSG_FreeFaceDescriptor(&(mesh->m_face_iterator));
86 }
87
88 static
89         int
90 MakeCSGMeshFromBlenderBase(
91         Base * base,
92         CSG_MeshDescriptor * output
93 ) {
94         Mesh *me;
95         if (output == NULL || base == NULL) return 0;
96
97         me = get_mesh(base->object);
98                 
99         output->m_descriptor.user_face_vertex_data_size = 0;
100         output->m_descriptor.user_data_size = sizeof(FaceData);
101
102         output->base = base;
103         
104         BuildMeshDescriptors(
105                 base->object,
106                 &(output->m_face_iterator),
107                 &(output->m_vertex_iterator)
108         );
109
110         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
111
112         return 1;
113 }       
114
115         int
116 CSG_LoadBlenderMesh(
117         Object * obj,
118         CSG_MeshDescriptor *output
119 ){
120
121         Mesh *me;
122         if (output == NULL || obj == NULL) return 0;
123
124         me = get_mesh(obj);
125                 
126         output->m_descriptor.user_face_vertex_data_size = 0;
127         output->m_descriptor.user_data_size = sizeof(FaceData);
128
129         output->base = NULL;
130         
131         BuildMeshDescriptors(
132                 obj,
133                 &(output->m_face_iterator),
134                 &(output->m_vertex_iterator)
135         );
136
137         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
138         output->base = NULL;
139
140         return 1;
141 }
142         
143
144
145
146         int
147 CSG_AddMeshToBlender(
148         CSG_MeshDescriptor *mesh
149 ){
150         Mesh *me_new = NULL;
151         Object *ob_new = NULL;
152         float inv_mat[4][4];
153
154         if (mesh == NULL) return 0;
155         if (mesh->base == NULL) return 0;
156
157         Mat4Invert(inv_mat,mesh->base->object->obmat);
158
159         // Create a new blender mesh object - using 'base' as 
160         // a template for the new object.
161         ob_new=  AddNewBlenderMesh(mesh->base);
162
163         me_new = ob_new->data;
164
165         // make sure the iterators are reset.
166         mesh->m_face_iterator.Reset(mesh->m_face_iterator.it);
167         mesh->m_vertex_iterator.Reset(mesh->m_vertex_iterator.it);
168
169         // iterate through results of operation and insert into new object
170         // see subsurf.c 
171
172         ConvertCSGDescriptorsToMeshObject(
173                 ob_new,
174                 &(mesh->m_descriptor),
175                 &(mesh->m_face_iterator),
176                 &(mesh->m_vertex_iterator),
177                 inv_mat
178         );
179
180         return 1;
181 }
182
183         int 
184 CSG_PerformOp(
185         CSG_MeshDescriptor *mesh1,
186         CSG_MeshDescriptor *mesh2,
187         int int_op_type,
188         CSG_MeshDescriptor *output
189 ){
190
191         CSG_OperationType op_type;
192         CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
193         int success = 0;
194
195         if (bool_op == NULL) return 0;
196
197         if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) {
198                 return 0;
199         }       
200         if ((int_op_type < 1) || (int_op_type > 3)) return 0;
201
202         switch (int_op_type) {
203                 case 1 : op_type = e_csg_intersection; break;
204                 case 2 : op_type = e_csg_union; break;
205                 case 3 : op_type = e_csg_difference; break;
206                 case 4 : op_type = e_csg_classify; break;
207                 default : op_type = e_csg_intersection;
208         }
209         
210         output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
211         output->base = mesh1->base;
212
213         if (output->m_descriptor.user_face_vertex_data_size) {
214                 // Then use the only interp function supported 
215                 success = 
216                 CSG_PerformBooleanOperation(
217                         bool_op,
218                         op_type,
219                         mesh1->m_face_iterator,
220                         mesh1->m_vertex_iterator,
221                         mesh2->m_face_iterator,
222                         mesh2->m_vertex_iterator,               
223                         InterpFaceVertexData    
224                 );
225         } else {
226                 success = 
227                 CSG_PerformBooleanOperation(
228                         bool_op,
229                         op_type,
230                         mesh1->m_face_iterator,
231                         mesh1->m_vertex_iterator,
232                         mesh2->m_face_iterator,
233                         mesh2->m_vertex_iterator,               
234                         InterpNoUserData        
235                 );
236         }
237
238         if (!success) {
239                 CSG_FreeBooleanOperation(bool_op);
240                 bool_op = NULL;
241                 return 0;
242         }
243                 
244         // get the ouput mesh descriptors.
245
246         CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
247         CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
248         output->m_destroy_func = CSG_DestroyCSGMeshInternals;
249
250         return 1;
251 }
252
253         int
254 NewBooleanMeshTest(
255         struct Base * base,
256         struct Base * base_select,
257         int op_type
258 ){
259
260         CSG_MeshDescriptor m1,m2,output;
261         CSG_MeshDescriptor output2,output3;
262         
263         if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
264                 return 0;
265         }
266         
267         if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
268                 return 0;
269         }
270         
271         CSG_PerformOp(&m1,&m2,1,&output);
272         CSG_PerformOp(&m1,&m2,2,&output2);
273         CSG_PerformOp(&m1,&m2,3,&output3);
274
275         if (!CSG_AddMeshToBlender(&output)) {
276                 return 0;
277         }
278         if (!CSG_AddMeshToBlender(&output2)) {
279                 return 0;
280         }
281         if (!CSG_AddMeshToBlender(&output3)) {
282                 return 0;
283         }
284
285         
286         CSG_DestroyMeshDescriptor(&m1);
287         CSG_DestroyMeshDescriptor(&m2);
288         CSG_DestroyMeshDescriptor(&output);
289         CSG_DestroyMeshDescriptor(&output2);
290         CSG_DestroyMeshDescriptor(&output3);
291
292         return 1;
293 }
294
295 #endif
296