Blender  V3.3
editmesh_bevel.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "MEM_guardedalloc.h"
8 
9 #include "DNA_object_types.h"
10 
11 #include "BLI_math.h"
12 #include "BLI_string.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_editmesh.h"
18 #include "BKE_global.h"
19 #include "BKE_layer.h"
20 #include "BKE_unit.h"
21 
22 #include "DNA_curveprofile_types.h"
23 #include "DNA_mesh_types.h"
24 
25 #include "RNA_access.h"
26 #include "RNA_define.h"
27 #include "RNA_prototypes.h"
28 
29 #include "WM_api.h"
30 #include "WM_types.h"
31 
32 #include "UI_interface.h"
33 #include "UI_resources.h"
34 
35 #include "ED_mesh.h"
36 #include "ED_numinput.h"
37 #include "ED_screen.h"
38 #include "ED_space_api.h"
39 #include "ED_transform.h"
40 #include "ED_util.h"
41 #include "ED_view3d.h"
42 
43 #include "mesh_intern.h" /* own include */
44 
45 #define MVAL_PIXEL_MARGIN 5.0f
46 
47 #define PROFILE_HARD_MIN 0.0f
48 
49 #define SEGMENTS_HARD_MAX 1000
50 
51 /* which value is mouse movement and numeric input controlling? */
52 #define OFFSET_VALUE 0
53 #define OFFSET_VALUE_PERCENT 1
54 #define PROFILE_VALUE 2
55 #define SEGMENTS_VALUE 3
56 #define NUM_VALUE_KINDS 4
57 
58 static const char *value_rna_name[NUM_VALUE_KINDS] = {
59  "offset", "offset_pct", "profile", "segments"};
60 static const float value_clamp_min[NUM_VALUE_KINDS] = {0.0f, 0.0f, PROFILE_HARD_MIN, 1.0f};
61 static const float value_clamp_max[NUM_VALUE_KINDS] = {1e6, 100.0f, 1.0f, SEGMENTS_HARD_MAX};
62 static const float value_start[NUM_VALUE_KINDS] = {0.0f, 0.0f, 0.5f, 1.0f};
63 static const float value_scale_per_inch[NUM_VALUE_KINDS] = {0.0f, 100.0f, 1.0f, 4.0f};
64 
65 typedef struct {
70 
71 typedef struct {
72  float initial_length[NUM_VALUE_KINDS];
73  float scale[NUM_VALUE_KINDS];
76  float shift_value[NUM_VALUE_KINDS];
78  bool is_modal;
79 
82 
83  /* modal only */
85  float mcenter[2];
87  short value_mode; /* Which value does mouse movement and numeric input affect? */
88  float segments; /* Segments as float so smooth mouse pan works in small increments */
89 
91 } BevelData;
92 
93 enum {
111 };
112 
113 static float get_bevel_offset(wmOperator *op)
114 {
115  if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) {
116  return RNA_float_get(op->ptr, "offset_pct");
117  }
118  return RNA_float_get(op->ptr, "offset");
119 }
120 
122 {
123  char status_text[UI_MAX_DRAW_STR];
124  char buf[UI_MAX_DRAW_STR];
125  char *p = buf;
126  int available_len = sizeof(buf);
127  Scene *sce = CTX_data_scene(C);
128 
129 #define WM_MODALKEY(_id) \
130  WM_modalkeymap_operator_items_to_string_buf( \
131  op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
132 
133  char offset_str[NUM_STR_REP_LEN];
134  if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) {
135  BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%.1f%%", RNA_float_get(op->ptr, "offset_pct"));
136  }
137  else {
138  double offset_val = (double)RNA_float_get(op->ptr, "offset");
139  BKE_unit_value_as_string(offset_str,
141  offset_val * sce->unit.scale_length,
142  3,
144  &sce->unit,
145  true);
146  }
147 
148  PropertyRNA *prop;
149  const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str;
150  prop = RNA_struct_find_property(op->ptr, "offset_type");
152  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &mode_str);
153  prop = RNA_struct_find_property(op->ptr, "profile_type");
155  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &profile_type_str);
156  prop = RNA_struct_find_property(op->ptr, "miter_outer");
158  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &omiter_str);
159  prop = RNA_struct_find_property(op->ptr, "miter_inner");
161  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &imiter_str);
162  prop = RNA_struct_find_property(op->ptr, "vmesh_method");
164  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &vmesh_str);
165  prop = RNA_struct_find_property(op->ptr, "affect");
167  C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &affect_str);
168 
169  BLI_snprintf(status_text,
170  sizeof(status_text),
171  TIP_("%s: Confirm, "
172  "%s: Cancel, "
173  "%s: Mode (%s), "
174  "%s: Width (%s), "
175  "%s: Segments (%d), "
176  "%s: Profile (%.3f), "
177  "%s: Clamp Overlap (%s), "
178  "%s: Affect (%s), "
179  "%s: Outer Miter (%s), "
180  "%s: Inner Miter (%s), "
181  "%s: Harden Normals (%s), "
182  "%s: Mark Seam (%s), "
183  "%s: Mark Sharp (%s), "
184  "%s: Profile Type (%s), "
185  "%s: Intersection (%s)"),
189  mode_str,
191  offset_str,
193  RNA_int_get(op->ptr, "segments"),
195  RNA_float_get(op->ptr, "profile"),
197  WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
199  affect_str,
201  omiter_str,
203  imiter_str,
205  WM_bool_as_string(RNA_boolean_get(op->ptr, "harden_normals")),
207  WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_seam")),
209  WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_sharp")),
211  profile_type_str,
213  vmesh_str);
214 
215 #undef WM_MODALKEY
216 
217  ED_workspace_status_text(C, status_text);
218 }
219 
220 static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
221 {
223  View3D *v3d = CTX_wm_view3d(C);
225  ViewLayer *view_layer = CTX_data_view_layer(C);
226 
227  if (is_modal) {
228  RNA_float_set(op->ptr, "offset", 0.0f);
229  RNA_float_set(op->ptr, "offset_pct", 0.0f);
230  }
231 
232  op->customdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
233  BevelData *opdata = op->customdata;
234  uint objects_used_len = 0;
235  opdata->max_obj_scale = FLT_MIN;
236 
237  /* Put the Curve Profile from the toolsettings into the opdata struct */
239 
240  {
241  uint ob_store_len = 0;
243  view_layer, v3d, &ob_store_len);
244  opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__);
245  for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) {
246  Object *obedit = objects[ob_index];
247  float scale = mat4_to_scale(obedit->obmat);
248  opdata->max_obj_scale = max_ff(opdata->max_obj_scale, scale);
249  BMEditMesh *em = BKE_editmesh_from_object(obedit);
250  if (em->bm->totvertsel > 0) {
251  opdata->ob_store[objects_used_len].ob = obedit;
252  objects_used_len++;
253  }
254  }
255  MEM_freeN(objects);
256  opdata->ob_store_len = objects_used_len;
257  }
258 
259  opdata->is_modal = is_modal;
260  int otype = RNA_enum_get(op->ptr, "offset_type");
262  opdata->segments = (float)RNA_int_get(op->ptr, "segments");
263  float pixels_per_inch = U.dpi * U.pixelsize;
264 
265  for (int i = 0; i < NUM_VALUE_KINDS; i++) {
266  opdata->shift_value[i] = -1.0f;
267  opdata->initial_length[i] = -1.0f;
268  /* NOTE: scale for #OFFSET_VALUE will get overwritten in #edbm_bevel_invoke. */
269  opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
270 
271  initNumInput(&opdata->num_input[i]);
272  opdata->num_input[i].idx_max = 0;
273  opdata->num_input[i].val_flag[0] |= NUM_NO_NEGATIVE;
274  opdata->num_input[i].unit_type[0] = B_UNIT_NONE;
275  if (i == SEGMENTS_VALUE) {
276  opdata->num_input[i].val_flag[0] |= NUM_NO_FRACTION | NUM_NO_ZERO;
277  }
278  if (i == OFFSET_VALUE) {
279  opdata->num_input[i].unit_sys = scene->unit.system;
280  opdata->num_input[i].unit_type[0] = B_UNIT_LENGTH;
281  }
282  }
283 
284  /* avoid the cost of allocating a bm copy */
285  if (is_modal) {
286  ARegion *region = CTX_wm_region(C);
287 
288  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
289  Object *obedit = opdata->ob_store[ob_index].ob;
290  BMEditMesh *em = BKE_editmesh_from_object(obedit);
291  opdata->ob_store[ob_index].mesh_backup = EDBM_redo_state_store(em);
292  }
295  G.moving = G_TRANSFORM_EDIT;
296  }
297 
298  return true;
299 }
300 
301 static bool edbm_bevel_calc(wmOperator *op)
302 {
303  BevelData *opdata = op->customdata;
304  BMOperator bmop;
305  bool changed = false;
306 
307  const float offset = get_bevel_offset(op);
308  const int offset_type = RNA_enum_get(op->ptr, "offset_type");
309  const int profile_type = RNA_enum_get(op->ptr, "profile_type");
310  const int segments = RNA_int_get(op->ptr, "segments");
311  const float profile = RNA_float_get(op->ptr, "profile");
312  const bool affect = RNA_enum_get(op->ptr, "affect");
313  const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
314  const int material_init = RNA_int_get(op->ptr, "material");
315  const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
316  const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
317  const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
318  const bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals");
319  const int face_strength_mode = RNA_enum_get(op->ptr, "face_strength_mode");
320  const int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
321  const int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
322  const float spread = RNA_float_get(op->ptr, "spread");
323  const int vmesh_method = RNA_enum_get(op->ptr, "vmesh_method");
324 
325  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
326  Object *obedit = opdata->ob_store[ob_index].ob;
327  BMEditMesh *em = BKE_editmesh_from_object(obedit);
328 
329  /* revert to original mesh */
330  if (opdata->is_modal) {
331  EDBM_redo_state_restore(&opdata->ob_store[ob_index].mesh_backup, em, false);
332  }
333 
334  const int material = CLAMPIS(material_init, -1, obedit->totcol - 1);
335 
336  Mesh *me = obedit->data;
337 
338  if (harden_normals && !(me->flag & ME_AUTOSMOOTH)) {
339  /* harden_normals only has a visible effect if autosmooth is on, so turn it on */
340  me->flag |= ME_AUTOSMOOTH;
341  }
342 
343  EDBM_op_init(em,
344  &bmop,
345  op,
346  "bevel geom=%hev offset=%f segments=%i affect=%i offset_type=%i "
347  "profile_type=%i profile=%f clamp_overlap=%b material=%i loop_slide=%b "
348  "mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i "
349  "miter_outer=%i miter_inner=%i spread=%f smoothresh=%f custom_profile=%p "
350  "vmesh_method=%i",
352  offset,
353  segments,
354  affect,
355  offset_type,
356  profile_type,
357  profile,
358  clamp_overlap,
359  material,
360  loop_slide,
361  mark_seam,
362  mark_sharp,
363  harden_normals,
364  face_strength_mode,
365  miter_outer,
366  miter_inner,
367  spread,
368  me->smoothresh,
369  opdata->custom_profile,
370  vmesh_method);
371 
372  BMO_op_exec(em->bm, &bmop);
373 
374  if (offset != 0.0f) {
375  /* not essential, but we may have some loose geometry that
376  * won't get bevel'd and better not leave it selected */
379  em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
380  }
381 
382  /* no need to de-select existing geometry */
383  if (!EDBM_op_finish(em, &bmop, op, true)) {
384  continue;
385  }
386 
387  EDBM_update(obedit->data,
388  &(const struct EDBMUpdate_Params){
389  .calc_looptri = true,
390  .calc_normals = true,
391  .is_destructive = true,
392  });
393  changed = true;
394  }
395  return changed;
396 }
397 
399 {
400  BevelData *opdata = op->customdata;
402 
403  if (area) {
405  }
406 
407  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
408  Object *obedit = opdata->ob_store[ob_index].ob;
409  BMEditMesh *em = BKE_editmesh_from_object(obedit);
410  /* Without this, faces surrounded by selected edges/verts will be unselected. */
411  if ((em->selectmode & SCE_SELECT_FACE) == 0) {
413  }
414  }
415 
416  if (opdata->is_modal) {
417  ARegion *region = CTX_wm_region(C);
418  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
419  EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
420  }
422  G.moving = 0;
423  }
424  MEM_SAFE_FREE(opdata->ob_store);
426  op->customdata = NULL;
427 }
428 
430 {
431  BevelData *opdata = op->customdata;
432  if (opdata->is_modal) {
433  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
434  Object *obedit = opdata->ob_store[ob_index].ob;
435  BMEditMesh *em = BKE_editmesh_from_object(obedit);
436  EDBM_redo_state_restore_and_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
437  EDBM_update(obedit->data,
438  &(const struct EDBMUpdate_Params){
439  .calc_looptri = false,
440  .calc_normals = true,
441  .is_destructive = true,
442  });
443  }
444  }
445 
446  edbm_bevel_exit(C, op);
447 
448  /* need to force redisplay or we may still view the modified result */
450 }
451 
452 /* bevel! yay!! */
454 {
455  if (!edbm_bevel_init(C, op, false)) {
456  return OPERATOR_CANCELLED;
457  }
458 
459  if (!edbm_bevel_calc(op)) {
460  edbm_bevel_cancel(C, op);
461  return OPERATOR_CANCELLED;
462  }
463 
464  edbm_bevel_exit(C, op);
465 
466  return OPERATOR_FINISHED;
467 }
468 
469 static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed)
470 {
471  BevelData *opdata = op->customdata;
472  const float mlen[2] = {
473  opdata->mcenter[0] - event->mval[0],
474  opdata->mcenter[1] - event->mval[1],
475  };
476  float len = len_v2(mlen);
477  int vmode = opdata->value_mode;
478  if (mode_changed || opdata->initial_length[vmode] == -1.0f) {
479  /* If current value is not default start value, adjust len so that
480  * the scaling and offset in edbm_bevel_mouse_set_value will
481  * start at current value */
482  float value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
483  RNA_float_get(op->ptr, value_rna_name[vmode]);
484  float sc = opdata->scale[vmode];
485  float st = value_start[vmode];
486  if (value != value_start[vmode]) {
487  len = (st + sc * (len - MVAL_PIXEL_MARGIN) - value) / sc;
488  }
489  }
490  opdata->initial_length[opdata->value_mode] = len;
491 }
492 
493 static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
494 {
496 
497  if (!edbm_bevel_init(C, op, true)) {
498  return OPERATOR_CANCELLED;
499  }
500 
501  BevelData *opdata = op->customdata;
502 
504 
505  /* initialize mouse values */
506  float center_3d[3];
507  if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, center_3d, opdata->mcenter)) {
508  /* in this case the tool will likely do nothing,
509  * ideally this will never happen and should be checked for above */
510  opdata->mcenter[0] = opdata->mcenter[1] = 0;
511  }
512 
513  /* for OFFSET_VALUE only, the scale is the size of a pixel under the mouse in 3d space */
514  opdata->scale[OFFSET_VALUE] = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
515  /* since we are affecting untransformed object but seeing in transformed space,
516  * compensate for that */
517  opdata->scale[OFFSET_VALUE] /= opdata->max_obj_scale;
518 
519  edbm_bevel_calc_initial_length(op, event, false);
520 
522 
523  if (!edbm_bevel_calc(op)) {
524  edbm_bevel_cancel(C, op);
526  return OPERATOR_CANCELLED;
527  }
528 
530 
531  return OPERATOR_RUNNING_MODAL;
532 }
533 
534 static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
535 {
536  BevelData *opdata = op->customdata;
537  int vmode = opdata->value_mode;
538 
539  const float mdiff[2] = {
540  opdata->mcenter[0] - event->mval[0],
541  opdata->mcenter[1] - event->mval[1],
542  };
543 
544  float value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]);
545 
546  /* Scale according to value mode */
547  value = value_start[vmode] + value * opdata->scale[vmode];
548 
549  /* Fake shift-transform... */
550  if (event->modifier & KM_SHIFT) {
551  if (opdata->shift_value[vmode] < 0.0f) {
552  opdata->shift_value[vmode] = (vmode == SEGMENTS_VALUE) ?
553  opdata->segments :
554  RNA_float_get(op->ptr, value_rna_name[vmode]);
555  }
556  value = (value - opdata->shift_value[vmode]) * 0.1f + opdata->shift_value[vmode];
557  }
558  else if (opdata->shift_value[vmode] >= 0.0f) {
559  opdata->shift_value[vmode] = -1.0f;
560  }
561 
562  /* Clamp according to value mode, and store value back. */
563  CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
564  if (vmode == SEGMENTS_VALUE) {
565  opdata->segments = value;
566  RNA_int_set(op->ptr, "segments", (int)(value + 0.5f));
567  }
568  else {
569  RNA_float_set(op->ptr, value_rna_name[vmode], value);
570  }
571 }
572 
574 {
575  BevelData *opdata = op->customdata;
576 
577  int vmode = opdata->value_mode;
578  float value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
579  RNA_float_get(op->ptr, value_rna_name[vmode]);
580  applyNumInput(&opdata->num_input[vmode], &value);
581  CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
582  if (vmode == SEGMENTS_VALUE) {
583  opdata->segments = value;
584  RNA_int_set(op->ptr, "segments", (int)value);
585  }
586  else {
587  RNA_float_set(op->ptr, value_rna_name[vmode], value);
588  }
589 }
590 
592 {
593  static const EnumPropertyItem modal_items[] = {
594  {BEV_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel bevel"},
595  {BEV_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", "Confirm bevel"},
596  {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change Offset", "Value changes offset"},
597  {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change Profile", "Value changes profile"},
598  {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change Segments", "Value changes segments"},
599  {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase Segments", "Increase segments"},
600  {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease Segments", "Decrease segments"},
602  "OFFSET_MODE_CHANGE",
603  0,
604  "Change Offset Mode",
605  "Cycle through offset modes"},
607  "CLAMP_OVERLAP_TOGGLE",
608  0,
609  "Toggle Clamp Overlap",
610  "Toggle clamp overlap flag"},
612  "AFFECT_CHANGE",
613  0,
614  "Change Affect Type",
615  "Change which geometry type the operation affects, edges or vertices"},
617  "HARDEN_NORMALS_TOGGLE",
618  0,
619  "Toggle Harden Normals",
620  "Toggle harden normals flag"},
622  "MARK_SEAM_TOGGLE",
623  0,
624  "Toggle Mark Seam",
625  "Toggle mark seam flag"},
627  "MARK_SHARP_TOGGLE",
628  0,
629  "Toggle Mark Sharp",
630  "Toggle mark sharp flag"},
632  "OUTER_MITER_CHANGE",
633  0,
634  "Change Outer Miter",
635  "Cycle through outer miter kinds"},
637  "INNER_MITER_CHANGE",
638  0,
639  "Change Inner Miter",
640  "Cycle through inner miter kinds"},
641  {BEV_MODAL_PROFILE_TYPE_CHANGE, "PROFILE_TYPE_CHANGE", 0, "Cycle through profile types", ""},
643  "VERTEX_MESH_CHANGE",
644  0,
645  "Change Intersection Method",
646  "Cycle through intersection methods"},
647  {0, NULL, 0, NULL, NULL},
648  };
649 
650  wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Bevel Modal Map");
651 
652  /* This function is called for each spacetype, only needs to add map once */
653  if (keymap && keymap->modal_items) {
654  return NULL;
655  }
656 
657  keymap = WM_modalkeymap_ensure(keyconf, "Bevel Modal Map", modal_items);
658 
659  WM_modalkeymap_assign(keymap, "MESH_OT_bevel");
660 
661  return keymap;
662 }
663 
664 static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
665 {
666  BevelData *opdata = op->customdata;
667  const bool has_numinput = hasNumInput(&opdata->num_input[opdata->value_mode]);
668  bool handled = false;
669  short etype = event->type;
670  short eval = event->val;
671 
672  /* When activated from toolbar, need to convert left-mouse release to confirm. */
673  if (ELEM(etype, LEFTMOUSE, opdata->launch_event) && (eval == KM_RELEASE) &&
674  RNA_boolean_get(op->ptr, "release_confirm")) {
675  etype = EVT_MODAL_MAP;
676  eval = BEV_MODAL_CONFIRM;
677  }
678  /* Modal numinput active, try to handle numeric inputs first... */
679  if (etype != EVT_MODAL_MAP && eval == KM_PRESS && has_numinput &&
680  handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
682  edbm_bevel_calc(op);
684  return OPERATOR_RUNNING_MODAL;
685  }
686  if (etype == MOUSEMOVE) {
687  if (!has_numinput) {
688  edbm_bevel_mouse_set_value(op, event);
689  edbm_bevel_calc(op);
691  handled = true;
692  }
693  }
694  else if (etype == MOUSEPAN) {
695  float delta = 0.02f * (event->xy[1] - event->prev_xy[1]);
696  if (opdata->segments >= 1 && opdata->segments + delta < 1) {
697  opdata->segments = 1;
698  }
699  else {
700  opdata->segments += delta;
701  }
702  RNA_int_set(op->ptr, "segments", (int)opdata->segments);
703  edbm_bevel_calc(op);
705  handled = true;
706  }
707  else if (etype == EVT_MODAL_MAP) {
708  switch (eval) {
709  case BEV_MODAL_CANCEL:
710  edbm_bevel_cancel(C, op);
712  return OPERATOR_CANCELLED;
713 
714  case BEV_MODAL_CONFIRM:
715  edbm_bevel_calc(op);
716  edbm_bevel_exit(C, op);
718  return OPERATOR_FINISHED;
719 
721  opdata->segments = opdata->segments + 1;
722  RNA_int_set(op->ptr, "segments", (int)opdata->segments);
723  edbm_bevel_calc(op);
725  handled = true;
726  break;
727 
729  opdata->segments = max_ff(opdata->segments - 1, 1);
730  RNA_int_set(op->ptr, "segments", (int)opdata->segments);
731  edbm_bevel_calc(op);
733  handled = true;
734  break;
735 
737  int type = RNA_enum_get(op->ptr, "offset_type");
738  type++;
739  if (type > BEVEL_AMT_PERCENT) {
741  }
742  if (opdata->value_mode == OFFSET_VALUE && type == BEVEL_AMT_PERCENT) {
744  }
745  else if (opdata->value_mode == OFFSET_VALUE_PERCENT && type != BEVEL_AMT_PERCENT) {
746  opdata->value_mode = OFFSET_VALUE;
747  }
748  RNA_enum_set(op->ptr, "offset_type", type);
749  if (opdata->initial_length[opdata->value_mode] == -1.0f) {
750  edbm_bevel_calc_initial_length(op, event, true);
751  }
752  }
753  /* Update offset accordingly to new offset_type. */
754  if (!has_numinput && (ELEM(opdata->value_mode, OFFSET_VALUE, OFFSET_VALUE_PERCENT))) {
755  edbm_bevel_mouse_set_value(op, event);
756  }
757  edbm_bevel_calc(op);
759  handled = true;
760  break;
761 
763  bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
764  RNA_boolean_set(op->ptr, "clamp_overlap", !clamp_overlap);
765  edbm_bevel_calc(op);
767  handled = true;
768  break;
769  }
770 
772  opdata->value_mode = OFFSET_VALUE;
773  edbm_bevel_calc_initial_length(op, event, true);
774  break;
775 
777  opdata->value_mode = PROFILE_VALUE;
778  edbm_bevel_calc_initial_length(op, event, true);
779  break;
780 
782  opdata->value_mode = SEGMENTS_VALUE;
783  edbm_bevel_calc_initial_length(op, event, true);
784  break;
785 
787  int affect_type = RNA_enum_get(op->ptr, "affect");
788  affect_type++;
789  if (affect_type > BEVEL_AFFECT_EDGES) {
790  affect_type = BEVEL_AFFECT_VERTICES;
791  }
792  RNA_enum_set(op->ptr, "affect", affect_type);
793  edbm_bevel_calc(op);
795  handled = true;
796  break;
797  }
798 
800  bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
801  RNA_boolean_set(op->ptr, "mark_seam", !mark_seam);
802  edbm_bevel_calc(op);
804  handled = true;
805  break;
806  }
807 
809  bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
810  RNA_boolean_set(op->ptr, "mark_sharp", !mark_sharp);
811  edbm_bevel_calc(op);
813  handled = true;
814  break;
815  }
816 
818  int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
819  miter_inner++;
820  if (miter_inner == BEVEL_MITER_PATCH) {
821  miter_inner++; /* no patch option for inner miter */
822  }
823  if (miter_inner > BEVEL_MITER_ARC) {
824  miter_inner = BEVEL_MITER_SHARP;
825  }
826  RNA_enum_set(op->ptr, "miter_inner", miter_inner);
827  edbm_bevel_calc(op);
829  handled = true;
830  break;
831  }
832 
834  int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
835  miter_outer++;
836  if (miter_outer > BEVEL_MITER_ARC) {
837  miter_outer = BEVEL_MITER_SHARP;
838  }
839  RNA_enum_set(op->ptr, "miter_outer", miter_outer);
840  edbm_bevel_calc(op);
842  handled = true;
843  break;
844  }
845 
847  bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals");
848  RNA_boolean_set(op->ptr, "harden_normals", !harden_normals);
849  edbm_bevel_calc(op);
851  handled = true;
852  break;
853  }
854 
856  int profile_type = RNA_enum_get(op->ptr, "profile_type");
857  profile_type++;
858  if (profile_type > BEVEL_PROFILE_CUSTOM) {
859  profile_type = BEVEL_PROFILE_SUPERELLIPSE;
860  }
861  RNA_enum_set(op->ptr, "profile_type", profile_type);
862  edbm_bevel_calc(op);
864  handled = true;
865  break;
866  }
867 
869  int vmesh_method = RNA_enum_get(op->ptr, "vmesh_method");
870  vmesh_method++;
871  if (vmesh_method > BEVEL_VMESH_CUTOFF) {
872  vmesh_method = BEVEL_VMESH_ADJ;
873  }
874  RNA_enum_set(op->ptr, "vmesh_method", vmesh_method);
875  edbm_bevel_calc(op);
877  handled = true;
878  break;
879  }
880  }
881  }
882 
883  /* Modal numinput inactive, try to handle numeric inputs last... */
884  if (!handled && eval == KM_PRESS &&
885  handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
887  edbm_bevel_calc(op);
889  return OPERATOR_RUNNING_MODAL;
890  }
891 
892  return OPERATOR_RUNNING_MODAL;
893 }
894 
895 static void edbm_bevel_ui(bContext *C, wmOperator *op)
896 {
897  uiLayout *layout = op->layout;
898  uiLayout *col, *row;
899  PointerRNA toolsettings_ptr;
900 
901  int profile_type = RNA_enum_get(op->ptr, "profile_type");
902  int offset_type = RNA_enum_get(op->ptr, "offset_type");
903  bool affect_type = RNA_enum_get(op->ptr, "affect");
904 
905  uiLayoutSetPropSep(layout, true);
906  uiLayoutSetPropDecorate(layout, false);
907 
908  row = uiLayoutRow(layout, false);
909  uiItemR(row, op->ptr, "affect", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
910 
911  uiItemS(layout);
912 
913  uiItemR(layout, op->ptr, "offset_type", 0, NULL, ICON_NONE);
914 
915  if (offset_type == BEVEL_AMT_PERCENT) {
916  uiItemR(layout, op->ptr, "offset_pct", 0, NULL, ICON_NONE);
917  }
918  else {
919  uiItemR(layout, op->ptr, "offset", 0, NULL, ICON_NONE);
920  }
921 
922  uiItemR(layout, op->ptr, "segments", 0, NULL, ICON_NONE);
924  uiItemR(layout,
925  op->ptr,
926  "profile",
928  (profile_type == BEVEL_PROFILE_SUPERELLIPSE) ? IFACE_("Shape") : IFACE_("Miter Shape"),
929  ICON_NONE);
930  }
931  uiItemR(layout, op->ptr, "material", 0, NULL, ICON_NONE);
932 
933  col = uiLayoutColumn(layout, true);
934  uiItemR(col, op->ptr, "harden_normals", 0, NULL, ICON_NONE);
935  uiItemR(col, op->ptr, "clamp_overlap", 0, NULL, ICON_NONE);
936  uiItemR(col, op->ptr, "loop_slide", 0, NULL, ICON_NONE);
937 
938  col = uiLayoutColumnWithHeading(layout, true, IFACE_("Mark"));
939  uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
940  uiItemR(col, op->ptr, "mark_seam", 0, IFACE_("Seams"), ICON_NONE);
941  uiItemR(col, op->ptr, "mark_sharp", 0, IFACE_("Sharp"), ICON_NONE);
942 
943  uiItemS(layout);
944 
945  col = uiLayoutColumn(layout, false);
946  uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
947  uiItemR(col, op->ptr, "miter_outer", 0, IFACE_("Miter Outer"), ICON_NONE);
948  uiItemR(col, op->ptr, "miter_inner", 0, IFACE_("Inner"), ICON_NONE);
949  if (RNA_enum_get(op->ptr, "miter_inner") == BEVEL_MITER_ARC) {
950  uiItemR(col, op->ptr, "spread", 0, NULL, ICON_NONE);
951  }
952 
953  uiItemS(layout);
954 
955  col = uiLayoutColumn(layout, false);
956  uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
957  uiItemR(col, op->ptr, "vmesh_method", 0, IFACE_("Intersection Type"), ICON_NONE);
958 
959  uiItemR(layout, op->ptr, "face_strength_mode", 0, IFACE_("Face Strength"), ICON_NONE);
960 
961  uiItemS(layout);
962 
963  row = uiLayoutRow(layout, false);
964  uiItemR(row, op->ptr, "profile_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
965  if (profile_type == BEVEL_PROFILE_CUSTOM) {
966  /* Get an RNA pointer to ToolSettings to give to the curve profile template code. */
968  RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
969  uiTemplateCurveProfile(layout, &toolsettings_ptr, "custom_bevel_profile_preset");
970  }
971 }
972 
974 {
975  PropertyRNA *prop;
976 
977  static const EnumPropertyItem offset_type_items[] = {
978  {BEVEL_AMT_OFFSET, "OFFSET", 0, "Offset", "Amount is offset of new edges from original"},
979  {BEVEL_AMT_WIDTH, "WIDTH", 0, "Width", "Amount is width of new face"},
981  "DEPTH",
982  0,
983  "Depth",
984  "Amount is perpendicular distance from original edge to bevel face"},
985  {BEVEL_AMT_PERCENT, "PERCENT", 0, "Percent", "Amount is percent of adjacent edge length"},
987  "ABSOLUTE",
988  0,
989  "Absolute",
990  "Amount is absolute distance along adjacent edge"},
991  {0, NULL, 0, NULL, NULL},
992  };
993 
994  static const EnumPropertyItem prop_profile_type_items[] = {
996  "SUPERELLIPSE",
997  0,
998  "Superellipse",
999  "The profile can be a concave or convex curve"},
1001  "CUSTOM",
1002  0,
1003  "Custom",
1004  "The profile can be any arbitrary path between its endpoints"},
1005  {0, NULL, 0, NULL, NULL},
1006  };
1007 
1008  static const EnumPropertyItem face_strength_mode_items[] = {
1009  {BEVEL_FACE_STRENGTH_NONE, "NONE", 0, "None", "Do not set face strength"},
1010  {BEVEL_FACE_STRENGTH_NEW, "NEW", 0, "New", "Set face strength on new faces only"},
1012  "AFFECTED",
1013  0,
1014  "Affected",
1015  "Set face strength on new and modified faces only"},
1016  {BEVEL_FACE_STRENGTH_ALL, "ALL", 0, "All", "Set face strength on all faces"},
1017  {0, NULL, 0, NULL, NULL},
1018  };
1019 
1020  static const EnumPropertyItem miter_outer_items[] = {
1021  {BEVEL_MITER_SHARP, "SHARP", 0, "Sharp", "Outside of miter is sharp"},
1022  {BEVEL_MITER_PATCH, "PATCH", 0, "Patch", "Outside of miter is squared-off patch"},
1023  {BEVEL_MITER_ARC, "ARC", 0, "Arc", "Outside of miter is arc"},
1024  {0, NULL, 0, NULL, NULL},
1025  };
1026 
1027  static const EnumPropertyItem miter_inner_items[] = {
1028  {BEVEL_MITER_SHARP, "SHARP", 0, "Sharp", "Inside of miter is sharp"},
1029  {BEVEL_MITER_ARC, "ARC", 0, "Arc", "Inside of miter is arc"},
1030  {0, NULL, 0, NULL, NULL},
1031  };
1032 
1033  static EnumPropertyItem vmesh_method_items[] = {
1034  {BEVEL_VMESH_ADJ, "ADJ", 0, "Grid Fill", "Default patterned fill"},
1036  "CUTOFF",
1037  0,
1038  "Cutoff",
1039  "A cutoff at each profile's end before the intersection"},
1040  {0, NULL, 0, NULL, NULL},
1041  };
1042 
1043  static const EnumPropertyItem prop_affect_items[] = {
1044  {BEVEL_AFFECT_VERTICES, "VERTICES", 0, "Vertices", "Affect only vertices"},
1045  {BEVEL_AFFECT_EDGES, "EDGES", 0, "Edges", "Affect only edges"},
1046  {0, NULL, 0, NULL, NULL},
1047  };
1048 
1049  /* identifiers */
1050  ot->name = "Bevel";
1051  ot->description = "Cut into selected items at an angle to create bevel or chamfer";
1052  ot->idname = "MESH_OT_bevel";
1053 
1054  /* api callbacks */
1055  ot->exec = edbm_bevel_exec;
1060  ot->ui = edbm_bevel_ui;
1061 
1062  /* flags */
1064 
1065  /* properties */
1066  RNA_def_enum(ot->srna,
1067  "offset_type",
1068  offset_type_items,
1069  0,
1070  "Width Type",
1071  "The method for determining the size of the bevel");
1072  prop = RNA_def_property(ot->srna, "offset", PROP_FLOAT, PROP_DISTANCE);
1073  RNA_def_property_range(prop, 0.0, 1e6);
1074  RNA_def_property_ui_range(prop, 0.0, 100.0, 1, 3);
1075  RNA_def_property_ui_text(prop, "Width", "Bevel amount");
1076 
1077  RNA_def_enum(ot->srna,
1078  "profile_type",
1079  prop_profile_type_items,
1080  0,
1081  "Profile Type",
1082  "The type of shape used to rebuild a beveled section");
1083 
1084  prop = RNA_def_property(ot->srna, "offset_pct", PROP_FLOAT, PROP_PERCENTAGE);
1085  RNA_def_property_range(prop, 0.0, 100);
1086  RNA_def_property_ui_text(prop, "Width Percent", "Bevel amount for percentage method");
1087 
1088  RNA_def_int(ot->srna,
1089  "segments",
1090  1,
1091  1,
1093  "Segments",
1094  "Segments for curved edge",
1095  1,
1096  100);
1097 
1099  "profile",
1100  0.5f,
1102  1.0f,
1103  "Profile",
1104  "Controls profile shape (0.5 = round)",
1106  1.0f);
1107 
1108  RNA_def_enum(ot->srna,
1109  "affect",
1110  prop_affect_items,
1112  "Affect",
1113  "Affect edges or vertices");
1114 
1116  "clamp_overlap",
1117  false,
1118  "Clamp Overlap",
1119  "Do not allow beveled edges/vertices to overlap each other");
1120 
1122  ot->srna, "loop_slide", true, "Loop Slide", "Prefer sliding along edges to even widths");
1123 
1124  RNA_def_boolean(ot->srna, "mark_seam", false, "Mark Seams", "Mark Seams along beveled edges");
1125 
1126  RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp");
1127 
1128  RNA_def_int(ot->srna,
1129  "material",
1130  -1,
1131  -1,
1132  INT_MAX,
1133  "Material Index",
1134  "Material for bevel faces (-1 means use adjacent faces)",
1135  -1,
1136  100);
1137 
1139  "harden_normals",
1140  false,
1141  "Harden Normals",
1142  "Match normals of new faces to adjacent faces");
1143 
1144  RNA_def_enum(ot->srna,
1145  "face_strength_mode",
1146  face_strength_mode_items,
1148  "Face Strength Mode",
1149  "Whether to set face strength, and which faces to set face strength on");
1150 
1151  RNA_def_enum(ot->srna,
1152  "miter_outer",
1153  miter_outer_items,
1155  "Outer Miter",
1156  "Pattern to use for outside of miters");
1157 
1158  RNA_def_enum(ot->srna,
1159  "miter_inner",
1160  miter_inner_items,
1162  "Inner Miter",
1163  "Pattern to use for inside of miters");
1164 
1166  "spread",
1167  0.1f,
1168  0.0f,
1169  1e6f,
1170  "Spread",
1171  "Amount to spread arcs for arc inner miters",
1172  0.0f,
1173  100.0f);
1174 
1175  RNA_def_enum(ot->srna,
1176  "vmesh_method",
1177  vmesh_method_items,
1179  "Vertex Mesh Method",
1180  "The method to use to create meshes at intersections");
1181 
1182  prop = RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "");
1184 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:248
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:542
@ B_UNIT_LENGTH
Definition: BKE_unit.h:101
@ B_UNIT_NONE
Definition: BKE_unit.h:100
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:2185
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:67
#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
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void void EDBM_redo_state_restore_and_free(struct BMBackup *backup, struct BMEditMesh *em, bool recalc_looptri) ATTR_NONNULL(1
void EDBM_update(struct Mesh *me, const struct EDBMUpdate_Params *params)
void EDBM_redo_state_restore(struct BMBackup *backup, struct BMEditMesh *em, bool recalc_looptri) ATTR_NONNULL(1
struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em)
void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag)
void void void EDBM_redo_state_free(struct BMBackup *backup) ATTR_NONNULL(1)
void EDBM_selectmode_flush(struct BMEditMesh *em)
void initNumInput(NumInput *n)
Definition: numinput.c:69
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:13
@ NUM_NO_NEGATIVE
Definition: ED_numinput.h:56
@ NUM_NO_ZERO
Definition: ED_numinput.h:57
@ NUM_NO_FRACTION
Definition: ED_numinput.h:58
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:189
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event)
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
bool ED_operator_editmesh(struct bContext *C)
Definition: screen_ops.c:433
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:816
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:226
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:63
bool ED_region_draw_cb_exit(struct ARegionType *art, void *handle)
Definition: spacetypes.c:241
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2])
Definition: transform.c:1341
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 Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
@ PROP_HIDDEN
Definition: RNA_types.h:216
@ PROP_DISTANCE
Definition: RNA_types.h:149
@ PROP_PERCENTAGE
Definition: RNA_types.h:143
#define C
Definition: RandGen.cpp:25
void uiLayoutSetActive(uiLayout *layout, bool active)
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)
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_SLIDER
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
@ KM_PRESS
Definition: WM_types.h:267
@ KM_RELEASE
Definition: WM_types.h:268
@ OPTYPE_BLOCKING
Definition: WM_types.h:150
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_GRAB_CURSOR_XY
Definition: WM_types.h:154
@ OPTYPE_REGISTER
Definition: WM_types.h:146
@ KM_SHIFT
Definition: WM_types.h:238
@ 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, char htype, char hflag, 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_PROFILE_SUPERELLIPSE
@ BEVEL_PROFILE_CUSTOM
@ BEVEL_AFFECT_VERTICES
@ BEVEL_AFFECT_EDGES
@ BEVEL_FACE_STRENGTH_NONE
@ BEVEL_FACE_STRENGTH_AFFECTED
@ BEVEL_FACE_STRENGTH_NEW
@ BEVEL_FACE_STRENGTH_ALL
@ BEVEL_MITER_PATCH
@ BEVEL_MITER_SHARP
@ BEVEL_MITER_ARC
@ BEVEL_AMT_WIDTH
@ BEVEL_AMT_ABSOLUTE
@ BEVEL_AMT_PERCENT
@ BEVEL_AMT_OFFSET
@ BEVEL_AMT_DEPTH
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
Material material
int len
Definition: draw_manager.c:108
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)
@ 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
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)
#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
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define G(x, y, z)
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:4921
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
Definition: rna_access.c:1796
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:4968
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
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:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
Definition: rna_define.c:1645
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
Definition: rna_define.c:1737
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
Definition: rna_define.c:1257
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
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:3597
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
Definition: rna_define.c:1664
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:3783
struct ARegionType * type
short selectmode
Definition: BKE_editmesh.h:52
struct BMesh * bm
Definition: BKE_editmesh.h:40
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]
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
uint16_t flag
short idx_max
Definition: ED_numinput.h:20
short val_flag[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:29
int unit_sys
Definition: ED_numinput.h:21
int unit_type[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:23
float obmat[4][4]
void * data
struct ToolSettings * toolsettings
struct UnitSettings unit
struct CurveProfile * custom_bevel_profile_preset
uint8_t modifier
Definition: WM_types.h:693
short type
Definition: WM_types.h:678
const void * modal_items
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:954
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct uiLayout * layout
struct PointerRNA * ptr
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
wmOperatorType * ot
Definition: wm_files.c:3479
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:2052
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition: wm_keymap.c:888