~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/modifiers/intern/MOD_array.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
#include "BKE_mesh.h"
54
54
#include "BKE_modifier.h"
55
55
#include "BKE_object.h"
56
 
#include "BKE_tessmesh.h"
 
56
 
 
57
#include "bmesh.h"
57
58
 
58
59
#include "depsgraph_private.h"
59
60
 
63
64
 
64
65
static void initData(ModifierData *md)
65
66
{
66
 
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
67
        ArrayModifierData *amd = (ArrayModifierData *) md;
67
68
 
68
69
        /* default to 2 duplicates distributed along the x-axis by an
69
70
         * offset of 1 object-width
82
83
 
83
84
static void copyData(ModifierData *md, ModifierData *target)
84
85
{
85
 
        ArrayModifierData *amd = (ArrayModifierData*) md;
86
 
        ArrayModifierData *tamd = (ArrayModifierData*) target;
 
86
        ArrayModifierData *amd = (ArrayModifierData *) md;
 
87
        ArrayModifierData *tamd = (ArrayModifierData *) target;
87
88
 
88
89
        tamd->start_cap = amd->start_cap;
89
90
        tamd->end_cap = amd->end_cap;
100
101
}
101
102
 
102
103
static void foreachObjectLink(
103
 
                                                ModifierData *md, Object *ob,
104
 
         void (*walk)(void *userData, Object *ob, Object **obpoin),
105
 
                void *userData)
 
104
        ModifierData *md, Object *ob,
 
105
        void (*walk)(void *userData, Object *ob, Object **obpoin),
 
106
        void *userData)
106
107
{
107
 
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
108
        ArrayModifierData *amd = (ArrayModifierData *) md;
108
109
 
109
110
        walk(userData, ob, &amd->start_cap);
110
111
        walk(userData, ob, &amd->end_cap);
113
114
}
114
115
 
115
116
static void updateDepgraph(ModifierData *md, DagForest *forest,
116
 
        struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode)
 
117
                           struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode)
117
118
{
118
 
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
119
        ArrayModifierData *amd = (ArrayModifierData *) md;
119
120
 
120
121
        if (amd->start_cap) {
121
122
                DagNode *curNode = dag_get_node(forest, amd->start_cap);
153
154
 
154
155
        /* find the minimum and maximum coordinates on the desired axis */
155
156
        min_co = max_co = mvert->co[axis];
156
 
        ++mvert;
 
157
        mvert++;
157
158
        for (i = 1; i < numVerts; ++i, ++mvert) {
158
159
                if (mvert->co[axis] < min_co) min_co = mvert->co[axis];
159
160
                if (mvert->co[axis] > max_co) max_co = mvert->co[axis];
163
164
}
164
165
 
165
166
static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
166
 
                                                                   const ArrayModifierData *amd,
167
 
                                                                   int *index_map_length)
 
167
                                   const ArrayModifierData *amd,
 
168
                                   int *index_map_length)
168
169
{
169
170
        BMOperator find_op;
170
171
        BMOIter oiter;
172
173
        BMElem *ele;
173
174
        int *index_map, i;
174
175
 
175
 
        BMO_op_initf(bm, &find_op,
176
 
                                 "finddoubles verts=%av dist=%f keepverts=%s",
177
 
                                 amd->merge_dist, dupe_op, "geom");
 
176
        BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
 
177
                     "find_doubles verts=%av dist=%f keep_verts=%s",
 
178
                     amd->merge_dist, dupe_op, "geom");
178
179
 
179
180
        BMO_op_exec(bm, &find_op);
180
 
                        
 
181
 
181
182
        i = 0;
