~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/editors/metaball/mball_edit.c

  • Committer: Reinhard Tartler
  • Date: 2014-05-31 01:50:05 UTC
  • mfrom: (14.2.27 sid)
  • Revision ID: siretart@tauware.de-20140531015005-ml6druahuj82nsav
mergeĀ fromĀ debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
91
91
}
92
92
 
93
93
/* This function is called, when MetaBall Object switched from
94
 
 * edit mode to object mode. List od MetaElements is copied
 
94
 * edit mode to object mode. List of MetaElements is copied
95
95
 * from object->data->edit_elems to object->data->elems. */
96
96
void load_editMball(Object *UNUSED(obedit))
97
97
{
131
131
        MetaElem *ml;
132
132
        int action = RNA_enum_get(op->ptr, "action");
133
133
 
134
 
        if (mb->editelems->first == NULL)
 
134
        if (BLI_listbase_is_empty(mb->editelems))
135
135
                return OPERATOR_CANCELLED;
136
136
 
137
137
        if (action == SEL_TOGGLE) {
178
178
        WM_operator_properties_select_all(ot);
179
179
}
180
180
 
 
181
 
 
182
/* -------------------------------------------------------------------- */
 
183
/* Select Similar */
 
184
 
 
185
enum {
 
186
        SIMMBALL_TYPE = 1,
 
187
        SIMMBALL_RADIUS,
 
188
        SIMMBALL_STIFFNESS,
 
189
        SIMMBALL_ROTATION
 
190
};
 
191
 
 
192
static EnumPropertyItem prop_similar_types[] = {
 
193
        {SIMMBALL_TYPE, "TYPE", 0, "Type", ""},
 
194
        {SIMMBALL_RADIUS, "RADIUS", 0, "Radius", ""},
 
195
    {SIMMBALL_STIFFNESS, "STIFFNESS", 0, "Stiffness", ""},
 
196
        {SIMMBALL_ROTATION, "ROTATION", 0, "Rotation", ""},
 
197
        {0, NULL, 0, NULL, NULL}
 
198
};
 
199
 
 
200
static bool mball_select_similar_type(MetaBall *mb)
 
201
{
 
202
        MetaElem *ml;
 
203
        bool changed = false;
 
204
 
 
205
        for (ml = mb->editelems->first; ml; ml = ml->next) {
 
206
                if (ml->flag & SELECT) {
 
207
                        MetaElem *ml_iter;
 
208
 
 
209
                        for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) {
 
210
                                if ((ml_iter->flag & SELECT) == 0) {
 
211
                                        if (ml->type == ml_iter->type) {
 
212
                                                ml_iter->flag |= SELECT;
 
213
                                                changed = true;
 
214
                                        }
 
215
                                }
 
216
                        }
 
217
                }
 
218
        }
 
219
 
 
220
        return changed;
 
221
}
 
222
 
 
223
static bool mball_select_similar_radius(MetaBall *mb, const float thresh)
 
224
{
 
225
        MetaElem *ml;
 
226
        bool changed = false;
 
227
 
 
228
        for (ml = mb->editelems->first; ml; ml = ml->next) {
 
229
                if (ml->flag & SELECT) {
 
230
                        MetaElem *ml_iter;
 
231
 
 
232
                        for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) {
 
233
                                if ((ml_iter->flag & SELECT) == 0) {
 
234
                                        if (fabsf(ml_iter->rad - ml->rad) <= (thresh * ml->rad)) {
 
235
                                                ml_iter->flag |= SELECT;
 
236
                                                changed = true;
 
237
                                        }
 
238
                                }
 
239
                        }
 
240
                }
 
241
        }
 
242
 
 
243
        return changed;
 
244
}
 
245
 
 
246
static bool mball_select_similar_stiffness(MetaBall *mb, const float thresh)
 
247
{
 
248
        MetaElem *ml;
 
249
        bool changed = false;
 
250
 
 
251
        for (ml = mb->editelems->first; ml; ml = ml->next) {
 
252
                if (ml->flag & SELECT) {
 
253
                        MetaElem *ml_iter;
 
254
 
 
255
                        for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) {
 
256
                                if ((ml_iter->flag & SELECT) == 0) {
 
257
                                        if (fabsf(ml_iter->s - ml->s) <= thresh) {
 
258
                                                ml_iter->flag |= SELECT;
 
259
                                                changed = true;
 
260
                                        }
 
261
                                }
 
262
                        }
 
263
                }
 
264
        }
 
265
 
 
266
        return changed;
 
267
}
 
