diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 9 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 50 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sculpt_paint.c | 22 |
4 files changed, 86 insertions, 4 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index e381800ae02..2294e109f0c 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1553,6 +1553,15 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): row.prop(sculpt, "lock_z", text="Z", toggle=True) + layout.label(text="Tiling:") + + row = layout.row(align=True) + row.prop(sculpt, "tile_x", text="X", toggle=True) + row.prop(sculpt, "tile_y", text="Y", toggle=True) + row.prop(sculpt, "tile_z", text="Z", toggle=True) + + layout.column().prop(sculpt, "tile_offset", text="Tile Offset") + class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel): bl_category = "Options" bl_label = "Appearance" 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); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a0b0cbea4c3..fd6d39c9ce6 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -941,6 +941,9 @@ typedef struct Paint { /* flags used for symmetry */ int symmetry_flags; + + float tile_offset[3]; + int pad2; } Paint; /* ------------------------------------------- */ @@ -1029,7 +1032,6 @@ typedef struct Sculpt { float pad; struct Object *gravity_object; - void *pad2; } Sculpt; typedef struct UvSculpt { @@ -1817,7 +1819,10 @@ typedef enum SymmetryFlags { PAINT_SYMM_X = (1 << 0), PAINT_SYMM_Y = (1 << 1), PAINT_SYMM_Z = (1 << 2), - PAINT_SYMMETRY_FEATHER = (1 << 3) + PAINT_SYMMETRY_FEATHER = (1 << 3), + PAINT_TILE_X = (1 << 4), + PAINT_TILE_Y = (1 << 5), + PAINT_TILE_Z = (1 << 6), } SymmetryFlags; #define PAINT_SYMM_AXIS_ALL (PAINT_SYMM_X | PAINT_SYMM_Y | PAINT_SYMM_Z) diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 7b30aa84cfb..3ec9944900a 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -443,6 +443,28 @@ static void rna_def_paint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Cavity Mask", "Mask painting according to mesh geometry cavity"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "tile_offset", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "tile_offset"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.01, FLT_MAX); + RNA_def_property_ui_range(prop, 0.01, 100, 1 * 100, 2); + RNA_def_property_ui_text(prop, "Tiling offset for the X Axis", + "Stride at which tiled strokes are copied"); + + prop = RNA_def_property(srna, "tile_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "symmetry_flags", PAINT_TILE_X); + RNA_def_property_ui_text(prop, "Tile X", "Tile along X axis"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "tile_y", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "symmetry_flags", PAINT_TILE_Y); + RNA_def_property_ui_text(prop, "Tile Y", "Tile along Y axis"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "tile_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "symmetry_flags", PAINT_TILE_Z); + RNA_def_property_ui_text(prop, "Tile Z", "Tile along Z axis"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); } static void rna_def_sculpt(BlenderRNA *brna) |