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:
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py5
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/intern/paint.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c46
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c84
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h4
-rw-r--r--source/blender/makesdna/DNA_brush_types.h13
-rw-r--r--source/blender/makesrna/intern/rna_brush.c8
8 files changed, 161 insertions, 7 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index c39f2ea051d..d96f8b04058 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -380,6 +380,11 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
row = col.row()
row.prop(brush, "use_automasking_topology")
+ if brush.sculpt_tool == 'GRAB':
+ col.separator()
+ row = col.row()
+ row.prop(brush, "grab_active_vertex")
+
# topology_rake_factor
if (
capabilities.has_topology_rake and
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 10c3f42bba7..ed4bcee3541 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -269,6 +269,10 @@ typedef struct SculptSession {
float pivot_pos[3];
+ /* Dynamic mesh preview */
+ int *preview_vert_index_list;
+ int preview_vert_index_count;
+
union {
struct {
struct SculptVertexPaintGeomMap gmap;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b386a0d4483..5980aa456e2 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1060,6 +1060,10 @@ void BKE_sculptsession_free(Object *ob)
MEM_freeN(ss->deform_imats);
}
+ if (ss->preview_vert_index_list) {
+ MEM_freeN(ss->preview_vert_index_list);
+ }
+
BKE_sculptsession_free_vwpaint_data(ob->sculpt);
MEM_freeN(ss);
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index a000da57383..62e44bf04c5 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1180,6 +1180,20 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr,
}
}
+static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession *ss)
+{
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f);
+ GPU_depth_test(true);
+ GPU_line_width(1.0f);
+ if (ss->preview_vert_index_count > 0) {
+ immBegin(GPU_PRIM_LINES, ss->preview_vert_index_count);
+ for (int i = 0; i < ss->preview_vert_index_count; i++) {
+ immVertex3fv(gpuattr, sculpt_vertex_co_get(ss, ss->preview_vert_index_list[i]));
+ }
+ immEnd();
+ }
+}
+
static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
{
Scene *scene = CTX_data_scene(C);
@@ -1348,6 +1362,17 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
imm_draw_circle_wire_3d(pos, 0, 0, rds, 40);
GPU_matrix_pop();
+ /* Update and draw dynamic mesh preview lines */
+ GPU_matrix_push();
+ GPU_matrix_mul(vc.obact->obmat);
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag2 & BRUSH_GRAB_ACTIVE_VERTEX) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->modifiers_active) {
+ sculpt_geometry_preview_lines_update(C, ss, rds);
+ sculpt_geometry_preview_lines_draw(pos, ss);
+ }
+ }
+ GPU_matrix_pop();
+
GPU_matrix_pop_projection();
wmWindowViewport(win);
@@ -1370,6 +1395,27 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
add_v3_v3(cursor_location, ss->cache->grab_delta);
}
cursor_draw_point_with_symmetry(pos, ar, cursor_location, sd, vc.obact, ss->cache->radius);
+
+ /* Draw cached dynamic mesh preview lines */
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag2 & BRUSH_GRAB_ACTIVE_VERTEX) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->modifiers_active) {
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(CTX_wm_window(C),
+ CTX_data_depsgraph_pointer(C),
+ CTX_data_scene(C),
+ ar,
+ CTX_wm_view3d(C),
+ NULL,
+ NULL,
+ NULL);
+ GPU_matrix_push();
+ GPU_matrix_mul(vc.obact->obmat);
+ sculpt_geometry_preview_lines_draw(pos, ss);
+ GPU_matrix_pop();
+ GPU_matrix_pop_projection();
+ }
+ }
+
wmWindowViewport(win);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 792a75746d3..688adc56ef5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -31,6 +31,7 @@
#include "BLI_gsqueue.h"
#include "BLI_stack.h"
#include "BLI_task.h"
+#include "BLI_stack.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -99,7 +100,7 @@
/* Do not use these functions while working with PBVH_GRIDS data in SculptSession */
-static float *sculpt_vertex_co_get(SculptSession *ss, int index)
+float *sculpt_vertex_co_get(SculptSession *ss, int index)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
@@ -5902,7 +5903,13 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
float grab_location[3], imat[4][4], delta[3], loc[3];
if (cache->first_time) {
- copy_v3_v3(cache->orig_grab_location, cache->true_location);
+ if (tool == SCULPT_TOOL_GRAB && brush->flag2 & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->orig_grab_location,
+ sculpt_vertex_co_get(ss, sculpt_active_vertex_get(ss)));
+ }
+ else {
+ copy_v3_v3(cache->orig_grab_location, cache->true_location);
+ }
}
else if (tool == SCULPT_TOOL_SNAKE_HOOK) {
add_v3_v3(cache->true_location, cache->grab_delta);
@@ -5955,7 +5962,12 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
copy_v3_v3(cache->old_grab_location, grab_location);
if (tool == SCULPT_TOOL_GRAB) {
- copy_v3_v3(cache->anchored_location, cache->true_location);
+ if (brush->flag2 & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
+ }
+ else {
+ copy_v3_v3(cache->anchored_location, cache->true_location);
+ }
}
else if (tool == SCULPT_TOOL_ELASTIC_DEFORM) {
copy_v3_v3(cache->anchored_location, cache->true_location);
@@ -8995,6 +9007,72 @@ static void SCULPT_OT_mask_expand(wmOperatorType *ot)
2000);
}
+void sculpt_geometry_preview_lines_update(bContext *C, SculptSession *ss, float radius)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = CTX_data_active_object(C);
+
+ ss->preview_vert_index_count = 0;
+ int totpoints = 0;
+
+ /* This function is called from the cursor drawing code, so the PBVH may not be build yet */
+ if (!ss->pbvh) {
+ return;
+ }
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+
+ if (!ss->pmap) {
+ return;
+ }
+
+ float brush_co[3];
+ copy_v3_v3(brush_co, sculpt_vertex_co_get(ss, sculpt_active_vertex_get(ss)));
+
+ char *visited_vertices = MEM_callocN(sculpt_vertex_count_get(ss) * sizeof(char),
+ "visited vertices");
+
+ if (ss->preview_vert_index_list == NULL) {
+ ss->preview_vert_index_list = MEM_callocN(4 * sizeof(int) * sculpt_vertex_count_get(ss),
+ "preview lines");
+ }
+
+ BLI_Stack *not_visited_vertices = BLI_stack_new(sizeof(VertexTopologyIterator),
+ "Not visited vertices stack");
+ VertexTopologyIterator mevit;
+ mevit.v = sculpt_active_vertex_get(ss);
+ BLI_stack_push(not_visited_vertices, &mevit);
+
+ while (!BLI_stack_is_empty(not_visited_vertices)) {
+ VertexTopologyIterator c_mevit;
+ BLI_stack_pop(not_visited_vertices, &c_mevit);
+ SculptVertexNeighborIter ni;
+ sculpt_vertex_neighbors_iter_begin(ss, c_mevit.v, ni)
+ {
+ VertexTopologyIterator new_entry;
+ new_entry.v = ni.index;
+ new_entry.it = c_mevit.it + 1;
+ ss->preview_vert_index_list[totpoints] = c_mevit.v;
+ totpoints++;
+ ss->preview_vert_index_list[totpoints] = new_entry.v;
+ totpoints++;
+ if (visited_vertices[(int)ni.index] == 0) {
+ visited_vertices[(int)ni.index] = 1;
+ if (len_squared_v3v3(brush_co, sculpt_vertex_co_get(ss, new_entry.v)) < radius * radius) {
+ BLI_stack_push(not_visited_vertices, &new_entry);
+ }
+ }
+ }
+ sculpt_vertex_neighbors_iter_end(ni)
+ }
+
+ BLI_stack_free(not_visited_vertices);
+
+ MEM_freeN(visited_vertices);
+
+ ss->preview_vert_index_count = totpoints;
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 3be8e0f7bb7..5995eadea59 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -57,6 +57,10 @@ bool sculpt_cursor_geometry_info_update(bContext *C,
SculptCursorGeometryInfo *out,
const float mouse[2],
bool use_sampled_normal);
+void sculpt_geometry_preview_lines_update(bContext *C, struct SculptSession *ss, float radius);
+
+/* Sculpt PBVH abstraction API */
+float *sculpt_vertex_co_get(struct SculptSession *ss, int index);
/* Dynamic topology */
void sculpt_pbvh_clear(Object *ob);
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 56e255b132a..5901163c3a9 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -244,6 +244,8 @@ typedef struct Brush {
int size;
/** General purpose flag. */
int flag;
+ int flag2;
+ char _pad[4];
/** Pressure influence for mask. */
int mask_pressure;
/** Jitter the position of the brush. */
@@ -280,7 +282,7 @@ typedef struct Brush {
/** Source for fill tool color gradient application. */
char gradient_fill_mode;
- char _pad;
+ char _pad0;
/** Projection shape (sphere, circle). */
char falloff_shape;
float falloff_angle;
@@ -289,7 +291,6 @@ typedef struct Brush {
char sculpt_tool;
/** Active sculpt tool. */
char uv_sculpt_tool;
- /** Active vertex paint. */
char vertexpaint_tool;
/** Active weight paint. */
char weightpaint_tool;
@@ -299,7 +300,7 @@ typedef struct Brush {
char mask_tool;
/** Active grease pencil tool. */
char gpencil_tool;
- char _pad0[1];
+ char _pad1[1];
float autosmooth_factor;
@@ -318,7 +319,7 @@ typedef struct Brush {
int curve_preset;
int automasking_flags;
- char _pad1[4];
+ char _pad2[4];
int elastic_deform_type;
float elastic_deform_compressibility;
@@ -431,6 +432,10 @@ typedef enum eBrushFlags {
BRUSH_CURVE = (1u << 31),
} eBrushFlags;
+typedef enum eBrushFlags2 {
+ BRUSH_GRAB_ACTIVE_VERTEX = (1 << 0),
+} eBrushFlags2;
+
typedef enum {
BRUSH_MASK_PRESSURE_RAMP = (1 << 1),
BRUSH_MASK_PRESSURE_CUTOFF = (1 << 2),
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 3aa96749512..a78a6fb264b 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1984,6 +1984,14 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Spacing distance", "Calculate the brush spacing using view or scene distance");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "grab_active_vertex", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_GRAB_ACTIVE_VERTEX);
+ RNA_def_property_ui_text(
+ prop,
+ "Grab Active Vertex",
+ "Apply the maximum grab strength to the active vertex instead of the cursor location");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);