Blender  V2.59
booleanops_mesh.c
Go to the documentation of this file.
00001 #if 0
00002 
00003 /*
00004  * $Id: booleanops_mesh.c 35247 2011-02-27 20:40:57Z jesterking $
00005  *
00006  * ***** BEGIN GPL LICENSE BLOCK *****
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License
00010  * as published by the Free Software Foundation; either version 2
00011  * of the License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software Foundation,
00020  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021  *
00022  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00023  * All rights reserved.
00024  *
00025  * The Original Code is: all of this file.
00026  *
00027  * Contributor(s): none yet.
00028  *
00029  * ***** END GPL LICENSE BLOCK *****
00030  */
00031 
00036 #include "CSG_BooleanOps.h"
00037 
00038 
00039 
00040 
00041 
00046         void
00047 CSG_DestroyMeshDescriptor(
00048         CSG_MeshDescriptor *mesh
00049 ){
00050         // Call mesh descriptors destroy function....
00051         mesh->m_destroy_func(mesh);
00052 }
00053         
00054 // Destroy function for blender mesh internals.
00055 
00056 static
00057         void
00058 CSG_DestroyBlenderMeshInternals(
00059         CSG_MeshDescriptor *mesh
00060 ) {
00061         // Free face and vertex iterators.
00062         FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));               
00063 }
00064 
00065 
00066 static
00067         void
00068 CSG_DestroyCSGMeshInternals(
00069         CSG_MeshDescriptor *mesh
00070 ){
00071         CSG_FreeVertexDescriptor(&(mesh->m_vertex_iterator));
00072         CSG_FreeFaceDescriptor(&(mesh->m_face_iterator));
00073 }
00074 
00075 static
00076         int
00077 MakeCSGMeshFromBlenderBase(
00078         Base * base,
00079         CSG_MeshDescriptor * output
00080 ) {
00081         Mesh *me;
00082         if (output == NULL || base == NULL) return 0;
00083 
00084         me = get_mesh(base->object);
00085                 
00086         output->m_descriptor.user_face_vertex_data_size = 0;
00087         output->m_descriptor.user_data_size = sizeof(FaceData);
00088 
00089         output->base = base;
00090         
00091         BuildMeshDescriptors(
00092                 base->object,
00093                 &(output->m_face_iterator),
00094                 &(output->m_vertex_iterator)
00095         );
00096 
00097         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
00098 
00099         return 1;
00100 }       
00101 
00102         int
00103 CSG_LoadBlenderMesh(
00104         Object * obj,
00105         CSG_MeshDescriptor *output
00106 ){
00107 
00108         Mesh *me;
00109         if (output == NULL || obj == NULL) return 0;
00110 
00111         me = get_mesh(obj);
00112                 
00113         output->m_descriptor.user_face_vertex_data_size = 0;
00114         output->m_descriptor.user_data_size = sizeof(FaceData);
00115 
00116         output->base = NULL;
00117         
00118         BuildMeshDescriptors(
00119                 obj,
00120                 &(output->m_face_iterator),
00121                 &(output->m_vertex_iterator)
00122         );
00123 
00124         output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
00125         output->base = NULL;
00126 
00127         return 1;
00128 }
00129         
00130 
00131 
00132 
00133         int
00134 CSG_AddMeshToBlender(
00135         CSG_MeshDescriptor *mesh
00136 ){
00137         Mesh *me_new = NULL;
00138         Object *ob_new = NULL;
00139         float inv_mat[4][4];
00140 
00141         if (mesh == NULL) return 0;
00142         if (mesh->base == NULL) return 0;
00143 
00144         invert_m4_m4(inv_mat,mesh->base->object->obmat);
00145 
00146         // Create a new blender mesh object - using 'base' as 
00147         // a template for the new object.
00148         ob_new=  AddNewBlenderMesh(mesh->base);
00149 
00150         me_new = ob_new->data;
00151 
00152         // make sure the iterators are reset.
00153         mesh->m_face_iterator.Reset(mesh->m_face_iterator.it);
00154         mesh->m_vertex_iterator.Reset(mesh->m_vertex_iterator.it);
00155 
00156         // iterate through results of operation and insert into new object
00157         // see subsurf.c 
00158 
00159         ConvertCSGDescriptorsToMeshObject(
00160                 ob_new,
00161                 &(mesh->m_descriptor),
00162                 &(mesh->m_face_iterator),
00163                 &(mesh->m_vertex_iterator),
00164                 inv_mat
00165         );
00166 
00167         return 1;
00168 }
00169 
00170         int 
00171 CSG_PerformOp(
00172         CSG_MeshDescriptor *mesh1,
00173         CSG_MeshDescriptor *mesh2,
00174         int int_op_type,
00175         CSG_MeshDescriptor *output
00176 ){
00177 
00178         CSG_OperationType op_type;
00179         CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
00180         int success = 0;
00181 
00182         if (bool_op == NULL) return 0;
00183 
00184         if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) {
00185                 return 0;
00186         }       
00187         if ((int_op_type < 1) || (int_op_type > 3)) return 0;
00188 
00189         switch (int_op_type) {
00190                 case 1 : op_type = e_csg_intersection; break;
00191                 case 2 : op_type = e_csg_union; break;
00192                 case 3 : op_type = e_csg_difference; break;
00193                 case 4 : op_type = e_csg_classify; break;
00194                 default : op_type = e_csg_intersection;
00195         }
00196         
00197         output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
00198         output->base = mesh1->base;
00199 
00200         if (output->m_descriptor.user_face_vertex_data_size) {
00201                 // Then use the only interp function supported 
00202                 success = 
00203                 CSG_PerformBooleanOperation(
00204                         bool_op,
00205                         op_type,
00206                         mesh1->m_face_iterator,
00207                         mesh1->m_vertex_iterator,
00208                         mesh2->m_face_iterator,
00209                         mesh2->m_vertex_iterator,               
00210                         InterpFaceVertexData    
00211                 );
00212         } else {
00213                 success = 
00214                 CSG_PerformBooleanOperation(
00215                         bool_op,
00216                         op_type,
00217                         mesh1->m_face_iterator,
00218                         mesh1->m_vertex_iterator,
00219                         mesh2->m_face_iterator,
00220                         mesh2->m_vertex_iterator,               
00221                         InterpNoUserData        
00222                 );
00223         }
00224 
00225         if (!success) {
00226                 CSG_FreeBooleanOperation(bool_op);
00227                 bool_op = NULL;
00228                 return 0;
00229         }
00230                 
00231         // get the ouput mesh descriptors.
00232 
00233         CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
00234         CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
00235         output->m_destroy_func = CSG_DestroyCSGMeshInternals;
00236 
00237         return 1;
00238 }
00239 
00240         int
00241 NewBooleanMeshTest(
00242         struct Base * base,
00243         struct Base * base_select,
00244         int op_type
00245 ){
00246 
00247         CSG_MeshDescriptor m1,m2,output;
00248         CSG_MeshDescriptor output2,output3;
00249         
00250         if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
00251                 return 0;
00252         }
00253         
00254         if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
00255                 return 0;
00256         }
00257         
00258         CSG_PerformOp(&m1,&m2,1,&output);
00259         CSG_PerformOp(&m1,&m2,2,&output2);
00260         CSG_PerformOp(&m1,&m2,3,&output3);
00261 
00262         if (!CSG_AddMeshToBlender(&output)) {
00263                 return 0;
00264         }
00265         if (!CSG_AddMeshToBlender(&output2)) {
00266                 return 0;
00267         }
00268         if (!CSG_AddMeshToBlender(&output3)) {
00269                 return 0;
00270         }
00271 
00272         
00273         CSG_DestroyMeshDescriptor(&m1);
00274         CSG_DestroyMeshDescriptor(&m2);
00275         CSG_DestroyMeshDescriptor(&output);
00276         CSG_DestroyMeshDescriptor(&output2);
00277         CSG_DestroyMeshDescriptor(&output3);
00278 
00279         return 1;
00280 }
00281 
00282 #endif
00283