merge with/from trunk at r35190
[blender.git] / source / blender / modifiers / intern / MOD_mirror.c
index cf31e86a2f536a77040b6c6f03873abc62fdf3c0..2540a1e3b3b64a91a1aa791971484230a55655c8 100644 (file)
 *
 */
 
 *
 */
 
-/** \file blender/modifiers/intern/MOD_mirror.c
- *  \ingroup modifiers
- */
-
-
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
 #include "BLI_math.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
 #include "BLI_math.h"
-#include "BLI_utildefines.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_deform.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_deform.h"
-
+#include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "MEM_guardedalloc.h"
 #include "depsgraph_private.h"
 
 
 #include "MEM_guardedalloc.h"
 #include "depsgraph_private.h"
 
-#include "MOD_util.h"
-
 static void initData(ModifierData *md)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
 static void initData(ModifierData *md)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
@@ -69,7 +62,7 @@ static void copyData(ModifierData *md, ModifierData *target)
        tmmd->axis = mmd->axis;
        tmmd->flag = mmd->flag;
        tmmd->tolerance = mmd->tolerance;
        tmmd->axis = mmd->axis;
        tmmd->flag = mmd->flag;
        tmmd->tolerance = mmd->tolerance;
-       tmmd->mirror_ob = mmd->mirror_ob;
+       tmmd->mirror_ob = mmd->mirror_ob;;
 }
 
 static void foreachObjectLink(
 }
 
 static void foreachObjectLink(
@@ -78,14 +71,13 @@ static void foreachObjectLink(
                 void *userData)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
                 void *userData)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
-
-       walk(userData, ob, &mmd->mirror_ob);
+       
+       if (mmd->mirror_ob)
+               walk(userData, ob, &mmd->mirror_ob);
 }
 
 }
 
-static void updateDepgraph(ModifierData *md, DagForest *forest,
-                                               struct Scene *UNUSED(scene),
-                                               Object *UNUSED(ob),
-                                               DagNode *obNode)
+static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *scene,
+                                         Object *ob, DagNode *obNode)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
 
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
 
@@ -97,194 +89,108 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
        }
 }
 
        }
 }
 
-static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
+
+/* Mirror */
+#define VERT_NEW       1
+
+void vertgroup_flip_name (char *name, int strip_number);
+DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                Object *ob,
                DerivedMesh *dm,
                int initFlags,
                int axis)
 {
                Object *ob,
                DerivedMesh *dm,
                int initFlags,
                int axis)
 {
-       int i;
        float tolerance = mmd->tolerance;
        float tolerance = mmd->tolerance;
-       DerivedMesh *result;
-       int numVerts, numEdges, numFaces;
-       int maxVerts = dm->getNumVerts(dm);
-       int maxEdges = dm->getNumEdges(dm);
-       int maxFaces = dm->getNumFaces(dm);
-       int *flip_map= NULL;
-       int do_vgroup_mirr= (mmd->flag & MOD_MIR_VGROUP);
-       int (*indexMap)[2];
+       DerivedMesh *result, *cddm;
+       BMEditMesh *em;
+       BMesh *bm;
+       BMOIter siter1;
+       BMOperator op;
+       BMVert *v1;
+       BMIter iter;
+       bDeformGroup *def, *defb;
+       bDeformGroup **vector_def = NULL;
        float mtx[4][4], imtx[4][4];
        float mtx[4][4], imtx[4][4];
-
-       numVerts = numEdges = numFaces = 0;
-
-       indexMap = MEM_mallocN(sizeof(*indexMap) * maxVerts, "indexmap");
-
-       result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2);
-
-
-       if (do_vgroup_mirr) {
-               flip_map= defgroup_flip_map(ob, 0);
-               if(flip_map == NULL)
-                       do_vgroup_mirr= 0;
+       int j;
+       int vector_size=0, a, b;
+
+       cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
+       em = CDDM_To_BMesh(dm, NULL);
+
+       /*convienence variable*/
+       bm = em->bm;
+
+       if (mmd->flag & MOD_MIR_VGROUP) {
+               /* calculate the number of deformedGroups */
+               for(vector_size = 0, def = ob->defbase.first; def;
+                       def = def->next, vector_size++);
+
+               /* load the deformedGroups for fast access */
+               vector_def =
+                       (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size,
+                                                                                "group_index");
+               for(a = 0, def = ob->defbase.first; def; def = def->next, a++) {
+                       vector_def[a] = def;
+               }
        }
 
        if (mmd->mirror_ob) {
        }
 
        if (mmd->mirror_ob) {
-               float obinv[4][4];
-               
-               invert_m4_m4(obinv, mmd->mirror_ob->obmat);
-               mul_m4_m4m4(mtx, ob->obmat, obinv);
-               invert_m4_m4(imtx, mtx);
-       }
+               float mtx2[4][4];
 
 
-       for(i = 0; i < maxVerts; i++) {
-               MVert inMV;
-               MVert *mv = CDDM_get_vert(result, numVerts);
-               int isShared;
-               float co[3];
-               
-               dm->getVert(dm, i, &inMV);
-               
-               copy_v3_v3(co, inMV.co);
-               
-               if (mmd->mirror_ob) {
-                       mul_m4_v3(mtx, co);
-               }
-               
-               if(mmd->flag & MOD_MIR_NO_MERGE)
-                       isShared = 0;
-               else
-                       isShared = ABS(co[axis])<=tolerance;
-               
-               /* Because the topology result (# of vertices) must be the same if
-               * the mesh data is overridden by vertex cos, have to calc sharedness
-               * based on original coordinates. This is why we test before copy.
-               */
-               DM_copy_vert_data(dm, result, i, numVerts, 1);
-               *mv = inMV;
-               numVerts++;
-               
-               indexMap[i][0] = numVerts - 1;
-               indexMap[i][1] = !isShared;
-               //
-               if(isShared ) {
-                       co[axis] = 0;
-                       if (mmd->mirror_ob) {
-                               mul_m4_v3(imtx, co);
-                       }
-                       copy_v3_v3(mv->co, co);
-                       
-                       mv->flag |= ME_VERT_MERGED;
-               } else {
-                       MVert *mv2 = CDDM_get_vert(result, numVerts);
-                       
-                       DM_copy_vert_data(dm, result, i, numVerts, 1);
-                       *mv2 = *mv;
-                       
-                       co[axis] = -co[axis];
-                       if (mmd->mirror_ob) {
-                               mul_m4_v3(imtx, co);
-                       }
-                       copy_v3_v3(mv2->co, co);
-                       
-                       if (do_vgroup_mirr) {
-                               MDeformVert *dvert= DM_get_vert_data(result, numVerts, CD_MDEFORMVERT);
-                               if(dvert) {
-                                       defvert_flip(dvert, flip_map);
-                               }
-                       }
-
-                       numVerts++;
-               }
+               invert_m4_m4(mtx2, mmd->mirror_ob->obmat);
+               mul_m4_m4m4(mtx, ob->obmat, mtx2);
+       } else {
+               unit_m4(mtx);
        }
 
        }
 
