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

« back to all changes in this revision

Viewing changes to source/blender/modifiers/intern/MOD_mask.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:
45
45
#include "DNA_modifier_types.h"
46
46
#include "DNA_object_types.h"
47
47
 
48
 
#include "BKE_action.h" /* get_pose_channel */
 
48
#include "BKE_action.h" /* BKE_pose_channel_find_name */
49
49
#include "BKE_cdderivedmesh.h"
50
50
#include "BKE_mesh.h"
51
51
#include "BKE_modifier.h"
57
57
 
58
58
static void copyData(ModifierData *md, ModifierData *target)
59
59
{
60
 
        MaskModifierData *mmd = (MaskModifierData*) md;
61
 
        MaskModifierData *tmmd = (MaskModifierData*) target;
 
60
        MaskModifierData *mmd = (MaskModifierData *) md;
 
61
        MaskModifierData *tmmd = (MaskModifierData *) target;
62
62
        
63
63
        BLI_strncpy(tmmd->vgroup, mmd->vgroup, sizeof(tmmd->vgroup));
64
64
        tmmd->flag = mmd->flag;
70
70
}
71
71
 
72
72
static void foreachObjectLink(
73
 
                                                  ModifierData *md, Object *ob,
74
 
           void (*walk)(void *userData, Object *ob, Object **obpoin),
75
 
                  void *userData)
 
73
        ModifierData *md, Object *ob,
 
74
        void (*walk)(void *userData, Object *ob, Object **obpoin),
 
75
        void *userData)
76
76
{
77
77
        MaskModifierData *mmd = (MaskModifierData *)md;
78
78
        walk(userData, ob, &mmd->ob_arm);
79
79
}
80
80
 
81
81
static void updateDepgraph(ModifierData *md, DagForest *forest,
82
 
                                                struct Scene *UNUSED(scene),
83
 
                                                Object *UNUSED(ob),
84
 
                                                DagNode *obNode)
 
82
                           struct Scene *UNUSED(scene),
 
83
                           Object *UNUSED(ob),
 
84
                           DagNode *obNode)
85
85
{
86
86
        MaskModifierData *mmd = (MaskModifierData *)md;
87
87
 
88
88
        if (mmd->ob_arm) {
 
89
                bArmature *arm = (bArmature *)mmd->ob_arm->data;
89
90
                DagNode *armNode = dag_get_node(forest, mmd->ob_arm);
90
91
                
 
92
                /* tag relationship in depsgraph, but also on the armature */
91
93
                dag_add_relation(forest, armNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mask Modifier");
 
94
                arm->flag |= ARM_HAS_VIZ_DEPS;
92
95
        }
93
96
}
94
97
 
95
98
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
96
 
                                                DerivedMesh *derivedData,
97
 
                                                int UNUSED(useRenderParams),
98
 
                                                int UNUSED(isFinalCalc))
 
99
                                  DerivedMesh *derivedData,
 
100
                                  ModifierApplyFlag UNUSED(flag))
99
101
{
100
 
        MaskModifierData *mmd= (MaskModifierData *)md;
101
 
        DerivedMesh *dm= derivedData, *result= NULL;
102
 
        GHash *vertHash=NULL, *edgeHash, *polyHash;
 
102
        MaskModifierData *mmd = (MaskModifierData *)md;
 
103
        DerivedMesh *dm = derivedData, *result = NULL;
 
104
        GHash *vertHash = NULL, *edgeHash, *polyHash;
103
105
        GHashIterator *hashIter;
104
 
        MDeformVert *dvert= NULL, *dv;
105
 
        int numPolys=0, numLoops=0, numEdges=0, numVerts=0;
 
106
        MDeformVert *dvert = NULL, *dv;
 
107
        int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
106
108
        int maxVerts, maxEdges, maxPolys;
107
109
        int i;
108
110
 
124
126
         */
125
127
        
126
128
        /* get original number of verts, edges, and faces */
127
 
        maxVerts= dm->getNumVerts(dm);
128
 
        maxEdges= dm->getNumEdges(dm);
129
 
        maxPolys= dm->getNumPolys(dm);
 
129
        maxVerts = dm->getNumVerts(dm);
 
130
        maxEdges = dm->getNumEdges(dm);
 
131
        maxPolys = dm->getNumPolys(dm);
130
132
        
131
133
        /* check if we can just return the original mesh 
132
134
         *      - must have verts and therefore verts assigned to vgroups to do anything useful
133
135
         */
134
 
        if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
135
 
                 (maxVerts == 0) || (ob->defbase.first == NULL) )
 
