[Bf-blender-cvs] [df598a9a5d4] temp-lineart-contained: Object: show preview plane for add-object tool

Campbell Barton noreply at git.blender.org
Sat Dec 19 06:18:51 CET 2020


Commit: df598a9a5d446a7d4157445f509b26d63e066772
Author: Campbell Barton
Date:   Tue Sep 29 12:52:37 2020 +1000
Branches: temp-lineart-contained
https://developer.blender.org/rBdf598a9a5d446a7d4157445f509b26d63e066772

Object: show preview plane for add-object tool

The orientation & depth settings are used to show the preview plane
that is used when adding the object.

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

M	source/blender/editors/space_view3d/view3d_placement.c

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

diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 5a0ca8e7d75..7c499cb645b 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -35,6 +35,7 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_context.h"
+#include "BKE_global.h"
 #include "BKE_main.h"
 
 #include "RNA_access.h"
@@ -57,12 +58,16 @@
 
 #include "GPU_batch.h"
 #include "GPU_immediate.h"
+#include "GPU_matrix.h"
 #include "GPU_state.h"
 
 #include "view3d_intern.h"
 
 static const char *view3d_gzgt_placement_id = "VIEW3D_GGT_placement";
 
+static void preview_plane_cursor_setup(wmGizmoGroup *gzgroup);
+static void preview_plane_cursor_visible_set(wmGizmoGroup *gzgroup, bool do_draw);
+
 /* -------------------------------------------------------------------- */
 /** \name Local Types
  * \{ */
@@ -240,6 +245,12 @@ static bool idp_poject_surface_normal(SnapObjectContext *snap_context,
   return success;
 }
 
+static wmGizmoGroup *idp_gizmogroup_from_region(ARegion *region)
+{
+  wmGizmoMap *gzmap = region->gizmo_map;
+  return gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -746,10 +757,13 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
 
   /* Assign snap gizmo which is may be used as part of the tool. */
   {
-    wmGizmoMap *gzmap = ipd->region->gizmo_map;
-    wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
-    if ((gzgroup != NULL) && gzgroup->gizmos.first) {
-      ipd->snap_gizmo = gzgroup->gizmos.first;
+    wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(ipd->region);
+    if (gzgroup != NULL) {
+      if (gzgroup->gizmos.first) {
+        ipd->snap_gizmo = gzgroup->gizmos.first;
+      }
+
+      preview_plane_cursor_visible_set(gzgroup, false);
     }
   }
 
@@ -864,6 +878,13 @@ static void view3d_interactive_add_exit(bContext *C, wmOperator *op)
 
   ED_region_tag_redraw(ipd->region);
 
+  {
+    wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(ipd->region);
+    if (gzgroup != NULL) {
+      preview_plane_cursor_visible_set(gzgroup, true);
+    }
+  }
+
   MEM_freeN(ipd);
 }
 
@@ -1285,6 +1306,9 @@ static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup
     /* Don't handle any events, this is for display only. */
     gizmo->flag |= WM_GIZMO_HIDDEN_KEYMAP;
   }
+
+  /* Sets the gizmos custom-data which has it's own free callback. */
+  preview_plane_cursor_setup(gzgroup);
 }
 
 void VIEW3D_GGT_placement(wmGizmoGroupType *gzgt)
