Blender  V2.93
editmesh_bevel.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include "MEM_guardedalloc.h"
22 
23 #include "DNA_object_types.h"
24 
25 #include "BLI_math.h"
26 #include "BLI_string.h"
27 
28 #include "BLT_translation.h"
29 
30 #include "BKE_context.h"
31 #include "BKE_editmesh.h"
32 #include "BKE_global.h"
33 #include "BKE_layer.h"
34 #include "BKE_unit.h"
35 
36 #include "DNA_curveprofile_types.h"
37 #include "DNA_mesh_types.h"
38 
39 #include "RNA_access.h"
40 #include "RNA_define.h"
41 
42 #include "WM_api.h"
43 #include "WM_types.h"
44 
45 #include "UI_interface.h"
46 #include "UI_resources.h"
47 
48 #include "ED_mesh.h"
49 #include "ED_numinput.h"
50 #include "ED_screen.h"
51 #include "ED_space_api.h"
52 #include "ED_transform.h"
53 #include "ED_util.h"
54 #include "ED_view3d.h"
55 
56 #include "mesh_intern.h" /* own include */
57 
58 #define MVAL_PIXEL_MARGIN 5.0f
59 
60 #define PROFILE_HARD_MIN 0.0f
61 
62 #define SEGMENTS_HARD_MAX 1000
63 
64 /* which value is mouse movement and numeric input controlling? */
65 #define OFFSET_VALUE 0
66 #define OFFSET_VALUE_PERCENT 1
67 #define PROFILE_VALUE 2
68 #define SEGMENTS_VALUE 3
69 #define NUM_VALUE_KINDS 4
70 
71 static const char *value_rna_name[NUM_VALUE_KINDS] = {
72  "offset", "offset_pct", "profile", "segments"};
73 static const float value_clamp_min[NUM_VALUE_KINDS] = {0.0f, 0.0f, PROFILE_HARD_MIN, 1.0f};
74 static const float value_clamp_max[NUM_VALUE_KINDS] = {1e6, 100.0f, 1.0f, SEGMENTS_HARD_MAX};
75 static const float value_start[NUM_VALUE_KINDS] = {0.0f, 0.0f, 0.5f, 1.0f};
76 static const float value_scale_per_inch[NUM_VALUE_KINDS] = {0.0f, 100.0f, 1.0f, 4.0f};
77 
78 typedef struct {
83 
84 typedef struct {
85  float initial_length[NUM_VALUE_KINDS];
86  float scale[NUM_VALUE_KINDS];
89  float shift_value[NUM_VALUE_KINDS];
91  bool is_modal;
92 
95 
96  /* modal only */
98  float mcenter[2];
100  short gizmo_flag;
101  short value_mode; /* Which value does mouse movement and numeric input affect? */
102  float segments; /* Segments as float so smooth mouse pan works in small increments */
103 
105 } BevelData;
106 
107 enum {
125 };
126 
127 static float get_bevel_offset(wmOperator *op)
128 {
129  if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) {
130  return RNA_float_get(op->ptr, "offset_pct");
131  }
132  return RNA_float_get(op->ptr, "offset");
133 }
134 
136 {
137  char status_text[UI_MAX_DRAW_STR];
138  char buf[UI_MAX_DRAW_STR];
139  char *p = buf;
140  int available_len = sizeof(buf);
141  Scene *sce = CTX_data_scene(C);
142 
143 #define WM_MODALKEY(_id) \
144  WM_modalkeymap_operator_items_to_string_buf( \
145  op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
146 
147  char offset_str[NUM_STR_REP_LEN];
148  if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) {
149  BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%.1f%%", RNA_float_get(op->ptr, "offset_pct"));
150  }
151  else {
152  double offset_val = (double)RNA_float_get(op->ptr, "offset");
153  BKE_unit_value_as_string(offset_str,
155  offset_val * sce->unit.scale_length,
156  3,
158  &sce->unit,
159  true);
160  }
161 
162  PropertyRNA *prop;
163  const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str;
164  prop = RNA_struct_find_property(op->ptr, "offset_type");
166  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &mode_str);
167  prop = RNA_struct_find_property(op->ptr, "profile_type");
169  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &profile_type_str);
170  prop = RNA_struct_find_property(op->ptr, "miter_outer");
172  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &omiter_str);
173  prop = RNA_struct_find_property(op->ptr, "miter_inner");
175  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &imiter_str);
176  prop = RNA_struct_find_property(op->ptr, "vmesh_method");
178  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &vmesh_str);
179  prop = RNA_struct_find_property(op->ptr, "affect");
181  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &affect_str);
182 
183  BLI_snprintf(status_text,
184  sizeof(status_text),
185  TIP_("%s: Confirm, "
186  "%s: Cancel, "
187  "%s: Mode (%s), "
188  "%s: Width (%s), "
189  "%s: Segments (%d), "
190  "%s: Profile (%.3f), "
191  "%s: Clamp Overlap (%s), "
192  "%s: Affect (%s), "
193  "%s: Outer Miter (%s), "
194  "%s: Inner Miter (%s), "
195  "%s: Harden Normals (%s), "
196  "%s: Mark Seam (%s), "
197  "%s: Mark Sharp (%s), "
198  "%s: Profile Type (%s), "
199  "%s: Intersection (%s)"),
203  mode_str,
205  offset_str,
207  RNA_int_get(op->ptr, "segments"),
209  RNA_float_get(op->ptr, "profile"),
211  WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
213  affect_str,
215  omiter_str,
217  imiter_str,
219  WM_bool_as_string(RNA_boolean_get(op->ptr, "harden_normals")),
221  WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_seam")),
223  WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_sharp")),
225  profile_type_str,
227  vmesh_str);
228 
229 #undef WM_MODALKEY
230 
231  ED_workspace_status_text(C, status_text);
232 }
233 
234 static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
235 {
237  View3D *v3d = CTX_wm_view3d(C);
239  ViewLayer *view_layer = CTX_data_view_layer(C);
240 
241  if (is_modal) {
242  RNA_float_set(op->ptr, "offset", 0.0f);
243  RNA_float_set(op->ptr, "offset_pct", 0.0f);
244  }
245 
246  op->customdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
247  BevelData *opdata = op->customdata;
248  uint objects_used_len = 0;
249  opdata->max_obj_scale = FLT_MIN;
250 
251  /* Put the Curve Profile from the toolsettings into the opdata struct */
253 
254  {
255  uint ob_store_len = 0;
257  view_layer, v3d, &ob_store_len);
258  opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__);
259  for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) {
260  Object *obedit = objects[ob_index];
261  float scale = mat4_to_scale(obedit->obmat);
262  opdata->max_obj_scale = max_ff(opdata->max_obj_scale, scale);
263  BMEditMesh *em = BKE_editmesh_from_object(obedit);
264  if (em->bm->totvertsel > 0) {
265  opdata->ob_store[objects_used_len].ob = obedit;
266  objects_used_len++;
267  }
268  }
269  MEM_freeN(objects);
270  opdata->ob_store_len = objects_used_len;
271  }
272 
273  opdata->is_modal = is_modal;
274  int otype = RNA_enum_get(op->ptr, "offset_type");
276  opdata->segments = (float)RNA_int_get(op->ptr, "segments");
277  float pixels_per_inch = U.dpi * U.pixelsize;
278 
279  for (int i = 0; i < NUM_VALUE_KINDS; i++) {
280  opdata->shift_value[i] = -1.0f;
281  opdata->initial_length[i] = -1.0f;
282  /* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
283  opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
284 
285  initNumInput(&opdata->num_input[i]);
286  opdata->num_input[i].idx_max = 0;
287  opdata->num_input[i].val_flag[0] |= NUM_NO_NEGATIVE;
288  opdata->num_input[i].unit_type[0] = B_UNIT_NONE;
289  if (i == SEGMENTS_VALUE) {
290  opdata->num_input[i].val_flag[0] |= NUM_NO_FRACTION | NUM_NO_ZERO;
291  }
292  if (i == OFFSET_VALUE) {
293  opdata->num_input[i].unit_sys = scene->unit.system;
294  opdata->num_input[i].unit_type[0] = B_UNIT_LENGTH;
295  }
296  }
297 
298  /* avoid the cost of allocating a bm copy */
299  if (is_modal) {
300  ARegion *region = CTX_wm_region(C);
301 
302  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
303  Object *obedit = opdata->ob_store[ob_index].ob;
304  BMEditMesh *em = BKE_editmesh_from_object(obedit);
305  opdata->ob_store[ob_index].mesh_backup = EDBM_redo_state_store(em);
306  }
309  G.moving = G_TRANSFORM_EDIT;
310 
311  if (v3d) {
312  opdata->gizmo_flag = v3d->gizmo_flag;
313  v3d->gizmo_flag = V3D_GIZMO_HIDE;
314  }
315  }
316 
317  return true;
318 }
319 
320 static bool edbm_bevel_calc(wmOperator *op)
321 {
322  BevelData *opdata = op->customdata;
323  BMOperator bmop;
324  bool changed = false;
325 
326  const float offset = get_bevel_offset(op);
327  const int offset_type = RNA_enum_get(op->ptr, "offset_type");
328  const int profile_type = RNA_enum_get(op->ptr, "profile_type");
329  const int segments = RNA_int_get(op->ptr, "segments");
330  const float profile = RNA_float_get(op->ptr, "profile");
331  const bool affect = RNA_enum_get(op->ptr, "affect");
332  const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
333  const int material_init = RNA_int_get(op->ptr, "material");
334  const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
335  const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
336  const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
337  const bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals");
338  const int face_strength_mode = RNA_enum_get(op->ptr, "face_strength_mode");
339  const int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
340  const int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
341  const float spread = RNA_float_get(op->ptr, "spread");
342  const int vmesh_method = RNA_enum_get(op->ptr, "vmesh_method");
343 
344  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
345  Object *obedit = opdata->ob_store[ob_index].ob;
346  BMEditMesh *em = BKE_editmesh_from_object(obedit);
347 
348  /* revert to original mesh */
349  if (opdata->is_modal) {
350  EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false);
351  }
352 
353  const int material = CLAMPIS(material_init, -1, obedit->totcol - 1);
354 
355  Mesh *me = obedit->data;
356 
357  if (harden_normals && !(me->flag & ME_AUTOSMOOTH)) {
358  /* harden_normals only has a visible effect if autosmooth is on, so turn it on */
359  me->flag |= ME_AUTOSMOOTH;
360  }
361 
362  EDBM_op_init(em,
363  &bmop,
364  op,
365  "bevel geom=%hev offset=%f segments=%i affect=%i offset_type=%i "
366  "profile_type=%i profile=%f clamp_overlap=%b material=%i loop_slide=%b "
367  "mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i "
368  "miter_outer=%i miter_inner=%i spread=%f smoothresh=%f custom_profile=%p "
369  "vmesh_method=%i",
371  offset,
372  segments,
373  affect,
374  offset_type,
375  profile_type,
376  profile,
377  clamp_overlap,
378  material,
379  loop_slide,
380  mark_seam,
381  mark_sharp,
382  harden_normals,
383  face_strength_mode,
384  miter_outer,
385  miter_inner,
386  spread,
387  me->smoothresh,
388  opdata->custom_profile,
389  vmesh_method);
390 
391  BMO_op_exec(em->bm, &bmop);
392 
393  if (offset != 0.0f) {
394  /* not essential, but we may have some loose geometry that
395  * won't get bevel'd and better not leave it selected */
398  em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
399  }
400 
401  /* no need to de-select existing geometry */
402  if (!EDBM_op_finish(em, &bmop, op, true)) {
403  continue;
404  }
405 
407 
408  EDBM_update_generic(obedit->data, true, true);
409  changed = true;
410  }
411  return changed;
412 }
413 
415 {
416  BevelData *opdata = op->customdata;
418 
419  if (area) {
421  }
422 
423  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
424  Object *obedit = opdata->ob_store[ob_index].ob;
425  BMEditMesh *em = BKE_editmesh_from_object(obedit);
426  /* Without this, faces surrounded by selected edges/verts will be unselected. */
427  if ((em->selectmode & SCE_SELECT_FACE) == 0) {
429  }
430  }
431 
432  if (opdata->is_modal) {
433  View3D *v3d = CTX_wm_view3d(C);
434  ARegion *region = CTX_wm_region(C);
435  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
436  EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, NULL, false);
437  }
439  if (v3d) {
440  v3d->gizmo_flag = opdata->gizmo_flag;
441  }
442  G.moving = 0;
443  }
444  MEM_SAFE_FREE(opdata->ob_store);
446  op->customdata = NULL;
447 }
448 
450 {
451  BevelData *opdata = op->customdata;
452  if (opdata->is_modal) {
453  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
454  Object *obedit = opdata->ob_store[ob_index].ob;
455  BMEditMesh *em = BKE_editmesh_from_object(obedit);
456  EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
457  EDBM_update_generic(obedit->data, false, true);
458  }
459  }
460 
461  edbm_bevel_exit(C, op);
462 
463  /* need to force redisplay or we may still view the modified result */
465 }
466 
467 /* bevel! yay!! */
469 {
470  if (!edbm_bevel_init(C, op, false)) {
471  return OPERATOR_CANCELLED;
472  }
473 
474  if (!edbm_bevel_calc(op)) {
475  edbm_bevel_cancel(C, op);
476  return OPERATOR_CANCELLED;
477  }
478 
479  edbm_bevel_exit(C, op);
480 
481  return OPERATOR_FINISHED;
482 }
483 
484 static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed)
485 {
486  BevelData *opdata = op->customdata;
487  const float mlen[2] = {
488  opdata->mcenter[0] - event->mval[0],
489  opdata->mcenter[1] - event->mval[1],
490  };
491  float len = len_v2(mlen);
492  int vmode = opdata->value_mode;
493  if (mode_changed || opdata->initial_length[vmode] == -1.0f) {
494  /* If current value is not default start value, adjust len so that
495  * the scaling and offset in edbm_bevel_mouse_set_value will
496  * start at current value */
497  float value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
498  RNA_float_get(op->ptr, value_rna_name[vmode]);
499  float sc = opdata->scale[vmode];
500  float st = value_start[vmode];
501  if (value != value_start[vmode]) {
502  len = (st + sc * (len - MVAL_PIXEL_MARGIN) - value) / sc;
503  }
504  }
505  opdata->initial_length[opdata->value_mode] = len;
506 }
507 
508 static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
509 {
511 
512  if (!edbm_bevel_init(C, op, true)) {
513  return OPERATOR_CANCELLED;
514  }
515 
516  BevelData *opdata = op->customdata;
517 
519 
520  /* initialize mouse values */
521  float center_3d[3];
522  if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, center_3d, opdata->mcenter)) {
523  /* in this case the tool will likely do nothing,
524  * ideally this will never happen and should be checked for above */
525  opdata->mcenter[0] = opdata->mcenter[1] = 0;
526  }
527 
528  /* for OFFSET_VALUE only, the scale is the size of a pixel under the mouse in 3d space */
529  opdata->scale[OFFSET_VALUE] = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
530  /* since we are affecting untransformed object but seeing in transformed space,
531  * compensate for that */
532  opdata->scale[OFFSET_VALUE] /= opdata->max_obj_scale;
533 
534  edbm_bevel_calc_initial_length(op, event, false);
535 
537 
538  if (!edbm_bevel_calc(op)) {
539  edbm_bevel_cancel(C, op);
541  return OPERATOR_CANCELLED;
542  }
543 
545 
546  return OPERATOR_RUNNING_MODAL;
547 }
548 
549 static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
550 {
551  BevelData *opdata = op->customdata;
552  int vmode = opdata->value_mode;
553 
554  const float mdiff[2] = {
555  opdata->mcenter[0] - event->mval[0],
556  opdata->mcenter[1] - event->mval[1],
557  };
558 
559  float value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]);
560 
561  /* Scale according to value mode */
562  value = value_start[vmode] + value * opdata->scale[vmode];
563 
564  /* Fake shift-transform... */
565  if (event->shift) {
566  if (opdata->shift_value[vmode] < 0.0f) {
567  opdata->shift_value[vmode] = (vmode == SEGMENTS_VALUE) ?
568  opdata->segments :
569  RNA_float_get(op->ptr, value_rna_name[vmode]);
570  }
571  value = (value - opdata->shift_value[vmode]) * 0.1f + opdata->shift_value[vmode];
572  }
573  else if (opdata->shift_value[vmode] >= 0.0f) {
574  opdata->shift_value[vmode] = -1.0f;
575  }
576 
577  /* Clamp according to value mode, and store value back. */
578  CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
579  if (vmode == SEGMENTS_VALUE) {
580  opdata->segments = value;
581  RNA_int_set(op->ptr, "segments", (int)(value + 0.5f));
582  }
583  else {
584  RNA_float_set(op->ptr, value_rna_name[vmode], value);
585  }
586 }
587 
589 {
590  BevelData *opdata = op->customdata;
591 
592  int vmode = opdata->value_mode;
593  float value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
594  RNA_float_get(op->ptr, value_rna_name[vmode]);
595  applyNumInput(&opdata->num_input[vmode], &value);
596  CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
597  if (vmode == SEGMENTS_VALUE) {
598  opdata->segments = value;
599  RNA_int_set(op->ptr, "segments", (int)value);
600  }
601  else {
602  RNA_float_set(op->ptr, value_rna_name[vmode], value);
603  }
604 }
605 
607 {
608  static const EnumPropertyItem modal_items[] = {
609  {BEV_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel bevel"},
610  {BEV_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", "Confirm bevel"},
611  {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change Offset", "Value changes offset"},
612  {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change Profile", "Value changes profile"},
613  {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change Segments", "Value changes segments"},
614  {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase Segments", "Increase segments"},
615  {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease Segments", "Decrease segments"},
617  "OFFSET_MODE_CHANGE",
618  0,
619  "Change Offset Mode",
620  "Cycle through offset modes"},
622  "CLAMP_OVERLAP_TOGGLE",
623  0,
624  "Toggle Clamp Overlap",
625  "Toggle clamp overlap flag"},
627  "AFFECT_CHANGE",
628  0,
629  "Change Affect Type",
630  "Change which geometry type the operation affects, edges or vertices"},
632  "HARDEN_NORMALS_TOGGLE",
633  0,
634  "Toggle Harden Normals",
635  "Toggle harden normals flag"},
637  "MARK_SEAM_TOGGLE",
638  0,
639  "Toggle Mark Seam",
640  "Toggle mark seam flag"},
642  "MARK_SHARP_TOGGLE",
643  0,
644  "Toggle Mark Sharp",
645  "Toggle mark sharp flag"},
647  "OUTER_MITER_CHANGE",
648  0,
649  "Change Outer Miter",
650  "Cycle through outer miter kinds"},
652  "INNER_MITER_CHANGE",
653  0,
654  "Change Inner Miter",
655  "Cycle through inner miter kinds"},
656  {BEV_MODAL_PROFILE_TYPE_CHANGE, "PROFILE_TYPE_CHANGE", 0, "Cycle through profile types", ""},
658  "VERTEX_MESH_CHANGE",
659  0,
660  "Change Intersection Method",
661  "Cycle through intersection methods"},
662  {0, NULL, 0, NULL, NULL},
663  };
664 
665  wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Bevel Modal Map");
666 
667  /* This function is called for each spacetype, only needs to add map once */
668  if (keymap && keymap->modal_items) {
669  return NULL;
670  }
671 
672  keymap = WM_modalkeymap_ensure(keyconf, "Bevel Modal Map", modal_items);
673 
674  WM_modalkeymap_assign(keymap, "MESH_OT_bevel");
675 
676  return keymap;
677 }
678 
679 static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
680 {
681  BevelData *opdata = op->customdata;
682  const bool has_numinput = hasNumInput(&opdata->num_input[opdata->value_mode]);
683  bool handled = false;
684  short etype = event->type;
685  short eval = event->val;
686 
687  /* When activated from toolbar, need to convert leftmouse release to confirm */
688  if (ELEM(etype, LEFTMOUSE, opdata->launch_event) && (eval == KM_RELEASE) &&
689  RNA_boolean_get(op->ptr, "release_confirm")) {
690  etype = EVT_MODAL_MAP;
691  eval = BEV_MODAL_CONFIRM;
692  }
693  /* Modal numinput active, try to handle numeric inputs first... */
694  if (etype != EVT_MODAL_MAP && eval == KM_PRESS && has_numinput &&
695  handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
697  edbm_bevel_calc(op);
699  return OPERATOR_RUNNING_MODAL;
700  }
701  if (etype == MOUSEMOVE) {
702  if (!has_numinput) {
703  edbm_bevel_mouse_set_value(op, event);
704  edbm_bevel_calc(op);
706  handled = true;
707  }
708  }
709  else if (etype == MOUSEPAN) {
710  float delta = 0.02f * (event->y - event->prevy);
711  if (opdata->segments >= 1 && opdata->segments + delta < 1) {
712  opdata->segments = 1;
713  }
714  else {
715  opdata->segments += delta;
716  }
717  RNA_int_set(op->ptr, "segments", (int)opdata->segments);
718  edbm_bevel_calc(op);
720  handled = true;
721  }
722  else if (etype == EVT_MODAL_MAP) {
723  switch (eval) {
724  case BEV_MODAL_CANCEL:
725  edbm_bevel_cancel(C, op);
727  return OPERATOR_CANCELLED;
728 
729  case BEV_MODAL_CONFIRM:
730  edbm_bevel_calc(op);
731  edbm_bevel_exit(C, op);
733  return OPERATOR_FINISHED;
734 
736  opdata->segments = opdata->segments + 1;
737  RNA_int_set(op->ptr, "segments", (int)opdata->segments);
738  edbm_bevel_calc(op);
740  handled = true;
741  break;
742 
744  opdata->segments = max_ff(opdata->segments - 1, 1);
745  RNA_int_set(op->ptr, "segments", (int)opdata->segments);
746  edbm_bevel_calc(op);
748  handled = true;
749  break;
750 
752  int type = RNA_enum_get(op->ptr, "offset_type");
753  type++;
754  if (type > BEVEL_AMT_PERCENT) {
756  }
757  if (opdata->value_mode == OFFSET_VALUE && type == BEVEL_AMT_PERCENT) {
759  }
760  else if (opdata->value_mode == OFFSET_VALUE_PERCENT && type != BEVEL_AMT_PERCENT) {
761  opdata->value_mode = OFFSET_VALUE;
762  }
763  RNA_enum_set(op->ptr, "offset_type", type);
764  if (opdata->initial_length[opdata->value_mode] == -1.0f) {
765  edbm_bevel_calc_initial_length(op, event, true);
766  }
767  }
768  /* Update offset accordingly to new offset_type. */
769  if (!has_numinput &&
770  (opdata->value_mode == OFFSET_VALUE || opdata->value_mode == OFFSET_VALUE_PERCENT)) {
771  edbm_bevel_mouse_set_value(op, event);
772  }
773  edbm_bevel_calc(op);
775  handled = true;
776  break;
777 
779  bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
780  RNA_boolean_set(op->ptr, "clamp_overlap", !clamp_overlap);
781  edbm_bevel_calc(op);
783  handled = true;
784  break;
785  }
786 
788  opdata->value_mode = OFFSET_VALUE;
789  edbm_bevel_calc_initial_length(op, event, true);
790  break;
791 
793  opdata->value_mode = PROFILE_VALUE;
794  edbm_bevel_calc_initial_length(op, event, true);
795  break;
796 
798  opdata->value_mode = SEGMENTS_VALUE;
799  edbm_bevel_calc_initial_length(op, event, true);
800  break;
801 
803  int affect_type = RNA_enum_get(op->ptr, "affect");
804  affect_type++;
805  if (affect_type > BEVEL_AFFECT_EDGES) {
806  affect_type = BEVEL_AFFECT_VERTICES;
807  }
808  RNA_enum_set(op->ptr, "affect", affect_type);
809  edbm_bevel_calc(op);
811  handled = true;
812  break;
813  }
814 
816  bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
817  RNA_boolean_set(op->ptr, "mark_seam", !mark_seam);
818  edbm_bevel_calc(op);
820  handled = true;
821  break;
822  }
823 
825  bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
826  RNA_boolean_set(op->ptr, "mark_sharp", !mark_sharp);
827  edbm_bevel_calc(op);
829  handled = true;
830  break;
831  }
832 
834  int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
835  miter_inner++;
836  if (miter_inner == BEVEL_MITER_PATCH) {
837  miter_inner++; /* no patch option for inner miter */
838  }
839  if (miter_inner > BEVEL_MITER_ARC) {
840  miter_inner = BEVEL_MITER_SHARP;
841  }
842  RNA_enum_set(op->ptr, "miter_inner", miter_inner);
843  edbm_bevel_calc(op);
845  handled = true;
846  break;
847  }
848 
850  int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
851  miter_outer++;
852  if (miter_outer > BEVEL_MITER_ARC) {
853  miter_outer = BEVEL_MITER_SHARP;
854  }
855  RNA_enum_set(op->ptr, "miter_outer", miter_outer);
856  edbm_bevel_calc(op);
858  handled = true;
859  break;
860  }
861 
863  bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals");
864  RNA_boolean_set(op->ptr, "harden_normals", !harden_normals);
865  edbm_bevel_calc(op);
867  handled = true;
868  break;
869  }
870 
872  int profile_type = RNA_enum_get(op->ptr, "profile_type");
873  profile_type++;
874  if (profile_type > BEVEL_PROFILE_CUSTOM) {
875  profile_type = BEVEL_PROFILE_SUPERELLIPSE;
876  }
877  RNA_enum_set(op->ptr, "profile_type", profile_type);
878  edbm_bevel_calc(op);
880  handled = true;
881  break;
882  }
883 
885  int vmesh_method = RNA_enum_get(op->ptr, "vmesh_method");
886  vmesh_method++;
887  if (vmesh_method > BEVEL_VMESH_CUTOFF) {
888  vmesh_method = BEVEL_VMESH_ADJ;
889  }
890  RNA_enum_set(op->ptr, "vmesh_method", vmesh_method);
891  edbm_bevel_calc(op);
893  handled = true;
894  break;
895  }
896  }
897  }
898 
899  /* Modal numinput inactive, try to handle numeric inputs last... */
900  if (!handled && eval == KM_PRESS &&
901  handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
903  edbm_bevel_calc(op);
905  return OPERATOR_RUNNING_MODAL;
906  }
907 
908  return OPERATOR_RUNNING_MODAL;
909 }
910 
911 static void edbm_bevel_ui(bContext *C, wmOperator *op)
912 {
913  uiLayout *layout = op->layout;
915  uiLayout *col, *row;
916  PointerRNA ptr, toolsettings_ptr;
917 
918  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
919 
920  int profile_type = RNA_enum_get(&ptr, "profile_type");
921  int offset_type = RNA_enum_get(&ptr, "offset_type");
922  bool affect_type = RNA_enum_get(&ptr, "affect");
923 
924  uiLayoutSetPropSep(layout, true);
925  uiLayoutSetPropDecorate(layout, false);
926 
927  row = uiLayoutRow(layout, false);
928  uiItemR(row, &ptr, "affect", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
929 
930  uiItemS(layout);
931 
932  uiItemR(layout, &ptr, "offset_type", 0, NULL, ICON_NONE);
933 
934  if (offset_type == BEVEL_AMT_PERCENT) {
935  uiItemR(layout, &ptr, "offset_pct", 0, NULL, ICON_NONE);
936  }
937  else {
938  uiItemR(layout, &ptr, "offset", 0, NULL, ICON_NONE);
939  }
940 
941  uiItemR(layout, &ptr, "segments", 0, NULL, ICON_NONE);
943  uiItemR(layout,
944  &ptr,
945  "profile",
947  (profile_type == BEVEL_PROFILE_SUPERELLIPSE) ? IFACE_("Shape") : IFACE_("Miter Shape"),
948  ICON_NONE);
949  }
950  uiItemR(layout, &ptr, "material", 0, NULL, ICON_NONE);
951 
952  col = uiLayoutColumn(layout, true);
953  uiItemR(col, &ptr, "harden_normals", 0, NULL, ICON_NONE);
954  uiItemR(col, &ptr, "clamp_overlap", 0, NULL, ICON_NONE);
955  uiItemR(col, &ptr, "loop_slide", 0, NULL, ICON_NONE);
956 
957  col = uiLayoutColumnWithHeading(layout, true, IFACE_("Mark"));
958  uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
959  uiItemR(col, &ptr, "mark_seam", 0, IFACE_("Seams"), ICON_NONE);
960  uiItemR(col, &ptr, "mark_sharp", 0, IFACE_("Sharp"), ICON_NONE);
961 
962  uiItemS(layout);
963 
964  col = uiLayoutColumn(layout, false);
965  uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
966  uiItemR(col, &ptr, "miter_outer", 0, IFACE_("Miter Outer"), ICON_NONE);
967  uiItemR(col, &ptr, "miter_inner", 0, IFACE_("Inner"), ICON_NONE);
968  if (RNA_enum_get(&ptr, "miter_inner") == BEVEL_MITER_ARC) {
969  uiItemR(col, &ptr, "spread", 0, NULL, ICON_NONE);
970  }
971 
972  uiItemS(layout);
973 
974  col = uiLayoutColumn(layout, false);
975  uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
976  uiItemR(col, &ptr, "vmesh_method", 0, IFACE_("Intersection Type"), ICON_NONE);
977 
978  uiItemR(layout, &ptr, "face_strength_mode", 0, IFACE_("Face Strength"), ICON_NONE);
979 
980  uiItemS(layout);
981 
982  row = uiLayoutRow(layout, false);
983  uiItemR(row, &ptr, "profile_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
984  if (profile_type == BEVEL_PROFILE_CUSTOM) {
985  /* Get an RNA pointer to ToolSettings to give to the curve profile template code. */
987  RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
988  uiTemplateCurveProfile(layout, &toolsettings_ptr, "custom_bevel_profile_preset");
989  }
990 }
991 
993 {
994  PropertyRNA *prop;
995 
996  static const EnumPropertyItem offset_type_items[] = {
997  {BEVEL_AMT_OFFSET, "OFFSET", 0, "Offset", "Amount is offset of new edges from original"},
998  {BEVEL_AMT_WIDTH, "WIDTH", 0, "Width", "Amount is width of new face"},
1000  "DEPTH",
1001  0,
1002  "Depth",
1003  "Amount is perpendicular distance from original edge to bevel face"},
1004  {BEVEL_AMT_PERCENT, "PERCENT", 0, "Percent", "Amount is percent of adjacent edge length"},
1006  "ABSOLUTE",
1007  0,
1008  "Absolute",
1009  "Amount is absolute distance along adjacent edge"},
1010  {0, NULL, 0, NULL, NULL},
1011  };
1012 
1013  static const EnumPropertyItem prop_profile_type_items[] = {
1015  "SUPERELLIPSE",
1016  0,
1017  "Superellipse",
1018  "The profile can be a concave or convex curve"},
1020  "CUSTOM",
1021  0,
1022  "Custom",
1023  "The profile can be any arbitrary path between its endpoints"},
1024  {0, NULL, 0, NULL, NULL},
1025  };
1026 
1027  static const EnumPropertyItem face_strength_mode_items[] = {
1028  {BEVEL_FACE_STRENGTH_NONE, "NONE", 0, "None", "Do not set face strength"},
1029  {BEVEL_FACE_STRENGTH_NEW, "NEW", 0, "New", "Set face strength on new faces only"},
1031  "AFFECTED",
1032  0,
1033  "Affected",
1034  "Set face strength on new and modified faces only"},
1035  {BEVEL_FACE_STRENGTH_ALL, "ALL", 0, "All", "Set face strength on all faces"},
1036  {0, NULL, 0, NULL, NULL},
1037  };
1038 
1039  static const EnumPropertyItem miter_outer_items[] = {
1040  {BEVEL_MITER_SHARP, "SHARP", 0, "Sharp", "Outside of miter is sharp"},
1041  {BEVEL_MITER_PATCH, "PATCH", 0, "Patch", "Outside of miter is squared-off patch"},
1042  {BEVEL_MITER_ARC, "ARC", 0, "Arc", "Outside of miter is arc"},
1043  {0, NULL, 0, NULL, NULL},
1044  };
1045 
1046  static const EnumPropertyItem miter_inner_items[] = {
1047  {BEVEL_MITER_SHARP, "SHARP", 0, "Sharp", "Inside of miter is sharp"},
1048  {BEVEL_MITER_ARC, "ARC", 0, "Arc", "Inside of miter is arc"},
1049  {0, NULL, 0, NULL, NULL},
1050  };
1051 
1052  static EnumPropertyItem vmesh_method_items[] = {
1053  {BEVEL_VMESH_ADJ, "ADJ", 0, "Grid Fill", "Default patterned fill"},
1055  "CUTOFF",
1056  0,
1057  "Cutoff",
1058  "A cutoff at each profile's end before the intersection"},
1059  {0, NULL, 0, NULL, NULL},
1060  };
1061 
1062  static const EnumPropertyItem prop_affect_items[] = {
1063  {BEVEL_AFFECT_VERTICES, "VERTICES", 0, "Vertices", "Affect only vertices"},
1064  {BEVEL_AFFECT_EDGES, "EDGES", 0, "Edges", "Affect only edges"},
1065  {0, NULL, 0, NULL, NULL},
1066  };
1067 
1068  /* identifiers */
1069  ot->name = "Bevel";
1070  ot->description = "Cut into selected items at an angle to create bevel or chamfer";
1071  ot->idname = "MESH_OT_bevel";
1072 
1073  /* api callbacks */
1074  ot->exec = edbm_bevel_exec;
1079  ot->ui = edbm_bevel_ui;
1080 
1081  /* flags */
1083 
1084  /* properties */
1085  RNA_def_enum(ot->srna,
1086  "offset_type",
1087  offset_type_items,
1088  0,
1089  "Width Type",
1090  "The method for determining the size of the bevel");
1091  prop = RNA_def_property(ot->srna, "offset", PROP_FLOAT, PROP_DISTANCE);
1092  RNA_def_property_range(prop, 0.0, 1e6);
1093  RNA_def_property_ui_range(prop, 0.0, 100.0, 1, 3);
1094  RNA_def_property_ui_text(prop, "Width", "Bevel amount");
1095 
1096  RNA_def_enum(ot->srna,
1097  "profile_type",
1098  prop_profile_type_items,
1099  0,
1100  "Profile Type",
1101  "The type of shape used to rebuild a beveled section");
1102 
1103  prop = RNA_def_property(ot->srna, "offset_pct", PROP_FLOAT, PROP_PERCENTAGE);
1104  RNA_def_property_range(prop, 0.0, 100);
1105  RNA_def_property_ui_text(prop, "Width Percent", "Bevel amount for percentage method");
1106 
1107  RNA_def_int(ot->srna,
1108  "segments",
1109  1,
1110  1,
1112  "Segments",
1113  "Segments for curved edge",
1114  1,
1115  100);
1116 
1118  "profile",
1119  0.5f,
1121  1.0f,
1122  "Profile",
1123  "Controls profile shape (0.5 = round)",
1125  1.0f);
1126 
1127  RNA_def_enum(ot->srna,
1128  "affect",
1129  prop_affect_items,
1131  "Affect",
1132  "Affect edges or vertices");
1133 
1135  "clamp_overlap",
1136  false,
1137  "Clamp Overlap",
1138  "Do not allow beveled edges/vertices to overlap each other");
1139 
1141  ot->srna, "loop_slide", true, "Loop Slide", "Prefer sliding along edges to even widths");
1142 
1143  RNA_def_boolean(ot->srna, "mark_seam", false, "Mark Seams", "Mark Seams along beveled edges");
1144 
1145  RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp");
1146 
1147  RNA_def_int(ot->srna,
1148  "material",
1149  -1,
1150  -1,
1151  INT_MAX,
1152  "Material Index",
1153  "Material for bevel faces (-1 means use adjacent faces)",
1154  -1,
1155  100);
1156 
1158  "harden_normals",
1159  false,
1160  "Harden Normals",
1161  "Match normals of new faces to adjacent faces");
1162 
1163  RNA_def_enum(ot->srna,
1164  "face_strength_mode",
1165  face_strength_mode_items,
1167  "Face Strength Mode",
1168  "Whether to set face strength, and which faces to set face strength on");
1169 
1170  RNA_def_enum(ot->srna,
1171  "miter_outer",
1172  miter_outer_items,
1174  "Outer Miter",
1175  "Pattern to use for outside of miters");
1176 
1177  RNA_def_enum(ot->srna,
1178  "miter_inner",
1179  miter_inner_items,
1181  "Inner Miter",
1182  "Pattern to use for inside of miters");
1183 
1185  "spread",
1186  0.1f,
1187  0.0f,
1188  1e6f,
1189  "Spread",
1190  "Amount to spread arcs for arc inner miters",
1191  0.0f,
1192  100.0f);
1193 
1194  RNA_def_enum(ot->srna,
1195  "vmesh_method",
1196  vmesh_method_items,
1198  "Vertex Mesh Method",
1199  "The method to use to create meshes at intersections");
1200 
1201  prop = RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "");
1203 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1208
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:219
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:426
@ B_UNIT_LENGTH
Definition: BKE_unit.h:79
@ B_UNIT_NONE
Definition: BKE_unit.h:78
size_t BKE_unit_value_as_string(char *str, int len_max, double value, int prec, int type, const struct UnitSettings *settings, bool pad)
MINLINE float max_ff(float a, float b)
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2196
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned int uint
Definition: BLI_sys_types.h:83
#define CLAMPIS(a, b, c)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
typedef double(DMatrix)[4][4]
@ ME_AUTOSMOOTH
Object is a sort of wrapper for general info.
#define SCE_SELECT_FACE
@ V3D_AROUND_CENTER_MEDIAN
@ V3D_GIZMO_HIDE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess)
struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em)
void EDBM_update_generic(struct Mesh *me, const bool do_tessellation, const bool is_destructive)
void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag)
void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalctess)
void EDBM_selectmode_flush(struct BMEditMesh *em)
void EDBM_mesh_normals_update(struct BMEditMesh *em)
void initNumInput(NumInput *n)
Definition: numinput.c:83
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:27
@ NUM_NO_NEGATIVE
Definition: ED_numinput.h:70
@ NUM_NO_ZERO
Definition: ED_numinput.h:71
@ NUM_NO_FRACTION
Definition: ED_numinput.h:72
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:207
bool hasNumInput(const NumInput *n)
Definition: numinput.c:185
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event)
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:815
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
bool ED_operator_editmesh(struct bContext *C)
Definition: screen_ops.c:404
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:840
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:238
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:67
void ED_region_draw_cb_exit(struct ARegionType *, void *)
Definition: spacetypes.c:253
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2])
Definition: transform.c:1259
void ED_region_draw_mouse_line_cb(const struct bContext *C, struct ARegion *region, void *arg_info)
float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group RGB to Bright Vector Camera CLAMP
StructRNA RNA_ToolSettings
@ PROP_FLOAT
Definition: RNA_types.h:75
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
@ PROP_HIDDEN
Definition: RNA_types.h:202
@ PROP_DISTANCE
Definition: RNA_types.h:135
@ PROP_PERCENTAGE
Definition: RNA_types.h:130
#define C
Definition: RandGen.cpp:39
void uiLayoutSetActive(uiLayout *layout, bool active)
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_SLIDER
uiLayout * uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *heading)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiTemplateCurveProfile(uiLayout *layout, struct PointerRNA *ptr, const char *propname)
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:90
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_GRAB_CURSOR_XY
Definition: WM_types.h:161
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define KM_PRESS
Definition: WM_types.h:242
#define KM_RELEASE
Definition: WM_types.h:243
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag, const bool do_flush)
BMO_FLAG_BUFFER.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
@ BEVEL_VMESH_ADJ
@ BEVEL_VMESH_CUTOFF
@ BEVEL_AMT_WIDTH
@ BEVEL_AMT_ABSOLUTE
@ BEVEL_AMT_PERCENT
@ BEVEL_AMT_OFFSET
@ BEVEL_AMT_DEPTH
@ BEVEL_MITER_PATCH
@ BEVEL_MITER_SHARP
@ BEVEL_MITER_ARC
@ BEVEL_PROFILE_SUPERELLIPSE
@ BEVEL_PROFILE_CUSTOM
@ BEVEL_FACE_STRENGTH_NONE
@ BEVEL_FACE_STRENGTH_AFFECTED
@ BEVEL_FACE_STRENGTH_NEW
@ BEVEL_FACE_STRENGTH_ALL
@ BEVEL_AFFECT_VERTICES
@ BEVEL_AFFECT_EDGES
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
Material material
static const float value_clamp_max[NUM_VALUE_KINDS]
static void edbm_bevel_cancel(bContext *C, wmOperator *op)
static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
static void edbm_bevel_ui(bContext *C, wmOperator *op)
static void edbm_bevel_exit(bContext *C, wmOperator *op)
static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
static const float value_start[NUM_VALUE_KINDS]
wmKeyMap * bevel_modal_keymap(wmKeyConfig *keyconf)
#define PROFILE_VALUE
static int edbm_bevel_exec(bContext *C, wmOperator *op)
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
#define WM_MODALKEY(_id)
static const float value_clamp_min[NUM_VALUE_KINDS]
#define OFFSET_VALUE_PERCENT
static float get_bevel_offset(wmOperator *op)
static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void edbm_bevel_numinput_set_value(wmOperator *op)
void MESH_OT_bevel(wmOperatorType *ot)
static const char * value_rna_name[NUM_VALUE_KINDS]
#define SEGMENTS_HARD_MAX
static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed)
#define OFFSET_VALUE
#define SEGMENTS_VALUE
static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
#define MVAL_PIXEL_MARGIN
#define PROFILE_HARD_MIN
static bool edbm_bevel_calc(wmOperator *op)
@ BEV_MODAL_CANCEL
@ BEV_MODAL_PROFILE_TYPE_CHANGE
@ BEV_MODAL_MARK_SHARP_TOGGLE
@ BEV_MODAL_AFFECT_CHANGE
@ BEV_MODAL_HARDEN_NORMALS_TOGGLE
@ BEV_MODAL_VERTEX_MESH_CHANGE
@ BEV_MODAL_OFFSET_MODE_CHANGE
@ BEV_MODAL_VALUE_OFFSET
@ BEV_MODAL_SEGMENTS_UP
@ BEV_MODAL_SEGMENTS_DOWN
@ BEV_MODAL_CONFIRM
@ BEV_MODAL_INNER_MITER_CHANGE
@ BEV_MODAL_MARK_SEAM_TOGGLE
@ BEV_MODAL_VALUE_SEGMENTS
@ BEV_MODAL_OUTER_MITER_CHANGE
@ BEV_MODAL_CLAMP_OVERLAP_TOGGLE
@ BEV_MODAL_VALUE_PROFILE
#define NUM_VALUE_KINDS
static const float value_scale_per_inch[NUM_VALUE_KINDS]
bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt,...)
bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool do_report)
uint col
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
Definition: rna_access.c:1962
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:6366
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
Definition: rna_define.c:1676
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
Definition: rna_define.c:1757
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
Definition: rna_define.c:1279
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
Definition: rna_define.c:1706
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
struct ARegionType * type
short selectmode
Definition: BKE_editmesh.h:72
struct BMesh * bm
Definition: BKE_editmesh.h:52
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
int totvertsel
Definition: bmesh_class.h:298
uint ob_store_len
float mcenter[2]
float max_obj_scale
void * draw_handle_pixel
float shift_value[NUM_VALUE_KINDS]
short gizmo_flag
float segments
BevelObjectStore * ob_store
NumInput num_input[NUM_VALUE_KINDS]
CurveProfile * custom_profile
float scale[NUM_VALUE_KINDS]
int launch_event
float initial_length[NUM_VALUE_KINDS]
short value_mode
BMBackup mesh_backup
float smoothresh
short flag
short idx_max
Definition: ED_numinput.h:34
short val_flag[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:43
int unit_sys
Definition: ED_numinput.h:35
int unit_type[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:37
float obmat[4][4]
void * data
struct ToolSettings * toolsettings
struct UnitSettings unit
struct CurveProfile * custom_bevel_profile_preset
char gizmo_flag
short shift
Definition: WM_types.h:618
short type
Definition: WM_types.h:577
const void * modal_items
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:787
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
#define G(x, y, z)
uint len
int WM_userdef_event_type_from_keymap_type(int kmitype)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
@ MOUSEPAN
@ EVT_MODAL_MAP
@ MOUSEMOVE
@ LEFTMOUSE
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
Definition: wm_keymap.c:914
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
Definition: wm_keymap.c:985
const char * WM_bool_as_string(bool test)
Definition: wm_keymap.c:2003
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition: wm_keymap.c:888