136
        if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
 
137
            (maxVerts == 0) || (ob->defbase.first == NULL) )
136
138
        {
137
139
                return derivedData;
138
140
        }
139
141
        
140
142
        /* if mode is to use selected armature bones, aggregate the bone groups */
141
143
        if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */
142
 
                GHash *vgroupHash;
143
 
                Object *oba= mmd->ob_arm;
 
144
                Object *oba = mmd->ob_arm;
144
145
                bPoseChannel *pchan;
145
146
                bDeformGroup *def;
146
147
                char *bone_select_array;
147
 
                int bone_select_tot= 0;
148
 
                const int defbase_tot= BLI_countlist(&ob->defbase);
149
 
 
 
148
                int bone_select_tot = 0;
 
149
                const int defbase_tot = BLI_countlist(&ob->defbase);
 
150
                
150
151
                /* check that there is armature object with bones to use, otherwise return original mesh */
151
 
                if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first))
 
152
                if (ELEM3(NULL, oba, oba->pose, ob->defbase.first))
152
153
                        return derivedData;
153
 
 
154
 
                bone_select_array= MEM_mallocN(defbase_tot * sizeof(char), "mask array");
155
 
 
 
154
                
 
155
                /* determine whether each vertexgroup is associated with a selected bone or not 
 
156
                 * - each cell is a boolean saying whether bone corresponding to the ith group is selected
 
157
                 * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts)
 
158
                 */
 
159
                bone_select_array = MEM_mallocN(defbase_tot * sizeof(char), "mask array");
 
160
                
156
161
                for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
157
 
                        pchan = get_pose_channel(oba->pose, def->name);
 
162
                        pchan = BKE_pose_channel_find_name(oba->pose, def->name);
158
163
                        if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
159
 
                                bone_select_array[i]= TRUE;
 
164
                                bone_select_array[i] = TRUE;
160
165
                                bone_select_tot++;
161
166
                        }
162
167
                        else {
163
 
                                bone_select_array[i]= FALSE;
 
168
                                bone_select_array[i] = FALSE;
164
169
                        }
165
170
                }
166
 
 
167
 
                /* hashes for finding mapping of:
168
 
                 *      - vgroups to indices -> vgroupHash  (string, int)
169
 
                 *      - bones to vgroup indices -> boneHash (index of vgroup, dummy)
 
171
                
 
172
                /* if no dverts (i.e. no data for vertex groups exists), we've got an
 
173
                 * inconsistent situation, so free hashes and return oirginal mesh
170
174
                 */
171
 
                vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "mask vgroup gh");
172
 
                
173
 
                /* build mapping of names of vertex groups to indices */
174
 
                for (i = 0, def = ob->defbase.first; def; def = def->next, i++) 
175
 
                        BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
176
 
                
177
 
                /* if no bones selected, free hashes and return original mesh */
178
 
                if (bone_select_tot == 0) {
179
 
                        BLI_ghash_free(vgroupHash, NULL, NULL);
180
 
                        MEM_freeN(bone_select_array);
181
 
                        
182
 
                        return derivedData;
183
 
                }
184
 
                
185
 
                /* repeat the previous check, but for dverts */
186
 
                dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
 
175
                dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
