diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 5 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 65 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sculpt_paint.c | 12 |
5 files changed, 96 insertions, 0 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index be76a8b8c88..e51b3a6f27e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5119,6 +5119,11 @@ static void lib_link_scene(FileData *fd, Main *main) link_paint(fd, sce, &sce->toolsettings->wpaint->paint); link_paint(fd, sce, &sce->toolsettings->imapaint.paint); link_paint(fd, sce, &sce->toolsettings->uvsculpt->paint); + + if (sce->toolsettings->sculpt) + sce->toolsettings->sculpt->gravity_object = + newlibadr_us(fd, sce->id.lib, sce->toolsettings->sculpt->gravity_object); + sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template); for (base = sce->base.first; base; base = next) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c0f0fcf8230..14b6ab8859a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -317,6 +317,7 @@ typedef struct StrokeCache { int alt_smooth; float plane_trim_squared; + float gravity_direction[3]; rcti previous_r; /* previous redraw rectangle */ } StrokeCache; @@ -2997,6 +2998,49 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod } } +static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + float offset[3]/*, an[3]*/; + int n; + float gravity_vector[3]; + + mul_v3_v3fl(gravity_vector, ss->cache->gravity_direction, -ss->cache->radius_squared); + + /* offset with as much as possible factored in already */ + mul_v3_v3v3(offset, gravity_vector, ss->cache->scale); + mul_v3_fl(offset, bstrength); + + /* threaded loop over nodes */ + #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) + for(n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + float (*proxy)[3]; + + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; + + sculpt_brush_test_init(ss, &test); + + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + if (sculpt_brush_test_sq(&test, vd.co)) { + const float fade = tex_strength(ss, brush, vd.co, sqrt(test.dist), + ss->cache->sculpt_normal_symm, vd.no, + vd.fno, vd.mask ? *vd.mask : 0.0f); + + mul_v3_v3fl(proxy[vd.i], offset, fade); + + if(vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + BKE_pbvh_vertex_iter_end; + } +} + + void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { Mesh *me = (Mesh *)ob->data; @@ -3223,6 +3267,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush) } } + if (brush->sculpt_tool != SCULPT_TOOL_MASK && sd->gravity_factor > 0.0f) + do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); + MEM_freeN(nodes); /* update average stroke position */ @@ -3826,6 +3873,24 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio cache->scale[1] = max_scale / ob->size[1]; cache->scale[2] = max_scale / ob->size[2]; + if (sd->gravity_object) { + Object *gravity_object = sd->gravity_object; + float rmat[3][3], loc[3], size[3]; + + /* get gravity vector in world space */ + copy_v3_v3(cache->gravity_direction, gravity_object->obmat[2]); + normalize_v3(cache->gravity_direction); + + /* transform to sculpted object space by inverting object rotation matrix */ + mat4_to_loc_rot_size(loc, rmat, size, ob->obmat); + /* transposition of orthogonal matrix (rotation), inverts */ + transpose_m3(rmat); + mul_m3_v3(rmat, cache->gravity_direction); + } + else { + cache->gravity_direction[0] = cache->gravity_direction[1] = 0.0; + cache->gravity_direction[2] = sd->gravity_factor; + } cache->plane_trim_squared = brush->plane_trim * brush->plane_trim; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 86145de3291..a539f26116e 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -850,6 +850,13 @@ typedef struct Sculpt { /* Direction used for SCULPT_OT_symmetrize operator */ int symmetrize_direction; + + /* gravity factor for sculpting */ + float gravity_factor; + int pad; + + struct Object *gravity_object; + void *pad2; } Sculpt; typedef struct UvSculpt { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 01e8c5956ff..bd4aa050689 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -248,6 +248,12 @@ static int rna_BrushCapabilities_has_texture_angle_get(PointerRNA *ptr) MTEX_MAP_MODE_RANDOM); } +static int rna_SculptToolCapabilities_has_gravity_get(PointerRNA *ptr) +{ + Brush *br = (Brush *)ptr->data; + return br->sculpt_tool != SCULPT_TOOL_MASK; +} + static int rna_BrushCapabilities_has_texture_angle_source_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; @@ -556,6 +562,7 @@ static void rna_def_sculpt_capabilities(BlenderRNA *brna) SCULPT_TOOL_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke"); SCULPT_TOOL_CAPABILITY(has_space_attenuation, "Has Space Attenuation"); SCULPT_TOOL_CAPABILITY(has_strength, "Has Strength"); + SCULPT_TOOL_CAPABILITY(has_gravity, "Has Gravity"); #undef SCULPT_CAPABILITY } diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 6280e0833e5..402b75c9594 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -427,6 +427,18 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Detail Refine Method", "In dynamic-topology mode, how to add or remove mesh detail"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "gravity_factor"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Gravity", "Amount of gravity after each dab"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "gravity_object", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Orientation", "Object whose Z axis defines orientation of gravity"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); } |