~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
* $Id: MOD_array.c 29318 2010-06-07 19:16:56Z nicholasbishop $
3
 
*
4
 
* ***** BEGIN GPL LICENSE BLOCK *****
5
 
*
6
 
* This program is free software; you can redistribute it and/or
7
 
* modify it under the terms of the GNU General Public License
8
 
* as published by the Free Software Foundation; either version 2
9
 
* of the License, or (at your option) any later version.
10
 
*
11
 
* This program is distributed in the hope that it will be useful,
12
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
* GNU General Public License for more details.
15
 
*
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program; if not, write to the Free Software  Foundation,
18
 
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 
*
20
 
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
21
 
* All rights reserved.
22
 
*
23
 
* Contributor(s): Daniel Dunbar
24
 
*                 Ton Roosendaal,
25
 
*                 Ben Batt,
26
 
*                 Brecht Van Lommel,
27
 
*                 Campbell Barton
28
 
*
29
 
* ***** END GPL LICENSE BLOCK *****
30
 
*
31
 
*/
 
2
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software  Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
 
19
 * All rights reserved.
 
20
 *
 
21
 * Contributor(s): Daniel Dunbar
 
22
 *                 Ton Roosendaal,
 
23
 *                 Ben Batt,
 
24
 *                 Brecht Van Lommel,
 
25
 *                 Campbell Barton
 
26
 *
 
27
 * ***** END GPL LICENSE BLOCK *****
 
28
 *
 
29
 */
 
30
 
 
31
/** \file blender/modifiers/intern/MOD_array.c
 
32
 *  \ingroup modifiers
 
33
 */
 
34
 
32
35
 
33
36
/* Array modifier: duplicates the object multiple times along an axis */
34
37
 
35
 
#include "DNA_curve_types.h"
36
 
#include "DNA_meshdata_types.h"
 
38
#include "MEM_guardedalloc.h"
37
39
 
38
40
#include "BLI_math.h"
 
41
#include "BLI_utildefines.h"
 
42
#include "BLI_string.h"
39
43
#include "BLI_ghash.h"
40
44
#include "BLI_edgehash.h"
41
45
 
 
46
#include "DNA_curve_types.h"
 
47
#include "DNA_meshdata_types.h"
 
48
#include "DNA_object_types.h"
 
49
#include "DNA_scene_types.h"
 
50
 
42
51
#include "BKE_cdderivedmesh.h"
43
52
#include "BKE_displist.h"
44
53
#include "BKE_mesh.h"
45
54
#include "BKE_modifier.h"
46
55
#include "BKE_object.h"
 
56
#include "BKE_tessmesh.h"
47
57
 
48
58
#include "depsgraph_private.h"
49
59
 
 
60
#include <ctype.h>
 
61
#include <stdlib.h>
 
62
#include <string.h>
 
63
 
50
64
static void initData(ModifierData *md)
51
65
{
52
66
        ArrayModifierData *amd = (ArrayModifierData*) md;
53
67
 
54
68
        /* default to 2 duplicates distributed along the x-axis by an
55
 
        offset of 1 object-width
56
 
        */
 
69
         * offset of 1 object-width
 
70
         */
57
71
        amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
58
72
        amd->count = 2;
59
 
        amd->offset[0] = amd->offset[1] = amd->offset[2] = 0;
 
73
        zero_v3(amd->offset);
60
74
        amd->scale[0] = 1;
61
75
        amd->scale[1] = amd->scale[2] = 0;
62
76
        amd->length = 0;
98
112
        walk(userData, ob, &amd->offset_ob);
99
113
}
100
114
 
101
 
static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *scene,
102
 
                                         Object *ob, DagNode *obNode)
 
115
static void updateDepgraph(ModifierData *md, DagForest *forest,
 
116
        struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode)
