178
178
WM_operator_properties_select_all(ot);
182
/* -------------------------------------------------------------------- */
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}
200
static bool mball_select_similar_type(MetaBall *mb)
203
bool changed = false;
205
for (ml = mb->editelems->first; ml; ml = ml->next) {
206
if (ml->flag & SELECT) {
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;
223
static bool mball_select_similar_radius(MetaBall *mb, const float thresh)
226
bool changed = false;
228
for (ml = mb->editelems->first; ml; ml = ml->next) {
229
if (ml->flag & SELECT) {
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;
246
static bool mball_select_similar_stiffness(MetaBall *mb, const float thresh)
249
bool changed = false;
251
for (ml = mb->editelems->first; ml; ml = ml->next) {
252
if (ml->flag & SELECT) {
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;
269
static bool mball_select_similar_rotation(MetaBall *mb, const float thresh)
271
const float thresh_rad = thresh * (float)M_PI_2;
273
bool changed = false;
275
for (ml = mb->editelems->first; ml; ml = ml->next) {
276
if (ml->flag & SELECT) {
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);
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];
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);
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)
301
ml_iter->flag |= SELECT;
312
static int mball_select_similar_exec(bContext *C, wmOperator *op)
314
Object *obedit = CTX_data_edit_object(C);
315
MetaBall *mb = (MetaBall *)obedit->data;
317
int type = RNA_enum_get(op->ptr, "type");
318
float thresh = RNA_float_get(op->ptr, "threshold");
319
bool changed = false;
323
changed = mball_select_similar_type(mb);
325
case SIMMBALL_RADIUS:
326
changed = mball_select_similar_radius(mb, thresh);
328
case SIMMBALL_STIFFNESS:
329
changed = mball_select_similar_stiffness(mb, thresh);
331
case SIMMBALL_ROTATION:
332
changed = mball_select_similar_rotation(mb, thresh);
340
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
343
return OPERATOR_FINISHED;
346
void MBALL_OT_select_similar(wmOperatorType *ot)
349
ot->name = "Select Similar";
350
ot->idname = "MBALL_OT_select_similar";
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";
359
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
362
ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, 0, "Type", "");
364
RNA_def_float(ot->srna, "threshold", 0.1, 0.0, 1.0, "Threshold", "", 0.01, 1.0);
181
368
/***************************** Select random operator *****************************/
183
370
/* Random metaball selection */
186
373
Object *obedit = CTX_data_edit_object(C);
187
374
MetaBall *mb = (MetaBall *)obedit->data;
189
float percent = RNA_float_get(op->ptr, "percent");
192
return OPERATOR_CANCELLED;
194
ml = mb->editelems->first;
196
/* Stupid version of random selection. Should be improved. */
198
if (BLI_frand() < percent)
376
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
377
float percent = RNA_float_get(op->ptr, "percent") / 100.0f;
379
for (ml = mb->editelems->first; ml; ml = ml->next) {
380
if (BLI_frand() < percent) {
205
388
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
211
394
void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot)
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";
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;
224
406
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
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);
231
413
/***************************** Duplicate operator *****************************/
581
745
undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL);
585
void ED_mball_transform(MetaBall *mb, float *mat)
748
void ED_mball_transform(MetaBall *mb, float mat[4][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);
592
mat4_to_quat(quat, (float (*)[4])mat);
755
mat4_to_quat(quat, mat);
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