268
 
 
269
static bool mball_select_similar_rotation(MetaBall *mb, const float thresh)
 
270
{
 
271
        const float thresh_rad = thresh * (float)M_PI_2;
 
272
        MetaElem *ml;
 
273
        bool changed = false;
 
274
 
 
275
        for (ml = mb->editelems->first; ml; ml = ml->next) {
 
276
                if (ml->flag & SELECT) {
 
277
                        MetaElem *ml_iter;
 
278
 
 
279
                        float ml_mat[3][3];
 
280
 
 
281
                        unit_m3(ml_mat);
 
282
                        mul_qt_v3(ml->quat, ml_mat[0]);
 
283
                        mul_qt_v3(ml->quat, ml_mat[1]);
 
284
                        mul_qt_v3(ml->quat, ml_mat[2]);
 
285
                        normalize_m3(ml_mat);
 
286
 
 
287
                        for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) {
 
288
                                if ((ml_iter->flag & SELECT) == 0) {
 
289
                                        float ml_iter_mat[3][3];
 
290
 
 
291
                                        unit_m3(ml_iter_mat);
 
292
                                        mul_qt_v3(ml_iter->quat, ml_iter_mat[0]);
 
293
                                        mul_qt_v3(ml_iter->quat, ml_iter_mat[1]);
 
294
                                        mul_qt_v3(ml_iter->quat, ml_iter_mat[2]);
 
295
                                        normalize_m3(ml_iter_mat);
 
296
 
 
297
                                        if ((angle_normalized_v3v3(ml_mat[0], ml_iter_mat[0]) +
 
298
                                             angle_normalized_v3v3(ml_mat[1], ml_iter_mat[1]) +
 
299
                                             angle_normalized_v3v3(ml_mat[2], ml_iter_mat[2])) < thresh_rad)
 
300
                                        {
 
301
                                                ml_iter->flag |= SELECT;
 
302
                                                changed = true;
 
303
                                        }
 
304
                                }
 
305
                        }
 
306
                }
 
307
        }
 
308
 
 
309
        return changed;
 
310
}
 
311
 
 
312
static int mball_select_similar_exec(bContext *C, wmOperator *op)
 
313
{
 
314
        Object *obedit = CTX_data_edit_object(C);
 
315
        MetaBall *mb = (MetaBall *)obedit->data;
 
316
 
 
317
        int type = RNA_enum_get(op->ptr, "type");
 
318
        float thresh = RNA_float_get(op->ptr, "threshold");
 
319
        bool changed = false;
 
320
 
 
321
        switch (type) {
 
322
                case SIMMBALL_TYPE:
 
323
                        changed = mball_select_similar_type(mb);
 
324
                        break;
 
325
                case SIMMBALL_RADIUS:
 
326
                        changed = mball_select_similar_radius(mb, thresh);
 
327
                        break;
 
328
                case SIMMBALL_STIFFNESS:
 
329
                        changed = mball_select_similar_stiffness(mb, thresh);
 
330
                        break;
 
331
                case SIMMBALL_ROTATION:
 
332
                        changed = mball_select_similar_rotation(mb, thresh);
 
333
                        break;
 
334
                default:
 
335
                        BLI_assert(0);
 
336
                        break;
 
337
        }
 
338
 
 
339
        if (changed) {
 
340
                WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
 
341
        }
 
342
 
 
343
        return OPERATOR_FINISHED;
 
344
}
 
345
 
 
346
void MBALL_OT_select_similar(wmOperatorType *ot)
 
347
{
 
348
        /* identifiers */
 
349
        ot->name = "Select Similar";
 
350
        ot->idname = "MBALL_OT_select_similar";
 
351
 
 
352
        /* callback functions */
 
353
        ot->invoke = WM_menu_invoke;
 
354
        ot->exec = mball_select_similar_exec;
 
355
        ot->poll = ED_operator_editmball;
 
356
        ot->description = "Select similar metaballs by property types";
 
357
 
 
358
        /* flags */
 
359
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
360
 
 
361
        /* properties */
 
362
        ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, 0, "Type", "");
 
363
 
 
364
        RNA_def_float(ot->srna, "threshold", 0.1, 0.0, 1.0, "Threshold", "", 0.01, 1.0);
 
365
}
 
366
 
 
367
 
181
368
/***************************** Select random operator *****************************/
182
369
 
183
370
/* Random metaball selection */
186
373
        Object *obedit = CTX_data_edit_object(C);
187
374
        MetaBall *mb = (MetaBall *)obedit->data;
188
375
        MetaElem *ml;
189
 
        float percent = RNA_float_get(op->ptr, "percent");