103
117
{
104
118
        ArrayModifierData *amd = (ArrayModifierData*) md;
105
119
 
107
121
                DagNode *curNode = dag_get_node(forest, amd->start_cap);
108
122
 
109
123
                dag_add_relation(forest, curNode, obNode,
110
 
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
 
124
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
111
125
        }
112
126
        if (amd->end_cap) {
113
127
                DagNode *curNode = dag_get_node(forest, amd->end_cap);
114
128
 
115
129
                dag_add_relation(forest, curNode, obNode,
116
 
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
 
130
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
117
131
        }
118
132
        if (amd->curve_ob) {
119
133
                DagNode *curNode = dag_get_node(forest, amd->curve_ob);
120
134
 
121
135
                dag_add_relation(forest, curNode, obNode,
122
 
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
 
136
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
123
137
        }
124
138
        if (amd->offset_ob) {
125
139
                DagNode *curNode = dag_get_node(forest, amd->offset_ob);
126
140
 
127
141
                dag_add_relation(forest, curNode, obNode,
128
 
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
 
142
                                 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
129
143
        }
130
144
}
131
145
 
135
149
        float min_co, max_co;
136
150
 
137
151
        /* if there are no vertices, width is 0 */
138
 
        if(numVerts == 0) return 0;
 
152
        if (numVerts == 0) return 0;
139
153
 
140
154
        /* find the minimum and maximum coordinates on the desired axis */
141
155
        min_co = max_co = mvert->co[axis];
142
156
        ++mvert;
143
 
        for(i = 1; i < numVerts; ++i, ++mvert) {
144
 
                if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
145
 
                if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
 
157
        for (i = 1; i < numVerts; ++i, ++mvert) {
 
158
                if (mvert->co[axis] < min_co) min_co = mvert->co[axis];
 
159
                if (mvert->co[axis] > max_co) max_co = mvert->co[axis];
146
160
        }
147
161
 
148
162
        return max_co - min_co;
149
163
}
150
164
 
151
 
typedef struct IndexMapEntry {
152
 
        /* the new vert index that this old vert index maps to */
153
 
        int new;
154
 
        /* -1 if this vert isn't merged, otherwise the old vert index it
155
 
        * should be replaced with
156
 
        */
157
 
        int merge;
158
 
        /* 1 if this vert's first copy is merged with the last copy of its
159
 
        * merge target, otherwise 0
160
 
        */
161
 
        short merge_final;
162
 
} IndexMapEntry;
163
 
 
164
 
/* indexMap - an array of IndexMap entries
165
 
 * oldIndex - the old index to map
166
 
 * copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
 
165
static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
 
166
                                                                   const ArrayModifierData *amd,
 
167
                                                                   int *index_map_length)
 
168
{
 
169
        BMOperator find_op;
 
170
        BMOIter oiter;
 
171
        BMVert *v, *v2;
 
172
        BMElem *ele;
 
173
        int *index_map, i;
 
174
 
 
175
        BMO_op_initf(bm, &find_op,
 
176
                                 "finddoubles verts=%av dist=%f keepverts=%s",
 
177
                                 amd->merge_dist, dupe_op, "geom");
 
178
 
 
179
        BMO_op_exec(bm, &find_op);
 
180
                        
 
181
        i = 0;
 
182
        BMO_ITER (ele, &oiter, bm, dupe_op, "geom", BM_ALL) {
 
183
                BM_elem_index_set(ele, i); /* set_dirty */
 
184
                i++;
 
185
        }
 
186
 
 
187
        BMO_ITER (ele, &oiter, bm, dupe_op, "newout", BM_ALL) {
 
188
                BM_elem_index_set(ele, i); /* set_dirty */
 
189
                i++;
 
190
        }
 
191
        /* above loops over all, so set all to dirty, if this is somehow
 
192
         * setting valid values, this line can be remvoed - campbell */
 
193
        bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
 
194
 
 
195
        (*index_map_length) = i;
 
196
        index_map = MEM_callocN(sizeof(int) * (*index_map_length), "index_map");
 
197
 
 
198
        /*element type argument doesn't do anything here*/
 
199
        BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
 
200
                v2 = BMO_iter_map_value_p(&oiter);
 
201
 
 
202
                index_map[BM_elem_index_get(v)] = BM_elem_index_get(v2) + 1;
 
203
        }
 
204
 
 
205
        BMO_op_finish(bm, &find_op);
 
206
 
 
207
        return index_map;
 
208
}
 
209
 
 
210
/* Used for start/end cap.
 
211
 *
 
212
 * this function expects all existing vertices to be tagged,
 
213
 * so we can know new verts are not tagged.
 
214
 *
 
215
 * All verts will be tagged on exit.
167
216
 */
168
 
static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
169
 
{
170
 
        if(indexMap[oldIndex].merge < 0) {
171
 
                /* vert wasn't merged, so use copy of this vert */
172
 
                return indexMap[oldIndex].new + copyNum;
173
 
        } else if(indexMap[oldIndex].merge == oldIndex) {
174
 
                /* vert was merged with itself */
175
 
                return indexMap[oldIndex].new;
176
 
        } else {
177
 
                /* vert was merged with another vert */
178
 
                /* follow the chain of merges to the end, or until we've passed
179
 
                * a number of vertices equal to the copy number
180
 
                */
181
 
                if(copyNum <= 0)
182
 
                        return indexMap[oldIndex].new;
183
 
                else
184
 
                        return calc_mapping(indexMap, indexMap[oldIndex].merge,
185
 
                                                copyNum - 1);
186
 
        }
 
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)
 
222
{
 
223
        BMVert *v, *v2;
 
224
        BMIter iter;
 
225
 
 
226
        DM_to_bmesh_ex(dm, bm);
 
227
 
 
228
        if (amd->flags & MOD_ARR_MERGE) {
 
229
                /* if merging is enabled, find doubles */
 
230
                
 
231
                BMOIter oiter;
 
232
                BMOperator find_op;
 
233
 
 
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);
 
238
 
 
239
                /* append the dupe's geom to the findop input verts */
 
240
                BMO_slot_buffer_append(&find_op, "verts", dupe_op, dupe_slot_name);
 
241
 
 
242
                /* transform and tag verts */
 
243
                BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
 
244
                        if (!BM_elem_flag_test(v, BM_ELEM_TAG)) {
 
245
                                mul_m4_v3(mat, v->co);
 
246
                                BM_elem_flag_enable(v, BM_ELEM_TAG);
 
247
                        }
 
248
                }
 
249
 
 
250
                BMO_op_exec(bm, &find_op);
 
251
 
 
252
                /* add new merge targets to weld operator */
 
253
                BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
 
254
                        v2 = BMO_iter_map_value_p(&oiter);
 
255
                        BMO_slot_map_ptr_insert(bm, weld_op, "targetmap", v, v2);
 
256
                }
 
257
 
 
258
                BMO_op_finish(bm, &find_op);
 
259
        }
 
260
        else {
 
261
                /* transform and tag verts */
 
262
                BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
 
263
                        if (!BM_elem_flag_test(v, BM_ELEM_TAG)) {
 
264
                                mul_m4_v3(mat, v->co);
 
265
                                BM_elem_flag_enable(v, BM_ELEM_TAG);
 
266
                        }
 
267
                }
 
268
        }
 
269
}
 
270
 
 
271
static void merge_first_last(BMesh* bm,
 
272
                                                         const ArrayModifierData *amd,
 
273
                                                         BMOperator *dupe_first,
 
274
                                                         BMOperator *dupe_last,
 
275
                                                         BMOperator *weld_op)
 
276
{
 
277
        BMOperator find_op;
 
278
        BMOIter oiter;
 
279
        BMVert *v, *v2;
 
280
 
 
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");
 
285
 
 
286
        /* append the last dupe's geom to the findop input verts */
 
287
        BMO_slot_buffer_append(&find_op, "verts", dupe_last, "newout");
 
288
 
 
289
        BMO_op_exec(bm, &find_op);
 
290
 
 
291
        /* add new merge targets to weld operator */
 
292
        BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
 
293
                v2 = BMO_iter_map_value_p(&oiter);
 
294
                BMO_slot_map_ptr_insert(bm, weld_op, "targetmap", v, v2);
 
295
        }
 
