Final merge of HEAD (bf-blender) into the orange branch.
[blender.git] / intern / bsp / intern / CSG_BooleanOps.cpp
1 /**
2  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. The Blender
8  * Foundation also sells licenses for use in proprietary software under
9  * the Blender License.  See http://www.blender.org/BL/ for information
10  * about this.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 /**
32
33  * Implementation of external api for CSG part of BSP lib interface.
34  */
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include "../extern/CSG_BooleanOps.h"
41 #include "BSP_CSGMesh_CFIterator.h"
42 #include "BSP_CSGMeshBuilder.h"
43 #include "BSP_CSGHelper.h"
44 #include "BSP_CSGUserData.h"
45 #include "MEM_RefCountPtr.h"
46
47 #include "../../boolop/extern/BOP_Interface.h"
48 #include <iostream>
49 using namespace std;
50 #include "BSP_MeshPrimitives.h";
51
52 struct BSP_MeshInfo {
53         BSP_CSGMesh *output_mesh;
54         CSG_MeshPropertyDescriptor obA_descriptor;
55         CSG_MeshPropertyDescriptor obB_descriptor;
56         CSG_MeshPropertyDescriptor output_descriptor;
57 };
58
59 using namespace std;
60         
61         CSG_BooleanOperation * 
62 CSG_NewBooleanFunction(
63         void
64 ){
65         BSP_MeshInfo * mesh_info = new BSP_MeshInfo;
66         CSG_BooleanOperation * output = new CSG_BooleanOperation;
67
68         if (mesh_info==NULL || output==NULL) return NULL;
69
70         mesh_info->output_mesh = NULL;
71         output->CSG_info = mesh_info;
72
73         return output;
74 }
75         
76         CSG_MeshPropertyDescriptor
77 CSG_DescibeOperands(
78         CSG_BooleanOperation * operation,
79         CSG_MeshPropertyDescriptor operandA_desciption,
80         CSG_MeshPropertyDescriptor operandB_desciption
81 ){
82         BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
83
84         mesh_info->obA_descriptor = operandA_desciption;
85         mesh_info->obB_descriptor = operandB_desciption;
86
87         if (
88                 (operandA_desciption.user_data_size == operandB_desciption.user_data_size) &&
89                 (operandA_desciption.user_face_vertex_data_size == operandB_desciption.user_face_vertex_data_size)
90         ) {
91                 // Then both operands have the same sets of data we can cope with this!
92                 mesh_info->output_descriptor.user_data_size = operandA_desciption.user_data_size;
93                 mesh_info->output_descriptor.user_face_vertex_data_size = operandA_desciption.user_face_vertex_data_size;
94         } else {
95                 // There maybe some common subset of data we can seperate out but for now we just use the 
96                 // default 
97                 mesh_info->output_descriptor.user_data_size = 0;
98                 mesh_info->output_descriptor.user_face_vertex_data_size = 0;
99         }
100         return mesh_info->output_descriptor;
101 }
102
103 /**
104  * Compute the boolean operation, UNION, INTERSECION or DIFFERENCE
105  */
106         int
107 CSG_PerformBooleanOperation(
108         CSG_BooleanOperation                 *operation,
109         CSG_OperationType                     op_type,
110         CSG_FaceIteratorDescriptor            obAFaces,
111         CSG_VertexIteratorDescriptor          obAVertices,
112         CSG_FaceIteratorDescriptor            obBFaces,
113         CSG_VertexIteratorDescriptor          obBVertices,
114         CSG_InterpolateUserFaceVertexDataFunc interp_func
115 ){
116         if (operation == NULL) return 0;
117         BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
118         if (mesh_info == NULL) return 0;
119
120         bool success = 1;
121
122         obAFaces.Reset(obAFaces.it);
123         obBFaces.Reset(obBFaces.it);
124         obAVertices.Reset(obAVertices.it);
125         obBVertices.Reset(obBVertices.it);
126
127         BoolOpType boolType;
128         
129         switch( op_type ) {
130         case e_csg_union:
131           boolType = BOP_UNION;
132           break;
133         case e_csg_difference:
134           boolType = BOP_DIFFERENCE;
135           break;
136         default:
137           boolType = BOP_INTERSECTION;
138           break;
139         }
140
141         try {
142         BOP_performBooleanOperation( boolType,
143                                      mesh_info->output_descriptor,
144                                      (BSP_CSGMesh**) &(mesh_info->output_mesh),
145                                          mesh_info->obB_descriptor,
146                                          obBFaces,
147                                          obBVertices,
148                                          mesh_info->obA_descriptor,
149                                      obAFaces,
150                                      obAVertices,
151                                      interp_func );
152         }
153         catch(...) {
154                 return 0;
155         }
156
157         return success;
158 }
159
160         int
161 CSG_OutputFaceDescriptor(
162         CSG_BooleanOperation * operation,
163         CSG_FaceIteratorDescriptor * output
164 ){
165         if (operation == NULL) return 0;
166         BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
167
168         if (mesh_info == NULL) return 0;
169         if (mesh_info->output_mesh == NULL) return 0;
170
171         BSP_CSGMesh_FaceIt_Construct(mesh_info->output_mesh,output);
172         return 1;
173 }
174
175
176         int
177 CSG_OutputVertexDescriptor(
178         CSG_BooleanOperation * operation,
179         CSG_VertexIteratorDescriptor *output
180 ){
181         if (operation == NULL) return 0;
182         BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
183
184         if (mesh_info == NULL) return 0;
185         if (mesh_info->output_mesh == NULL) return 0;
186
187         BSP_CSGMeshVertexIt_Construct(mesh_info->output_mesh,output);
188         return 1;
189 }
190
191         void
192 CSG_FreeVertexDescriptor(
193         CSG_VertexIteratorDescriptor * v_descriptor
194 ){      
195         BSP_CSGMesh_VertexIt_Destruct(v_descriptor);
196 }       
197
198
199         void
200 CSG_FreeFaceDescriptor(
201         CSG_FaceIteratorDescriptor * f_descriptor
202 ){
203         BSP_CSGMesh_FaceIt_Destruct(f_descriptor);
204 }
205
206
207         void
208 CSG_FreeBooleanOperation(
209         CSG_BooleanOperation *operation
210 ){
211         if (operation != NULL) {
212                 BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
213
214                 delete (mesh_info->output_mesh);
215                 delete(mesh_info);
216                 delete(operation);
217         }
218 }