[Bf-blender-cvs] [bec317858d3] soc-2021-knife-tools: Knife: Added visible distance and angle measurements

Cian Jinks noreply at git.blender.org
Wed Jun 23 13:19:57 CEST 2021


Commit: bec317858d3b4924c649632234d8a8fab86508a6
Author: Cian Jinks
Date:   Wed Jun 23 12:12:48 2021 +0100
Branches: soc-2021-knife-tools
https://developer.blender.org/rBbec317858d3b4924c649632234d8a8fab86508a6

Knife: Added visible distance and angle measurements

Pressing M while using the knife tool will now cycle through showing various measurements related to the current cut.

The different modes are:
Just Distance - Shows the length of the current cut segment
Just Angles - If the cut segment is touching any edges the corresponding angle is displayed
Both - Shows both distance and angles

===================================================================

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/editors/mesh/CMakeLists.txt
M	source/blender/editors/mesh/editmesh_knife.c

===================================================================

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index d1ddfa87f6e..803cbc5b2e1 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5364,6 +5364,7 @@ def km_knife_tool_modal_map(_params):
         ("IGNORE_SNAP_OFF", {"type": 'RIGHT_SHIFT', "value": 'RELEASE', "any": True}, None),
         ("ANGLE_SNAP_TOGGLE", {"type": 'C', "value": 'PRESS'}, None),
         ("CUT_THROUGH_TOGGLE", {"type": 'T', "value": 'PRESS'}, None),
+        ("SHOW_DISTANCE_ANGLE_TOGGLE", {"type": 'M', "value": 'PRESS'}, None),
     ])
 
     return keymap
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 35bf295a678..4ad2e57d266 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -18,6 +18,7 @@
 set(INC
   ../include
   ../uvedit
+  ../../blenfont
   ../../blenkernel
   ../../blenlib
   ../../blentranslation
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 82814b09ea1..a2044d80ff5 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -29,6 +29,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLF_api.h"
+
 #include "BLI_alloca.h"
 #include "BLI_array.h"
 #include "BLI_linklist.h"
@@ -263,6 +265,15 @@ typedef struct KnifeTool_OpData {
   bool axis_constrained;
   float curr_cage_adjusted[3];
   char axis_string[2];
+
+  short dist_angle_mode;
+  bool show_dist_angle;
+  /* Save the second most recent point for angle drawing calculations */
+  float old_cage[3];
+  float old_mval[2];
+  bool old_stored;
+  float corr_prev_cage[3]; /* "knife_start_cut" updates prev.cage breaking angle calculations,
+                              store correct version */
 } KnifeTool_OpData;
 
 enum {
@@ -276,6 +287,7 @@ enum {
   KNF_MODAL_ADD_CUT,
   KNF_MODAL_ANGLE_SNAP_TOGGLE,
   KNF_MODAL_CUT_THROUGH_TOGGLE,
+  KNF_MODAL_SHOW_DISTANCE_ANGLE_TOGGLE,
   KNF_MODAL_PANNING,
   KNF_MODAL_ADD_CUT_CLOSED,
 };
@@ -293,6 +305,13 @@ enum {
   KNF_CONSTRAIN_AXIS_MODE_LOCAL = 2
 };
 
+enum {
+  KNF_MEASUREMENT_NONE = 0,
+  KNF_MEASUREMENT_BOTH = 1,
+  KNF_MEASUREMENT_DISTANCE = 2,
+  KNF_MEASUREMENT_ANGLE = 3
+};
+
 /* -------------------------------------------------------------------- */
 /** \name Drawing
  * \{ */
@@ -413,6 +432,316 @@ static void knifetool_draw_orientation_locking(const KnifeTool_OpData *kcd)
   }
 }
 