296
 
 
297
        BMO_op_finish(bm, &find_op);
187
298
}
188
299
 
189
300
static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
190
 
                                          struct Scene *scene, Object *ob, DerivedMesh *dm,
191
 
           int initFlags)
 
301
                                          Scene *scene, Object *ob, DerivedMesh *dm,
 
302
                                          int UNUSED(initFlags))
192
303
{
193
 
        int i, j;
 
304
        DerivedMesh *result;
 
305
        BMEditMesh *em = DM_to_editbmesh(dm, NULL, FALSE);
 
306
        BMOperator first_dupe_op, dupe_op, old_dupe_op, weld_op;
 
307
        BMVert **first_geom = NULL;
 
308
        int i, j, indexLen;
194
309
        /* offset matrix */
195
310
        float offset[4][4];
196
311
        float final_offset[4][4];
197
312
        float tmp_mat[4][4];
198
313
        float length = amd->length;
199
 
        int count = amd->count;
200
 
        int numVerts, numEdges, numFaces;
201
 
        int maxVerts, maxEdges, maxFaces;
202
 
        int finalVerts, finalEdges, finalFaces;
203
 
        DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
204
 
        MVert *mvert, *src_mvert;
205
 
        MEdge *medge;
206
 
        MFace *mface;
207
 
 
208
 
        IndexMapEntry *indexMap;
209
 
 
210
 
        EdgeHash *edges;
 
314
        int count = amd->count, maxVerts;
 
315
        int *indexMap = NULL;
 
316
        DerivedMesh *start_cap = NULL, *end_cap = NULL;
 
317
        MVert *src_mvert;
211
318
 
212
319
        /* need to avoid infinite recursion here */
213
 
        if(amd->start_cap && amd->start_cap != ob)
214
 
                start_cap = amd->start_cap->derivedFinal;
215
 
        if(amd->end_cap && amd->end_cap != ob)
216
 
                end_cap = amd->end_cap->derivedFinal;
 
320
        if (amd->start_cap && amd->start_cap != ob)
 
321
                start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
 
322
        if (amd->end_cap && amd->end_cap != ob)
 
323
                end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
217
324
 
218
325
        unit_m4(offset);
219
326
 
220
 
        indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
221
 
                                   "indexmap");
222
 
 
223
327
        src_mvert = dm->getVertArray(dm);
224
 
 
225
328
        maxVerts = dm->getNumVerts(dm);
226
329
 
227
 
        if(amd->offset_type & MOD_ARR_OFF_CONST)
228
 
                add_v3_v3(offset[3], amd->offset);
229
 
        if(amd->offset_type & MOD_ARR_OFF_RELATIVE) {
230
 
                for(j = 0; j < 3; j++)
 
330
        if (amd->offset_type & MOD_ARR_OFF_CONST)
 
331
                add_v3_v3v3(offset[3], offset[3], amd->offset);
 
332
        if (amd->offset_type & MOD_ARR_OFF_RELATIVE) {
 
333
                for (j = 0; j < 3; j++)
231
334
                        offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
232
335
                                        maxVerts, j);
233
336
        }
234
337
 
235
 
        if((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
 
338
        if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
236
339
                float obinv[4][4];
237
340
                float result_mat[4][4];
238
341
 
239
 
                if(ob)
 
342
                if (ob)
240
343
                        invert_m4_m4(obinv, ob->obmat);
241
344
                else
242
345
                        unit_m4(obinv);
243
346
 
244
347
                mul_serie_m4(result_mat, offset,
245
 
                                 obinv, amd->offset_ob->obmat,
246
 
         NULL, NULL, NULL, NULL, NULL);
 
348
                             obinv, amd->offset_ob->obmat,
 
349
                             NULL, NULL, NULL, NULL, NULL);
247
350
                copy_m4_m4(offset, result_mat);
248
351
        }
249
352
 
250
 
        if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
 
353
        if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
251
354
                Curve *cu = amd->curve_ob->data;
