converted more mixed tab/space indentations to tabs. only whitespace changes.
[blender.git] / source / blender / modifiers / intern / MOD_array.c
index 3a34b04..90954fe 100644 (file)
@@ -313,60 +313,60 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                else
                        /* if the offset has no translation, just make one copy */
                        count = 1;
-                 }
+       }
 
-                 if(count < 1)
-                         count = 1;
+       if(count < 1)
+               count = 1;
 
        /* allocate memory for count duplicates (including original) plus
                  * start and end caps
        */
-                 finalVerts = dm->getNumVerts(dm) * count;
-                 finalEdges = dm->getNumEdges(dm) * count;
-                 finalFaces = dm->getNumFaces(dm) * count;
-                 if(start_cap) {
-                         finalVerts += start_cap->getNumVerts(start_cap);
-                         finalEdges += start_cap->getNumEdges(start_cap);
-                         finalFaces += start_cap->getNumFaces(start_cap);
-                 }
-                 if(end_cap) {
-                         finalVerts += end_cap->getNumVerts(end_cap);
-                         finalEdges += end_cap->getNumEdges(end_cap);
-                         finalFaces += end_cap->getNumFaces(end_cap);
-                 }
-                 result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
-
-                 /* calculate the offset matrix of the final copy (for merging) */ 
-                 unit_m4(final_offset);
-
-                 for(j=0; j < count - 1; j++) {
-                         mul_m4_m4m4(tmp_mat, final_offset, offset);
-                         copy_m4_m4(final_offset, tmp_mat);
-                 }
-
-                 numVerts = numEdges = numFaces = 0;
-                 mvert = CDDM_get_verts(result);
-
-                 for (i = 0; i < maxVerts; i++) {
-                         indexMap[i].merge = -1; /* default to no merge */
-                         indexMap[i].merge_final = 0; /* default to no merge */
-                 }
-
-                 for (i = 0; i < maxVerts; i++) {
-                         MVert *inMV;
-                         MVert *mv = &mvert[numVerts];
-                         MVert *mv2;
-                         float co[3];
-
-                         inMV = &src_mvert[i];
-
-                         DM_copy_vert_data(dm, result, i, numVerts, 1);
-                         *mv = *inMV;
-                         numVerts++;
-
-                         indexMap[i].new = numVerts - 1;
-
-                         copy_v3_v3(co, mv->co);
+       finalVerts = dm->getNumVerts(dm) * count;
+       finalEdges = dm->getNumEdges(dm) * count;
+       finalFaces = dm->getNumFaces(dm) * count;
+       if(start_cap) {
+               finalVerts += start_cap->getNumVerts(start_cap);
+               finalEdges += start_cap->getNumEdges(start_cap);
+               finalFaces += start_cap->getNumFaces(start_cap);
+       }
+       if(end_cap) {
+               finalVerts += end_cap->getNumVerts(end_cap);
+               finalEdges += end_cap->getNumEdges(end_cap);
+               finalFaces += end_cap->getNumFaces(end_cap);
+       }
+       result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
+
+       /* calculate the offset matrix of the final copy (for merging) */
+       unit_m4(final_offset);
+
+       for(j=0; j < count - 1; j++) {
+               mul_m4_m4m4(tmp_mat, final_offset, offset);
+               copy_m4_m4(final_offset, tmp_mat);
+       }
+
+       numVerts = numEdges = numFaces = 0;
+       mvert = CDDM_get_verts(result);
+
+       for (i = 0; i < maxVerts; i++) {
+               indexMap[i].merge = -1; /* default to no merge */
+               indexMap[i].merge_final = 0; /* default to no merge */
+       }
+
+       for (i = 0; i < maxVerts; i++) {
+               MVert *inMV;
+               MVert *mv = &mvert[numVerts];
+               MVert *mv2;
+               float co[3];
+
+               inMV = &src_mvert[i];
+
+               DM_copy_vert_data(dm, result, i, numVerts, 1);
+               *mv = *inMV;
+               numVerts++;
+
+               indexMap[i].new = numVerts - 1;
+
+               copy_v3_v3(co, mv->co);
                
                /* Attempts to merge verts from one duplicate with verts from the
                          * next duplicate which are closer than amd->merge_dist.
@@ -374,405 +374,405 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                          * If verts are merged in the first duplicate pair, they are merged
                          * in all pairs.
                */
-                         if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
-                                 float tmp_co[3];
-                                 mul_v3_m4v3(tmp_co, offset, mv->co);
-
-                                 for(j = 0; j < maxVerts; j++) {
-                                         /* if vertex already merged, don't use it */
-                                         if( indexMap[j].merge != -1 ) continue;
-
-                                         inMV = &src_mvert[j];
-                                         /* if this vert is within merge limit, merge */
-                                         if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) {
-                                                 indexMap[i].merge = j;
-
-                                                 /* test for merging with final copy of merge target */
-                                                 if(amd->flags & MOD_ARR_MERGEFINAL) {
-                                                         copy_v3_v3(tmp_co, inMV->co);
-                                                         inMV = &src_mvert[i];
-                                                         mul_m4_v3(final_offset, tmp_co);
-                                                         if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist))
-                                                                 indexMap[i].merge_final = 1;
-                                                 }
-                                                 break;
-                                         }
-                                 }
-                         }
-
-                         /* if no merging, generate copies of this vert */
-                         if(indexMap[i].merge < 0) {
-                                 for(j=0; j < count - 1; j++) {
-                                         mv2 = &mvert[numVerts];
-
-                                         DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1);
-                                         *mv2 = *mv;
-                                         numVerts++;
-
-                                         mul_m4_v3(offset, co);
-                                         copy_v3_v3(mv2->co, co);
-                                 }
-                         } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
+               if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
+                       float tmp_co[3];
+                       mul_v3_m4v3(tmp_co, offset, mv->co);
+
+                       for(j = 0; j < maxVerts; j++) {
+                               /* if vertex already merged, don't use it */
+                               if( indexMap[j].merge != -1 ) continue;
+
+                               inMV = &src_mvert[j];
+                               /* if this vert is within merge limit, merge */
+                               if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) {
+                                       indexMap[i].merge = j;
+
+                                       /* test for merging with final copy of merge target */
+                                       if(amd->flags & MOD_ARR_MERGEFINAL) {
+                                               copy_v3_v3(tmp_co, inMV->co);
+                                               inMV = &src_mvert[i];
+                                               mul_m4_v3(final_offset, tmp_co);
+                                               if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist))
+                                                       indexMap[i].merge_final = 1;
+                                       }
+                                       break;
+                               }
+                       }
+               }
+
+               /* if no merging, generate copies of this vert */
+               if(indexMap[i].merge < 0) {
+                       for(j=0; j < count - 1; j++) {
+                               mv2 = &mvert[numVerts];
+
+                               DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1);
+                               *mv2 = *mv;
+                               numVerts++;
+
+                               mul_m4_v3(offset, co);
+                               copy_v3_v3(mv2->co, co);
+                       }
+               } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
                        /* if this vert is not merging with itself, and it is merging
                                  * with the final copy of its merge target, remove the first copy
                        */