+static void knifetool_draw_visible_distances(const KnifeTool_OpData *kcd)
+{
+  GPU_matrix_push_projection();
+  GPU_matrix_push();
+  GPU_matrix_identity_set();
+  wmOrtho2_region_pixelspace(kcd->region);
+
+  uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+  char numstr[256];
+  float numstr_size[2];
+  float posit[2];
+  const float bg_margin = 4.0f * U.dpi_fac;
+  const int font_size = 14.0f * U.pixelsize;
+  const int distance_precision = 4;
+
+  /* calculate distance and convert to string */
+  float prev_cage_world[3];
+  float curr_cage_world[3];
+  copy_v3_v3(prev_cage_world, kcd->corr_prev_cage);
+  copy_v3_v3(curr_cage_world, kcd->curr.cage);
+  mul_m4_v3(kcd->ob->obmat, prev_cage_world);
+  mul_m4_v3(kcd->ob->obmat, curr_cage_world);
+  const float cut_len = len_v3v3(prev_cage_world, curr_cage_world);
+
+  UnitSettings *unit = &kcd->scene->unit;
+  if (unit->system == USER_UNIT_NONE) {
+    BLI_snprintf(numstr, sizeof(numstr), "%.*f", distance_precision, cut_len);
+  }
+  else {
+    BKE_unit_value_as_string(numstr,
+                             sizeof(numstr),
+                             (double)(cut_len * unit->scale_length),
+                             distance_precision,
+                             B_UNIT_LENGTH,
+                             unit,
+                             false);
+  }
+
+  BLF_enable(blf_mono_font, BLF_ROTATION);
+  BLF_size(blf_mono_font, font_size, U.dpi);
+  BLF_rotation(blf_mono_font, 0.0f);
+  BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+
+  /* center text */
+  mid_v2_v2v2(posit, kcd->prev.mval, kcd->curr.mval);
+  posit[0] -= numstr_size[0] / 2.0f;
+  posit[1] -= numstr_size[1] / 2.0f;
+
+  /* draw text background */
+  float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f}; /* TODO: replace with theme color */
+  immUniformColor4fv(color_back);
+
+  GPU_blend(GPU_BLEND_ALPHA);
+  immRectf(pos,
+           posit[0] - bg_margin,
+           posit[1] - bg_margin,
+           posit[0] + bg_margin + numstr_size[0],
+           posit[1] + bg_margin + numstr_size[1]);
+  GPU_blend(GPU_BLEND_NONE);
+  immUnbindProgram();
+
+  /* draw text */
+  uchar color_text[3];
+  UI_GetThemeColor3ubv(TH_TEXT, color_text);
+
+  BLF_color3ubv(blf_mono_font, color_text);
+  BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+  BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+  BLF_disable(blf_mono_font, BLF_ROTATION);
+
+  GPU_matrix_pop();
+  GPU_matrix_pop_projection();
+}
+
+static void knifetool_draw_angle(const KnifeTool_OpData *kcd,
+                                 const float start[3],
+                                 const float mid[3],
+                                 const float end[3],
+                                 const float start_ss[2],
+                                 const float mid_ss[2],
+                                 const float end_ss[2],
+                                 const float angle)
+{
+  const RegionView3D *rv3d = kcd->region->regiondata;
+  const int arc_steps = 24;
+  const float arc_size = 64.0f * U.dpi_fac;
+  const float bg_margin = 4.0f * U.dpi_fac;
+  const float cap_size = 4.0f * U.dpi_fac;
+  const int font_size = 14 * U.pixelsize;
+  const int angle_precision = 2;
+
+  /* angle arc in 3d space */
+  GPU_blend(GPU_BLEND_ALPHA);
+
+  const uint pos_3d = GPU_vertformat_attr_add(
+      immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+  {
+    float dir_tmp[3];
+    float ar_coord[3];
+
+    float dir_a[3];
+    float dir_b[3];
+    float quat[4];
+    float axis[3];
+    float arc_angle;
+
+    const float inverse_average_scale = 1 / (kcd->ob->obmat[0][0] + kcd->ob->obmat[1][1] +
+                                             kcd->ob->obmat[2][2]);
+    const float px_scale =
+        3.0f * inverse_average_scale *
+        (ED_view3d_pixel_size_no_ui_scale(rv3d, mid) *
+         min_fff(arc_size, len_v2v2(start_ss, mid_ss) / 2.0f, len_v2v2(end_ss, mid_ss) / 2.0f));
+
+    sub_v3_v3v3(dir_a, start, mid);
+    sub_v3_v3v3(dir_b, end, mid);
+    normalize_v3(dir_a);
+    normalize_v3(dir_b);
+
+    cross_v3_v3v3(axis, dir_a, dir_b);
+    arc_angle = angle_normalized_v3v3(dir_a, dir_b);
+
+    axis_angle_to_quat(quat, axis, arc_angle / arc_steps);
+
+    copy_v3_v3(dir_tmp, dir_a);
+
+    immUniformThemeColor3(TH_WIRE);
+    immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
+    for (int j = 0; j <= arc_steps; j++) {
+      madd_v3_v3v3fl(ar_coord, mid, dir_tmp, px_scale);
+      mul_qt_v3(quat, dir_tmp);
+
+      immVertex3fv(pos_3d, ar_coord);
+    }
+    immEnd();
+  }
+
+  immUnbindProgram();
+
+  /* angle text and background in 2d space */
+  GPU_matrix_push_projection();
+  GPU_matrix_push();
+  GPU_matrix_identity_set();
+  wmOrtho2_region_pixelspace(kcd->region);
+
+  uint pos_2d = GPU_vertformat_attr_add(
+      immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+  /* angle as string */
+  char numstr[256];
+  float numstr_size[2];
+  float posit[2];
+
+  UnitSettings *unit = &kcd->scene->unit;
+  if (unit->system == USER_UNIT_NONE) {
+    BLI_snprintf(numstr, sizeof(numstr), "%.*f°", angle_precision, RAD2DEGF(angle));
+  }
+  else {
+    BKE_unit_value_as_string(
+        numstr, sizeof(numstr), (double)angle, angle_precision, B_UNIT_ROTATION, unit, false);
+  }
+
+  BLF_enable(blf_mono_font, BLF_ROTATION);
+  BLF_size(blf_mono_font, font_size, U.dpi);
+  BLF_rotation(blf_mono_font, 0.0f);
+  BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+
+  posit[0] = mid_ss[0] + (cap_size * 2.0f);
+  posit[1] = mid_ss[1] - (numstr_size[1] / 2.0f);
+
+  /* draw text background */
+  float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f}; /* TODO: replace with theme color */
+  immUniformColor4fv(color_back);
+
+  GPU_blend(GPU_BLEND_ALPHA);
+  immRectf(pos_2d,
+           posit[0] - bg_margin,
+           posit[1] - bg_margin,
+           posit[0] + bg_margin + numstr_size[0],
+           posit[1] + bg_margin + numstr_size[1]);
+  GPU_blend(GPU_BLEND_NONE);
+  immUnbindProgram();
+
+  /* draw text */
+  uchar color_text[3];
+  UI_GetThemeColor3ubv(TH_TEXT, color_text);
+
+  BLF_color3ubv(blf_mono_font, color_text);
+  BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+  BLF_rotation(blf_mono_font, 0.0f);
+  BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+  BLF_disable(blf_mono_font, BLF_ROTATION);
+
+  GPU_matrix_pop();
+  GPU_matrix_pop_projection();
+
+  GPU_blend(GPU_BLEND_NONE);
+}
+
+static void knifetool_draw_visible_angles(const KnifeTool_OpData *kcd)
+{
+  if (kcd->curr.edge) {
+    KnifeEdge *kfe = kcd->curr.edge;
+    /* check for most recent cut (if cage is part of previous cut) */
+    if (!compare_v3v3(kfe->v1->cageco, kcd->corr_prev_cage, KNIFE_FLT_EPSBIG) &&
+        !compare_v3v3(kfe->v2->cageco, kcd->corr_prev_cage, KNIFE_FLT_EPSBIG)) {
+      /* determine acute angle */
+      float angle1 = angle_v3v3v3(kcd->corr_prev_cage, kcd->curr.cage, kfe->v1->cageco);
+      float angle2 = angle_v3v3v3(kcd->corr_prev_cage, kcd->curr.cage, kfe->v2->cageco);
+
+      float angle;
+      float *end;
+      if (angle1 < angle2) {
+        angle = angle1;
+        end = kfe->v1->cageco;
+      }
+      else {
+        angle = angle2;
+        end = kfe->v2->cageco;
+      }
+
+      /* last vertex in screen space */
+      float end_ss[2];
+      ED_view3d_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list