252
 
                if(cu) {
 
355
                if (cu) {
253
356
                        float tmp_mat[3][3];
254
357
                        float scale;
255
358
                        
256
359
                        object_to_mat3(amd->curve_ob, tmp_mat);
257
360
                        scale = mat3_to_scale(tmp_mat);
258
361
                                
259
 
                        if(!cu->path) {
 
362
                        if (!cu->path) {
260
363
                                cu->flag |= CU_PATH; // needed for path & bevlist
261
364
                                makeDispListCurveTypes(scene, amd->curve_ob, 0);
262
365
                        }
263
 
                        if(cu->path)
 
366
                        if (cu->path)
264
367
                                length = scale*cu->path->totdist;
265
368
                }
266
369
        }
267
370
 
268
371
        /* calculate the maximum number of copies which will fit within the
269
 
        prescribed length */
270
 
        if(amd->fit_type == MOD_ARR_FITLENGTH
271
 
                  || amd->fit_type == MOD_ARR_FITCURVE) {
 
372
         * prescribed length */
 
373
        if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) {
272
374
                float dist = sqrt(dot_v3v3(offset[3], offset[3]));
273
375
 
274
 
                if(dist > 1e-6f)
 
376
                if (dist > 1e-6f)
275
377
                        /* this gives length = first copy start to last copy end
276
 
                        add a tiny offset for floating point rounding errors */
 
378
                         * add a tiny offset for floating point rounding errors */
277
379
                        count = (length + 1e-6f) / dist;
278
380
                else
279
381
                        /* if the offset has no translation, just make one copy */
280
382
                        count = 1;
281
 
                  }
282
 
 
283
 
                  if(count < 1)
284
 
                          count = 1;
285
 
 
286
 
        /* allocate memory for count duplicates (including original) plus
287
 
                  * start and end caps
288
 
        */
289
 
                  finalVerts = dm->getNumVerts(dm) * count;
290
 
                  finalEdges = dm->getNumEdges(dm) * count;
291
 
                  finalFaces = dm->getNumFaces(dm) * count;
292
 
                  if(start_cap) {
293
 
                          finalVerts += start_cap->getNumVerts(start_cap);
294
 
                          finalEdges += start_cap->getNumEdges(start_cap);
295
 
                          finalFaces += start_cap->getNumFaces(start_cap);
296
 
                  }
297
 
                  if(end_cap) {
298
 
                          finalVerts += end_cap->getNumVerts(end_cap);
299
 
                          finalEdges += end_cap->getNumEdges(end_cap);
300
 
                          finalFaces += end_cap->getNumFaces(end_cap);
301
 
                  }
302
 
                  result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
303
 
 
304
 
                  /* calculate the offset matrix of the final copy (for merging) */ 
305
 
                  unit_m4(final_offset);
306
 
 
307
 
                  for(j=0; j < count - 1; j++) {
308
 
                          mul_m4_m4m4(tmp_mat, final_offset, offset);
309
 
                          copy_m4_m4(final_offset, tmp_mat);
310
 
                  }
311
 
 
312
 
                  numVerts = numEdges = numFaces = 0;
313
 
                  mvert = CDDM_get_verts(result);
314
 
 
315
 
                  for (i = 0; i < maxVerts; i++) {
316
 
                          indexMap[i].merge = -1; /* default to no merge */
317
 
                          indexMap[i].merge_final = 0; /* default to no merge */
318
 
                  }
319
 
 
320
 
                  for (i = 0; i < maxVerts; i++) {
321
 
                          MVert *inMV;
322
 
                          MVert *mv = &mvert[numVerts];
323
 
                          MVert *mv2;
324
 
                          float co[3];
325
 
 
326
 
                          inMV = &src_mvert[i];
327
 
 
328
 
                          DM_copy_vert_data(dm, result, i, numVerts, 1);
329
 
                          *mv = *inMV;
330
 
                          numVerts++;
331
 
 
332
 
                          indexMap[i].new = numVerts - 1;
333
 
 
334
 
                          copy_v3_v3(co, mv->co);
335
 
                
336
 
                /* Attempts to merge verts from one duplicate with verts from the
337
 
                          * next duplicate which are closer than amd->merge_dist.
338
 
                          * Only the first such vert pair is merged.
339
 
                          * If verts are merged in the first duplicate pair, they are merged
340
 
                          * in all pairs.
341
 
                */
342
 
                          if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
343
 
                                  float tmp_co[3];
344
 
                                  mul_v3_m4v3(tmp_co, offset, mv->co);
345
 
 
346
 
                                  for(j = 0; j < maxVerts; j++) {
347
 
                                          /* if vertex already merged, don't use it */
348
 
                                          if( indexMap[j].merge != -1 ) continue;
349
 
 
350
 
                                          inMV = &src_mvert[j];
351
 
                                          /* if this vert is within merge limit, merge */
352
 
                                          if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) {
353
 
                                                  indexMap[i].merge = j;
354
 
 
355
 
                                                  /* test for merging with final copy of merge target */
356
 
                                                  if(amd->flags & MOD_ARR_MERGEFINAL) {
357
 
                                                          copy_v3_v3(tmp_co, inMV->co);
358
 
                                                          inMV = &src_mvert[i];
359
 
                                                          mul_m4_v3(final_offset, tmp_co);
360
 
                                                          if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist))
361
 
                                                                  indexMap[i].merge_final = 1;
362
 
                                                  }
363
 
                                                  break;
364
 
                                          }
365
 
                                  }
366
 
                          }
367
 
 
368
 
                          /* if no merging, generate copies of this vert */
369
 
                          if(indexMap[i].merge < 0) {
370
 
                                  for(j=0; j < count - 1; j++) {
371
 
                                          mv2 = &mvert[numVerts];
372
 
 
373
 
                                          DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1);
374
 
                                          *mv2 = *mv;
375
 
                                          numVerts++;
376
 
 
377
 
                                          mul_m4_v3(offset, co);
378
 
                                          copy_v3_v3(mv2->co, co);
379
 
                                  }
380
 
                          } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
381
 
                        /* if this vert is not merging with itself, and it is merging
382
 
                                  * with the final copy of its merge target, remove the first copy
383
 
                        */
384
 
                                  numVerts--;
385
 
                                  DM_free_vert_data(result, numVerts, 1);
386
 
                          }
387
 
                  }
388
 
 
389
 
                  /* make a hashtable so we can avoid duplicate edges from merging */
390
 
                  edges = BLI_edgehash_new();
391
 
 
392
 
                  maxEdges = dm->getNumEdges(dm);
393
 
                  medge = CDDM_get_edges(result);
394
 
                  for(i = 0; i < maxEdges; i++) {
395
 
                          MEdge inMED;
396
 
                          MEdge med;
397
 
                          MEdge *med2;
398
 
                          int vert1, vert2;
399
 
 
400
 
                          dm->getEdge(dm, i, &inMED);
401
 
 
402
 
                          med = inMED;
403
 
                          med.v1 = indexMap[inMED.v1].new;
404
 
                          med.v2 = indexMap[inMED.v2].new;
405
 
 
406
 
                /* if vertices are to be merged with the final copies of their
407
 
                          * merge targets, calculate that final copy
408
 
                */
409
 
                          if(indexMap[inMED.v1].merge_final) {
410
 
                                  med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge,
411
 
                                                  count - 1);
412
 
                          }
413
 
                          if(indexMap[inMED.v2].merge_final) {
414
 
                                  med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge,
415
 
                                                  count - 1);
416
 
                          }