190
 
        
191
 
        if (percent == 0.0f)
192
 
                return OPERATOR_CANCELLED;
193
 
        
194
 
        ml = mb->editelems->first;
195
 
        
196
 
        /* Stupid version of random selection. Should be improved. */
197
 
        while (ml) {
198
 
                if (BLI_frand() < percent)
199
 
                        ml->flag |= SELECT;
200
 
                else
201
 
                        ml->flag &= ~SELECT;
202
 
                ml = ml->next;
 
376
        const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
 
377
        float percent = RNA_float_get(op->ptr, "percent") / 100.0f;
 
378
        
 
379
        for (ml = mb->editelems->first; ml; ml = ml->next) {
 
380
                if (BLI_frand() < percent) {
 
381
                        if (select)
 
382
                                ml->flag |= SELECT;
 
383
                        else
 
384
                                ml->flag &= ~SELECT;
 
385
                }
203
386
        }
204
387
        
205
388
        WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
211
394
void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot)
212
395
{
213
396
        /* identifiers */
214
 
        ot->name = "Random...";
 
397
        ot->name = "Select Random";
215
398
        ot->description = "Randomly select metaelements";
216
399
        ot->idname = "MBALL_OT_select_random_metaelems";
217
400
        
218
401
        /* callback functions */
219
402
        ot->exec = select_random_metaelems_exec;
220
 
        ot->invoke = WM_operator_props_popup;
221
403
        ot->poll = ED_operator_editmball;
222
404
        
223
405
        /* flags */
224
406
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
225
407
        
226
408
        /* properties */
227
 
        RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent",
228
 
                                 "Percentage of metaelements to select randomly", 0.0001f, 1.0f);
 
409
        RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, "Percent", "Percentage of elements to select randomly", 0.f, 100.0f);
 
410
        WM_operator_properties_select_action_simple(ot, SEL_SELECT);
229
411
}
230
412
 
231
413
/***************************** Duplicate operator *****************************/
255
437
        return OPERATOR_FINISHED;
256
438
}
257
439
 
258
 
static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
259
 
{
260
 
        int retv = duplicate_metaelems_exec(C, op);
261
 
        
262
 
        if (retv == OPERATOR_FINISHED) {
263
 
                RNA_enum_set(op->ptr, "mode", TFM_TRANSLATION);
264
 
                WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
265
 
        }
266
 
        
267
 
        return retv;
268
 
}
269
 
 
270
 
 
271
440
void MBALL_OT_duplicate_metaelems(wmOperatorType *ot)
272
441
{
273
442
        /* identifiers */
277
446
 
278
447
        /* callback functions */
279
448
        ot->exec = duplicate_metaelems_exec;
280
 
        ot->invoke = duplicate_metaelems_invoke;
281
449
        ot->poll = ED_operator_editmball;
282
450
 
283
451
        /* flags */
284
452
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
285
 
        
286
 
        /* to give to transform */
287
 
        RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
288
453
}
289
454
 
290
455
/***************************** Delete operator *****************************/
537
702
 
538
703
        /* allocate memory for undo ListBase */
539
704
        lb = MEM_callocN(sizeof(ListBase), "listbase undo");
540
 
        lb->first = lb->last = NULL;
541
705
        
542
706
        /* copy contents of current ListBase to the undo ListBase */
543
707
        ml = editelems->first;
581
745
        undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL);
582
746
}
583
747
 
584
 
/* matrix is 4x4 */
585
 
void ED_mball_transform(MetaBall *mb, float *mat)
 
748
void ED_mball_transform(MetaBall *mb, float mat[4][4])
586
749
{
587
750
        MetaElem *me;
588
751
        float quat[4];
589
 
        const float scale = mat4_to_scale((float (*)[4])mat);
 
752
        const float scale = mat4_to_scale(mat);
590
753
        const float scale_sqrt = sqrtf(scale);
591
754
 
592
 
        mat4_to_quat(quat, (float (*)[4])mat);
 
755
        mat4_to_quat(quat, mat);
593
756
 
594
757
        for (me = mb->elems.first; me; me = me->next) {
595
 
                mul_m4_v3((float (*)[4])mat, &me->x);
 
758
                mul_m4_v3(mat, &me->x);
596
759
                mul_qt_qtqt(me->quat, quat, me->quat);
597
760
                me->rad *= scale;
598
761
                /* hrmf, probably elems shouldn't be
604
767
                        mul_v3_fl(&me->expx, scale_sqrt);
605
768
                }
606
769
        }
 
770
        DAG_id_tag_update(&mb->id, 0);
607
771
}