182
 
        BMO_ITER (ele, &oiter, bm, dupe_op, "geom", BM_ALL) {
 
183
        BMO_ITER (ele, &oiter, dupe_op->slots_in, "geom", BM_ALL) {
183
184
                BM_elem_index_set(ele, i); /* set_dirty */
184
185
                i++;
185
186
        }
186
187
 
187
 
        BMO_ITER (ele, &oiter, bm, dupe_op, "newout", BM_ALL) {
 
188
        BMO_ITER (ele, &oiter, dupe_op->slots_out, "geom.out", BM_ALL) {
188
189
                BM_elem_index_set(ele, i); /* set_dirty */
189
190
                i++;
190
191
        }
191
192
        /* above loops over all, so set all to dirty, if this is somehow
192
 
         * setting valid values, this line can be remvoed - campbell */
 
193
         * setting valid values, this line can be removed - campbell */
193
194
        bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
194
195
 
195
196
        (*index_map_length) = i;
196
197
        index_map = MEM_callocN(sizeof(int) * (*index_map_length), "index_map");
197
198
 
198
199
        /*element type argument doesn't do anything here*/
199
 
        BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
 
200
        BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
200
201
                v2 = BMO_iter_map_value_p(&oiter);
201
202
 
202
203
                index_map[BM_elem_index_get(v)] = BM_elem_index_get(v2) + 1;
214
215
 *
215
216
 * All verts will be tagged on exit.
216
217
 */
217
 
static void bm_merge_dm_transform(BMesh* bm, DerivedMesh *dm, float mat[4][4],
218
 
                                                                  const ArrayModifierData *amd,
219
 
                                                                  BMOperator *dupe_op,
220
 
                                                                  const char *dupe_slot_name,
221
 
                                                                  BMOperator *weld_op)
 
218
static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
 
219
                                  const ArrayModifierData *amd,
 
220
                                  BMOperator *dupe_op,
 
221
                                  BMOpSlot dupe_op_slot_args[BMO_OP_MAX_SLOTS], const char *dupe_slot_name,
 
222
                                  BMOperator *weld_op)
222
223
{
223
 
        BMVert *v, *v2;
 
224
        const int is_input = (dupe_op->slots_in == dupe_op_slot_args);
 
225
        BMVert *v, *v2, *v3;
224
226
        BMIter iter;
225
227
 
 
228
        /* Add the DerivedMesh's elements to the BMesh. The pre-existing
 
229
         * elements were already tagged, so the new elements can be
 
230
         * identified by not having the BM_ELEM_TAG flag set. */
226
231
        DM_to_bmesh_ex(dm, bm);
227
232
 
228
233
        if (amd->flags & MOD_ARR_MERGE) {
230
235
                
231
236
                BMOIter oiter;
232
237
                BMOperator find_op;
 
238
                BMOpSlot *slot_targetmap;
233
239
 
234
 
                BMO_op_initf(bm, &find_op,
235
 
                                         "finddoubles verts=%Hv dist=%f keepverts=%s",
236
 
                                         BM_ELEM_TAG, amd->merge_dist,
237
 
                                         dupe_op, dupe_slot_name);
 
240
                BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
 
241
                             is_input ?  /* ugh */
 
242
                             "find_doubles verts=%Hv dist=%f keep_verts=%s" :
 
243
                             "find_doubles verts=%Hv dist=%f keep_verts=%S",
 
244
                             BM_ELEM_TAG, amd->merge_dist,
 
245
                             dupe_op, dupe_slot_name);
238
246
 
239
247
                /* append the dupe's geom to the findop input verts */
240
 
                BMO_slot_buffer_append(&find_op, "verts", dupe_op, dupe_slot_name);
 
248
                if (is_input) {
 
249
                        BMO_slot_buffer_append(&find_op, slots_in, "verts",
 
250
                                               dupe_op,  slots_in, dupe_slot_name);
 
251
                }
 
252
                else if (dupe_op->slots_out == dupe_op_slot_args) {
 
253
                        BMO_slot_buffer_append(&find_op, slots_in,  "verts",
 
254
                                               dupe_op,  slots_out, dupe_slot_name);
 
255
                }
 
256
                else {
 
257
                        BLI_assert(0);
 
258
                }
241
259
 
242
260
                /* transform and tag verts */
243
261
                BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
249
267
 
250
268
                BMO_op_exec(bm, &find_op);
251
269
 
 
270
                slot_targetmap = BMO_slot_get(weld_op->slots_in, "targetmap");
 
271
 
252
272
                /* add new merge targets to weld operator */
253
 
                BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
 
273
                BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
254
274
                        v2 = BMO_iter_map_value_p(&oiter);
255
 
                        BMO_slot_map_ptr_insert(bm, weld_op, "targetmap", v, v2);
 
275
                        /* check in case the target vertex (v2) is already marked
 
276
                         * for merging */
 
277
                        while ((v3 = BMO_slot_map_elem_get(slot_targetmap, v2))) {
 
278
                                v2 = v3;
 
279
                        }
 
280
                        BMO_slot_map_elem_insert(weld_op, slot_targetmap, v, v2);
256
281
                }
257
282
 
258
283
                BMO_op_finish(bm, &find_op);
268
293
        }