417
 
 
418
 
                          if(med.v1 == med.v2) continue;
419
 
 
420
 
                          if (initFlags) {
421
 
                                  med.flag |= ME_EDGEDRAW | ME_EDGERENDER;
422
 
                          }
423
 
 
424
 
                          if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) {
425
 
                                  DM_copy_edge_data(dm, result, i, numEdges, 1);
426
 
                                  medge[numEdges] = med;
427
 
                                  numEdges++;
428
 
 
429
 
                                  BLI_edgehash_insert(edges, med.v1, med.v2, NULL);
430
 
                          }
431
 
 
432
 
                          for(j = 1; j < count; j++)
433
 
                          {
434
 
                                  vert1 = calc_mapping(indexMap, inMED.v1, j);
435
 
                                  vert2 = calc_mapping(indexMap, inMED.v2, j);
436
 
                                  /* avoid duplicate edges */
437
 
                                  if(!BLI_edgehash_haskey(edges, vert1, vert2)) {
438
 
                                          med2 = &medge[numEdges];
439
 
 
440
 
                                          DM_copy_edge_data(dm, result, i, numEdges, 1);
441
 
                                          *med2 = med;
442
 
                                          numEdges++;
443
 
 
444
 
                                          med2->v1 = vert1;
445
 
                                          med2->v2 = vert2;
446
 
 
447
 
                                          BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL);
448
 
                                  }
449
 
                          }
450
 
                  }
451
 
 
452
 
                  maxFaces = dm->getNumFaces(dm);
453
 
                  mface = CDDM_get_faces(result);
454
 
                  for (i=0; i < maxFaces; i++) {
455
 
                          MFace inMF;
456
 
                          MFace *mf = &mface[numFaces];
457
 
 
458
 
                          dm->getFace(dm, i, &inMF);
459
 
 
460
 
                          DM_copy_face_data(dm, result, i, numFaces, 1);
461
 
                          *mf = inMF;
462
 
 
463
 
                          mf->v1 = indexMap[inMF.v1].new;
464
 
                          mf->v2 = indexMap[inMF.v2].new;
465
 
                          mf->v3 = indexMap[inMF.v3].new;
466
 
                          if(inMF.v4)
467
 
                                  mf->v4 = indexMap[inMF.v4].new;
468
 
 
469
 
                /* if vertices are to be merged with the final copies of their
470
 
                          * merge targets, calculate that final copy
471
 
                */
472
 
                          if(indexMap[inMF.v1].merge_final)
473
 
                                  mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1);
474
 
                          if(indexMap[inMF.v2].merge_final)
475
 
                                  mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1);
476
 
                          if(indexMap[inMF.v3].merge_final)
477
 
                                  mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1);
478
 
                          if(inMF.v4 && indexMap[inMF.v4].merge_final)
479
 
                                  mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1);
480
 
 
481
 
                          if(test_index_face(mf, &result->faceData, numFaces, inMF.v4?4:3) < 3)
482
 
                                  continue;
483
 
 
484
 
                          numFaces++;
485
 
 
486
 
                          /* if the face has fewer than 3 vertices, don't create it */
487
 
                          if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) {
488
 
                                  numFaces--;
489
 
                                  DM_free_face_data(result, numFaces, 1);
490
 
                          }
491
 
 
492
 
                          for(j = 1; j < count; j++)
493
 
                          {
494
 
                                  MFace *mf2 = &mface[numFaces];
495
 
 
496
 
                                  DM_copy_face_data(dm, result, i, numFaces, 1);
497
 
                                  *mf2 = *mf;
498
 
 
499
 
                                  mf2->v1 = calc_mapping(indexMap, inMF.v1, j);
500
 
                                  mf2->v2 = calc_mapping(indexMap, inMF.v2, j);
501
 
                                  mf2->v3 = calc_mapping(indexMap, inMF.v3, j);
502
 
                                  if (inMF.v4)
503
 
                                          mf2->v4 = calc_mapping(indexMap, inMF.v4, j);
504
 
 
505
 
                                  test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
506
 
                                  numFaces++;
507
 
 
508
 
                                  /* if the face has fewer than 3 vertices, don't create it */
509
 
                                  if(mf2->v3 == 0 || (mf2->v1 && (mf2->v1 == mf2->v3 || mf2->v1 ==
510
 
                                                                 mf2->v4))) {
511
 
                                          numFaces--;
512
 
                                          DM_free_face_data(result, numFaces, 1);
513
 
                                                                 }
514
 
                          }
515
 
                  }
516
 
 
517
 
                  /* add start and end caps */
518
 
                  if(start_cap) {
519
 
                          float startoffset[4][4];
520
 
                          MVert *cap_mvert;
521
 
                          MEdge *cap_medge;
522
 
                          MFace *cap_mface;
523
 
                          int *origindex;
524
 
                          int *vert_map;
525
 
                          int capVerts, capEdges, capFaces;
526
 
 
527
 
                          capVerts = start_cap->getNumVerts(start_cap);
528
 
                          capEdges = start_cap->getNumEdges(start_cap);
529
 
                          capFaces = start_cap->getNumFaces(start_cap);
530
 
                          cap_mvert = start_cap->getVertArray(start_cap);
531
 
                          cap_medge = start_cap->getEdgeArray(start_cap);
532
 
                          cap_mface = start_cap->getFaceArray(start_cap);
533
 
 
534
 
                          invert_m4_m4(startoffset, offset);
535
 
 
536
 
                          vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
537
 
                                          "arrayModifier_doArray vert_map");
538
 
 
539
 
                          origindex = result->getVertDataArray(result, CD_ORIGINDEX);