-       for(i = 0; i < maxEdges; i++) {
-               MEdge inMED;
-               MEdge *med = CDDM_get_edge(result, numEdges);
-               
-               dm->getEdge(dm, i, &inMED);
-               
-               DM_copy_edge_data(dm, result, i, numEdges, 1);
-               *med = inMED;
-               numEdges++;
-               
-               med->v1 = indexMap[inMED.v1][0];
-               med->v2 = indexMap[inMED.v2][0];
-               if(initFlags)
-                       med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
-               
-               if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) {
-                       MEdge *med2 = CDDM_get_edge(result, numEdges);
-                       
-                       DM_copy_edge_data(dm, result, i, numEdges, 1);
-                       *med2 = *med;
-                       numEdges++;
-                       
-                       med2->v1 += indexMap[inMED.v1][1];
-                       med2->v2 += indexMap[inMED.v2][1];
-               }
-       }
+       BMO_InitOpf(bm, &op, "mirror geom=%avef mat=%m4 mergedist=%f axis=%d",
+                               mtx, mmd->tolerance, axis);
+
+       BMO_Exec_Op(bm, &op);
 
 
-       for(i = 0; i < maxFaces; i++) {
-               MFace inMF;
-               MFace *mf = CDDM_get_face(result, numFaces);
-               
-               dm->getFace(dm, i, &inMF);
-               
-               DM_copy_face_data(dm, result, i, numFaces, 1);
-               *mf = inMF;
-               numFaces++;
-               
-               mf->v1 = indexMap[inMF.v1][0];
-               mf->v2 = indexMap[inMF.v2][0];
-               mf->v3 = indexMap[inMF.v3][0];
-               mf->v4 = indexMap[inMF.v4][0];
-               
-               if(indexMap[inMF.v1][1]
-                                || indexMap[inMF.v2][1]
-                                || indexMap[inMF.v3][1]
-                                || (mf->v4 && indexMap[inMF.v4][1])) {
-                       MFace *mf2 = CDDM_get_face(result, numFaces);
-                       static int corner_indices[4] = {2, 1, 0, 3};
-                       
-                       DM_copy_face_data(dm, result, i, numFaces, 1);
-                       *mf2 = *mf;
-                       
-                       mf2->v1 += indexMap[inMF.v1][1];
-                       mf2->v2 += indexMap[inMF.v2][1];
-                       mf2->v3 += indexMap[inMF.v3][1];
-                       if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1];
-                       
-                       /* mirror UVs if enabled */
-                       if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) {
-                               MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE);
-                               if(tf) {
-                                       int j;
-                                       for(j = 0; j < 4; ++j) {
-                                               if(mmd->flag & MOD_MIR_MIRROR_U)
-                                                       tf->uv[j][0] = 1.0f - tf->uv[j][0];
-                                               if(mmd->flag & MOD_MIR_MIRROR_V)
-                                                       tf->uv[j][1] = 1.0f - tf->uv[j][1];
+       BMO_CallOpf(bm, "reversefaces faces=%s", &op, "newout");
+       
+       /*handle vgroup stuff*/
+       if (mmd->flag & MOD_MIR_VGROUP) {
+               BMO_ITER(v1, &siter1, bm, &op, "newout", BM_VERT) {
+                       MDeformVert *dvert = CustomData_bmesh_get(&bm->vdata, v1->head.data, CD_MDEFORMVERT);
+
+                       if (dvert) {
+                               for(j = 0; j < dvert[0].totweight; ++j) {
+                                       char tmpname[32];
+
+                                       if(dvert->dw[j].def_nr < 0 ||
+                                          dvert->dw[j].def_nr >= vector_size)
+                                               continue;
+
+                                       def = vector_def[dvert->dw[j].def_nr];
+                                       strcpy(tmpname, def->name);
+                                       vertgroup_flip_name(tmpname,0);
+
+                                       for(b = 0, defb = ob->defbase.first; defb;
+                                               defb = defb->next, b++)
+                                       {
+                                               if(!strcmp(defb->name, tmpname))
+                                               {
+                                                       dvert->dw[j].def_nr = b;
+                                                       break;
+                                               }
                                        }
                                }
                        }
                                        }
                                }
                        }
-                       
-                       /* Flip face normal */
-                       SWAP(int, mf2->v1, mf2->v3);
-                       DM_swap_face_data(result, numFaces, corner_indices);
-                       
-                       test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
-                       numFaces++;
                }
        }
 
                }
        }
 