187
176
                if (dvert == NULL) {
188
 
                        BLI_ghash_free(vgroupHash, NULL, NULL);
189
177
                        MEM_freeN(bone_select_array);
190
 
                        
191
178
                        return derivedData;
192
179
                }
193
180
                
194
 
                /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
195
 
                vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert gh");
 
181
                /* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
 
182
                 * key = oldindex, value = newindex
 
183
                 */
 
184
                vertHash = BLI_ghash_int_new("mask vert gh");
196
185
                
197
 
                /* add vertices which exist in vertexgroups into vertHash for filtering */
198
 
                for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
199
 
                {
200
 
                        MDeformWeight *dw= dv->dw;
 
186
                /* add vertices which exist in vertexgroups into vertHash for filtering 
 
187
                 * - dv = for each vertex, what vertexgroups does it belong to
 
188
                 * - dw = weight that vertex was assigned to a vertexgroup it belongs to
 
189
                 */
 
190
                for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
 
191
                        MDeformWeight *dw = dv->dw;
 
192
                        short found = 0;
201
193
                        int j;
202
 
 
203
 
                        for (j= dv->totweight; j > 0; j--, dw++) {
 
194
                        
 
195
                        /* check the groups that vertex is assigned to, and see if it was any use */
 
196
                        for (j = 0; j < dv->totweight; j++, dw++) {
204
197
                                if (dw->def_nr < defbase_tot) {
205
198
                                        if (bone_select_array[dw->def_nr]) {
206
199
                                                if (dw->weight != 0.0f) {
 
200
                                                        found = TRUE;
207
201
                                                        break;
208
202
                                                }
209
203
                                        }
213
207
                        /* check if include vert in vertHash */
214
208
                        if (mmd->flag & MOD_MASK_INV) {
215
209
                                /* if this vert is in the vgroup, don't include it in vertHash */
216
 
                                if (dw) continue;
 
210
                                if (found) continue;
217
211
                        }
218
212
                        else {
219
213
                                /* if this vert isn't in the vgroup, don't include it in vertHash */
220
 
                                if (!dw) continue;
 
214
                                if (!found) continue;
221
215
                        }
222
216
                        
223
217
                        /* add to ghash for verts (numVerts acts as counter for mapping) */
226
220
                }
227
221
                
228
222
                /* free temp hashes */
229
 
                BLI_ghash_free(vgroupHash, NULL, NULL);
230
223
                MEM_freeN(bone_select_array);
231
224
        }
232
 
        else            /* --- Using Nominated VertexGroup only --- */ 
233
 
        {
 
225
        else {  /* --- Using Nominated VertexGroup only --- */
234
226
                int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
235
227
                
236
228
                /* get dverts */
237
 
                if (defgrp_index >= 0)
 
229
                if (defgrp_index != -1)
238
230
                        dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
239
231
                        
240
232
                /* if no vgroup (i.e. dverts) found, return the initial mesh */
241
 
                if ((defgrp_index < 0) || (dvert == NULL))
 
233
                if ((defgrp_index == -1) || (dvert == NULL))
242
234
                        return dm;
243
235
                        
244
236
                /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
245
 
                vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert2 bh");
 
237
                vertHash = BLI_ghash_int_new("mask vert2 bh");
246
238
                
247
239
                /* add vertices which exist in vertexgroup into ghash for filtering */
248
 
                for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
249
 
                {
250
 
                        const int weight_set= defvert_find_weight(dv, defgrp_index) != 0.0f;
 
240
                for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
 
241
                        const int weight_set = defvert_find_weight(dv, defgrp_index) != 0.0f;
251
242
                        
252
243
                        /* check if include vert in vertHash */
253
244
                        if (mmd->flag & MOD_MASK_INV) {
266
257
        }
267
258
 
268
259
        /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
269
 
        edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask ed2 gh");
270
 
        polyHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask fa2 gh");
 
260
        edgeHash = BLI_ghash_int_new("mask ed2 gh");
 
261
        polyHash = BLI_ghash_int_new("mask fa2 gh");
271
262
        
272
263
        mpoly = dm->getPolyArray(dm);
273
264
        mloop = dm->getLoopArray(dm);
277
268
        /* loop over edges and faces, and do the same thing to 
278
269
         * ensure that they only reference existing verts 
279
270
         */
280
 
        for (i = 0; i < maxEdges; i++) 
281
 
        {
 
271
        for (i = 0; i < maxEdges; i++) {
282
272
                MEdge me;
283
273
                dm->getEdge(dm, i, &me);
284
274
                
285
275
                /* only add if both verts will be in new mesh */
286
 
                if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
287
 
                         BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)) )
 
276
                if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
 
277
                    BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
288
278
                {
289
279
                        BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
290
280
                        numEdges++;
291
281
                }
292
282
        }
293
 
        for (i = 0; i < maxPolys; i++)
294
 
        {
 
283
        for (i = 0; i < maxPolys; i++) {
295
284
                MPoly *mp = &mpoly[i];
296
285
                MLoop *ml = mloop + mp->loopstart;
297
286
                int ok = TRUE;
298
287
                int j;
299
 
 
 
288
                
300
289
                for (j = 0; j < mp->totloop; j++, ml++) {
301
290
                        if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) {
302
291
                                ok = FALSE;
325
314
        mvert_new = CDDM_get_verts(result);
326
315
        
327
316
        /* using ghash-iterators, map data into new mesh */
328
 
                /* vertices */
329
 
        for ( hashIter = BLI_ghashIterator_new(vertHash);
330
 
                  !BLI_ghashIterator_isDone(hashIter);
331
 
                  BLI_ghashIterator_step(hashIter) ) 
 
317
        /* vertices */
 
318
        for (hashIter = BLI_ghashIterator_new(vertHash);
 
319
             !BLI_ghashIterator_isDone(hashIter);
 
320
             BLI_ghashIterator_step(hashIter) )
332
321
        {
333
322
                MVert source;
334
323
                MVert *dest;
343
332
        }
344
333
        BLI_ghashIterator_free(hashIter);
345
334
                
346
 
                /* edges */
347
 
        for ( hashIter = BLI_ghashIterator_new(edgeHash);
348
 
                  !BLI_ghashIterator_isDone(hashIter);
349
 
                  BLI_ghashIterator_step(hashIter) ) 
 
335
        /* edges */
 
336
        for (hashIter = BLI_ghashIterator_new(edgeHash);
 
337
             !BLI_ghashIterator_isDone(hashIter);
 
338
             BLI_ghashIterator_step(hashIter))
350
339
        {
351
340
                MEdge source;
352
341
                MEdge *dest;
364
353
        }
365
354
        BLI_ghashIterator_free(hashIter);
366
355
        
367
 
                /* faces */
368
 
        for ( hashIter = BLI_ghashIterator_new(polyHash);
369
 
                  !BLI_ghashIterator_isDone(hashIter);
370
 
                  BLI_ghashIterator_step(hashIter) ) 
 
356
        /* faces */
 
357
        for (hashIter = BLI_ghashIterator_new(polyHash);
 
358
             !BLI_ghashIterator_isDone(hashIter);
 
359
             BLI_ghashIterator_step(hashIter) )
371
360
        {
372
361
                int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
373
362
                int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
412
401
        /* structName */        "MaskModifierData",
413
402
        /* structSize */        sizeof(MaskModifierData),
414
403
        /* type */              eModifierTypeType_Nonconstructive,
415
 
        /* flags */             eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping|eModifierTypeFlag_SupportsEditmode,
 
404
        /* flags */             eModifierTypeFlag_AcceptsMesh |
 
405
                                eModifierTypeFlag_SupportsMapping |
 
406
                                eModifierTypeFlag_SupportsEditmode,
416
407
 
417
408
        /* copyData */          copyData,
418
409
        /* deformVerts */       NULL,