diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-07-23 23:52:03 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-07-23 23:52:27 +0300 |
commit | 0c0db92d7aabb486be5cfd4d5c6e2e1ed3f56dbc (patch) | |
tree | e597008ada2bd52b09d4d16c1356cc30d7326eac /source/blender/editors | |
parent | 36630b7e854ba69520aab9be411361589eb3ce83 (diff) |
Sculpt Tiling Feature
Adds 3D-Tiling options to the sculpt tool. This is very similar to the
symmetry options in the sense that it replicates the strokes. For tiling
this replication happens with a linear offset to fill the whole object
along one or more axis.
This allows to create geometry that can be tiled seamless. One use case
is the creation of tileable textures by sculpting high resolution
geometry and then rendering it with an orthographic camera to create
maps for diffuse, normal, etc
Notes:
Patch by Tilman Blumhagen with minor changes (move tile flags to paint
symmetry flags).
After some feedback from artists, leaving tiling value to constant
offset, though I suspect that some method that uses the object
bounding box dynamically might be good to have too. It can
be added later though :)
Thanks a lot for the patch!
Patch: D1426
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 37b37ed4ccc..44de9e66d0c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3454,6 +3454,46 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm, typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups); +static void do_tiled(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups, BrushActionFunc action) +{ + SculptSession *ss = ob->sculpt; + StrokeCache *cache = ss->cache; + const float * bbMin = ob->bb->vec[0]; + const float * bbMax = ob->bb->vec[6]; + + float start[3]; + float end[3]; + const float * step = sd->paint.tile_offset; + int dim; + + for (dim = 0; dim < 3; ++dim) { + if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) { + int n = (cache->location[dim] - bbMin[dim]) / step[dim]; + start[dim] = cache->location[dim] - n * step[dim]; + end[dim] = bbMax[dim]; + } + else + start[dim] = end[dim] = cache->location[dim]; + } + + copy_v3_v3(cache->location, start); + do { + do { + do { + action(sd, ob, brush, ups); + cache->location[2] += step[2]; + } while (cache->location[2] < end[2]); + cache->location[2] = start[2]; + + cache->location[1] += step[1]; + } while (cache->location[1] < end[1]); + cache->location[1] = start[1]; + + cache->location[0] += step[0]; + } while (cache->location[0] < end[0]); +} + + static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups, BrushActionFunc action, const char symm, const int axis, @@ -3466,7 +3506,7 @@ static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, UnifiedPain const float angle = 2 * M_PI * i / sd->radial_symm[axis - 'X']; ss->cache->radial_symmetry_pass = i; calc_brushdata_symm(sd, ss->cache, symm, axis, angle, feather); - action(sd, ob, brush, ups); + do_tiled(sd, ob, brush, ups, action); } } @@ -3504,7 +3544,7 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob, cache->radial_symmetry_pass = 0; calc_brushdata_symm(sd, cache, i, 0, 0, feather); - action(sd, ob, brush, ups); + do_tiled(sd, ob, brush, ups, action); do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather); do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather); @@ -5053,6 +5093,12 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) if (ts->sculpt->constant_detail == 0.0f) ts->sculpt->constant_detail = 30.0f; + /* Set sane default tiling offsets */ + if (!ts->sculpt->paint.tile_offset[0]) ts->sculpt->paint.tile_offset[0] = 1.0f; + if (!ts->sculpt->paint.tile_offset[1]) ts->sculpt->paint.tile_offset[1] = 1.0f; + if (!ts->sculpt->paint.tile_offset[2]) ts->sculpt->paint.tile_offset[2] = 1.0f; + + /* Create sculpt mode session data */ if (ob->sculpt) BKE_sculptsession_free(ob); |