-       if (flip_map) MEM_freeN(flip_map);
-
-       MEM_freeN(indexMap);
+       BMO_Finish_Op(bm, &op);
 
 
-       CDDM_lower_num_verts(result, numVerts);
-       CDDM_lower_num_edges(result, numEdges);
-       CDDM_lower_num_faces(result, numFaces);
+       if (vector_def) MEM_freeN(vector_def);
+       
+       BMEdit_RecalcTesselation(em);
+       result = CDDM_from_BMEditMesh(em, NULL);
 
 
+       BMEdit_Free(em);
+       MEM_freeN(em);
+       
        return result;
 }
 
        return result;
 }
 
@@ -312,10 +218,9 @@ static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
        return result;
 }
 
        return result;
 }
 
-static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
-                                               DerivedMesh *derivedData,
-                                               int UNUSED(useRenderParams),
-                                               int UNUSED(isFinalCalc))
+static DerivedMesh *applyModifier(
+               ModifierData *md, Object *ob, DerivedMesh *derivedData,
+  int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *result;
        MirrorModifierData *mmd = (MirrorModifierData*) md;
 {
        DerivedMesh *result;
        MirrorModifierData *mmd = (MirrorModifierData*) md;
@@ -328,9 +233,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
        return result;
 }
 
        return result;
 }
 
-static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
-                                               struct EditMesh *UNUSED(editData),
-                                               DerivedMesh *derivedData)
+static DerivedMesh *applyModifierEM(
+               ModifierData *md, Object *ob, struct BMEditMesh *editData,
+  DerivedMesh *derivedData)
 {
        return applyModifier(md, ob, derivedData, 0, 1);
 }
 {
        return applyModifier(md, ob, derivedData, 0, 1);
 }
@@ -349,8 +254,8 @@ ModifierTypeInfo modifierType_Mirror = {
 
        /* copyData */          copyData,
        /* deformVerts */       0,
 
        /* copyData */          copyData,
        /* deformVerts */       0,
-       /* deformMatrices */    0,
        /* deformVertsEM */     0,
        /* deformVertsEM */     0,
+       /* deformMatrices */    0,
        /* deformMatricesEM */  0,
        /* applyModifier */     applyModifier,
        /* applyModifierEM */   applyModifierEM,
        /* deformMatricesEM */  0,
        /* applyModifier */     applyModifier,
        /* applyModifierEM */   applyModifierEM,
@@ -360,7 +265,6 @@ ModifierTypeInfo modifierType_Mirror = {
        /* isDisabled */        0,
        /* updateDepgraph */    updateDepgraph,
        /* dependsOnTime */     0,
        /* isDisabled */        0,
        /* updateDepgraph */    updateDepgraph,
        /* dependsOnTime */     0,
-       /* dependsOnNormals */  0,
        /* foreachObjectLink */ foreachObjectLink,
        /* foreachIDLink */     0,
 };
        /* foreachObjectLink */ foreachObjectLink,
        /* foreachIDLink */     0,
 };