@@ -1302,3 +1326,309 @@ void VIEW3D_GGT_placement(wmGizmoGroupType *gzgt)
 }
 
 /** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Placement Preview Plane
+ *
+ * Preview the plane that will be used for placement.
+ *
+ * Note that we might want to split this into its own file,
+ * for now this is coupled with the 3D view placement gizmo.
+ * \{ */
+
+static void gizmo_plane_update_cursor(const bContext *C,
+                                      ARegion *region,
+                                      const int mval[2],
+                                      float r_co[3],
+                                      float r_matrix_orient[3][3],
+                                      int *r_plane_axis)
+{
+  wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_interactive_add", true);
+  BLI_assert(ot != NULL);
+  PointerRNA ptr;
+
+  ScrArea *area = CTX_wm_area(C);
+  BLI_assert(region == CTX_wm_region(C));
+  bToolRef *tref = area->runtime.tool;
+  WM_toolsystem_ref_properties_ensure_from_operator(tref, ot, &ptr);
+
+  const int plane_axis = RNA_enum_get(&ptr, "plane_axis");
+  const enum ePlace_Depth plane_depth = RNA_enum_get(&ptr, "plane_depth");
+  const enum ePlace_Orient plane_orient = RNA_enum_get(&ptr, "plane_orientation");
+
+  const float mval_fl[2] = {UNPACK2(mval)};
+
+  Scene *scene = CTX_data_scene(C);
+  View3D *v3d = CTX_wm_view3d(C);
+
+  /* Assign snap gizmo which is may be used as part of the tool. */
+  wmGizmo *snap_gizmo = NULL;
+  {
+    wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(region);
+    if ((gzgroup != NULL) && gzgroup->gizmos.first) {
+      snap_gizmo = gzgroup->gizmos.first;
+    }
+  }
+
+  view3d_interactive_add_calc_plane((bContext *)C,
+                                    scene,
+                                    v3d,
+                                    region,
+                                    snap_gizmo,
+                                    mval_fl,
+                                    plane_depth,
+                                    plane_orient,
+                                    plane_axis,
+                                    r_co,
+                                    r_matrix_orient);
+  *r_plane_axis = plane_axis;
+}
+
+static void gizmo_plane_draw_grid(const int resolution,
+                                  const float scale,
+                                  const float scale_fade,
+                                  const float matrix[4][4],
+                                  const int plane_axis,
+                                  const float color[4])
+{
+  BLI_assert(scale_fade <= scale);
+  const int resolution_min = resolution - 1;
+  float color_fade[4] = {UNPACK4(color)};
+  const float *center = matrix[3];
+
+  GPU_blend(GPU_BLEND_ADDITIVE);
+  GPU_line_smooth(true);
+  GPU_line_width(1.0f);
+
+  GPUVertFormat *format = immVertexFormat();
+  const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+  const uint col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+  immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+
+  const size_t coords_len = resolution * resolution;
+  float(*coords)[3] = MEM_mallocN(sizeof(*coords) * coords_len, __func__);
+
+  const int axis_x = (plane_axis + 0) % 3;
+  const int axis_y = (plane_axis + 1) % 3;
+  const int axis_z = (plane_axis + 2) % 3;
+
+  int i;
+  const float resolution_div = (float)1.0f / (float)resolution;
+  i = 0;
+  for (int x = 0; x < resolution; x++) {
+    const float x_fl = (x * resolution_div) - 0.5f;
+    for (int y = 0; y < resolution; y++) {
+      const float y_fl = (y * resolution_div) - 0.5f;
+      coords[i][axis_x] = 0.0f;
+      coords[i][axis_y] = x_fl * scale;
+      coords[i][axis_z] = y_fl * scale;
+      mul_m4_v3(matrix, coords[i]);
+      i += 1;
+    }
+  }
+  BLI_assert(i == coords_len);
+  immBeginAtMost(GPU_PRIM_LINES, coords_len * 4);
+  i = 0;
+  for (int x = 0; x < resolution_min; x++) {
+    for (int y = 0; y < resolution_min; y++) {
+
+      /* Add #resolution_div to ensure we fade-out entirely. */
+#define FADE(v) \
+  max_ff(0.0f, (1.0f - square_f(((len_v3v3(v, center) / scale_fade) + resolution_div) * 2.0f)))
+
+      const float *v0 = coords[(resolution * x) + y];
+      const float *v1 = coords[(resolution * (x + 1)) + y];
+      const float *v2 = coords[(resolution * x) + (y + 1)];
+
+      const float f0 = FADE(v0);
+      const float f1 = FADE(v1);
+      const float f2 = FADE(v2);
+
+      if (f0 > 0.0f || f1 > 0.0f) {
+        color_fade[3] = color[3] * f0;
+        immAttr4fv(col_id, color_fade);
+        immVertex3fv(pos_id, v0);
+        color_fade[3] = color[3] * f1;
+        immAttr4fv(col_id, color_fade);
+        immVertex3fv(pos_id, v1);
+      }
+      if (f0 > 0.0f || f2 > 0.0f) {
+        color_fade[3] = color[3] * f0;
+        immAttr4fv(col_id, color_fade);
+        immVertex3fv(pos_id, v0);
+
+        color_fade[3] = color[3] * f2;
+        immAttr4fv(col_id, color_fade);
+        immVertex3fv(pos_id, v2);
+      }
+
+#undef FADE
+
+      i++;
+    }
+  }
+
+  MEM_freeN(coords);
+
+  immEnd();
+
+  immUnbindProgram();
+
+  GPU_line_smooth(false);
+  GPU_blend(GPU_BLEND_NONE);
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Preview Plane Cursor
+ * \{ */
+
+struct PlacementCursor {
+  /**
+   * Back-pointer to the gizmo-group that uses this cursor.
+   * Needed so we know that the cursor belongs to the region.
+   */
+  wmGizmoGroup *gzgroup;
+
+  /**
+   * Enable this while the modal operator is running,
+   * so the preview-plane doesn't show at the same time time as add-object preview shape
+   * since it's distracting & not helpful.
+   */
+  bool do_draw;
+
+  void *paintcursor;
+
+  int plane_axis;
+  float matrix[4][4];
+
+  /* Check if we need to re-calculate the plane matrix. */
+  int mval_prev[2];
+  float viewmat_prev[4][4];
+};
+
+static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
+{
+  struct PlacementCursor *plc = (struct PlacementCursor *)customdata;
+  ARegion *region = CTX_wm_region(C);
+  const RegionView3D *rv3d = region->regiondata;
+
+  /* Early exit.
+   * Note that we can't do most of these checks in the poll function (besides global checks)
+   * so test them here instead.
+   *
+   * This cursor is only active while the gizmo is being used
+   * so it's not so important to have a poll function. */
+  if (plc->do_draw == false) {
+    return;
+  }
+  if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
+    return;
+  }
+  if (rv3d->rflag & RV3D_NAVIGATING) {
+    return;
+  }
+
+  /* Check this gizmo group is in the region. */
+  {
+    wmGizmoMap *gzmap = region->gizmo_map;
+    wmGizmoGroup *gzgroup_test = WM_gizmomap_group_find_ptr(gzmap, plc->gzgroup->type);
+    if (gzgroup_test != plc->gzgroup) {
+      /* Wrong viewport. */
+      return;
+    }
+  }
+
+  const int mval[2] = {x - region->winrct.xmin, y - region->winrct.ymin};
+
+  /* Update matrix? */
+  if ((plc->mval_prev[0] != mval[0]) || (plc->mval_prev[1] != mval[1]) ||
+      !equals_m4m4(plc->viewmat_prev, rv3d->viewmat)) {
+    plc->mval_prev[0] = mval[0];
+    plc->mval_prev[1] = mval[1];
+
+    float orient_matrix[3][3];
+    float co[3];
+    gizmo_plane_update_cursor(C, region, mval, co, orient_matrix, &plc->plane_axis);
+    copy_m4_m3(plc->matrix, orient_matrix);
+    copy_v3_v3(plc->matrix[3], co);
+
+    copy_m

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list