540
 
                          for(i = 0; i < capVerts; i++) {
541
 
                                  MVert *mv = &cap_mvert[i];
542
 
                                  short merged = 0;
543
 
 
544
 
                                  if(amd->flags & MOD_ARR_MERGE) {
545
 
                                          float tmp_co[3];
546
 
                                          MVert *in_mv;
547
 
                                          int j;
548
 
 
549
 
                                          copy_v3_v3(tmp_co, mv->co);
550
 
                                          mul_m4_v3(startoffset, tmp_co);
551
 
 
552
 
                                          for(j = 0; j < maxVerts; j++) {
553
 
                                                  in_mv = &src_mvert[j];
554
 
                                                  /* if this vert is within merge limit, merge */
555
 
                                                  if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
556
 
                                                          vert_map[i] = calc_mapping(indexMap, j, 0);
557
 
                                                          merged = 1;
558
 
                                                          break;
559
 
                                                  }
560
 
                                          }
561
 
                                  }
562
 
 
563
 
                                  if(!merged) {
564
 
                                          DM_copy_vert_data(start_cap, result, i, numVerts, 1);
565
 
                                          mvert[numVerts] = *mv;
566
 
                                          mul_m4_v3(startoffset, mvert[numVerts].co);
567
 
                                          origindex[numVerts] = ORIGINDEX_NONE;
568
 
 
569
 
                                          vert_map[i] = numVerts;
570
 
 
571
 
                                          numVerts++;
572
 
                                  }
573
 
                          }
574
 
                          origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
575
 
                          for(i = 0; i < capEdges; i++) {
576
 
                                  int v1, v2;
577
 
 
578
 
                                  v1 = vert_map[cap_medge[i].v1];
579
 
                                  v2 = vert_map[cap_medge[i].v2];
580
 
 
581
 
                                  if(!BLI_edgehash_haskey(edges, v1, v2)) {
582
 
                                          DM_copy_edge_data(start_cap, result, i, numEdges, 1);
583
 
                                          medge[numEdges] = cap_medge[i];
584
 
                                          medge[numEdges].v1 = v1;
585
 
                                          medge[numEdges].v2 = v2;
586
 
                                          origindex[numEdges] = ORIGINDEX_NONE;
587
 
 
588
 
                                          numEdges++;
589
 
                                  }
590
 
                          }
591
 
                          origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
592
 
                          for(i = 0; i < capFaces; i++) {
593
 
                                  DM_copy_face_data(start_cap, result, i, numFaces, 1);
594
 
                                  mface[numFaces] = cap_mface[i];
595
 
                                  mface[numFaces].v1 = vert_map[mface[numFaces].v1];
596
 
                                  mface[numFaces].v2 = vert_map[mface[numFaces].v2];
597
 
                                  mface[numFaces].v3 = vert_map[mface[numFaces].v3];
598
 
                                  if(mface[numFaces].v4) {
599
 
                                          mface[numFaces].v4 = vert_map[mface[numFaces].v4];
600
 
 
601
 
                                          test_index_face(&mface[numFaces], &result->faceData,
602
 
                                                                          numFaces, 4);
603
 
                                  }
604
 
                                  else
605
 
                                  {
606
 
                                          test_index_face(&mface[numFaces], &result->faceData,
607
 
                                                                          numFaces, 3);
608
 
                                  }
609
 
 
610
 
                                  origindex[numFaces] = ORIGINDEX_NONE;
611
 
 
612
 
                                  numFaces++;
613
 
                          }
614
 
 
615
 
                          MEM_freeN(vert_map);
616
 
                          start_cap->release(start_cap);
617
 
                  }
618
 
 
619
 
                  if(end_cap) {
620
 
                          float endoffset[4][4];
621
 
                          MVert *cap_mvert;
622
 
                          MEdge *cap_medge;
623
 
                          MFace *cap_mface;
624
 
                          int *origindex;
625
 
                          int *vert_map;
626
 
                          int capVerts, capEdges, capFaces;
627
 
 
628
 
                          capVerts = end_cap->getNumVerts(end_cap);
629
 
                          capEdges = end_cap->getNumEdges(end_cap);
630
 
                          capFaces = end_cap->getNumFaces(end_cap);
631
 
                          cap_mvert = end_cap->getVertArray(end_cap);
632
 
                          cap_medge = end_cap->getEdgeArray(end_cap);
633
 
                          cap_mface = end_cap->getFaceArray(end_cap);
634
 
 
635
 
                          mul_m4_m4m4(endoffset, final_offset, offset);
636
 
 
637
 
                          vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
638
 
                                          "arrayModifier_doArray vert_map");
639
 
 
640
 
                          origindex = result->getVertDataArray(result, CD_ORIGINDEX);
641
 
                          for(i = 0; i < capVerts; i++) {
642
 
                                  MVert *mv = &cap_mvert[i];
643
 
                                  short merged = 0;
644
 
 
645
 
                                  if(amd->flags & MOD_ARR_MERGE) {
646
 
                                          float tmp_co[3];
647
 
                                          MVert *in_mv;
648
 
                                          int j;
649
 
 
650
 
                                          copy_v3_v3(tmp_co, mv->co);
651
 
                                          mul_m4_v3(offset, tmp_co);
652
 
 
653
 
                                          for(j = 0; j < maxVerts; j++) {
654
 
                                                  in_mv = &src_mvert[j];
655
 
                                                  /* if this vert is within merge limit, merge */
656
 
                                                  if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
657
 
                                                          vert_map[i] = calc_mapping(indexMap, j, count - 1);
658
 
                                                          merged = 1;
659
 
                                                          break;
660
 
                                                  }
661
 
                                          }
662
 
                                  }
663
 
 
664
 
                                  if(!merged) {
665
 
                                          DM_copy_vert_data(end_cap, result, i, numVerts, 1);
666
 
                                          mvert[numVerts] = *mv;
667
 
                                          mul_m4_v3(endoffset, mvert[numVerts].co);
668
 
                                          origindex[numVerts] = ORIGINDEX_NONE;
669
 
 
670
 
                                          vert_map[i] = numVerts;
671
 
 
672
 
                                          numVerts++;
673
 
                                  }
674
 
                          }
