Saturday morning first cup of coffee hack (yeah, its a late
authorDaniel Dunbar <daniel@zuster.org>
Sat, 3 Sep 2005 17:22:29 +0000 (17:22 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 3 Sep 2005 17:22:29 +0000 (17:22 +0000)
morning)

 - fun for the whole family, boolean mesh modifier... doesn't work
   with layered modifiers yet (just uses base mesh), although may
   god have mercy on your soul if you want to run boolean on a
   subsurf anyway
 - added displistmesh_add_edges

This exposes a bug in boolean, apparently the output is somehow
random (hash on alloc'd pointer value perhaps) which is sortof
lame.

It also makes more apparent the desire for some level of control
over dep graph evaluation during editmode (at the moment dep
graph is reevaluated for a mesh object in editmode, but since
mesh changes are on editmesh other objects don't really see
any change, so it is a wasted recalc).

source/blender/blenkernel/BKE_booleanops.h
source/blender/blenkernel/BKE_displist.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/booleanops.c
source/blender/src/booleanops_mesh.c
source/blender/src/buttons_editing.c

index c3dcb320b5bb5bf623a1e4c98202488b42a14540..f033dd7000328af84ffc5e6eec50a49a636c43b1 100644 (file)
@@ -55,6 +55,8 @@ NewBooleanMesh(
        int op_type
 );
 
+struct DispListMesh *NewBooleanMeshDLM(struct Object *ob, struct Object *ob_select, int int_op_type);
+
        
 /**
  * Functions exposed for use by BKE_booleanops_mesh
@@ -81,16 +83,6 @@ FreeMeshDescriptors(
        struct CSG_VertexIteratorDescriptor * vertex_it
 );
 
-extern
-       int
-ConvertCSGDescriptorsToMeshObject(
-       struct Object *ob,
-       struct CSG_MeshPropertyDescriptor * props,
-       struct CSG_FaceIteratorDescriptor * face_it,
-       struct CSG_VertexIteratorDescriptor * vertex_it,
-       float parinv[][4]
-);
-
 /**
  * This little function adds a new mesh object 
  * to the blender object list. It uses ob to duplicate
index 021b584036ffae6f9cfc9774b78d4f56d6994241..2dcf4bfe1be60d100da34b268204c20e2ad219b4 100644 (file)
@@ -151,6 +151,7 @@ void reshadeall_displist(void);
 void filldisplist(struct ListBase *dispbase, struct ListBase *to);
 
 void mesh_create_shadedColors(struct Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r);
+void displistmesh_add_edges(DispListMesh *dlm);
 
 #endif
 
index 90c5dec19b4ff127ce74c3894ce262d7e616d566..998f3fda59de69bce6390ba656fc9fee10feae90 100644 (file)
@@ -68,6 +68,7 @@ void set_mesh(struct Object *ob, struct Mesh *me);
 void mball_to_mesh(struct ListBase *lb, struct Mesh *me);
 void nurbs_to_mesh(struct Object *ob);
 void mcol_to_tface(struct Mesh *me, int freedata);
+struct MCol *tface_to_mcol_p(struct TFace *tface, int totface);
 void tface_to_mcol(struct Mesh *me);
 void free_dverts(struct MDeformVert *dvert, int totvert);
 void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
index 077060b7890807773fb6504665a4e42eeffd32ea..d18c205d82560e12e01ce7ca5a84a28a2cc25e83 100644 (file)
@@ -66,6 +66,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_editVert.h"
+#include "BLI_edgehash.h"
 
 #include "BKE_bad_level_calls.h"
 #include "BKE_utildefines.h"
@@ -2049,3 +2050,43 @@ static void boundbox_displist(Object *ob)
        }
 }
 
+void displistmesh_add_edges(DispListMesh *dlm)
+{
+       EdgeHash *eh = BLI_edgehash_new();
+       EdgeHashIterator *ehi;
+       int i;
+
+       for (i=0; i<dlm->totface; i++) {
+               MFace *mf = &dlm->mface[i];
+
+               if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
+                       BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
+               if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
+                       BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
+               
+               if (mf->v4) {
+                       if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
+                               BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
+                       if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
+                               BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
+               } else {
+                       if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
+                               BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+               }
+       }
+
+       dlm->totedge = BLI_edgehash_size(eh);
+       dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "medge");
+
+       ehi = BLI_edgehashIterator_new(eh);
+       for (i=0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+               MEdge *med = &dlm->medge[i++];
+
+               BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
+
+               med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+       }
+       BLI_edgehashIterator_free(ehi);
+
+       BLI_edgehash_free(eh, NULL);
+}
index 3e1e11c6950117f4629ab10ea53c510aaef6b039..fbd15267ead1b4a069156f867964898e701b0149 100644 (file)
@@ -952,22 +952,26 @@ void nurbs_to_mesh(Object *ob)
 
 }
 
-void tface_to_mcol(Mesh *me)
+MCol *tface_to_mcol_p(TFace *tface, int totface)
 {
-       TFace *tface;
-       unsigned int *mcol;
+       unsigned int *mcol, *mcoldata;
        int a;
        
-       me->mcol= MEM_mallocN(4*sizeof(int)*me->totface, "nepmcol");
-       mcol= (unsigned int *)me->mcol;
+       mcol= mcoldata= MEM_mallocN(4*sizeof(int)*totface, "nepmcol");
        
-       a= me->totface;
-       tface= me->tface;
+       a= totface;
        while(a--) {
                memcpy(mcol, tface->col, 16);
                mcol+= 4;
                tface++;
        }
+
+       return (MCol*) mcoldata;
+}
+
+void tface_to_mcol(Mesh *me)
+{
+       me->mcol = tface_to_mcol_p(me->tface, me->totface);
 }
 
 void mcol_to_tface(Mesh *me, int freedata)
index b937c4fb71df7dcb15cbb8870a6ce317e5e9c699..cc24f4200981e4d60de52060deb9948bea4630c4 100644 (file)
@@ -5,7 +5,6 @@
 #include "BLI_blenlib.h"
 #include "BLI_rand.h"
 #include "BLI_arithb.h"
-#include "BLI_edgehash.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -22,6 +21,7 @@
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_booleanops.h"
 #include "BKE_displist.h"
 #include "BKE_modifier.h"
 #include "BKE_lattice.h"
@@ -804,9 +804,6 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *
        dmd->faceCount = 0;
        if(LOD_LoadMesh(&lod) ) {
                if( LOD_PreprocessMesh(&lod) ) {
-                       EdgeHash *eh;
-                       EdgeHashIterator *ehi;
-
                        /* we assume the decim_faces tells how much to reduce */
 
                        while(lod.face_num > numTris*dmd->percent) {
@@ -826,7 +823,6 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *
                                VECCOPY(mv->co, vbCo);
                        }
 
-                       eh = BLI_edgehash_new();
                        for(a=0; a<lod.face_num; a++) {
                                MFace *mf = &ndlm->mface[a];
                                int *tri = &lod.triangle_index_buffer[a*3];
@@ -834,28 +830,9 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *
                                mf->v2 = tri[1];
                                mf->v3 = tri[2];
                                test_index_face(mface, NULL, NULL, 3);
-
-                               if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
-                                       BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
-                               if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
-                                       BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
-                               if (!BLI_edgehash_haskey(eh, mf->v1, mf->v3))
-                                       BLI_edgehash_insert(eh, mf->v1, mf->v3, NULL);
                        }
 
-                       ndlm->totedge = BLI_edgehash_size(eh);
-                       ndlm->medge = MEM_callocN(ndlm->totedge*sizeof(MEdge), "mdge");
-                       ehi = BLI_edgehashIterator_new(eh);
-                       for (a=0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
-                               MEdge *med = &ndlm->medge[a++];
-
-                               BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
-
-                               med->flag = ME_EDGEDRAW|ME_EDGERENDER;
-                       }
-                       BLI_edgehashIterator_free(ehi);
-
-                       BLI_edgehash_free(eh, NULL);
+                       displistmesh_add_edges(ndlm);
                }
                else {
                        modifier_setError(md, "Out of memory.");
@@ -1130,6 +1107,42 @@ static void softbodyModifier_deformVerts(ModifierData *md, Object *ob, void *der
        sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
 }
 
+/* Boolean */
+
+static int booleanModifier_isDisabled(ModifierData *md)
+{
+       BooleanModifierData *bmd = (BooleanModifierData*) md;
+
+       return !bmd->object;
+}
+
+static void booleanModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
+{
+       BooleanModifierData *bmd = (BooleanModifierData*) md;
+
+       walk(userData, ob, &bmd->object);
+}
+
+static void booleanModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
+{
+       BooleanModifierData *bmd = (BooleanModifierData*) md;
+
+       if (bmd->object) {
+               DagNode *curNode = dag_get_node(forest, bmd->object);
+
+               dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+       }
+}
+
+static void *booleanModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
+{      
+               // XXX doesn't handle derived data
+       BooleanModifierData *bmd = (BooleanModifierData*) md;
+       DispListMesh *dlm = NewBooleanMeshDLM(bmd->object, ob, 1+bmd->operation);
+
+       return derivedmesh_from_displistmesh(dlm, NULL);
+}
+
 /***/
 
 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -1248,6 +1261,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_RequiresOriginalData;
                mti->deformVerts = softbodyModifier_deformVerts;
 
+               mti = INIT_TYPE(Boolean);
+               mti->type = eModifierTypeType_Nonconstructive;
+               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->isDisabled = booleanModifier_isDisabled;
+               mti->applyModifier = booleanModifier_applyModifier;
+               mti->foreachObjectLink = booleanModifier_foreachObjectLink;
+               mti->updateDepgraph = booleanModifier_updateDepgraph;
+
                typeArrInit = 0;
 #undef INIT_TYPE
        }
index 78c5b9d8c766ce434c13b1a72993ae47a1de66cc..e858fa5aa967738e2e000246807239e91eed5c42 100644 (file)
@@ -17,6 +17,7 @@ typedef enum ModifierType {
        eModifierType_Armature,
        eModifierType_Hook,
        eModifierType_Softbody,
+       eModifierType_Boolean,
 
        NUM_MODIFIER_TYPES
 } ModifierType;
@@ -123,4 +124,16 @@ typedef struct SoftbodyModifierData {
        ModifierData modifier;
 } SoftbodyModifierData;
 
+typedef enum {
+       eBooleanModifierOp_Intersect,
+       eBooleanModifierOp_Union,
+       eBooleanModifierOp_Difference,
+} BooleanModifierOp;
+typedef struct BooleanModifierData {
+       ModifierData modifier;
+
+       struct Object *object;
+       int operation, pad;
+} BooleanModifierData;
+
 #endif
index 6a7a5ced25eedccc32e7caab1a8b012d4cdef7af..8b07527c585af9fd54a5605d18ea729b76437d46 100644 (file)
 #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]);
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -363,6 +370,193 @@ InterpFaceVertexData(
  * Assumes mesh is valid and forms part of a fresh
  * blender object.
  */
+DispListMesh *NewBooleanMeshDLM(Object *ob, Object *ob_select, int int_op_type)
+{
+       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;
+       }
+
+       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);
+
+       // 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
+
+               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) {
+                       // descriptions of the output;
+                       CSG_VertexIteratorDescriptor vd_o;
+                       CSG_FaceIteratorDescriptor fd_o;
+                       
+                       dlm = MEM_callocN(sizeof(*dlm),"dlm");
+
+                       CSG_OutputFaceDescriptor(bool_op,&fd_o);
+                       CSG_OutputVertexDescriptor(bool_op,&vd_o);
+
+                       // iterate through results of operation and insert into new object
+
+                       ConvertCSGDescriptorsToDLM(
+                               dlm,
+                               NULL,
+                               &output_mpd,
+                               &fd_o,
+                               &vd_o,
+                               inv_mat
+                       );
+
+                       // free up the memory
+
+                       CSG_FreeVertexDescriptor(&vd_o);
+                       CSG_FreeFaceDescriptor(&fd_o);
+               }
+
+               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 (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;
+}
 
        int
 NewBooleanMesh(
@@ -504,6 +698,7 @@ NewBooleanMesh(
                        // descriptions of the output;
                        CSG_VertexIteratorDescriptor vd_o;
                        CSG_FaceIteratorDescriptor fd_o;
+                       DispListMesh dlm;
 
                        // Create a new blender mesh object - using 'base' as 
                        // a template for the new object.
@@ -518,14 +713,27 @@ NewBooleanMesh(
                        // iterate through results of operation and insert into new object
                        // see subsurf.c 
 
-                       ConvertCSGDescriptorsToMeshObject(
-                               ob_new,
+                       ConvertCSGDescriptorsToDLM(
+                               &dlm,
+                               ob,
                                &output_mpd,
                                &fd_o,
                                &vd_o,
                                inv_mat
                        );
 
+                       if (dlm.nors) MEM_freeN(dlm.nors);
+
+                       me->mvert = dlm.mvert;
+                       me->medge = dlm.medge;
+                       me->mface = dlm.mface;
+                       me->tface = dlm.tface;
+                       me->mcol = dlm.mcol;
+                       me->totvert = dlm.totvert;
+                       me->totedge = dlm.totedge;
+                       me->totface = dlm.totface;
+
+
                        // free up the memory
 
                        CSG_FreeVertexDescriptor(&vd_o);
@@ -615,15 +823,15 @@ AddNewBlenderMesh(
  * the CSG module. It declares all the necessary blender cruft and 
  * fills in the vertex and face arrays.
  */
-       int
-ConvertCSGDescriptorsToMeshObject(
+       static void 
+ConvertCSGDescriptorsToDLM(
+       DispListMesh *dlm,
        Object *ob,
        CSG_MeshPropertyDescriptor *props,
        CSG_FaceIteratorDescriptor *face_it,
        CSG_VertexIteratorDescriptor *vertex_it,
        float parinv[][4]
 ){
-       Mesh *me = ob->data;
        FaceVertexData *user_face_vertex_data;
        GHash *material_hash;
        CSG_IVertex vert;
@@ -635,11 +843,6 @@ ConvertCSGDescriptorsToMeshObject(
 
        // create some memory for the Iface according to output mesh props.
 
-       if (face_it == NULL || vertex_it == NULL || props == NULL || me == NULL) {
-               return 0;
-       }
-       if (vertex_it->num_elements > MESH_MAX_VERTS) return 0;
-
        // initialize the face structure for readback
        
        face.user_face_data = MEM_callocN(sizeof(FaceData),"BooleanOp_IFaceData");
@@ -656,21 +859,18 @@ ConvertCSGDescriptorsToMeshObject(
        
        // create memory for the vertex array.
 
-       me->mvert = MEM_callocN(sizeof(MVert) * vertex_it->num_elements,"BooleanOp_VertexArray");
-       me->mface = MEM_callocN(sizeof(MFace) * face_it->num_elements,"BooleanOp_FaceArray");
+       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) {
-               me->tface = MEM_callocN(sizeof(TFace) * face_it->num_elements,"BooleanOp_TFaceArray");
-               if (me->tface == NULL) return 0;
+               dlm->tface = MEM_callocN(sizeof(TFace) * face_it->num_elements,"BooleanOp_TFaceArray");
        } else {
-               me->tface = NULL;
+               dlm->tface = NULL;
        }
 
-       if (me->mvert == NULL || me->mface == NULL) return 0;
-
-       insert_pos = me->mvert;
-       mfaces = me->mface;
-       tfaces = me->tface;
+       insert_pos = dlm->mvert;
+       mfaces = dlm->mface;
+       tfaces = dlm->tface;
 
        fi_insert_pos = 0;
 
@@ -691,7 +891,7 @@ ConvertCSGDescriptorsToMeshObject(
                vertex_it->Step(vertex_it->it);
        }
 
-       me->totvert = vertex_it->num_elements;
+       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);
@@ -717,7 +917,7 @@ ConvertCSGDescriptorsToMeshObject(
                 * hash table, just tuck the int into a void *.
                 */
                
-               if (!BLI_ghash_haskey(material_hash, fdata->material)) {
+               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);
@@ -761,17 +961,17 @@ ConvertCSGDescriptorsToMeshObject(
 
        BLI_ghash_free(material_hash, NULL, NULL);
 
-       me->totface = face_it->num_elements;
+       dlm->totface = face_it->num_elements;
 
-       mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+       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);
-
-       return 1;
 }      
        
        void
index 88f2cb98aac93c0a8fb6710627e36f1baa53fc0d..e2bdc51ecea7d30873ea24a80769ab412caf4e9a 100644 (file)
@@ -1,3 +1,5 @@
+#if 0
+
 /**
  * $Id$
  *
@@ -302,3 +304,5 @@ NewBooleanMeshTest(
        return 1;
 }
 
+
+#endif
\ No newline at end of file
index 3d0cac60147f87af958538a536bba1fe2182ee59..28a0319b27c2eacfbeb7a884cdfb110c3665aab6 100644 (file)
@@ -664,6 +664,23 @@ static void modifier_testCurveObj(char *name, ID **idpp)
        *idpp= 0;
 }
 
+static void modifier_testMeshObj(char *name, ID **idpp)
+{
+       ID *id;
+
+       for (id= G.main->object.first; id; id= id->next) {
+               if( strcmp(name, id->name+2)==0 ) {
+                       if (((Object *)id)->type != OB_MESH) {
+                               error ("Boolean modifier object must be a mesh");
+                               break;
+                       } 
+                       *idpp= id;
+                       return;
+               }
+       }
+       *idpp= 0;
+}
+
 static void modifier_testArmatureObj(char *name, ID **idpp)
 {
        ID *id;
@@ -979,6 +996,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                                height += 20;
                } else if (md->type==eModifierType_Softbody) {
                        height = 26;
+               } else if (md->type==eModifierType_Boolean) {
+                       height = 46;
                }
 
                                                        /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
@@ -1076,6 +1095,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                        }
                } else if (md->type==eModifierType_Softbody) {
                        uiDefBut(block, LABEL, 1, "See Softbody panel.",        lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+               } else if (md->type==eModifierType_Boolean) {
+                       BooleanModifierData *bmd = (BooleanModifierData*) md;
+                       uiDefButI(block, MENU, B_MODIFIER_RECALC, "Operation%t|Intersect%x0|Union%x1|Difference%x2",    lx,(cy-=19),buttonWidth,19, &bmd->operation, 0.0, 1.0, 0, 0, "Boolean operation to perform");
+                       uiDefIDPoinBut(block, modifier_testMeshObj, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
                }
                uiBlockEndAlign(block);