-                                 numVerts--;
-                                 DM_free_vert_data(result, numVerts, 1);
-                         }
-                 }
+                       numVerts--;
+                       DM_free_vert_data(result, numVerts, 1);
+               }
+       }
 
-                 /* make a hashtable so we can avoid duplicate edges from merging */
-                 edges = BLI_edgehash_new();
+       /* make a hashtable so we can avoid duplicate edges from merging */
+       edges = BLI_edgehash_new();
 
-                 maxEdges = dm->getNumEdges(dm);
-                 medge = CDDM_get_edges(result);
-                 for(i = 0; i < maxEdges; i++) {
-                         MEdge inMED;
-                         MEdge med;
-                         MEdge *med2;
-                         int vert1, vert2;
+       maxEdges = dm->getNumEdges(dm);
+       medge = CDDM_get_edges(result);
+       for(i = 0; i < maxEdges; i++) {
+               MEdge inMED;
+               MEdge med;
+               MEdge *med2;
+               int vert1, vert2;
 
-                         dm->getEdge(dm, i, &inMED);
+               dm->getEdge(dm, i, &inMED);
 
-                         med = inMED;
-                         med.v1 = indexMap[inMED.v1].new;
-                         med.v2 = indexMap[inMED.v2].new;
+               med = inMED;
+               med.v1 = indexMap[inMED.v1].new;
+               med.v2 = indexMap[inMED.v2].new;
 
                /* if vertices are to be merged with the final copies of their
                          * merge targets, calculate that final copy
                */
-                         if(indexMap[inMED.v1].merge_final) {
-                                 med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge,
-                                                 count - 1);
-                         }
-                         if(indexMap[inMED.v2].merge_final) {
-                                 med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge,
-                                                 count - 1);
-                         }
-
-                         if(med.v1 == med.v2) continue;
-                         
-                         /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */
-                         if(med.v1 >= numVerts)
-                                 med.v1= numVerts-1;
-                         if(med.v2 >= numVerts)
-                                 med.v2= numVerts-1;
-                         
-                         if (initFlags) {
-                                 med.flag |= ME_EDGEDRAW | ME_EDGERENDER;
-                         }
-
-                         if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) {
-                                 DM_copy_edge_data(dm, result, i, numEdges, 1);
-                                 medge[numEdges] = med;
-                                 numEdges++;
-
-                                 BLI_edgehash_insert(edges, med.v1, med.v2, NULL);
-                         }
-
-                         for(j = 1; j < count; j++)
-                         {
-                                 vert1 = calc_mapping(indexMap, inMED.v1, j);
-                                 vert2 = calc_mapping(indexMap, inMED.v2, j);
-                                 
-                                 /* edge could collapse to single point after mapping */
-                                 if(vert1 == vert2) continue;
-                                 
-                                 /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */
-                                 if(vert1 >= numVerts)
-                                         vert1= numVerts-1;
-                                 if(vert2 >= numVerts)
-                                         vert2= numVerts-1;
-
-                                 /* avoid duplicate edges */
-                                 if(!BLI_edgehash_haskey(edges, vert1, vert2)) {
-                                         med2 = &medge[numEdges];
-
-                                         DM_copy_edge_data(dm, result, i, numEdges, 1);
-                                         *med2 = med;
-                                         numEdges++;
-
-                                         med2->v1 = vert1;
-                                         med2->v2 = vert2;
-
-                                         BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL);
-                                 }
-                         }
-                 }
-
-                 maxFaces = dm->getNumFaces(dm);
-                 mface = CDDM_get_faces(result);
-                 for (i=0; i < maxFaces; i++) {
-                         MFace inMF;
-                         MFace *mf = &mface[numFaces];
-
-                         dm->getFace(dm, i, &inMF);
-
-                         DM_copy_face_data(dm, result, i, numFaces, 1);
-                         *mf = inMF;
-
-                         mf->v1 = indexMap[inMF.v1].new;
-                         mf->v2 = indexMap[inMF.v2].new;
-                         mf->v3 = indexMap[inMF.v3].new;
-                         if(inMF.v4)
-                                 mf->v4 = indexMap[inMF.v4].new;
+               if(indexMap[inMED.v1].merge_final) {
+                       med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge,
+                       count - 1);
+               }
+               if(indexMap[inMED.v2].merge_final) {
+                       med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge,
+                       count - 1);
+               }
+
+               if(med.v1 == med.v2) continue;
+
+               /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */
+               if(med.v1 >= numVerts)
+                       med.v1= numVerts-1;
+               if(med.v2 >= numVerts)
+                       med.v2= numVerts-1;
+
+               if (initFlags) {
+                       med.flag |= ME_EDGEDRAW | ME_EDGERENDER;
+               }
+
+               if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) {
+                       DM_copy_edge_data(dm, result, i, numEdges, 1);
+                       medge[numEdges] = med;
+                       numEdges++;
+
+                       BLI_edgehash_insert(edges, med.v1, med.v2, NULL);
+               }
+
+               for(j = 1; j < count; j++)
+               {
+                       vert1 = calc_mapping(indexMap, inMED.v1, j);
+                       vert2 = calc_mapping(indexMap, inMED.v2, j);
+
+                       /* edge could collapse to single point after mapping */
+                       if(vert1 == vert2) continue;
+
+                       /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */
+                       if(vert1 >= numVerts)
+                               vert1= numVerts-1;
+                       if(vert2 >= numVerts)
+                               vert2= numVerts-1;
+
+                       /* avoid duplicate edges */
+                       if(!BLI_edgehash_haskey(edges, vert1, vert2)) {
+                               med2 = &medge[numEdges];
+
+                               DM_copy_edge_data(dm, result, i, numEdges, 1);
+                               *med2 = med;
+                               numEdges++;
+
+                               med2->v1 = vert1;
+                               med2->v2 = vert2;
+
+                               BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL);
+                       }
+               }
+       }
+
+       maxFaces = dm->getNumFaces(dm);
+       mface = CDDM_get_faces(result);
+       for (i=0; i < maxFaces; i++) {
+               MFace inMF;
+               MFace *mf = &mface[numFaces];
+
+               dm->getFace(dm, i, &inMF);
+
+               DM_copy_face_data(dm, result, i, numFaces, 1);
+               *mf = inMF;
+
+               mf->v1 = indexMap[inMF.v1].new;
+               mf->v2 = indexMap[inMF.v2].new;
+               mf->v3 = indexMap[inMF.v3].new;
+               if(inMF.v4)
+                       mf->v4 = indexMap[inMF.v4].new;
 
                /* if vertices are to be merged with the final copies of their
                          * merge targets, calculate that final copy
                */
-                         if(indexMap[inMF.v1].merge_final)
-                                 mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1);
-                         if(indexMap[inMF.v2].merge_final)
-                                 mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1);
-                         if(indexMap[inMF.v3].merge_final)
-                                 mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1);
-                         if(inMF.v4 && indexMap[inMF.v4].merge_final)
-                                 mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1);
-
-                         if(test_index_face_maxvert(mf, &result->faceData, numFaces, inMF.v4?4:3, numVerts) < 3)
-                                 continue;
-
-                         numFaces++;
-
-                         /* if the face has fewer than 3 vertices, don't create it */
-                         if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) {
-                                 numFaces--;
-                                 DM_free_face_data(result, numFaces, 1);
-                         }
-
-                         for(j = 1; j < count; j++)
-                         {
-                                 MFace *mf2 = &mface[numFaces];
-
-                                 DM_copy_face_data(dm, result, i, numFaces, 1);
-                                 *mf2 = *mf;
-
-                                 mf2->v1 = calc_mapping(indexMap, inMF.v1, j);
-                                 mf2->v2 = calc_mapping(indexMap, inMF.v2, j);
-                                 mf2->v3 = calc_mapping(indexMap, inMF.v3, j);
-                                 if (inMF.v4)
-                                         mf2->v4 = calc_mapping(indexMap, inMF.v4, j);
-
-                                 numFaces++;
-
-                                 /* if the face has fewer than 3 vertices, don't create it */
-                                 if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) {
-                                         numFaces--;
-                                         DM_free_face_data(result, numFaces, 1);
-                                                                }
-                         }
-                 }
-
-                 /* add start and end caps */
-                 if(start_cap) {
-                         float startoffset[4][4];
-                         MVert *cap_mvert;
-                         MEdge *cap_medge;
-                         MFace *cap_mface;
-                         int *origindex;
-                         int *vert_map;
-                         int capVerts, capEdges, capFaces;
-
-                         capVerts = start_cap->getNumVerts(start_cap);
-                         capEdges = start_cap->getNumEdges(start_cap);
-                         capFaces = start_cap->getNumFaces(start_cap);
-                         cap_mvert = start_cap->getVertArray(start_cap);
-                         cap_medge = start_cap->getEdgeArray(start_cap);
-                         cap_mface = start_cap->getFaceArray(start_cap);
-
-                         invert_m4_m4(startoffset, offset);
-
-                         vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
-                                         "arrayModifier_doArray vert_map");
-
-                         origindex = result->getVertDataArray(result, CD_ORIGINDEX);
-                         for(i = 0; i < capVerts; i++) {
-                                 MVert *mv = &cap_mvert[i];
-                                 short merged = 0;
-
-                                 if(amd->flags & MOD_ARR_MERGE) {
-                                         float tmp_co[3];
-                                         MVert *in_mv;
-                                         int j;
-
-                                         copy_v3_v3(tmp_co, mv->co);
-                                         mul_m4_v3(startoffset, tmp_co);
-
-                                         for(j = 0; j < maxVerts; j++) {
-                                                 in_mv = &src_mvert[j];
-                                                 /* if this vert is within merge limit, merge */
-                                                 if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
-                                                         vert_map[i] = calc_mapping(indexMap, j, 0);
-                                                         merged = 1;
-                                                         break;
-                                                 }
-                                         }
-                                 }
-
-                                 if(!merged) {
-                                         DM_copy_vert_data(start_cap, result, i, numVerts, 1);
-                                         mvert[numVerts] = *mv;
-                                         mul_m4_v3(startoffset, mvert[numVerts].co);
-                                         origindex[numVerts] = ORIGINDEX_NONE;
-
-                                         vert_map[i] = numVerts;
-
-                                         numVerts++;
-                                 }
-                         }
-                         origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
-                         for(i = 0; i < capEdges; i++) {
-                                 int v1, v2;
-
-                                 v1 = vert_map[cap_medge[i].v1];
-                                 v2 = vert_map[cap_medge[i].v2];
-
-                                 if(!BLI_edgehash_haskey(edges, v1, v2)) {
-                                         DM_copy_edge_data(start_cap, result, i, numEdges, 1);
-                                         medge[numEdges] = cap_medge[i];
-                                         medge[numEdges].v1 = v1;
-                                         medge[numEdges].v2 = v2;
-                                         origindex[numEdges] = ORIGINDEX_NONE;
-
-                                         numEdges++;
-                                 }
-                         }
-                         origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
-                         for(i = 0; i < capFaces; i++) {
-                                 DM_copy_face_data(start_cap, result, i, numFaces, 1);
-                                 mface[numFaces] = cap_mface[i];
-                                 mface[numFaces].v1 = vert_map[mface[numFaces].v1];
-                                 mface[numFaces].v2 = vert_map[mface[numFaces].v2];
-                                 mface[numFaces].v3 = vert_map[mface[numFaces].v3];
-                                 if(mface[numFaces].v4) {
-                                         mface[numFaces].v4 = vert_map[mface[numFaces].v4];
-
-                                         test_index_face_maxvert(&mface[numFaces], &result->faceData,
-                                                                         numFaces, 4, numVerts);
-                                 }
-                                 else
-                                 {
-                                         test_index_face(&mface[numFaces], &result->faceData,
-                                                                         numFaces, 3);
-                                 }
-
-                                 origindex[numFaces] = ORIGINDEX_NONE;
-
-                                 numFaces++;
-                         }
-
-                         MEM_freeN(vert_map);
-                         start_cap->release(start_cap);
-                 }
-
-                 if(end_cap) {
-                         float endoffset[4][4];
-                         MVert *cap_mvert;
-                         MEdge *cap_medge;
-                         MFace *cap_mface;
-                         int *origindex;
-                         int *vert_map;
-                         int capVerts, capEdges, capFaces;
-
-                         capVerts = end_cap->getNumVerts(end_cap);
-                         capEdges = end_cap->getNumEdges(end_cap);
-                         capFaces = end_cap->getNumFaces(end_cap);
-                         cap_mvert = end_cap->getVertArray(end_cap);
-                         cap_medge = end_cap->getEdgeArray(end_cap);
-                         cap_mface = end_cap->getFaceArray(end_cap);
-
-                         mul_m4_m4m4(endoffset, final_offset, offset);
-
-                         vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
-                                         "arrayModifier_doArray vert_map");
-
-                         origindex = result->getVertDataArray(result, CD_ORIGINDEX);
-                         for(i = 0; i < capVerts; i++) {
-                                 MVert *mv = &cap_mvert[i];
-                                 short merged = 0;
-
-                                 if(amd->flags & MOD_ARR_MERGE) {
-                                         float tmp_co[3];
-                                         MVert *in_mv;
-                                         int j;
-
-                                         copy_v3_v3(tmp_co, mv->co);
-                                         mul_m4_v3(offset, tmp_co);
-
-                                         for(j = 0; j < maxVerts; j++) {
-                                                 in_mv = &src_mvert[j];
-                                                 /* if this vert is within merge limit, merge */
-                                                 if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
-                                                         vert_map[i] = calc_mapping(indexMap, j, count - 1);
-                                                         merged = 1;
-                                                         break;
-                                                 }
-                                         }
-                                 }
-
-                                 if(!merged) {
-                                         DM_copy_vert_data(end_cap, result, i, numVerts, 1);
-                                         mvert[numVerts] = *mv;
-                                         mul_m4_v3(endoffset, mvert[numVerts].co);
-                                         origindex[numVerts] = ORIGINDEX_NONE;
-
-                                         vert_map[i] = numVerts;
-
-                                         numVerts++;
-                                 }
-                         }
-                         origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
-                         for(i = 0; i < capEdges; i++) {
-                                 int v1, v2;
-
-                                 v1 = vert_map[cap_medge[i].v1];
-                                 v2 = vert_map[cap_medge[i].v2];
-
-                                 if(!BLI_edgehash_haskey(edges, v1, v2)) {
-                                         DM_copy_edge_data(end_cap, result, i, numEdges, 1);
-                                         medge[numEdges] = cap_medge[i];
-                                         medge[numEdges].v1 = v1;
-                                         medge[numEdges].v2 = v2;
-                                         origindex[numEdges] = ORIGINDEX_NONE;
-
-                                         numEdges++;
-                                 }
-                         }
-                         origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
-                         for(i = 0; i < capFaces; i++) {
-                                 DM_copy_face_data(end_cap, result, i, numFaces, 1);
-                                 mface[numFaces] = cap_mface[i];
-                                 mface[numFaces].v1 = vert_map[mface[numFaces].v1];
-                                 mface[numFaces].v2 = vert_map[mface[numFaces].v2];
-                                 mface[numFaces].v3 = vert_map[mface[numFaces].v3];
-                                 if(mface[numFaces].v4) {
-                                         mface[numFaces].v4 = vert_map[mface[numFaces].v4];
-
-                                         test_index_face(&mface[numFaces], &result->faceData,
-                                                                         numFaces, 4);
-                                 }
-                                 else
-                                 {
-                                         test_index_face(&mface[numFaces], &result->faceData,
-                                                                         numFaces, 3);
-                                 }
-                                 origindex[numFaces] = ORIGINDEX_NONE;
-
-                                 numFaces++;
-                         }
-
-                         MEM_freeN(vert_map);
-                         end_cap->release(end_cap);
-                 }
-
-                 BLI_edgehash_free(edges, NULL);
-                 MEM_freeN(indexMap);
-
-                 CDDM_lower_num_verts(result, numVerts);
-                 CDDM_lower_num_edges(result, numEdges);
-                 CDDM_lower_num_faces(result, numFaces);
-
-                 return result;
+               if(indexMap[inMF.v1].merge_final)
+                       mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1);
+               if(indexMap[inMF.v2].merge_final)
+                       mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1);
+               if(indexMap[inMF.v3].merge_final)
+                       mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1);
+               if(inMF.v4 && indexMap[inMF.v4].merge_final)
+                       mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1);
+
+               if(test_index_face_maxvert(mf, &result->faceData, numFaces, inMF.v4?4:3, numVerts) < 3)
+                       continue;
+
+               numFaces++;
+
+               /* if the face has fewer than 3 vertices, don't create it */
+               if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) {
+                       numFaces--;
+                       DM_free_face_data(result, numFaces, 1);
+               }
+
+               for(j = 1; j < count; j++)
+               {
+                       MFace *mf2 = &mface[numFaces];
+
+                       DM_copy_face_data(dm, result, i, numFaces, 1);
+                       *mf2 = *mf;
+
+                       mf2->v1 = calc_mapping(indexMap, inMF.v1, j);
+                       mf2->v2 = calc_mapping(indexMap, inMF.v2, j);
+                       mf2->v3 = calc_mapping(indexMap, inMF.v3, j);
+                       if (inMF.v4)
+                               mf2->v4 = calc_mapping(indexMap, inMF.v4, j);
+
+                       numFaces++;
+
+                       /* if the face has fewer than 3 vertices, don't create it */
+                       if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) {
+                               numFaces--;
+                               DM_free_face_data(result, numFaces, 1);
+                       }
+               }
+       }
+
+       /* add start and end caps */
+       if(start_cap) {
+               float startoffset[4][4];
+               MVert *cap_mvert;
+               MEdge *cap_medge;
+               MFace *cap_mface;
+               int *origindex;
+               int *vert_map;
+               int capVerts, capEdges, capFaces;
+
+               capVerts = start_cap->getNumVerts(start_cap);
+               capEdges = start_cap->getNumEdges(start_cap);
+               capFaces = start_cap->getNumFaces(start_cap);
+               cap_mvert = start_cap->getVertArray(start_cap);
+               cap_medge = start_cap->getEdgeArray(start_cap);
+               cap_mface = start_cap->getFaceArray(start_cap);
+
+               invert_m4_m4(startoffset, offset);
+
+               vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
+               "arrayModifier_doArray vert_map");
+
+               origindex = result->getVertDataArray(result, CD_ORIGINDEX);
+               for(i = 0; i < capVerts; i++) {
+                       MVert *mv = &cap_mvert[i];
+                       short merged = 0;
+
+                       if(amd->flags & MOD_ARR_MERGE) {
+                               float tmp_co[3];
+                               MVert *in_mv;
+                               int j;
+
+                               copy_v3_v3(tmp_co, mv->co);
+                               mul_m4_v3(startoffset, tmp_co);
+
+                               for(j = 0; j < maxVerts; j++) {
+                                       in_mv = &src_mvert[j];
+                                       /* if this vert is within merge limit, merge */
+                                       if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
+                                               vert_map[i] = calc_mapping(indexMap, j, 0);
+                                               merged = 1;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if(!merged) {
+                               DM_copy_vert_data(start_cap, result, i, numVerts, 1);
+                               mvert[numVerts] = *mv;
+                               mul_m4_v3(startoffset, mvert[numVerts].co);
+                               origindex[numVerts] = ORIGINDEX_NONE;
+
+                               vert_map[i] = numVerts;
+
+                               numVerts++;
+                       }
+               }
+               origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
+               for(i = 0; i < capEdges; i++) {
+                       int v1, v2;
+
+                       v1 = vert_map[cap_medge[i].v1];
+                       v2 = vert_map[cap_medge[i].v2];
+
+                       if(!BLI_edgehash_haskey(edges, v1, v2)) {
+                               DM_copy_edge_data(start_cap, result, i, numEdges, 1);
+                               medge[numEdges] = cap_medge[i];
+                               medge[numEdges].v1 = v1;
+                               medge[numEdges].v2 = v2;
+                               origindex[numEdges] = ORIGINDEX_NONE;
+
+                               numEdges++;
+                       }
+               }
+               origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
+               for(i = 0; i < capFaces; i++) {
+                       DM_copy_face_data(start_cap, result, i, numFaces, 1);
+                       mface[numFaces] = cap_mface[i];
+                       mface[numFaces].v1 = vert_map[mface[numFaces].v1];
+                       mface[numFaces].v2 = vert_map[mface[numFaces].v2];
+                       mface[numFaces].v3 = vert_map[mface[numFaces].v3];
+                       if(mface[numFaces].v4) {
+                               mface[numFaces].v4 = vert_map[mface[numFaces].v4];
+
+                               test_index_face_maxvert(&mface[numFaces], &result->faceData,
+                               numFaces, 4, numVerts);
+                       }
+                       else
+                       {
+                               test_index_face(&mface[numFaces], &result->faceData,
+                               numFaces, 3);
+                       }
+
+                       origindex[numFaces] = ORIGINDEX_NONE;
+
+                       numFaces++;
+               }
+
+               MEM_freeN(vert_map);
+               start_cap->release(start_cap);
+       }
+
+       if(end_cap) {
+               float endoffset[4][4];
+               MVert *cap_mvert;
+               MEdge *cap_medge;
+               MFace *cap_mface;
+               int *origindex;
+               int *vert_map;
+               int capVerts, capEdges, capFaces;
+
+               capVerts = end_cap->getNumVerts(end_cap);
+               capEdges = end_cap->getNumEdges(end_cap);
+               capFaces = end_cap->getNumFaces(end_cap);
+               cap_mvert = end_cap->getVertArray(end_cap);
+               cap_medge = end_cap->getEdgeArray(end_cap);
+               cap_mface = end_cap->getFaceArray(end_cap);
+
+               mul_m4_m4m4(endoffset, final_offset, offset);
+
+               vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
+               "arrayModifier_doArray vert_map");
+
+               origindex = result->getVertDataArray(result, CD_ORIGINDEX);
+               for(i = 0; i < capVerts; i++) {
+                       MVert *mv = &cap_mvert[i];
+                       short merged = 0;
+
+                       if(amd->flags & MOD_ARR_MERGE) {
+                               float tmp_co[3];
+                               MVert *in_mv;
+                               int j;
+
+                               copy_v3_v3(tmp_co, mv->co);
+                               mul_m4_v3(offset, tmp_co);
+
+                               for(j = 0; j < maxVerts; j++) {
+                                       in_mv = &src_mvert[j];
+                                       /* if this vert is within merge limit, merge */
+                                       if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
+                                               vert_map[i] = calc_mapping(indexMap, j, count - 1);
+                                               merged = 1;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if(!merged) {
+                               DM_copy_vert_data(end_cap, result, i, numVerts, 1);
+                               mvert[numVerts] = *mv;
+                               mul_m4_v3(endoffset, mvert[numVerts].co);
+                               origindex[numVerts] = ORIGINDEX_NONE;
+
+                               vert_map[i] = numVerts;
+
+                               numVerts++;
+                       }
+               }
+               origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
+               for(i = 0; i < capEdges; i++) {
+                       int v1, v2;
+
+                       v1 = vert_map[cap_medge[i].v1];
+                       v2 = vert_map[cap_medge[i].v2];
+
+                       if(!BLI_edgehash_haskey(edges, v1, v2)) {
+                               DM_copy_edge_data(end_cap, result, i, numEdges, 1);
+                               medge[numEdges] = cap_medge[i];
+                               medge[numEdges].v1 = v1;
+                               medge[numEdges].v2 = v2;
+                               origindex[numEdges] = ORIGINDEX_NONE;
+
+                               numEdges++;
+                       }
+               }
+               origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
+               for(i = 0; i < capFaces; i++) {
+                       DM_copy_face_data(end_cap, result, i, numFaces, 1);
+                       mface[numFaces] = cap_mface[i];
+                       mface[numFaces].v1 = vert_map[mface[numFaces].v1];
+                       mface[numFaces].v2 = vert_map[mface[numFaces].v2];
+                       mface[numFaces].v3 = vert_map[mface[numFaces].v3];
+                       if(mface[numFaces].v4) {
+                               mface[numFaces].v4 = vert_map[mface[numFaces].v4];
+
+                               test_index_face(&mface[numFaces], &result->faceData,
+                               numFaces, 4);
+                       }
+                       else
+                       {
+                               test_index_face(&mface[numFaces], &result->faceData,
+                               numFaces, 3);
+                       }
+                       origindex[numFaces] = ORIGINDEX_NONE;
+
+                       numFaces++;
+               }
+
+               MEM_freeN(vert_map);
+               end_cap->release(end_cap);
+       }
+
+       BLI_edgehash_free(edges, NULL);
+       MEM_freeN(indexMap);
+
+       CDDM_lower_num_verts(result, numVerts);
+       CDDM_lower_num_edges(result, numEdges);
+       CDDM_lower_num_faces(result, numFaces);
+
+       return result;
 }
 
 static DerivedMesh *applyModifier(ModifierData *md, Object *ob,