675
 
                          origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
676
 
                          for(i = 0; i < capEdges; i++) {
677
 
                                  int v1, v2;
678
 
 
679
 
                                  v1 = vert_map[cap_medge[i].v1];
680
 
                                  v2 = vert_map[cap_medge[i].v2];
681
 
 
682
 
                                  if(!BLI_edgehash_haskey(edges, v1, v2)) {
683
 
                                          DM_copy_edge_data(end_cap, result, i, numEdges, 1);
684
 
                                          medge[numEdges] = cap_medge[i];
685
 
                                          medge[numEdges].v1 = v1;
686
 
                                          medge[numEdges].v2 = v2;
687
 
                                          origindex[numEdges] = ORIGINDEX_NONE;
688
 
 
689
 
                                          numEdges++;
690
 
                                  }
691
 
                          }
692
 
                          origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
693
 
                          for(i = 0; i < capFaces; i++) {
694
 
                                  DM_copy_face_data(end_cap, result, i, numFaces, 1);
695
 
                                  mface[numFaces] = cap_mface[i];
696
 
                                  mface[numFaces].v1 = vert_map[mface[numFaces].v1];
697
 
                                  mface[numFaces].v2 = vert_map[mface[numFaces].v2];
698
 
                                  mface[numFaces].v3 = vert_map[mface[numFaces].v3];
699
 
                                  if(mface[numFaces].v4) {
700
 
                                          mface[numFaces].v4 = vert_map[mface[numFaces].v4];
701
 
 
702
 
                                          test_index_face(&mface[numFaces], &result->faceData,
703
 
                                                                          numFaces, 4);
704
 
                                  }
705
 
                                  else
706
 
                                  {
707
 
                                          test_index_face(&mface[numFaces], &result->faceData,
708
 
                                                                          numFaces, 3);
709
 
                                  }
710
 
                                  origindex[numFaces] = ORIGINDEX_NONE;
711
 
 
712
 
                                  numFaces++;
713
 
                          }
714
 
 
715
 
                          MEM_freeN(vert_map);
716
 
                          end_cap->release(end_cap);
717
 
                  }
718
 
 
719
 
                  BLI_edgehash_free(edges, NULL);
720
 
                  MEM_freeN(indexMap);
721
 
 
722
 
                  CDDM_lower_num_verts(result, numVerts);
723
 
                  CDDM_lower_num_edges(result, numEdges);
724
 
                  CDDM_lower_num_faces(result, numFaces);
725
 
 
726
 
                  return result;
727
 
}
728
 
 
729
 
static DerivedMesh *applyModifier(
730
 
                ModifierData *md, Object *ob, DerivedMesh *derivedData,
731
 
  int useRenderParams, int isFinalCalc)
732
 
{
733
 
        DerivedMesh *result;
734
 
        ArrayModifierData *amd = (ArrayModifierData*) md;
735
 
 
736
 
        result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
737
 
 
738
 
        if(result != derivedData)
 
383
        }
 
384
 
 
385
        if (count < 1)
 
386
                count = 1;
 
387
 
 
388
        /* calculate the offset matrix of the final copy (for merging) */
 
389
        unit_m4(final_offset);
 
390
 
 
391
        for (j=0; j < count - 1; j++) {
 
392
                mult_m4_m4m4(tmp_mat, offset, final_offset);
 
393
                copy_m4_m4(final_offset, tmp_mat);
 
394
        }
 
395
 
 
396
        /* BMESH_TODO: bumping up the stack level avoids computing the normals
 
397
         * after every top-level operator execution (and this modifier has the
 
398
         * potential to execute a *lot* of top-level BMOps. There should be a
 
399
         * cleaner way to do this. One possibility: a "mirror" BMOp would
 
400
         * certainly help by compressing it all into one top-level BMOp that
 
401
         * 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");
 
409
        first_dupe_op = dupe_op;
 
410
 
 
411
        for (j=0; j < count - 1; j++) {
 
412
                BMVert *v, *v2, *v3;
 
413
                BMOpSlot *geom_slot;
 
414
                BMOpSlot *newout_slot;
 
415
                BMOIter oiter;
 
416
 
 
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);
 
420
 
 
421
                geom_slot = BMO_slot_get(&dupe_op, "geom");
 
422
                newout_slot = BMO_slot_get(&dupe_op, "newout");
 
423
 
 
424
                if ((amd->flags & MOD_ARR_MERGEFINAL) && j == 0) {
 
425
                        int first_geom_bytes = sizeof(BMVert*) * geom_slot->len;
 
426
                                
 
427
                        /* make a copy of the initial geometry ordering so the
 
428
                         * last duplicate can be merged into it */
 
429
                        first_geom = MEM_mallocN(first_geom_bytes, "first_geom");
 
430
                        memcpy(first_geom, geom_slot->data.buf, first_geom_bytes);
 
431
                }
 
432
 
 
433
                /* apply transformation matrix */
 
434
                BMO_ITER (v, &oiter, em->bm, &dupe_op, "newout", BM_VERT) {
 
435
                        mul_m4_v3(offset, v->co);
 
436
                }
 
437
 
 
438
                if (amd->flags & MOD_ARR_MERGE) {
 
439
                        /*calculate merge mapping*/
 
440
                        if (j == 0) {
 
441
                                indexMap = find_doubles_index_map(em->bm, &dupe_op,
 
442
                                                                                                  amd, &indexLen);
 
443
                        }
 
444
 
 
445
                        #define _E(s, i) ((BMVert **)(s)->data.buf)[i]
 
446
 
 
447
                        for (i=0; i<indexLen; i++) {
 
448
                                if (!indexMap[i]) continue;
 
449
 
 
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);
 
453
 
 
454
                                /* check in case the target vertex (v2) is already marked
 
455
                                 * for merging */
 
456
                                while ((v3 = BMO_slot_map_ptr_get(em->bm, &weld_op, "targetmap", v2))) {
 
457
                                        v2 = v3;
 
458
                                }
 
459
 
 
460
                                BMO_slot_map_ptr_insert(em->bm, &weld_op, "targetmap", v, v2);
 
461
                        }
 
