[Bf-blender-cvs] [1c1a14dcdff] master: Voxel Remesh: Edit Voxel Size operator

Pablo Dobarro noreply at git.blender.org
Tue Mar 31 17:31:45 CEST 2020


Commit: 1c1a14dcdfffd8572bade4f9a55784eb6bc94d5f
Author: Pablo Dobarro
Date:   Wed Mar 25 17:39:48 2020 +0100
Branches: master
https://developer.blender.org/rB1c1a14dcdfffd8572bade4f9a55784eb6bc94d5f

Voxel Remesh: Edit Voxel Size operator

This operator lets the user control the voxel/detail size of the voxel remesher directly from the 3D view in a similar way the Brush radius and strength are controlled.  The shorcut from sculpt mode is Shift + R (similar to Shift + F for brush strength).
It shows a grid that represents the real voxel size of the object. The grid and the text are automatically aligned to the view to avoid rendering all voxels with thousands of lines.

It also has a slow mode when pressing shift that works like the slow mode of the brush radius control.

This operator controls the value changes sensitivity automatically to avoid jumping to extremelly high resolutions and run out of memory.
This way, adjusments done in lower voxel sizes are more precise. Pressing Ctrl disables this functionality and allows changing the voxel size directly in a linear way.

Reviewed By: jbakker, #user_interface, billreynish

Differential Revision: https://developer.blender.org/D6449

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/editors/object/CMakeLists.txt
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.c
M	source/blender/editors/object/object_remesh.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 22b62d27684..971c702aeac 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -4323,6 +4323,7 @@ def km_sculpt(params):
         ("sculpt.set_detail_size", {"type": 'D', "value": 'PRESS', "shift": True}, None),
         # Remesh
         ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None),
+        ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None),
         ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None),
         # Brush properties
         ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'},
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index a5b6fa55aa9..c2c25e47908 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -18,6 +18,7 @@
 set(INC
   ../include
   ../../blenkernel
+  ../../blenfont
   ../../blenlib
   ../../blentranslation
   ../../bmesh
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 559bb434f9d..d8ba270073e 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -291,6 +291,7 @@ void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot);
 
 /* object_remesh.c */
 void OBJECT_OT_voxel_remesh(struct wmOperatorType *ot);
+void OBJECT_OT_voxel_size_edit(struct wmOperatorType *ot);
 void OBJECT_OT_quadriflow_remesh(struct wmOperatorType *ot);
 
 /* object_transfer_data.c */
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index cacf7b67777..fef046169a7 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -265,6 +265,8 @@ void ED_operatortypes_object(void)
   WM_operatortype_append(OBJECT_OT_hide_collection);
 
   WM_operatortype_append(OBJECT_OT_voxel_remesh);
+  WM_operatortype_append(OBJECT_OT_voxel_size_edit);
+
   WM_operatortype_append(OBJECT_OT_quadriflow_remesh);
 }
 
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index a9f2319d926..08c44b87664 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -37,6 +37,9 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BLT_translation.h"
 
 #include "BKE_context.h"
 #include "BKE_customdata.h"
@@ -61,17 +64,29 @@
 #include "ED_object.h"
 #include "ED_screen.h"
 #include "ED_sculpt.h"
+#include "ED_space_api.h"
 #include "ED_undo.h"
+#include "ED_view3d.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
 #include "RNA_enum_types.h"
 
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_state.h"
+
 #include "WM_api.h"
 #include "WM_message.h"
 #include "WM_toolsystem.h"
 #include "WM_types.h"
 
+#include "UI_interface.h"
+
+#include "BLF_api.h"
+
 #include "object_intern.h"  // own include
 
 /* TODO(sebpa): unstable, can lead to unrecoverable errors. */
