Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2019-11-26 20:53:38 +0300
committerPablo Dobarro <pablodp606@gmail.com>2019-11-27 19:24:40 +0300
commit47645a8db6223ba31b8128db7502f27876a2586b (patch)
tree75ddb061a924a017648dca3315c581f7cda09cf8 /source/blender
parent9251b077203c763f1be83505ed0a4d1e19dab947 (diff)
Sculpt: Sample Voxel Size
This adds support to the current sculpt sample detail operator to sample a voxel size for the voxel remesher when sculpting on regular meshes. It provides an approximation of a voxel size that is going to preserve the sampled sculpt details after remeshing. It is not going to be 100% accurate in all cases as it relies on having consistent edge length in the whole sculpt, but it saves a lot of time and avoids guessing the voxel size by trying different values. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D6251
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c107
1 files changed, 85 insertions, 22 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 38e4d119aa5..63b9949e0ef 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -8445,36 +8445,60 @@ static void SCULPT_OT_detail_flood_fill(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void sample_detail(bContext *C, int mx, int my)
+typedef enum eSculptSampleDetailModeTypes {
+ SAMPLE_DETAIL_DYNTOPO = 0,
+ SAMPLE_DETAIL_VOXEL = 1,
+} eSculptSampleDetailModeTypes;
+
+static EnumPropertyItem prop_sculpt_sample_detail_mode_types[] = {
+ {SAMPLE_DETAIL_DYNTOPO, "DYNTOPO", 0, "Dyntopo", "Sample dyntopo detail"},
+ {SAMPLE_DETAIL_VOXEL, "VOXEL", 0, "Voxel", "Sample mesh voxel size"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my)
{
- /* Find 3D view to pick from. */
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, mx, my);
- ARegion *ar = (sa) ? BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my) : NULL;
- if (ar == NULL) {
- return;
- }
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = vc->obact;
+ Mesh *mesh = ob->data;
- /* Set context to 3D view. */
- ScrArea *prev_sa = CTX_wm_area(C);
- ARegion *prev_ar = CTX_wm_region(C);
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
+ SculptSession *ss = ob->sculpt;
+ SculptCursorGeometryInfo sgi;
+ sculpt_vertex_random_access_init(ss);
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ /* Update the active vertex */
+ float mouse[2] = {mx, my};
+ sculpt_cursor_geometry_info_update(C, &sgi, mouse, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
- /* Pick sample detail. */
+ /* Average the edge length of the connected edges to the active vertex */
+ int active_vertex = sculpt_active_vertex_get(ss);
+ const float *active_vertex_co = sculpt_active_vertex_co_get(ss);
+ float edge_length = 0.0f;
+ int tot = 0;
+ SculptVertexNeighborIter ni;
+ sculpt_vertex_neighbors_iter_begin(ss, active_vertex, ni)
+ {
+ edge_length += len_v3v3(active_vertex_co, sculpt_vertex_co_get(ss, ni.index));
+ tot += 1;
+ }
+ sculpt_vertex_neighbors_iter_end(ni);
+ if (tot > 0) {
+ mesh->remesh_voxel_size = edge_length / (float)tot;
+ }
+}
+
+static void sample_detail_dyntopo(bContext *C, ViewContext *vc, ARegion *ar, int mx, int my)
+{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- Object *ob = vc.obact;
+ Object *ob = vc->obact;
Brush *brush = BKE_paint_brush(&sd->paint);
sculpt_stroke_modifiers_check(C, ob, brush);
float mouse[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
float ray_start[3], ray_end[3], ray_normal[3];
- float depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
+ float depth = sculpt_raycast_init(vc, mouse, ray_start, ray_end, ray_normal, false);
SculptDetailRaycastData srd;
srd.hit = 0;
@@ -8489,6 +8513,37 @@ static void sample_detail(bContext *C, int mx, int my)
/* Convert edge length to world space detail resolution. */
sd->constant_detail = 1 / (srd.edge_length * mat4_to_scale(ob->obmat));
}
+}
+
+static void sample_detail(bContext *C, int mx, int my, int mode)
+{
+ /* Find 3D view to pick from. */
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, mx, my);
+ ARegion *ar = (sa) ? BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my) : NULL;
+ if (ar == NULL) {
+ return;
+ }
+
+ /* Set context to 3D view. */
+ ScrArea *prev_sa = CTX_wm_area(C);
+ ARegion *prev_ar = CTX_wm_region(C);
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ViewContext vc;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+
+ /* Pick sample detail. */
+ switch (mode) {
+ case SAMPLE_DETAIL_DYNTOPO:
+ sample_detail_dyntopo(C, &vc, ar, mx, my);
+ break;
+ case SAMPLE_DETAIL_VOXEL:
+ sample_detail_voxel(C, &vc, mx, my);
+ break;
+ }
/* Restore context. */
CTX_wm_area_set(C, prev_sa);
@@ -8499,7 +8554,8 @@ static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op)
{
int ss_co[2];
RNA_int_get_array(op->ptr, "location", ss_co);
- sample_detail(C, ss_co[0], ss_co[1]);
+ int mode = RNA_enum_get(op->ptr, "mode");
+ sample_detail(C, ss_co[0], ss_co[1], mode);
return OPERATOR_FINISHED;
}
@@ -8518,7 +8574,8 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm
if (event->val == KM_PRESS) {
int ss_co[2] = {event->x, event->y};
- sample_detail(C, ss_co[0], ss_co[1]);
+ int mode = RNA_enum_get(op->ptr, "mode");
+ sample_detail(C, ss_co[0], ss_co[1], mode);
RNA_int_set_array(op->ptr, "location", ss_co);
WM_cursor_modal_restore(CTX_wm_window(C));
@@ -8551,7 +8608,7 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
ot->invoke = sculpt_sample_detail_size_invoke;
ot->exec = sculpt_sample_detail_size_exec;
ot->modal = sculpt_sample_detail_size_modal;
- ot->poll = sculpt_and_constant_or_manual_detail_poll;
+ ot->poll = sculpt_mode_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8565,6 +8622,12 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
"Screen Coordinates of sampling",
0,
SHRT_MAX);
+ RNA_def_enum(ot->srna,
+ "mode",
+ prop_sculpt_sample_detail_mode_types,
+ SAMPLE_DETAIL_DYNTOPO,
+ "Detail Mode",
+ "Target sculpting workflow that is going to use the sampled size");
}
/* Dynamic-topology detail size