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