269
294
}
270
295
 
271
 
static void merge_first_last(BMesh* bm,
272
 
                                                         const ArrayModifierData *amd,
273
 
                                                         BMOperator *dupe_first,
274
 
                                                         BMOperator *dupe_last,
275
 
                                                         BMOperator *weld_op)
 
296
static void merge_first_last(BMesh *bm,
 
297
                             const ArrayModifierData *amd,
 
298
                             BMOperator *dupe_first,
 
299
                             BMOperator *dupe_last,
 
300
                             BMOperator *weld_op)
276
301
{
277
302
        BMOperator find_op;
278
303
        BMOIter oiter;
279
304
        BMVert *v, *v2;
 
305
        BMOpSlot *slot_targetmap;
280
306
 
281
 
        BMO_op_initf(bm, &find_op,
282
 
                                 "finddoubles verts=%s dist=%f keepverts=%s",
283
 
                                 dupe_first, "geom", amd->merge_dist,
284
 
                                 dupe_first, "geom");
 
307
        BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
 
308
                     "find_doubles verts=%s dist=%f keep_verts=%s",
 
309
                     dupe_first, "geom", amd->merge_dist,
 
310
                     dupe_first, "geom");
285
311
 
286
312
        /* append the last dupe's geom to the findop input verts */
287
 
        BMO_slot_buffer_append(&find_op, "verts", dupe_last, "newout");
 
313
        BMO_slot_buffer_append(&find_op,  slots_in,  "verts",
 
314
                               dupe_last, slots_out, "geom.out");
288
315
 
289
316
        BMO_op_exec(bm, &find_op);
290
317
 
291
318
        /* add new merge targets to weld operator */
292
 
        BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
 
319
        slot_targetmap = BMO_slot_get(weld_op->slots_in, "targetmap");
 
320
        BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
293
321
                v2 = BMO_iter_map_value_p(&oiter);
294
 
                BMO_slot_map_ptr_insert(bm, weld_op, "targetmap", v, v2);
 
322
                BMO_slot_map_elem_insert(weld_op, slot_targetmap, v, v2);
295
323
        }
296
324
 
297
325
        BMO_op_finish(bm, &find_op);
302
330
                                          int UNUSED(initFlags))
303
331
{
304
332
        DerivedMesh *result;
305
 
        BMEditMesh *em = DM_to_editbmesh(dm, NULL, FALSE);
 
333
        BMesh *bm = DM_to_bmesh(dm);
306
334
        BMOperator first_dupe_op, dupe_op, old_dupe_op, weld_op;
307
335
        BMVert **first_geom = NULL;
308
 
        int i, j, indexLen;
 
336
        int i, j;
 
337
        int index_len = -1;  /* initialize to an invalid value */
309
338
        /* offset matrix */
310
339
        float offset[4][4];
311
340
        float final_offset[4][4];
315
344
        int *indexMap = NULL;
316
345
        DerivedMesh *start_cap = NULL, *end_cap = NULL;
317
346
        MVert *src_mvert;
 
347
        BMOpSlot *slot_targetmap = NULL;  /* for weldop */
318
348
 
319
349
        /* need to avoid infinite recursion here */
320
350
        if (amd->start_cap && amd->start_cap != ob)
331
361
                add_v3_v3v3(offset[3], offset[3], amd->offset);
332
362
        if (amd->offset_type & MOD_ARR_OFF_RELATIVE) {
333
363
                for (j = 0; j < 3; j++)
334
 
                        offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
335
 
                                        maxVerts, j);
 
364
                        offset[3][j] += amd->scale[j] * vertarray_size(src_mvert, maxVerts, j);
336
365
        }
337
366
 
338
367
        if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
