Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/booleanops.c')
-rw-r--r--source/blender/src/booleanops.c1361
1 files changed, 293 insertions, 1068 deletions
diff --git a/source/blender/src/booleanops.c b/source/blender/src/booleanops.c
index 8a2d6d4d7f9..11a3577ec0d 100644
--- a/source/blender/src/booleanops.c
+++ b/source/blender/src/booleanops.c
@@ -48,7 +48,6 @@
#include "BKE_booleanops.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -59,6 +58,8 @@
#include "BIF_toolbox.h"
+#include "BDR_editface.h"
+
#include <math.h>
// TODO check to see how many of these includes are necessary
@@ -68,32 +69,14 @@
#include "BLI_linklist.h"
#include "BLI_memarena.h"
-static void ConvertCSGDescriptorsToDLM(
- DispListMesh *dlm,
- Object *ob,
- CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4]);
-
-static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
- Object *ob, CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4]);
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/**
* Here's the vertex iterator structure used to walk through
* the blender vertex structure.
*/
typedef struct {
- Object *ob;
Mesh *mesh;
+ Object *ob;
int pos;
} VertexIt;
@@ -102,11 +85,8 @@ typedef struct {
* These describe a blender mesh to the CSG module.
*/
-static
- void
-VertexIt_Destruct(
- CSG_VertexIteratorDescriptor * iterator
-){
+static void VertexIt_Destruct(CSG_VertexIteratorDescriptor * iterator)
+{
if (iterator->it) {
// deallocate memory for iterator
MEM_freeN(iterator->it);
@@ -120,27 +100,20 @@ VertexIt_Destruct(
}
-static
- int
-VertexIt_Done(
- CSG_IteratorPtr it
-){
+static int VertexIt_Done(CSG_IteratorPtr it)
+{
VertexIt * iterator = (VertexIt *)it;
return(iterator->pos >= iterator->mesh->totvert);
}
-
-static
- void
-VertexIt_Fill(
- CSG_IteratorPtr it,
- CSG_IVertex *vert
-){
+static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert)
+{
VertexIt * iterator = (VertexIt *)it;
MVert *verts = iterator->mesh->mvert;
float global_pos[3];
+ /* boolean happens in global space, transform both with obmat */
VecMat4MulVecfl(
global_pos,
iterator->ob->obmat,
@@ -152,30 +125,20 @@ VertexIt_Fill(
vert->position[2] = global_pos[2];
}
-static
- void
-VertexIt_Step(
- CSG_IteratorPtr it
-){
+static void VertexIt_Step(CSG_IteratorPtr it)
+{
VertexIt * iterator = (VertexIt *)it;
iterator->pos ++;
}
-static
- void
-VertexIt_Reset(
- CSG_IteratorPtr it
-){
+static void VertexIt_Reset(CSG_IteratorPtr it)
+{
VertexIt * iterator = (VertexIt *)it;
iterator->pos = 0;
}
-static
- void
-VertexIt_Construct(
- CSG_VertexIteratorDescriptor * output,
- Object *ob
-){
+static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob)
+{
VertexIt *it;
if (output == 0) return;
@@ -205,17 +168,13 @@ VertexIt_Construct(
*/
typedef struct {
- Object *ob;
Mesh *mesh;
int pos;
+ int offset;
} FaceIt;
-
-static
- void
-FaceIt_Destruct(
- CSG_FaceIteratorDescriptor * iterator
-) {
+static void FaceIt_Destruct(CSG_FaceIteratorDescriptor * iterator)
+{
MEM_freeN(iterator->it);
iterator->Done = NULL;
iterator->Fill = NULL;
@@ -224,33 +183,20 @@ FaceIt_Destruct(
iterator->num_elements = 0;
}
-
-static
- int
-FaceIt_Done(
- CSG_IteratorPtr it
-) {
+static int FaceIt_Done(CSG_IteratorPtr it)
+{
// assume CSG_IteratorPtr is of the correct type.
FaceIt * iterator = (FaceIt *)it;
return(iterator->pos >= iterator->mesh->totface);
}
-static
- void
-FaceIt_Fill(
- CSG_IteratorPtr it,
- CSG_IFace *face
-){
+static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face)
+{
// assume CSG_IteratorPtr is of the correct type.
- FaceIt * face_it = (FaceIt *)it;
- Object *ob = face_it->ob;
+ FaceIt *face_it = (FaceIt *)it;
MFace *mfaces = face_it->mesh->mface;
- TFace *tfaces = face_it->mesh->tface;
- int f_index = face_it->pos;
- MFace *mface = &mfaces[f_index];
- FaceData *fdata = face->user_face_data;
-
- // ignore lines (faces with mface->v3==0)
+ MFace *mface = &mfaces[face_it->pos];
+
face->vertex_index[0] = mface->v1;
face->vertex_index[1] = mface->v2;
face->vertex_index[2] = mface->v3;
@@ -261,59 +207,24 @@ FaceIt_Fill(
face->vertex_number = 3;
}
- fdata->faceflag = mface->flag;
- fdata->material = give_current_material(ob, mface->mat_nr+1);
-
- // pack rgba colors.
- if (tfaces) {
- TFace *tface= &tfaces[f_index];
- int i;
-
- fdata->tpage = tface->tpage;
- fdata->flag = tface->flag;
- fdata->transp = tface->transp;
- fdata->mode = tface->mode;
- fdata->tile = tface->tile;
-
- for (i=0; i<4; i++) {
- FaceVertexData *fvdata= face->user_face_vertex_data[i];
-
- fvdata->uv[0] = tface->uv[i][0];
- fvdata->uv[1] = tface->uv[i][1];
- fvdata->color[0] = (float) ((tface->col[i] >> 24) & 0xff);
- fvdata->color[1] = (float) ((tface->col[i] >> 16) & 0xff);
- fvdata->color[2] = (float) ((tface->col[i] >> 8) & 0xff);
- fvdata->color[3] = (float) ((tface->col[i] >> 0) & 0xff);
- }
- }
+ face->orig_face = face_it->offset + face_it->pos;
}
-
-static
- void
-FaceIt_Step(
- CSG_IteratorPtr it
-) {
+static void FaceIt_Step(CSG_IteratorPtr it)
+{
FaceIt * face_it = (FaceIt *)it;
face_it->pos ++;
}
-static
- void
-FaceIt_Reset(
- CSG_IteratorPtr it
-) {
+static void FaceIt_Reset(CSG_IteratorPtr it)
+{
FaceIt * face_it = (FaceIt *)it;
face_it->pos = 0;
}
-static
- void
-FaceIt_Construct(
- CSG_FaceIteratorDescriptor * output,
- Object * ob
-){
-
+static void FaceIt_Construct(
+ CSG_FaceIteratorDescriptor *output, Object *ob, int offset)
+{
FaceIt *it;
if (output == 0) return;
@@ -323,8 +234,8 @@ FaceIt_Construct(
return ;
}
// assign blender specific variables
- it->ob = ob;
it->mesh = ob->data;
+ it->offset = offset;
it->pos = 0;
// assign iterator function pointers.
@@ -336,1032 +247,346 @@ FaceIt_Construct(
output->it = it;
}
-
-/**
- * Interpolation functions for various user data types.
- */
-
- int
-InterpNoUserData(
- void *d1,
- void *d2,
- void *dnew,
- float epsilon
-) {
- // nothing to do of course.
- return 0;
-}
-
- int
-InterpFaceVertexData(
- void *d1,
- void *d2,
- void *dnew,
- float epsilon
-) {
- /* XXX, passed backwards, should be fixed inside
- * BSP lib I guess.
- */
- FaceVertexData *fv1 = d2;
- FaceVertexData *fv2 = d1;
- FaceVertexData *fvO = dnew;
-
- fvO->uv[0] = (fv2->uv[0] - fv1->uv[0]) * epsilon + fv1->uv[0];
- fvO->uv[1] = (fv2->uv[1] - fv1->uv[1]) * epsilon + fv1->uv[1];
- fvO->color[0] = (fv2->color[0] - fv1->color[0]) * epsilon + fv1->color[0];
- fvO->color[1] = (fv2->color[1] - fv1->color[1]) * epsilon + fv1->color[1];
- fvO->color[2] = (fv2->color[2] - fv1->color[2]) * epsilon + fv1->color[2];
- fvO->color[3] = (fv2->color[3] - fv1->color[3]) * epsilon + fv1->color[3];
-
- return 0;
-}
-
-/**
- * Assumes mesh is valid and forms part of a fresh
- * blender object.
- */
-DispListMesh *NewBooleanMeshDLM(Object *ob, Object *ob_select, int int_op_type)
+static Object *AddNewBlenderMesh(Base *base)
{
- Mesh *me2 = get_mesh(ob_select);
- Mesh *me = get_mesh(ob);
- int free_tface1,free_tface2;
- DispListMesh *dlm = NULL;
-
- float inv_mat[4][4];
- int success = 0;
- // build and fill new descriptors for these meshes
- CSG_VertexIteratorDescriptor vd_1;
- CSG_VertexIteratorDescriptor vd_2;
- CSG_FaceIteratorDescriptor fd_1;
- CSG_FaceIteratorDescriptor fd_2;
-
- CSG_MeshPropertyDescriptor mpd1,mpd2;
-
- // work out the operation they chose and pick the appropriate
- // enum from the csg module.
-
- CSG_OperationType op_type;
-
- if (me == NULL || me2 == NULL) return 0;
-
- if(!me->totface || !me2->totface) return 0;
-
- success = 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;
- }
-
- // Here is the section where we describe the properties of
- // both meshes to the bsp module.
-
- if (me->mcol != NULL) {
- // Then this mesh has vertex colors only
- // well this is awkward because there is no equivalent
- // test_index_mface just for vertex colors!
- // as a temporary hack we can convert these vertex colors
- // into tfaces do the operation and turn them back again.
-
- // create some memory for the tfaces.
- me->tface = (TFace *)MEM_callocN(sizeof(TFace)*me->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me,1);
- free_tface1 = 1;
- } else {
- free_tface1 = 0;
- }
-
- mpd1.user_face_vertex_data_size = 0;
- mpd1.user_data_size = sizeof(FaceData);
-
- if (me->tface) {
- mpd1.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
-
- // same for mesh2
-
- if (me2->mcol != NULL) {
- // create some memory for the tfaces.
- me2->tface = (TFace *)MEM_callocN(sizeof(TFace)*me2->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me2,1);
- free_tface2 = 1;
- } else {
- free_tface2 = 0;
- }
+ // This little function adds a new mesh object to the blender object list
+ // It uses ob to duplicate data as this seems to be easier than creating
+ // a new one. This new oject contains no faces nor vertices.
+ Mesh *old_me;
+ Base *basen;
+ Object *ob_new;
- mpd2.user_face_vertex_data_size = 0;
- mpd2.user_data_size = sizeof(FaceData);
+ // now create a new blender object.
+ // duplicating all the settings from the previous object
+ // to the new one.
+ ob_new= copy_object(base->object);
- if (me2->tface) {
- mpd2.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
+ // Ok we don't want to use the actual data from the
+ // last object, the above function incremented the
+ // number of users, so decrement it here.
+ old_me= ob_new->data;
+ old_me->id.us--;
- // we map the final object back into object 1's (ob)
- // local coordinate space. For this we need to compute
- // the inverse transform from global to local.
+ // Now create a new base to add into the linked list of
+ // vase objects.
- Mat4Invert(inv_mat,ob_select->obmat);
-
- // make a boolean operation;
- {
- CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
- CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,mpd1,mpd2);
- // analyse the result and choose mesh descriptors accordingly
- int output_type;
- if (output_mpd.user_face_vertex_data_size) {
- output_type = 1;
- } else {
- output_type = 0;
- }
-
- BuildMeshDescriptors(
- ob,
- &fd_1,
- &vd_1
- );
- BuildMeshDescriptors(
- ob_select,
- &fd_2,
- &vd_2
- );
+ basen= MEM_mallocN(sizeof(Base), "duplibase");
+ *basen= *base;
+ BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */
+ basen->object= ob_new;
+ basen->flag &= ~SELECT;
+
+ // Initialize the mesh data associated with this object.
+ ob_new->data= add_mesh();
+ G.totmesh++;
- // perform the operation
+ // Finally assign the object type.
+ ob_new->type= OB_MESH;
- if (output_type == 0) {
-
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpNoUserData
- );
- } else {
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpFaceVertexData
- );
- }
+ return ob_new;
+}
- switch( success ) {
- case 1:
- {
- // descriptions of the output;
- CSG_VertexIteratorDescriptor vd_o;
- CSG_FaceIteratorDescriptor fd_o;
-
- dlm = MEM_callocN(sizeof(*dlm),"dlm");
+/* editmode function, will be replaced soon once custom face data arrives */
+void interp_uv_vcol(float *v1, float *v2, float *v3, float *v4, float *co,
+ TFace *tf, TFace *outtf, int j);
- CSG_OutputFaceDescriptor(bool_op,&fd_o);
- CSG_OutputVertexDescriptor(bool_op,&vd_o);
+static void ConvertCSGTFace(
+ DerivedMesh *dm, Mesh *orig_me, int index, int orig_index, int nr,
+ TFace *tface, TFace *orig_tface, float mapmat[][4])
+{
+ float obco[3], *co[4], *orig_co[4];
+ MFace *mface, *orig_mface;
+ int j;
- // iterate through results of operation and insert into new object
+ mface = CDDM_get_face(dm, index);
+ orig_mface = orig_me->mface + orig_index;
- ConvertCSGDescriptorsToDLM(
- dlm,
- NULL,
- &output_mpd,
- &fd_o,
- &vd_o,
- inv_mat
- );
+ *tface = *orig_tface;
- // free up the memory
+ // get the vertex coordinates from the original mesh
+ orig_co[0] = (orig_me->mvert + orig_mface->v1)->co;
+ orig_co[1] = (orig_me->mvert + orig_mface->v2)->co;
+ orig_co[2] = (orig_me->mvert + orig_mface->v3)->co;
+ orig_co[3] = (orig_mface->v4)? (orig_me->mvert + orig_mface->v4)->co: NULL;
- CSG_FreeVertexDescriptor(&vd_o);
- CSG_FreeFaceDescriptor(&fd_o);
- }
- break;
- case -1:
- error("Selected meshes must have faces to perform boolean operations");
- break;
- case -2:
- error("Both meshes must be closed");
- break;
- default:
- error("unknown internal error");
- break;
- }
+ // get the vertex coordinates from the new derivedmesh
+ co[0] = CDDM_get_vert(dm, mface->v1)->co;
+ co[1] = CDDM_get_vert(dm, mface->v2)->co;
+ co[2] = CDDM_get_vert(dm, mface->v3)->co;
+ co[3] = (nr == 4)? CDDM_get_vert(dm, mface->v4)->co: NULL;
- CSG_FreeBooleanOperation(bool_op);
- }
+ for (j = 0; j < nr; j++) {
+ // get coordinate into the space of the original mesh
+ if (mapmat)
+ VecMat4MulVecfl(obco, mapmat, co[j]);
+ else
+ VecCopyf(obco, co[j]);
- // We may need to map back the tfaces to mcols here.
- if (free_tface1) {
- tface_to_mcol(me);
- MEM_freeN(me->tface);
- me->tface = NULL;
+ interp_uv_vcol(orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco,
+ orig_tface, tface, j);
}
- if (free_tface2) {
- tface_to_mcol(me2);
- MEM_freeN(me2->tface);
- me2->tface = NULL;
- }
-
- if (free_tface1 && free_tface2) {
- // then we need to map the output tfaces into mcols
- if (dlm) {
- dlm->mcol = tface_to_mcol_p(dlm->tface, dlm->totface);
- MEM_freeN(dlm->tface);
- dlm->tface = NULL;
- }
- }
-
- FreeMeshDescriptors(&fd_1,&vd_1);
- FreeMeshDescriptors(&fd_2,&vd_2);
-
- return dlm;
}
-DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select,
- int int_op_type)
+/* Iterate over the CSG Output Descriptors and create a new DerivedMesh
+ from them */
+static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
+ CSG_FaceIteratorDescriptor *face_it,
+ CSG_VertexIteratorDescriptor *vertex_it,
+ float parinv[][4],
+ float mapmat[][4],
+ Material **mat,
+ int *totmat,
+ Object *ob1,
+ Object *ob2)
{
- Mesh *me2 = get_mesh(ob_select);
- Mesh *me = get_mesh(ob);
- int free_tface1, free_tface2;
- DerivedMesh *result;
-
- float inv_mat[4][4];
- int success = 0;
- // build and fill new descriptors for these meshes
- CSG_VertexIteratorDescriptor vd_1;
- CSG_VertexIteratorDescriptor vd_2;
- CSG_FaceIteratorDescriptor fd_1;
- CSG_FaceIteratorDescriptor fd_2;
-
- CSG_MeshPropertyDescriptor mpd1, mpd2;
-
- // work out the operation they chose and pick the appropriate
- // enum from the csg module.
-
- CSG_OperationType op_type;
+ DerivedMesh *dm;
+ GHash *material_hash = NULL;
+ Mesh *me1= (Mesh*)ob1->data;
+ Mesh *me2= (Mesh*)ob2->data;
+ int i;
- if(me == NULL || me2 == NULL) return 0;
+ // create a new DerivedMesh
+ dm = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
- if(!me->totface || !me2->totface) return 0;
+ // add tface layers
+ if (me1->mcol)
+ mcol_to_tface(me1, 1);
+ if (me2->mcol)
+ mcol_to_tface(me2, 1);
- success = 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;
- }
+ if (me1->tface || me2->tface)
+ DM_add_face_layer(dm, LAYERTYPE_TFACE, 0, NULL);
- // Here is the section where we describe the properties of
- // both meshes to the bsp module.
-
- if(me->mcol != NULL) {
- // Then this mesh has vertex colors only
- // well this is awkward because there is no equivalent
- // test_index_mface just for vertex colors!
- // as a temporary hack we can convert these vertex colors
- // into tfaces do the operation and turn them back again.
-
- // create some memory for the tfaces.
- me->tface = (TFace *)MEM_callocN(sizeof(TFace) * me->totface,
- "BooleanOps_TempTFace");
- mcol_to_tface(me, 1);
- free_tface1 = 1;
- } else {
- free_tface1 = 0;
- }
+ // step through the vertex iterators:
+ for (i = 0; !vertex_it->Done(vertex_it->it); i++) {
+ CSG_IVertex csgvert;
+ MVert *mvert = CDDM_get_vert(dm, i);
- mpd1.user_face_vertex_data_size = 0;
- mpd1.user_data_size = sizeof(FaceData);
+ // retrieve a csg vertex from the boolean module
+ vertex_it->Fill(vertex_it->it, &csgvert);
+ vertex_it->Step(vertex_it->it);
- if(me->tface) {
- mpd1.user_face_vertex_data_size = sizeof(FaceVertexData);
+ // we have to map the vertex coordinates back in the coordinate frame
+ // of the resulting object, since it was computed in world space
+ VecMat4MulVecfl(mvert->co, parinv, csgvert.position);
}
-
- // same for mesh2
- if(me2->mcol != NULL) {
- // create some memory for the tfaces.
- me2->tface = (TFace *)MEM_callocN(sizeof(TFace) * me2->totface,
- "BooleanOps_TempTFace");
- mcol_to_tface(me2, 1);
- free_tface2 = 1;
- } else {
- free_tface2 = 0;
+ // a hash table to remap materials to indices
+ if (mat) {
+ material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ *totmat = 0;
}
- mpd2.user_face_vertex_data_size = 0;
- mpd2.user_data_size = sizeof(FaceData);
-
- if(me2->tface) {
- mpd2.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
-
- // we map the final object back into object 1's (ob)
- // local coordinate space. For this we need to compute
- // the inverse transform from global to local.
-
- Mat4Invert(inv_mat, ob_select->obmat);
+ // step through the face iterators
+ for(i = 0; !face_it->Done(face_it->it); i++) {
+ Mesh *orig_me;
+ Object *orig_ob;
+ Material *orig_mat;
+ CSG_IFace csgface;
+ MFace *mface, *orig_mface;
+ TFace *tface, *orig_tface;
+ int orig_index, mat_nr;
- // make a boolean operation;
- {
- CSG_BooleanOperation *bool_op = CSG_NewBooleanFunction();
- CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,
- mpd1, mpd2);
- // analyse the result and choose mesh descriptors accordingly
- int output_type;
- if(output_mpd. user_face_vertex_data_size) {
- output_type = 1;
- } else {
- output_type = 0;
- }
-
- BuildMeshDescriptors(ob, &fd_1, &vd_1);
- BuildMeshDescriptors(ob_select, &fd_2, &vd_2);
-
- // perform the operation
+ // retrieve a csg face from the boolean module
+ face_it->Fill(face_it->it, &csgface);
+ face_it->Step(face_it->it);
- if(output_type == 0) {
- success = CSG_PerformBooleanOperation(bool_op, op_type,
- fd_1, vd_1, fd_2, vd_2,
- InterpNoUserData);
- } else {
- success = CSG_PerformBooleanOperation(bool_op, op_type,
- fd_1, vd_1, fd_2, vd_2,
- InterpFaceVertexData);
+ // find the original mesh and data
+ orig_me = (csgface.orig_face < me1->totface)? me1: me2;
+ orig_ob = (orig_me == me1)? ob1: ob2;
+ orig_index = (orig_me == me1)? csgface.orig_face: csgface.orig_face - me1->totface;
+ orig_mface = orig_me->mface + orig_index;
+ orig_mat= give_current_material(orig_ob, orig_mface->mat_nr+1);
+
+ // set mface
+ mface = CDDM_get_face(dm, i);
+ mface->v1 = csgface.vertex_index[0];
+ mface->v2 = csgface.vertex_index[1];
+ mface->v3 = csgface.vertex_index[2];
+ mface->v4 = (csgface.vertex_number == 4)? csgface.vertex_index[3]: 0;
+ mface->flag = orig_mface->flag;
+
+ // set material, based on lookup in hash table
+ if (mat && orig_mat) {
+ if (!BLI_ghash_haskey(material_hash, orig_mat)) {
+ mat[*totmat] = orig_mat;
+ mat_nr = mface->mat_nr = (*totmat)++;
+ BLI_ghash_insert(material_hash, orig_mat, (void*)mat_nr);
+ }
+ else
+ mface->mat_nr = (int)BLI_ghash_lookup(material_hash, orig_mat);
}
+ else
+ mface->mat_nr = 0;
- switch(success) {
- case 1:
- {
- // descriptions of the output;
- CSG_VertexIteratorDescriptor vd_o;
- CSG_FaceIteratorDescriptor fd_o;
-
- CSG_OutputFaceDescriptor(bool_op, &fd_o);
- CSG_OutputVertexDescriptor(bool_op, &vd_o);
-
- // iterate through results of operation and insert
- // into new object
-
- result = ConvertCSGDescriptorsToDerivedMesh(
- NULL, &output_mpd,
- &fd_o, &vd_o, inv_mat);
+ // set tface
+ if (me1->tface || me2->tface) {
+ tface = DM_get_face_data(dm, i, LAYERTYPE_TFACE);;
- // free up the memory
+ if (orig_me->tface) {
+ orig_tface = orig_me->tface + orig_index;
- CSG_FreeVertexDescriptor(&vd_o);
- CSG_FreeFaceDescriptor(&fd_o);
+ ConvertCSGTFace(dm, orig_me, i, orig_index,
+ csgface.vertex_number, tface, orig_tface,
+ (orig_me == me2)? mapmat: NULL);
}
- break;
- case -1:
- error("Selected meshes must have faces to perform "
- "boolean operations");
- break;
- case -2:
- error("Both meshes must be closed");
- break;
- default:
- error("unknown internal error");
- break;
+ else
+ default_tface(tface);
}
+ else
+ tface = NULL;
- CSG_FreeBooleanOperation(bool_op);
- }
-
- // We may need to map back the tfaces to mcols here.
- if(free_tface1) {
- tface_to_mcol(me);
- MEM_freeN(me->tface);
- me->tface = NULL;
+ test_index_face(mface, NULL, tface, csgface.vertex_number);
}
- if(free_tface2) {
- tface_to_mcol(me2);
- MEM_freeN(me2->tface);
- me2->tface = NULL;
- }
-
- if(free_tface1 && free_tface2) {
- // then we need to map the output tfaces into mcols
- if(result && DM_get_vert_data(result, 0, LAYERTYPE_TFACE)) {
- int i;
- int maxFaces = result->getNumFaces(result);
- if(!DM_get_vert_data(result, 0, LAYERTYPE_MCOL))
- DM_add_vert_layer(result, LAYERTYPE_MCOL, 0, NULL);
+ if (material_hash)
+ BLI_ghash_free(material_hash, NULL, NULL);
- for(i = 0; i < maxFaces; ++i) {
- MCol *mcol = DM_get_vert_data(result, i, LAYERTYPE_MCOL);
- TFace *tface = DM_get_vert_data(result, i, LAYERTYPE_TFACE);
-
- memcpy(mcol, tface->col, sizeof(*mcol) * 4);
- }
- }
- }
-
- FreeMeshDescriptors(&fd_1, &vd_1);
- FreeMeshDescriptors(&fd_2, &vd_2);
+ CDDM_calc_edges(dm);
+ CDDM_calc_normals(dm);
- return result;
+ return dm;
}
-
- int
-NewBooleanMesh(
- struct Base * base,
- struct Base * base_select,
- int int_op_type
-){
- Mesh *me2 = get_mesh(base_select->object);
- Mesh *me = get_mesh(base->object);
- Mesh *me_new = NULL;
- Object *ob, *ob_new = NULL;
- int free_tface1,free_tface2;
-
- float inv_mat[4][4];
- int success = 0;
- // build and fill new descriptors for these meshes
- CSG_VertexIteratorDescriptor vd_1;
- CSG_VertexIteratorDescriptor vd_2;
- CSG_FaceIteratorDescriptor fd_1;
- CSG_FaceIteratorDescriptor fd_2;
-
- CSG_MeshPropertyDescriptor mpd1,mpd2;
-
- // work out the operation they chose and pick the appropriate
- // enum from the csg module.
-
- CSG_OperationType op_type;
-
- if (me == NULL || me2 == NULL) return 0;
-
- if(!me->totface || !me2->totface) return -1;
- success = 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;
- }
-
- // Here is the section where we describe the properties of
- // both meshes to the bsp module.
-
- if (me->mcol != NULL) {
- // Then this mesh has vertex colors only
- // well this is awkward because there is no equivalent
- // test_index_mface just for vertex colors!
- // as a temporary hack we can convert these vertex colors
- // into tfaces do the operation and turn them back again.
-
- // create some memory for the tfaces.
- me->tface = (TFace *)MEM_callocN(sizeof(TFace)*me->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me,1);
- free_tface1 = 1;
- } else {
- free_tface1 = 0;
- }
-
- mpd1.user_face_vertex_data_size = 0;
- mpd1.user_data_size = sizeof(FaceData);
-
- if (me->tface) {
- mpd1.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
+static void BuildMeshDescriptors(
+ struct Object *ob,
+ int face_offset,
+ struct CSG_FaceIteratorDescriptor * face_it,
+ struct CSG_VertexIteratorDescriptor * vertex_it)
+{
+ VertexIt_Construct(vertex_it,ob);
+ FaceIt_Construct(face_it,ob,face_offset);
+}
- // same for mesh2
+static void FreeMeshDescriptors(
+ struct CSG_FaceIteratorDescriptor *face_it,
+ struct CSG_VertexIteratorDescriptor *vertex_it)
+{
+ VertexIt_Destruct(vertex_it);
+ FaceIt_Destruct(face_it);
+}
- if (me2->mcol != NULL) {
- // create some memory for the tfaces.
- me2->tface = (TFace *)MEM_callocN(sizeof(TFace)*me2->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me2,1);
- free_tface2 = 1;
- } else {
- free_tface2 = 0;
- }
+DerivedMesh *NewBooleanDerivedMesh_intern(
+ struct Object *ob, struct Object *ob_select,
+ int int_op_type, Material **mat, int *totmat)
+{
- mpd2.user_face_vertex_data_size = 0;
- mpd2.user_data_size = sizeof(FaceData);
+ float inv_mat[4][4];
+ float map_mat[4][4];
- if (me2->tface) {
- mpd2.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
+ DerivedMesh *dm = NULL;
+ Mesh *me1 = get_mesh(ob);
+ Mesh *me2 = get_mesh(ob_select);
- ob = base->object;
+ if (me1 == NULL || me2 == NULL) return 0;
+ if (!me1->totface || !me2->totface) return 0;
- // we map the final object back into object 1's (ob)
- // local coordinate space. For this we need to compute
- // the inverse transform from global to local.
-
- Mat4Invert(inv_mat,ob->obmat);
+ // we map the final object back into ob's local coordinate space. For this
+ // we need to compute the inverse transform from global to ob (inv_mat),
+ // and the transform from ob to ob_select for use in interpolation (map_mat)
+ Mat4Invert(inv_mat, ob_select->obmat);
+ Mat4MulMat4(map_mat, ob->obmat, inv_mat);
+ Mat4Invert(inv_mat, ob->obmat);
- // make a boolean operation;
{
- CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
- CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,mpd1,mpd2);
- // analyse the result and choose mesh descriptors accordingly
- int output_type;
- if (output_mpd.user_face_vertex_data_size) {
- output_type = 1;
- } else {
- output_type = 0;
+ // interface with the boolean module:
+ //
+ // the idea is, we pass the boolean module verts and faces using the
+ // provided descriptors. once the boolean operation is performed, we
+ // get back output descriptors, from which we then build a DerivedMesh
+
+ CSG_VertexIteratorDescriptor vd_1, vd_2;
+ CSG_FaceIteratorDescriptor fd_1, fd_2;
+ CSG_OperationType op_type;
+ CSG_BooleanOperation *bool_op;
+
+ // work out the operation they chose and pick the appropriate
+ // enum from the csg module.
+ 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;
}
- BuildMeshDescriptors(
- base->object,
- &fd_1,
- &vd_1
- );
- BuildMeshDescriptors(
- base_select->object,
- &fd_2,
- &vd_2
- );
+ BuildMeshDescriptors(ob, 0, &fd_1, &vd_1);
+ BuildMeshDescriptors(ob_select, me1->totface, &fd_2, &vd_2);
- // perform the operation
+ bool_op = CSG_NewBooleanFunction();
- if (output_type == 0) {
-
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpNoUserData
- );
- } else {
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpFaceVertexData
- );
- }
-
- if (success==1) {
- // descriptions of the output;
+ // perform the operation
+ if (CSG_PerformBooleanOperation(bool_op, op_type, fd_1, vd_1, fd_2, vd_2)) {
CSG_VertexIteratorDescriptor vd_o;
CSG_FaceIteratorDescriptor fd_o;
- DispListMesh dlm;
-
- // need to make sure its zeroed
- memset (&dlm, 0, sizeof (dlm));
-
- // Create a new blender mesh object - using 'base' as
- // a template for the new object.
- ob_new= AddNewBlenderMesh(base);
-
- // get the output descriptors
-
- CSG_OutputFaceDescriptor(bool_op,&fd_o);
- CSG_OutputVertexDescriptor(bool_op,&vd_o);
-
- me_new = ob_new->data;
- // iterate through results of operation and insert into new object
- // see subsurf.c
-
- ConvertCSGDescriptorsToDLM(
- &dlm,
- ob_new,
- &output_mpd,
- &fd_o,
- &vd_o,
- inv_mat
- );
-
- if (dlm.nors) MEM_freeN(dlm.nors);
-
- me_new->mvert = dlm.mvert;
- me_new->medge = dlm.medge;
- me_new->mface = dlm.mface;
- me_new->tface = dlm.tface;
- me_new->mcol = dlm.mcol;
- me_new->totvert = dlm.totvert;
- me_new->totedge = dlm.totedge;
- me_new->totface = dlm.totface;
- // free up the memory
+ CSG_OutputFaceDescriptor(bool_op, &fd_o);
+ CSG_OutputVertexDescriptor(bool_op, &vd_o);
+
+ // iterate through results of operation and insert
+ // into new object
+ dm = ConvertCSGDescriptorsToDerivedMesh(
+ &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob, ob_select);
+ // free up the memory
CSG_FreeVertexDescriptor(&vd_o);
CSG_FreeFaceDescriptor(&fd_o);
}
+ else
+ error("Unknown internal error in boolean");
CSG_FreeBooleanOperation(bool_op);
- bool_op = NULL;
-
- }
-
- // We may need to map back the tfaces to mcols here.
- if (free_tface1) {
- tface_to_mcol(me);
- MEM_freeN(me->tface);
- me->tface = NULL;
- }
- if (free_tface2) {
- tface_to_mcol(me2);
- MEM_freeN(me2->tface);
- me2->tface = NULL;
- }
-
- if (free_tface1 && free_tface2) {
- // then we need to map the output tfaces into mcols
- if (me_new) {
- tface_to_mcol(me_new);
- MEM_freeN(me_new->tface);
- me_new->tface = NULL;
- }
- }
-
- FreeMeshDescriptors(&fd_1,&vd_1);
- FreeMeshDescriptors(&fd_2,&vd_2);
- if (ob_new) {
- DAG_object_flush_update(G.scene, ob_new, OB_RECALC_DATA);
+ FreeMeshDescriptors(&fd_1, &vd_1);
+ FreeMeshDescriptors(&fd_2, &vd_2);
}
- return success;
+ return dm;
}
-
- Object *
-AddNewBlenderMesh(
- Base *base
-){
- Mesh *old_me;
- Base *basen;
- Object *ob_new;
-
- // now create a new blender object.
- // duplicating all the settings from the previous object
- // to the new one.
- ob_new= copy_object(base->object);
-
- // Ok we don't want to use the actual data from the
- // last object, the above function incremented the
- // number of users, so decrement it here.
- old_me= ob_new->data;
- old_me->id.us--;
-
- // Now create a new base to add into the linked list of
- // vase objects.
-
- basen= MEM_mallocN(sizeof(Base), "duplibase");
- *basen= *base;
- BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */
- basen->object= ob_new;
- basen->flag &= ~SELECT;
-
- // Initialize the mesh data associated with this object.
- ob_new->data= add_mesh();
- G.totmesh++;
-
- // Finally assign the object type.
- ob_new->type= OB_MESH;
-
- return ob_new;
-}
-
-/**
- *
- * External interface
- *
- * This function builds a blender mesh using the output information from
- * the CSG module. It declares all the necessary blender cruft and
- * fills in the vertex and face arrays.
- */
- static void
-ConvertCSGDescriptorsToDLM(
- DispListMesh *dlm,
- Object *ob,
- CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4]
-){
- FaceVertexData *user_face_vertex_data;
- GHash *material_hash;
- CSG_IVertex vert;
- CSG_IFace face;
- MVert *insert_pos;
- MFace *mfaces;
- TFace *tfaces;
- int fi_insert_pos, nmaterials;
-
- // create some memory for the Iface according to output mesh props.
-
- // initialize the face structure for readback
-
- face.user_face_data = MEM_callocN(sizeof(FaceData),"BooleanOp_IFaceData");
-
- if (props->user_face_vertex_data_size) {
- user_face_vertex_data = MEM_callocN(sizeof(FaceVertexData)*4,"BooleanOp_IFaceData");
- face.user_face_vertex_data[0] = &user_face_vertex_data[0];
- face.user_face_vertex_data[1] = &user_face_vertex_data[1];
- face.user_face_vertex_data[2] = &user_face_vertex_data[2];
- face.user_face_vertex_data[3] = &user_face_vertex_data[3];
- } else {
- user_face_vertex_data = NULL;
- }
-
- // create memory for the vertex array.
-
- dlm->mvert = MEM_callocN(sizeof(MVert) * vertex_it->num_elements,"BooleanOp_VertexArray");
- dlm->mface = MEM_callocN(sizeof(MFace) * face_it->num_elements,"BooleanOp_FaceArray");
-
- if (user_face_vertex_data) {
- dlm->tface = MEM_callocN(sizeof(TFace) * face_it->num_elements,"BooleanOp_TFaceArray");
- } else {
- dlm->tface = NULL;
- }
-
- insert_pos = dlm->mvert;
- mfaces = dlm->mface;
- tfaces = dlm->tface;
-
- fi_insert_pos = 0;
-
- // step through the iterators.
-
- while (!vertex_it->Done(vertex_it->it)) {
- vertex_it->Fill(vertex_it->it,&vert);
-
- // map output vertex into insert_pos
- // and transform at by parinv at the same time.
-
- VecMat4MulVecfl(
- insert_pos->co,
- parinv,
- vert.position
- );
- insert_pos ++;
- vertex_it->Step(vertex_it->it);
- }
-
- dlm->totvert = vertex_it->num_elements;
-
- // a hash table to remap materials to indices with
- material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- nmaterials = 0;
-
- while (!face_it->Done(face_it->it)) {
- MFace *mface = &mfaces[fi_insert_pos];
- FaceData *fdata;
-
- face_it->Fill(face_it->it,&face);
- fdata = face.user_face_data;
-
- // cheat CSG never dumps out quads.
-
- if (face.vertex_number>3) {
- // QUAD
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = face.vertex_index[3];
- }
- else {
- // TRIANGLE
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = 0;
- }
-
- mface->mat_nr = 0;
- mface->flag = fdata->faceflag;
-
- /* HACK, perform material to index mapping using a general
- * hash table, just tuck the int into a void *.
- */
-
- if (ob && !BLI_ghash_haskey(material_hash, fdata->material)) {
- int matnr = nmaterials++;
- BLI_ghash_insert(material_hash, fdata->material, (void*) matnr);
- assign_material(ob, fdata->material, matnr+1);
- }
- mface->mat_nr = (int) BLI_ghash_lookup(material_hash, fdata->material);
-
- // grab the vertex colors and texture cos and dump them into the tface.
-
- if (tfaces) {
- TFace *tface= &tfaces[fi_insert_pos];
- int i;
-
- // copy all the tface settings back
- tface->tpage = fdata->tpage;
- tface->flag = fdata->flag;
- tface->transp = fdata->transp;
- tface->mode = fdata->mode;
- tface->tile = fdata->tile;
-
- for (i=0; i<4; i++) {
- FaceVertexData *fvdata = face.user_face_vertex_data[i];
- float *color = fvdata->color;
-
- tface->uv[i][0] = fvdata->uv[0];
- tface->uv[i][1] = fvdata->uv[1];
- tface->col[i] =
- ((((unsigned int)floor(color[0] + 0.5f)) & 0xff) << 24) |
- ((((unsigned int)floor(color[1] + 0.5f)) & 0xff) << 16) |
- ((((unsigned int)floor(color[2] + 0.5f)) & 0xff) << 8) |
- ((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0);
- }
-
- test_index_face(mface, NULL, tface, face.vertex_number);
- } else {
- test_index_face(mface, NULL, NULL, face.vertex_number);
- }
-
- fi_insert_pos++;
- face_it->Step(face_it->it);
- }
-
- BLI_ghash_free(material_hash, NULL, NULL);
-
- dlm->totface = face_it->num_elements;
-
- displistmesh_add_edges(dlm);
-
- mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
-
- // thats it!
- if (user_face_vertex_data) {
- MEM_freeN(user_face_vertex_data);
- }
- MEM_freeN(face.user_face_data);
-}
-
-static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
- Object *ob, CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4])
+int NewBooleanMesh(Base *base, Base *base_select, int int_op_type)
{
- FaceVertexData *user_face_vertex_data;
- GHash *material_hash;
- CSG_IVertex vert;
- CSG_IFace face;
- DerivedMesh *result;
- int i;
-#if 0
- MFace *mfaces;
- TFace *tfaces;
-#endif
- int fi_insert_pos, nmaterials;
+ Mesh *me_new;
+ int a, maxmat, totmat= 0;
+ Object *ob_new, *ob, *ob_select;
+ Material **mat;
+ DerivedMesh *dm;
- // create some memory for the Iface according to output mesh props.
+ ob= base->object;
+ ob_select= base_select->object;
- // initialize the face structure for readback
-
- face.user_face_data = MEM_callocN(sizeof(FaceData),"BooleanOp_IFaceData");
+ maxmat= ob->totcol + ob_select->totcol;
+ mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat");
- if(props->user_face_vertex_data_size) {
- user_face_vertex_data = MEM_callocN(sizeof(FaceVertexData) * 4,
- "BooleanOp_IFaceData");
- face.user_face_vertex_data[0] = &user_face_vertex_data[0];
- face.user_face_vertex_data[1] = &user_face_vertex_data[1];
- face.user_face_vertex_data[2] = &user_face_vertex_data[2];
- face.user_face_vertex_data[3] = &user_face_vertex_data[3];
- } else {
- user_face_vertex_data = NULL;
- }
-
- // create memory for the vertex array.
-
- result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
-
- if(user_face_vertex_data)
- DM_add_face_layer(result, LAYERTYPE_TFACE, 0, NULL);
-
- // step through the iterators.
+ dm= NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, mat, &totmat);
- i = 0;
- while(!vertex_it->Done(vertex_it->it)) {
- MVert *insert_pos = CDDM_get_vert(result, i);
- vertex_it->Fill(vertex_it->it, &vert);
-
- // map output vertex into insert_pos
- // and transform at by parinv at the same time.
-
- VecMat4MulVecfl(insert_pos->co, parinv, vert.position);
-
- vertex_it->Step(vertex_it->it);
- i++;
+ if (dm == NULL) {
+ MEM_freeN(mat);
+ return 0;
}
- // a hash table to remap materials to indices with
- material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- nmaterials = 0;
+ /* create a new blender mesh object - using 'base' as a template */
+ ob_new= AddNewBlenderMesh(base);
+ me_new= ob_new->data;
- fi_insert_pos = 0;
- while(!face_it->Done(face_it->it)) {
- MFace *mface = CDDM_get_face(result, fi_insert_pos);
- FaceData *fdata;
-
- face_it->Fill(face_it->it, &face);
- fdata = face.user_face_data;
-
- // cheat CSG never dumps out quads.
-
- if(face.vertex_number>3) {
- // QUAD
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = face.vertex_index[3];
- } else {
- // TRIANGLE
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = 0;
- }
+ DM_to_mesh(dm, me_new);
+ dm->release(dm);
- mface->mat_nr = 0;
- mface->flag = fdata->faceflag;
-
- /* HACK, perform material to index mapping using a general
- * hash table, just tuck the int into a void *.
- */
-
- if(ob && !BLI_ghash_haskey(material_hash, fdata->material)) {
- int matnr = nmaterials++;
- BLI_ghash_insert(material_hash, fdata->material, (void*)matnr);
- assign_material(ob, fdata->material, matnr + 1);
- }
- mface->mat_nr = (int)BLI_ghash_lookup(material_hash, fdata->material);
-
- // grab the vertex colors and texture cos and dump them into the tface.
-
- if(user_face_vertex_data) {
- TFace *tface = DM_get_face_data(result, fi_insert_pos,
- LAYERTYPE_TFACE);
-
- // copy all the tface settings back
- tface->tpage = fdata->tpage;
- tface->flag = fdata->flag;
- tface->transp = fdata->transp;
- tface->mode = fdata->mode;
- tface->tile = fdata->tile;
-
- for(i = 0; i < 4; i++) {
- FaceVertexData *fvdata = face.user_face_vertex_data[i];
- float *color = fvdata->color;
-
- tface->uv[i][0] = fvdata->uv[0];
- tface->uv[i][1] = fvdata->uv[1];
- tface->col[i] =
- ((((unsigned int)floor(color[0] + 0.5f)) & 0xff) << 24)
- | ((((unsigned int)floor(color[1] + 0.5f)) & 0xff) << 16)
- | ((((unsigned int)floor(color[2] + 0.5f)) & 0xff) << 8)
- | ((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0);
- }
+ /* add materials to object */
+ for (a = 0; a < totmat; a++)
+ assign_material(ob_new, mat[a], a+1);
- test_index_face(mface, NULL, tface, face.vertex_number);
- } else {
- test_index_face(mface, NULL, NULL, face.vertex_number);
- }
-
- fi_insert_pos++;
- face_it->Step(face_it->it);
- }
-
- BLI_ghash_free(material_hash, NULL, NULL);
+ MEM_freeN(mat);
- CDDM_calc_edges(result);
+ /* update dag */
+ DAG_object_flush_update(G.scene, ob_new, OB_RECALC_DATA);
- CDDM_calc_normals(result);
-
- // thats it!
- if(user_face_vertex_data) MEM_freeN(user_face_vertex_data);
- MEM_freeN(face.user_face_data);
-
- return result;
-}
-
- void
-BuildMeshDescriptors(
- struct Object *ob,
- struct CSG_FaceIteratorDescriptor * face_it,
- struct CSG_VertexIteratorDescriptor * vertex_it
-){
- VertexIt_Construct(vertex_it,ob);
- FaceIt_Construct(face_it,ob);
+ return 1;
}
-
- void
-FreeMeshDescriptors(
- struct CSG_FaceIteratorDescriptor *face_it,
- struct CSG_VertexIteratorDescriptor *vertex_it
-){
- VertexIt_Destruct(vertex_it);
- FaceIt_Destruct(face_it);
+
+DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select,
+ int int_op_type)
+{
+ return NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, NULL, NULL);
}