462
 
 
463
                        #undef _E
 
464
                }
 
465
 
 
466
                /* already copied earlier, but after executation more slot
 
467
                 * memory may be allocated */
 
468
                if (j == 0)
 
469
                        first_dupe_op = dupe_op;
 
470
                
 
471
                if (j >= 2)
 
472
                        BMO_op_finish(em->bm, &old_dupe_op);
 
473
                old_dupe_op = dupe_op;
 
474
        }
 
475
 
 
476
        if ((amd->flags & MOD_ARR_MERGE) &&
 
477
            (amd->flags & MOD_ARR_MERGEFINAL) &&
 
478
            (count > 1))
 
479
        {
 
480
                /* Merge first and last copies. Note that we can't use the
 
481
                 * indexMap for this because (unless the array is forming a
 
482
                 * loop) the offset between first and last is different from
 
483
                 * dupe X to dupe X+1. */
 
484
 
 
485
                merge_first_last(em->bm, amd, &first_dupe_op, &dupe_op, &weld_op);
 
486
        }
 
487
 
 
488
        /* start capping */
 
489
        if (start_cap || end_cap) {
 
490
                BM_mesh_elem_hflag_enable_all(em->bm, BM_VERT, BM_ELEM_TAG, FALSE);
 
491
 
 
492
                if (start_cap) {
 
493
                        float startoffset[4][4];
 
494
                        invert_m4_m4(startoffset, offset);
 
495
                        bm_merge_dm_transform(em->bm, start_cap, startoffset, amd,
 
496
                                                  &first_dupe_op, "geom", &weld_op);
 
497
                }
 
498
 
 
499
                if (end_cap) {
 
500
                        float endoffset[4][4];
 
501
                        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);
 
504
                }
 
505
        }
 
506
        /* done capping */
 
507
 
 
508
        /* free remaining dupe operators */
 
509
        BMO_op_finish(em->bm, &first_dupe_op);
 
510
        if (count > 2)
 
511
                BMO_op_finish(em->bm, &dupe_op);
 
512
 
 
513
        /* run merge operator */
 
514
        if (amd->flags & MOD_ARR_MERGE) {
 
515
                BMO_op_exec(em->bm, &weld_op);
 
516
                BMO_op_finish(em->bm, &weld_op);
 
517
        }
 
518
 
 
519
        /* Bump the stack level back down to match the adjustment up above */
 
520
        BMO_pop(em->bm);
 
521
 
 
522
        BLI_assert(em->looptris == NULL);
 
523
        result = CDDM_from_BMEditMesh(em, NULL, FALSE, FALSE);
 
524
 
 
525
        if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
 
526
                /* Update normals in case offset object has rotation. */
 
527
                
 
528
                /* BMESH_TODO: check if normal recalc needed under any other
 
529
                 * conditions? */
 
530
 
739
531
                CDDM_calc_normals(result);
740
 
 
741
 
        return result;
742
 
}
743
 
 
744
 
static DerivedMesh *applyModifierEM(
745
 
                ModifierData *md, Object *ob, struct EditMesh *editData,
746
 
  DerivedMesh *derivedData)
747
 
{
748
 
        return applyModifier(md, ob, derivedData, 0, 1);
 
532
        }
 
533
 
 
534
        BMEdit_Free(em);
 
535
        MEM_freeN(em);
 
536
        if (indexMap)
 
537
                MEM_freeN(indexMap);
 
538
        if (first_geom)
 
539
                MEM_freeN(first_geom);
 
540
 
 
541
        return result;
 
542
}
 
543
 
 
544
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 
545
                                                DerivedMesh *dm,
 
546
                                                int UNUSED(useRenderParams),
 
547
                                                int UNUSED(isFinalCalc))
 
548
{
 
549
        DerivedMesh *result;
 
550
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
551
 
 
552
        result = arrayModifier_doArray(amd, md->scene, ob, dm, 0);
 
553
 
 
554
        //if (result != dm)
 
555
        //      CDDM_calc_normals_mapping(result);
 
556
 
 
557
        return result;
 
558
}
 
559
 
 
560
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
 
561
                                                struct BMEditMesh *UNUSED(editData),
 
562
                                                DerivedMesh *dm)
 
563
{
 
564
        return applyModifier(md, ob, dm, 0, 1);
749
565
}
750
566
 
751
567
 
761
577
                                                        | eModifierTypeFlag_AcceptsCVs,
762
578
 
763
579
        /* copyData */          copyData,
764
 
        /* deformVerts */       0,
765
 
        /* deformVertsEM */     0,
766
 
        /* deformMatricesEM */  0,
 
580
        /* deformVerts */       NULL,
 
581
        /* deformMatrices */    NULL,
 
582
        /* deformVertsEM */     NULL,
 
583
        /* deformMatricesEM */  NULL,
767
584
        /* applyModifier */     applyModifier,
768
585
        /* applyModifierEM */   applyModifierEM,
769
586
        /* initData */          initData,
770
 
        /* requiredDataMask */  0,
771
 
        /* freeData */          0,
772
 
        /* isDisabled */        0,
 
587
        /* requiredDataMask */  NULL,
 
588
        /* freeData */          NULL,
 
589
        /* isDisabled */        NULL,
773
590
        /* updateDepgraph */    updateDepgraph,
774
 
        /* dependsOnTime */     0,
 
591
        /* dependsOnTime */     NULL,
 
592
        /* dependsOnNormals */  NULL,
775
593
        /* foreachObjectLink */ foreachObjectLink,
776
 
        /* foreachIDLink */     0,
 
594
        /* foreachIDLink */     NULL,
 
595
        /* foreachTexLink */    NULL,
777
596
};