356
385
                        float tmp_mat[3][3];
357
386
                        float scale;
358
387
                        
359
 
                        object_to_mat3(amd->curve_ob, tmp_mat);
 
388
                        BKE_object_to_mat3(amd->curve_ob, tmp_mat);
360
389
                        scale = mat3_to_scale(tmp_mat);
361
390
                                
362
391
                        if (!cu->path) {
363
392
                                cu->flag |= CU_PATH; // needed for path & bevlist
364
 
                                makeDispListCurveTypes(scene, amd->curve_ob, 0);
 
393
                                BKE_displist_make_curveTypes(scene, amd->curve_ob, 0);
365
394
                        }
366
395
                        if (cu->path)
367
 
                                length = scale*cu->path->totdist;
 
396
                                length = scale * cu->path->totdist;
368
397
                }
369
398
        }
370
399
 
388
417
        /* calculate the offset matrix of the final copy (for merging) */
389
418
        unit_m4(final_offset);
390
419
 
391
 
        for (j=0; j < count - 1; j++) {
 
420
        for (j = 0; j < count - 1; j++) {
392
421
                mult_m4_m4m4(tmp_mat, offset, final_offset);
393
422
                copy_m4_m4(final_offset, tmp_mat);
394
423
        }
399
428
         * cleaner way to do this. One possibility: a "mirror" BMOp would
400
429
         * certainly help by compressing it all into one top-level BMOp that
401
430
         * executes a lot of second-level BMOps. */
402
 
        BMO_push(em->bm, NULL);
403
 
        bmesh_edit_begin(em->bm, 0);
404
 
 
405
 
        if (amd->flags & MOD_ARR_MERGE)
406
 
                BMO_op_init(em->bm, &weld_op, "weldverts");
407
 
 
408
 
        BMO_op_initf(em->bm, &dupe_op, "dupe geom=%avef");
 
431
        BM_mesh_elem_toolflags_ensure(bm);
 
432
        BMO_push(bm, NULL);
 
433
        bmesh_edit_begin(bm, 0);
 
434
 
 
435
        if (amd->flags & MOD_ARR_MERGE) {
 
436
                BMO_op_init(bm, &weld_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
 
437
                            "weld_verts");
 
438
 
 
439
                slot_targetmap = BMO_slot_get(weld_op.slots_in, "targetmap");
 
440
        }
 
441
 
 
442
        BMO_op_initf(bm, &dupe_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
 
443
                     "duplicate geom=%avef");
409
444
        first_dupe_op = dupe_op;
410
445
 
411
 
        for (j=0; j < count - 1; j++) {
 
446
        for (j = 0; j < count - 1; j++) {
412
447
                BMVert *v, *v2, *v3;
413
448
                BMOpSlot *geom_slot;
414
 
                BMOpSlot *newout_slot;
 
449
                BMOpSlot *geom_out_slot;
415
450
                BMOIter oiter;
416
451
 
417
 
                if (j != 0)
418
 
                        BMO_op_initf(em->bm, &dupe_op, "dupe geom=%s", &old_dupe_op, "newout");
419
 
                BMO_op_exec(em->bm, &dupe_op);
 
452
                if (j != 0) {
 
453
                        BMO_op_initf(bm, &dupe_op,
 
454
                                     (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
 
455
                                     "duplicate geom=%S", &old_dupe_op, "geom.out");
 
456
                }
 
457
                BMO_op_exec(bm, &dupe_op);
420
458
 
421
 
                geom_slot = BMO_slot_get(&dupe_op, "geom");
422
 
                newout_slot = BMO_slot_get(&dupe_op, "newout");
 
459
                geom_slot   = BMO_slot_get(dupe_op.slots_in,  "geom");
 
460
                geom_out_slot = BMO_slot_get(dupe_op.slots_out, "geom.out");
423
461
 
424
462
                if ((amd->flags & MOD_ARR_MERGEFINAL) && j == 0) {
425
 
                        int first_geom_bytes = sizeof(BMVert*) * geom_slot->len;
 
463
                        int first_geom_bytes = sizeof(BMVert *) * geom_slot->len;
426
464
                                
427
465
                        /* make a copy of the initial geometry ordering so the
428
466
                         * last duplicate can be merged into it */
431
469
                }
432
470
 
433
471
                /* apply transformation matrix */
434
 
                BMO_ITER (v, &oiter, em->bm, &dupe_op, "newout", BM_VERT) {
 
472
                BMO_ITER (v, &oiter, dupe_op.slots_out, "geom.out", BM_VERT) {
435
473
                        mul_m4_v3(offset, v->co);
436
474
                }
437
475
 
438
476
                if (amd->flags & MOD_ARR_MERGE) {
439
477
                        /*calculate merge mapping*/
440
478
                        if (j == 0) {
441
 
                                indexMap = find_doubles_index_map(em->bm, &dupe_op,
442
 
                                                                                                  amd, &indexLen);
 
479
                                indexMap = find_doubles_index_map(bm, &dupe_op,
 
480
                                                                  amd, &index_len);
443
481
                        }
444
482
 
445
483
                        #define _E(s, i) ((BMVert **)(s)->data.buf)[i]
446
484
 
447
 
                        for (i=0; i<indexLen; i++) {
 
485
                        /* ensure this is set */
 
486
                        BLI_assert(index_len != -1);
 
487
 
 
488
                        for (i = 0; i < index_len; i++) {
448
489
                                if (!indexMap[i]) continue;
449
490
 
450
 
                                /* merge v (from 'newout') into v2 (from old 'geom') */
451
 
                                v = _E(newout_slot, i - geom_slot->len);
452
 
                                v2 = _E(geom_slot, indexMap[i]-1);
 
491
                                /* merge v (from 'geom.out') into v2 (from old 'geom') */
 
492
                                v = _E(geom_out_slot, i - geom_slot->len);
 
493
                                v2 = _E(geom_slot, indexMap[i] - 1);
453
494
 
454
495
                                /* check in case the target vertex (v2) is already marked
455
496
                                 * for merging */
456
 
                                while ((v3 = BMO_slot_map_ptr_get(em->bm, &weld_op, "targetmap", v2))) {
 
497
                                while ((v3 = BMO_slot_map_elem_get(slot_targetmap, v2))) {
457
498
                                        v2 = v3;
458
499
                                }
459
500
 
460
 
                                BMO_slot_map_ptr_insert(em->bm, &weld_op, "targetmap", v, v2);
 
501
                                BMO_slot_map_elem_insert(&weld_op, slot_targetmap, v, v2);
461
502
                        }
462
503
 
463
504
                        #undef _E
469
510
                        first_dupe_op = dupe_op;
470
511
                
471
512
                if (j >= 2)
472
 
                        BMO_op_finish(em->bm, &old_dupe_op);
 
513
                        BMO_op_finish(bm, &old_dupe_op);
473
514
                old_dupe_op = dupe_op;
474
515
        }
475
516
 
482
523
                 * loop) the offset between first and last is different from
483
524
                 * dupe X to dupe X+1. */
484
525
 
485
 
                merge_first_last(em->bm, amd, &first_dupe_op, &dupe_op, &weld_op);
 
526
                merge_first_last(bm, amd, &first_dupe_op, &dupe_op, &weld_op);
486
527
        }
487
528
 
488
529
        /* start capping */
489
530
        if (start_cap || end_cap) {
490
 
                BM_mesh_elem_hflag_enable_all(em->bm, BM_VERT, BM_ELEM_TAG, FALSE);
 
531
                BM_mesh_elem_hflag_enable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
491
532
 
492
533
                if (start_cap) {
493
534
                        float startoffset[4][4];
494
535
                        invert_m4_m4(startoffset, offset);
495
 
                        bm_merge_dm_transform(em->bm, start_cap, startoffset, amd,
496
 
                                                  &first_dupe_op, "geom", &weld_op);
 
536
                        bm_merge_dm_transform(bm, start_cap, startoffset, amd,
 
537
                                              &first_dupe_op, first_dupe_op.slots_in, "geom", &weld_op);
497
538
                }
498
539
 
499
540
                if (end_cap) {
500
541
                        float endoffset[4][4];
501
542
                        mult_m4_m4m4(endoffset, offset, final_offset);
502
 
                        bm_merge_dm_transform(em->bm, end_cap, endoffset, amd,
503
 
                                &dupe_op, count == 1 ? "geom" : "newout", &weld_op);
 
543
                        bm_merge_dm_transform(bm, end_cap, endoffset, amd,
 
544
                                              &dupe_op, (count == 1) ? dupe_op.slots_in : dupe_op.slots_out,
 
545
                                              (count == 1) ? "geom" : "geom.out", &weld_op);
504
546
                }
505
547
        }
506
548
        /* done capping */
507
549
 
508
550
        /* free remaining dupe operators */
509
 
        BMO_op_finish(em->bm, &first_dupe_op);
 
551
        BMO_op_finish(bm, &first_dupe_op);
510
552
        if (count > 2)
511
 
                BMO_op_finish(em->bm, &dupe_op);
 
553
                BMO_op_finish(bm, &dupe_op);
512
554
 
513
555
        /* run merge operator */
514
556
        if (amd->flags & MOD_ARR_MERGE) {
515
 
                BMO_op_exec(em->bm, &weld_op);
516
 
                BMO_op_finish(em->bm, &weld_op);
 
557
                BMO_op_exec(bm, &weld_op);
 
558
                BMO_op_finish(bm, &weld_op);
517
559
        }
518
560
 
519
561
        /* Bump the stack level back down to match the adjustment up above */
520
 
        BMO_pop(em->bm);
 
562
        BMO_pop(bm);
521
563
 
522
 
        BLI_assert(em->looptris == NULL);
523
 
        result = CDDM_from_BMEditMesh(em, NULL, FALSE, FALSE);
 
564
        result = CDDM_from_bmesh(bm, FALSE);
524
565
 
525
566
        if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
526
567
                /* Update normals in case offset object has rotation. */
531
572
                CDDM_calc_normals(result);
532
573
        }
533
574
 
534
 
        BMEdit_Free(em);
535
 
        MEM_freeN(em);
 
575
        BM_mesh_free(bm);
 
576
 
536
577
        if (indexMap)
537
578
                MEM_freeN(indexMap);
538
579
        if (first_geom)
542
583
}
543
584
 
544
585
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
545
 
                                                DerivedMesh *dm,
546
 
                                                int UNUSED(useRenderParams),
547
 
                                                int UNUSED(isFinalCalc))
 
586
                                  DerivedMesh *dm,
 
587
                                  ModifierApplyFlag UNUSED(flag))
548
588
{
549
589
        DerivedMesh *result;
550
 
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
590
        ArrayModifierData *amd = (ArrayModifierData *) md;
551
591
 
552
592
        result = arrayModifier_doArray(amd, md->scene, ob, dm, 0);
553
593
 
558
598
}
559
599
 
560
600
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
561
 
                                                struct BMEditMesh *UNUSED(editData),
562
 
                                                DerivedMesh *dm)
 
