Logo Search packages:      
Sourcecode: blender version File versions

booleanops_mesh.c

/**
 * $Id: booleanops_mesh.c,v 1.4 2004/02/23 19:14:38 sirdude Exp $
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
#include "CSG_BooleanOps.h"

#include "BKE_booleanops.h"
#include "BKE_booleanops_mesh.h"
#include "MEM_guardedalloc.h"

#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"

#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_displist.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BKE_library.h"
#include "BKE_material.h"

#include "BLI_arithb.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/**
 * Implementation of boolean ops mesh interface.
 */

      void
CSG_DestroyMeshDescriptor(
      CSG_MeshDescriptor *mesh
){
      // Call mesh descriptors destroy function....
      mesh->m_destroy_func(mesh);
}
      
// Destroy function for blender mesh internals.

static
      void
CSG_DestroyBlenderMeshInternals(
      CSG_MeshDescriptor *mesh
) {
      // Free face and vertex iterators.
      FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));           
}


static
      void
CSG_DestroyCSGMeshInternals(
      CSG_MeshDescriptor *mesh
){
      CSG_FreeVertexDescriptor(&(mesh->m_vertex_iterator));
      CSG_FreeFaceDescriptor(&(mesh->m_face_iterator));
}

static
      int
MakeCSGMeshFromBlenderBase(
      Base * base,
      CSG_MeshDescriptor * output
) {
      Mesh *me;
      if (output == NULL || base == NULL) return 0;

      me = get_mesh(base->object);
            
      output->m_descriptor.user_face_vertex_data_size = 0;
      output->m_descriptor.user_data_size = sizeof(FaceData);

      if (me->tface) {
            output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData);
      }

      output->base = base;
      
      BuildMeshDescriptors(
            base->object,
            &(output->m_face_iterator),
            &(output->m_vertex_iterator)
      );

      output->m_destroy_func = CSG_DestroyBlenderMeshInternals;

      return 1;
}     

      int
CSG_LoadBlenderMesh(
      Object * obj,
      CSG_MeshDescriptor *output
){

      Mesh *me;
      if (output == NULL || obj == NULL) return 0;

      me = get_mesh(obj);
            
      output->m_descriptor.user_face_vertex_data_size = 0;
      output->m_descriptor.user_data_size = sizeof(FaceData);

      if (me->tface) {
            output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData);
      }

      output->base = NULL;
      
      BuildMeshDescriptors(
            obj,
            &(output->m_face_iterator),
            &(output->m_vertex_iterator)
      );

      output->m_destroy_func = CSG_DestroyBlenderMeshInternals;
      output->base = NULL;

      return 1;
}
      



      int
CSG_AddMeshToBlender(
      CSG_MeshDescriptor *mesh
){
      Mesh *me_new = NULL;
      Object *ob_new = NULL;
      float inv_mat[4][4];

      if (mesh == NULL) return 0;
      if (mesh->base == NULL) return 0;

      Mat4Invert(inv_mat,mesh->base->object->obmat);

      // Create a new blender mesh object - using 'base' as 
      // a template for the new object.
      ob_new=  AddNewBlenderMesh(mesh->base);

      me_new = ob_new->data;

      // make sure the iterators are reset.
      mesh->m_face_iterator.Reset(mesh->m_face_iterator.it);
      mesh->m_vertex_iterator.Reset(mesh->m_vertex_iterator.it);

      // iterate through results of operation and insert into new object
      // see subsurf.c 

      ConvertCSGDescriptorsToMeshObject(
            ob_new,
            &(mesh->m_descriptor),
            &(mesh->m_face_iterator),
            &(mesh->m_vertex_iterator),
            inv_mat
      );

      // initialize the object
      tex_space_mesh(me_new);

      return 1;
}

      int 
CSG_PerformOp(
      CSG_MeshDescriptor *mesh1,
      CSG_MeshDescriptor *mesh2,
      int int_op_type,
      CSG_MeshDescriptor *output
){

      CSG_OperationType op_type;
      CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
      int success = 0;

      if (bool_op == NULL) return 0;

      if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) {
            return 0;
      }     
      if ((int_op_type < 1) || (int_op_type > 3)) return 0;

      switch (int_op_type) {
            case 1 : op_type = e_csg_intersection; break;
            case 2 : op_type = e_csg_union; break;
            case 3 : op_type = e_csg_difference; break;
            case 4 : op_type = e_csg_classify; break;
            default : op_type = e_csg_intersection;
      }
      
      output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
      output->base = mesh1->base;

      if (output->m_descriptor.user_face_vertex_data_size) {
            // Then use the only interp function supported 
            success = 
            CSG_PerformBooleanOperation(
                  bool_op,
                  op_type,
                  mesh1->m_face_iterator,
                  mesh1->m_vertex_iterator,
                  mesh2->m_face_iterator,
                  mesh2->m_vertex_iterator,           
                  InterpFaceVertexData    
            );
      } else {
            success = 
            CSG_PerformBooleanOperation(
                  bool_op,
                  op_type,
                  mesh1->m_face_iterator,
                  mesh1->m_vertex_iterator,
                  mesh2->m_face_iterator,
                  mesh2->m_vertex_iterator,           
                  InterpNoUserData  
            );
      }

      if (!success) {
            CSG_FreeBooleanOperation(bool_op);
            bool_op = NULL;
            return 0;
      }
            
      // get the ouput mesh descriptors.

      CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
      CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
      output->m_destroy_func = CSG_DestroyCSGMeshInternals;

      return 1;
}

      int
NewBooleanMeshTest(
      struct Base * base,
      struct Base * base_select,
      int op_type
){

      CSG_MeshDescriptor m1,m2,output;
      CSG_MeshDescriptor output2,output3;
      
      if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
            return 0;
      }
      
      if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
            return 0;
      }
      
      CSG_PerformOp(&m1,&m2,1,&output);
      CSG_PerformOp(&m1,&m2,2,&output2);
      CSG_PerformOp(&m1,&m2,3,&output3);

      if (!CSG_AddMeshToBlender(&output)) {
            return 0;
      }
      if (!CSG_AddMeshToBlender(&output2)) {
            return 0;
      }
      if (!CSG_AddMeshToBlender(&output3)) {
            return 0;
      }

      
      CSG_DestroyMeshDescriptor(&m1);
      CSG_DestroyMeshDescriptor(&m2);
      CSG_DestroyMeshDescriptor(&output);
      CSG_DestroyMeshDescriptor(&output2);
      CSG_DestroyMeshDescriptor(&output3);

      return 1;
}


Generated by  Doxygen 1.6.0   Back to index