@@ -188,16 +203,403 @@ void OBJECT_OT_voxel_remesh(wmOperatorType *ot)
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+#define VOXEL_SIZE_EDIT_MAX_GRIDS_LINES 500
+#define VOXEL_SIZE_EDIT_MAX_STR_LEN 20
+
+typedef struct VoxelSizeEditCustomData {
+  void *draw_handle;
+  Object *active_object;
+
+  float init_mval[2];
+  float slow_mval[2];
+
+  bool slow_mode;
+
+  float init_voxel_size;
+  float slow_voxel_size;
+  float voxel_size;
+
+  float preview_plane[4][3];
+
+  float text_mat[4][4];
+} VoxelSizeEditCustomData;
+
+static void voxel_size_parallel_lines_draw(uint pos3d,
+                                           const float initial_co[3],
+                                           const float end_co[3],
+                                           const float length_co[3],
+                                           const float spacing)
+{
+  const float total_len = len_v3v3(initial_co, end_co);
+  const int tot_lines = (int)(total_len / spacing);
+  const int tot_lines_half = (tot_lines / 2) + 1;
+  float spacing_dir[3], lines_start[3];
+  float line_dir[3];
+  sub_v3_v3v3(spacing_dir, end_co, initial_co);
+  normalize_v3(spacing_dir);
+
+  sub_v3_v3v3(line_dir, length_co, initial_co);
+
+  if (tot_lines > VOXEL_SIZE_EDIT_MAX_GRIDS_LINES || tot_lines <= 1) {
+    return;
+  }
+
+  mid_v3_v3v3(lines_start, initial_co, end_co);
+
+  immBegin(GPU_PRIM_LINES, (uint)tot_lines_half * 2);
+  for (int i = 0; i < tot_lines_half; i++) {
+    float line_start[3];
+    float line_end[3];
+    madd_v3_v3v3fl(line_start, lines_start, spacing_dir, spacing * i);
+    add_v3_v3v3(line_end, line_start, line_dir);
+    immVertex3fv(pos3d, line_start);
+    immVertex3fv(pos3d, line_end);
+  }
+  immEnd();
+
+  mul_v3_fl(spacing_dir, -1.0f);
+
+  immBegin(GPU_PRIM_LINES, (uint)(tot_lines_half - 1) * 2);
+  for (int i = 1; i < tot_lines_half; i++) {
+    float line_start[3];
+    float line_end[3];
+    madd_v3_v3v3fl(line_start, lines_start, spacing_dir, spacing * i);
+    add_v3_v3v3(line_end, line_start, line_dir);
+    immVertex3fv(pos3d, line_start);
+    immVertex3fv(pos3d, line_end);
+  }
+  immEnd();
+}
+
+static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
+{
+  VoxelSizeEditCustomData *cd = arg;
+
+  GPU_blend(true);
+  GPU_line_smooth(true);
+
+  uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+  GPU_matrix_push();
+  GPU_matrix_mul(cd->active_object->obmat);
+
+  /* Draw Rect */
+  immUniformColor4f(0.9f, 0.9f, 0.9f, 0.8f);
+  GPU_line_width(3.0f);
+
+  immBegin(GPU_PRIM_LINES, 8);
+  immVertex3fv(pos3d, cd->preview_plane[0]);
+  immVertex3fv(pos3d, cd->preview_plane[1]);
+
+  immVertex3fv(pos3d, cd->preview_plane[1]);
+  immVertex3fv(pos3d, cd->preview_plane[2]);
+
+  immVertex3fv(pos3d, cd->preview_plane[2]);
+  immVertex3fv(pos3d, cd->preview_plane[3]);
+
+  immVertex3fv(pos3d, cd->preview_plane[3]);
+  immVertex3fv(pos3d, cd->preview_plane[0]);
+  immEnd();
+
+  /* Draw Grid */
+  GPU_line_width(1.0f);
+
+  const float total_len = len_v3v3(cd->preview_plane[0], cd->preview_plane[1]);
+  const int tot_lines = (int)(total_len / cd->voxel_size);
+
+  /* Smoothstep to reduce the alpha of the grid as the line number increases. */
+  const float a = VOXEL_SIZE_EDIT_MAX_GRIDS_LINES * 0.1f;
+  const float b = VOXEL_SIZE_EDIT_MAX_GRIDS_LINES;
+  const float x = clamp_f((tot_lines - a) / (b - a), 0.0f, 1.0);
+  const float alpha_factor = 1.0f - (x * x * (3.0f - 2.0f * x));
+
+  immUniformColor4f(0.9f, 0.9f, 0.9f, 0.75f * alpha_factor);
+  voxel_size_parallel_lines_draw(
+      pos3d, cd->preview_plane[0], cd->preview_plane[1], cd->preview_plane[3], cd->voxel_size);
+  voxel_size_parallel_lines_draw(
+      pos3d, cd->preview_plane[1], cd->preview_plane[2], cd->preview_plane[0], cd->voxel_size);
+
+  /* Draw text */
+  uiStyle *style = UI_style_get();
+  const uiFontStyle *fstyle = &style->widget;
+  const int fontid = fstyle->uifont_id;
+  float strwidth, strheight;
+  short fstyle_points = fstyle->points;
+  char str[VOXEL_SIZE_EDIT_MAX_STR_LEN];
+  short strdrawlen = 0;
+
+  BLI_snprintf(str, VOXEL_SIZE_EDIT_MAX_STR_LEN, "%3.4f%%", cd->voxel_size);
+  strdrawlen = BLI_strlen_utf8(str);
+
+  immUnbindProgram();
+
+  GPU_matrix_push();
+  GPU_matrix_mul(cd->text_mat);
+  BLF_size(fontid, 10.0f * fstyle_points, U.dpi);
+  BLF_color3f(fontid, 1.0f, 1.0f, 1.0f);
+  BLF_width_and_height(fontid, str, strdrawlen, &strwidth, &strheight);
+  BLF_position(fontid, -0.5f * strwidth, -0.5f * strheight, 0.0f);
+  BLF_draw(fontid, str, strdrawlen);
+  GPU_matrix_pop();
+
+  GPU_matrix_pop();
+
+  GPU_blend(false);
+  GPU_line_smooth(false);
+}
+
+static void voxel_size_edit_cancel(bContext *C, wmOperator *op)
+{
+  ARegion *ar = CTX_wm_region(C);
+  VoxelSizeEditCustomData *cd = op->customdata;
+
+  ED_region_draw_cb_exit(ar->type, cd->draw_handle);
+
+  MEM_freeN(op->customdata);
+
+  ED_workspace_status_text(C, NULL);
+}
+
+static int voxel_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  ARegion *ar = CTX_wm_region(C);
+  VoxelSizeEditCustomData *cd = op->customdata;
+  Object *active_object = cd->active_object;
+  Mesh *mesh = (Mesh *)active_object->data;
+
+  /* Cancel modal operator */
+  if ((event->type == EVT_ESCKEY && event->val == KM_PRESS) ||
+      (event->type == RIGHTMOUSE && event->val == KM_PRESS)) {
+    voxel_size_edit_cancel(C, op);
+    ED_region_tag_redraw(ar);
+    return OPERATOR_FINISHED;
+  }
+
+  /* Finish modal operator */
+  if ((event->type == LEFTMOUSE && event->val == KM_RELEASE) ||
+      (event->type == EVT_RETKEY && event->val == KM_PRESS) ||
+      (event->type == EVT_PADENTER && event->val == KM_PRESS)) {
+    ED_region_draw_cb_exit(ar->type, cd->draw_handle);
+    mesh->remesh_voxel_size = cd->voxel_size;
+    MEM_freeN(op->customdata);
+    ED_region_tag_redraw(ar);
+    return OPERATOR_FINISHED;
+  }
+
+  float mval[2] = {event->mval[0], event->mval[1]};
+
+  float d = cd->init_mval[0] - mval[0];
+
+  if (cd->slow_mode) {
+    d = cd->slow_mval[0] - mval[0];
+  }
+
+  if (event->ctrl) {
+    /* Linear mode, enables jumping to any voxel size. */
+    d = d * 0.0005f;
+  }
+  else {
+    /* Multiply d by the initial voxel size to prevent incontrolable speeds when using low voxel
+     * sizes. */
+    /* When the voxel size is slower, it needs more precision. */
+    d = d * min_ff(pow2f(cd->init_voxel_size), 0.1f) * 0.05f;
+  }
+  if (cd->slow_mode) {
+    cd->voxel_size = cd->slow_voxel_size + d * 0.05f;
+  }
+  else {
+    cd->voxel_size = cd->init_voxel_size + d;
+  }
+
+  if (event->type == EVT_LEFTSHIFTKEY && event->val == KM_PRESS) {
+    cd->slow_mode = true;
+    c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list