601
                                    struct BMEditMesh *UNUSED(editData),
 
602
                                    DerivedMesh *dm)
563
603
{
564
 
        return applyModifier(md, ob, dm, 0, 1);
 
604
        return applyModifier(md, ob, dm, MOD_APPLY_USECACHE);
565
605
}
566
606
 
567
607
 
570
610
        /* structName */        "ArrayModifierData",
571
611
        /* structSize */        sizeof(ArrayModifierData),
572
612
        /* type */              eModifierTypeType_Constructive,
573
 
        /* flags */             eModifierTypeFlag_AcceptsMesh
574
 
                                                        | eModifierTypeFlag_SupportsMapping
575
 
                                                        | eModifierTypeFlag_SupportsEditmode
576
 
                                                        | eModifierTypeFlag_EnableInEditmode
577
 
                                                        | eModifierTypeFlag_AcceptsCVs,
 
613
        /* flags */             eModifierTypeFlag_AcceptsMesh |
 
614
                                eModifierTypeFlag_SupportsMapping |
 
615
                                eModifierTypeFlag_SupportsEditmode |
 
616
                                eModifierTypeFlag_EnableInEditmode |
 
617
                                eModifierTypeFlag_AcceptsCVs,
578
618
 
579
619
        /* copyData */          copyData,
580
620
        /* deformVerts */       NULL,