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