blender/intern/bsp/extern/CSG_BooleanOps.h
2011-02-25 10:44:20 +00:00

363 lines
10 KiB
C

/*
* $Id$
* ***** BEGIN GPL 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.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
*/
/** \file bsp/extern/CSG_BooleanOps.h
* \ingroup bsp
*/
#ifndef CSG_BOOLEANOPS_H
#define CSG_BOOLEANOPS_H
/**
* @section Interface structures for CSG module.
* This interface falls into 2 categories.
* The first section deals with an abstract mesh description
* between blender and this module. The second deals with
* the module functions.
* The CSG module needs to know about the following entities:
*/
/**
* CSG_IFace -- an interface polygon structure.
* vertex_index is a fixed size array of 4 elements containing indices into
* an abstract vertex container. 3 or 4 of these elements may be used to
* describe either quads or triangles.
* vertex_number is the number of vertices in this face - either 3 or 4.
* vertex_colors is an array of {r,g,b} triplets one for each vertex index.
* tex_coords is an array of {u,v} triplets one for each vertex index.
* user_data is a pointer to arbitary data of fixed width ,
* this data is copied around with the face, and duplicated if a face is
* split. Contains things like material index.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int vertex_index[4];
int vertex_number;
int orig_face;
} CSG_IFace;
/**
* CSG_IVertex -- an interface vertex structure.
* position is the location of the vertex in 3d space.
*/
typedef struct {
float position[3];
} CSG_IVertex;
/**
* The actual useful data contained in a group of faces is
* described by the following struct
*/
/**
* @section Iterator abstraction.
*
* The CSG module asks blender to fill in an instance of the above
* structure, and requests blender to move up and down (iterate) through
* it's face and vertex containers.
*
* An iterator supports the following functions.
* int IsDone(iterator *it) -- returns true if the iterator has reached
* the end of it's container.
*
* void Fill(iterator *it,DataType *data) -- Return the contents of the
* container at the current iterator position.
*
* void Step(iterator *it) -- increment the iterator to the next position
* in the container.
*
* The iterator is used in the following manner.
*
* MyIterator * iterator = ...
* DataType data;
*
* while (!IsDone(iterator)) {
* Fill(iterator,&data);
* //process information pointed to by data
* ...
* Step(iterator);
* }
*
* The CSG module does not want to know about the implementation of these
* functions so we use the c function ptr mechanism to hide them. Our
* iterator descriptor now looks like this.
*/
typedef void* CSG_IteratorPtr;
typedef int (*CSG_FaceItDoneFunc)(CSG_IteratorPtr it);
typedef void (*CSG_FaceItFillFunc)(CSG_IteratorPtr it,CSG_IFace *face);
typedef void (*CSG_FaceItStepFunc)(CSG_IteratorPtr it);
typedef void (*CSG_FaceItResetFunc)(CSG_IteratorPtr it);
typedef struct CSG_FaceIteratorDescriptor {
CSG_IteratorPtr it;
CSG_FaceItDoneFunc Done;
CSG_FaceItFillFunc Fill;
CSG_FaceItStepFunc Step;
CSG_FaceItResetFunc Reset;
unsigned int num_elements;
} CSG_FaceIteratorDescriptor;
/**
* Similarly to walk through the vertex arrays we have.
*/
typedef int (*CSG_VertexItDoneFunc)(CSG_IteratorPtr it);
typedef void (*CSG_VertexItFillFunc)(CSG_IteratorPtr it,CSG_IVertex *face);
typedef void (*CSG_VertexItStepFunc)(CSG_IteratorPtr it);
typedef void (*CSG_VertexItResetFunc)(CSG_IteratorPtr it);
typedef struct CSG_VertexIteratorDescriptor {
CSG_IteratorPtr it;
CSG_VertexItDoneFunc Done;
CSG_VertexItFillFunc Fill;
CSG_VertexItStepFunc Step;
CSG_VertexItResetFunc Reset;
unsigned int num_elements;
} CSG_VertexIteratorDescriptor;
/**
* The actual iterator structures are not exposed to the CSG module, they
* will contain datatypes specific to blender.
*/
/**
* @section CSG Module interface functions.
*
* The functions below are to be used in the following way:
*
* // Create a boolean operation handle
* CSG_BooleanOperation *operation = CSG_NewBooleanFunction();
* if (operation == NULL) {
* // deal with low memory exception
* }
*
* // Report to the user if they will loose any data!
* ...
*
* // Get some mesh iterators for your mesh data structures
* CSG_FaceIteratorDescriptor obA_faces = ...
* CSG_VertexIteratorDescriptor obA_verts = ...
*
* // same for object B
* CSG_FaceIteratorDescriptor obB_faces = ...
* CSG_VertexIteratorDescriptor obB_verts = ...
*
* // perform the operation...!
*
* int success = CSG_PerformBooleanOperation(
* operation,
* e_csg_intersection,
* obA_faces,
* obA_vertices,
* obB_faces,
* obB_vertices
* );
*
* // if the operation failes report miserable faiulre to user
* // and clear up data structures.
* if (!success) {
* ...
* CSG_FreeBooleanOperation(operation);
* return;
* }
*
* // read the new mesh vertices back from the module
* // and assign to your own mesh structure.
*
* // First we need to create a CSG_IVertex so the module can fill it in.
* CSG_IVertex vertex;
* CSG_VertexIteratorDescriptor * verts_it = CSG_OutputVertexDescriptor(operation);
*
* // initialize your vertex container with the number of verts (verts_it->num_elements)
*
* while (!verts_it->Done(verts_it->it)) {
* verts_it->Fill(verts_it->it,&vertex);
*
* // create a new vertex of your own type and add it
* // to your mesh structure.
* verts_it->Step(verts_it->it);
* }
* // Free the vertex iterator
* CSG_FreeVertexDescriptor(verts_it);
*
* // similarly for faces.
* CSG_IFace face;
*
* // you may need to reserve some memory in face->user_data here.
*
* // initialize your face container with the number of faces (faces_it->num_elements)
*
* CSG_FaceIteratorDescriptor * faces_it = CSG_OutputFaceDescriptor(operation);
*
* while (!faces_it->Done(faces_it->it)) {
* faces_it->Fill(faces_it->it,&face);
*
* // create a new face of your own type and add it
* // to your mesh structure.
* faces_it->Step(&faces_it->it);
* }
*
* // Free the face iterator
* CSG_FreeVertexDescriptor(faces_it);
*
* // that's it free the operation.
*
* CSG_FreeBooleanOperation(operation);
* return;
*
*/
/**
* Description of boolean operation type.
*/
typedef enum {
e_csg_union,
e_csg_intersection,
e_csg_difference,
e_csg_classify
} CSG_OperationType;
/**
* 'Handle' into the CSG module that identifies a particular CSG operation.
* the pointer CSG_info containers module specific data, and should not
* be touched in anyway outside of the module.
*/
typedef struct {
void *CSG_info;
} CSG_BooleanOperation;
/**
* Return a ptr to a CSG_BooleanOperation object allocated
* on the heap. The CSG module owns the memory associated with
* the returned ptr, use CSG_FreeBooleanOperation() to free this memory.
*/
CSG_BooleanOperation *
CSG_NewBooleanFunction(
void
);
/**
* Attempt to perform a boolean operation between the 2 objects of the
* desired type. This may fail due to an internal error or lack of memory.
* In this case 0 is returned, otehrwise 1 is returned indicating success.
* @param operation is a 'handle' into the CSG_Module created by CSG_NewBooleanFunction()
* @param op_type is the operation to perform.
* @param obAFaces is an iterator over the faces of objectA,
* @param obAVertices is an iterator over the vertices of objectA
* @param obAFaces is an iterator over the faces of objectB,
* @param obAVertices is an iterator over the vertices of objectB
* @param interp_func the face_vertex data interpolation function.(see above)
*
* All iterators must be valid and pointing to the first element in their
* respective containers.
*/
int
CSG_PerformBooleanOperation(
CSG_BooleanOperation * operation,
CSG_OperationType op_type,
CSG_FaceIteratorDescriptor obAFaces,
CSG_VertexIteratorDescriptor obAVertices,
CSG_FaceIteratorDescriptor obBFaces,
CSG_VertexIteratorDescriptor obBVertices
);
/**
* If the a boolean operation was successful, you may access the results
* through the following functions.
*
* CSG_OuputFaceDescriptor() returns a ptr to a CSG_FaceIteratorDesciptor
* allocated on the heap and owned by the CSG module. The iterator is
* positioned at the start of the internal face container.
* CSG_OutputVertexDescriptor() returns a ptr to a CSG_VertexIteratorDescriptor
* allocated on the heap and owned by the CSG module. The iterator is
* positioned at the start of the internal vertex container.
* There is no function to rewind an iterator but you may obtain more
* than one
* iterator at a time. Please use the function CSG_FreeFaceIterator()
* and CSG_FreeVertexIterator to free internal memory allocated for these
* iterators.
*
* If the last operation was not successful, these functions return NULL.
*/
int
CSG_OutputFaceDescriptor(
CSG_BooleanOperation * operation,
CSG_FaceIteratorDescriptor * output
);
int
CSG_OutputVertexDescriptor(
CSG_BooleanOperation * operation,
CSG_VertexIteratorDescriptor *output
);
/**
* Clean up functions.
* Free internal memory associated with CSG interface structures. You must
* call these functions on any structures created by the module, even if
* subsequent operations did not succeed.
*/
void
CSG_FreeVertexDescriptor(
CSG_VertexIteratorDescriptor * v_descriptor
);
void
CSG_FreeFaceDescriptor(
CSG_FaceIteratorDescriptor * f_descriptor
);
/**
* Free the memory associated with a boolean operation.
* NOTE any iterator descriptor describing the output will become
* invalid after this call and should be freed immediately.
*/
void
CSG_FreeBooleanOperation(
CSG_BooleanOperation *operation
);
#ifdef __cplusplus
}
#endif
#endif