diff --git a/scripts/startup/bl_ui/space_view3d_toolbar.py b/scripts/startup/bl_ui/space_view3d_toolbar.py index 764fcd6648e..fb88f265192 100644 --- a/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -95,6 +95,8 @@ class View3DPanel: # Used by vertex & weight paint def draw_vpaint_symmetry(layout, vpaint, obj): + mesh = obj.data + col = layout.column() row = col.row(heading="Mirror", align=True) row.prop(obj, "use_mesh_mirror_x", text="X", toggle=True) @@ -103,7 +105,7 @@ def draw_vpaint_symmetry(layout, vpaint, obj): col = layout.column() col.active = not obj.data.use_mirror_vertex_groups - col.prop(vpaint, "radial_symmetry", text="Radial") + col.prop(mesh, "radial_symmetry", text="Radial") # ********** default tools for object mode **************** @@ -1147,7 +1149,7 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): row.prop(sculpt, "tile_z", text="Z", toggle=True) layout.prop(sculpt, "use_symmetry_feather", text="Feather") - layout.prop(sculpt, "radial_symmetry", text="Radial") + layout.prop(mesh, "radial_symmetry", text="Radial") layout.prop(sculpt, "tile_offset", text="Tile Offset") layout.separator() diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 7a2e8ab1e54..295a5aafcd2 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 31 +#define BLENDER_FILE_SUBVERSION 32 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_500.cc b/source/blender/blenloader/intern/versioning_500.cc index b85a769fdb5..2d2b2776d7a 100644 --- a/source/blender/blenloader/intern/versioning_500.cc +++ b/source/blender/blenloader/intern/versioning_500.cc @@ -1253,6 +1253,14 @@ void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 32)) { + LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { + mesh->radial_symmetry[0] = 1; + mesh->radial_symmetry[1] = 1; + mesh->radial_symmetry[2] = 1; + } + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check. diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index abda5854d2c..36c8752e57f 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -1150,6 +1150,7 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr, const Object &ob, const float radius) { + const Mesh *mesh = static_cast(ob.data); const char symm = SCULPT_mesh_symmetry_xyz_get(ob); float3 location; float symm_rot_mat[4][4]; @@ -1166,8 +1167,8 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr, /* Radial Symmetry. */ for (char raxis = 0; raxis < 3; raxis++) { - for (int r = 1; r < sd.radial_symm[raxis]; r++) { - float angle = 2 * M_PI * r / sd.radial_symm[int(raxis)]; + for (int r = 1; r < mesh->radial_symmetry[raxis]; r++) { + float angle = 2 * M_PI * r / mesh->radial_symmetry[int(raxis)]; location = symmetry_flip(true_location, ePaintSymmetryFlags(i)); unit_m4(symm_rot_mat); rotate_m4(symm_rot_mat, raxis + 'X', angle); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index ec867cecc08..a473e2171cc 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -1977,8 +1977,8 @@ static void vpaint_do_radial_symmetry(bContext *C, const ePaintSymmetryFlags symm, const int axis) { - for (int i = 1; i < vp.radial_symm[axis - 'X']; i++) { - const float angle = (2.0 * M_PI) * i / vp.radial_symm[axis - 'X']; + for (int i = 1; i < mesh.radial_symmetry[axis - 'X']; i++) { + const float angle = (2.0 * M_PI) * i / mesh.radial_symmetry[axis - 'X']; vpaint_do_paint(C, vp, vpd, ob, mesh, brush, symm, axis, i, angle); } } diff --git a/source/blender/editors/sculpt_paint/paint_weight.cc b/source/blender/editors/sculpt_paint/paint_weight.cc index 0c8aaf88932..3de5d046816 100644 --- a/source/blender/editors/sculpt_paint/paint_weight.cc +++ b/source/blender/editors/sculpt_paint/paint_weight.cc @@ -1719,8 +1719,8 @@ static void wpaint_do_radial_symmetry(bContext *C, const ePaintSymmetryFlags symm, const int axis) { - for (int i = 1; i < wp.radial_symm[axis - 'X']; i++) { - const float angle = (2.0 * M_PI) * i / wp.radial_symm[axis - 'X']; + for (int i = 1; i < mesh.radial_symmetry[axis - 'X']; i++) { + const float angle = (2.0 * M_PI) * i / mesh.radial_symmetry[axis - 'X']; wpaint_do_paint(C, ob, wp, wpd, wpi, mesh, brush, symm, axis, i, angle); } } diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 9cce2b8e12d..6be7cbb25e0 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -1212,15 +1212,15 @@ static float calc_overlap(const blender::ed::sculpt_paint::StrokeCache &cache, return 0.0f; } -static float calc_radial_symmetry_feather(const Sculpt &sd, +static float calc_radial_symmetry_feather(const Mesh &mesh, const blender::ed::sculpt_paint::StrokeCache &cache, const ePaintSymmetryFlags symm, const char axis) { float overlap = 0.0f; - for (int i = 1; i < sd.radial_symm[axis - 'X']; i++) { - const float angle = 2.0f * M_PI * i / sd.radial_symm[axis - 'X']; + for (int i = 1; i < mesh.radial_symmetry[axis - 'X']; i++) { + const float angle = 2.0f * M_PI * i / mesh.radial_symmetry[axis - 'X']; overlap += calc_overlap(cache, symm, axis, angle); } @@ -1228,6 +1228,7 @@ static float calc_radial_symmetry_feather(const Sculpt &sd, } static float calc_symmetry_feather(const Sculpt &sd, + const Mesh &mesh, const blender::ed::sculpt_paint::StrokeCache &cache) { if (!(sd.paint.symmetry_flags & PAINT_SYMMETRY_FEATHER)) { @@ -1244,9 +1245,9 @@ static float calc_symmetry_feather(const Sculpt &sd, overlap += calc_overlap(cache, ePaintSymmetryFlags(i), 0, 0); - overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'X'); - overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'Y'); - overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'Z'); + overlap += calc_radial_symmetry_feather(mesh, cache, ePaintSymmetryFlags(i), 'X'); + overlap += calc_radial_symmetry_feather(mesh, cache, ePaintSymmetryFlags(i), 'Y'); + overlap += calc_radial_symmetry_feather(mesh, cache, ePaintSymmetryFlags(i), 'Z'); } return 1.0f / overlap; } @@ -3576,9 +3577,10 @@ static void do_radial_symmetry(const Depsgraph &depsgraph, const float /*feather*/) { SculptSession &ss = *ob.sculpt; + const Mesh &mesh = *static_cast(ob.data); - for (int i = 1; i < sd.radial_symm[axis - 'X']; i++) { - const float angle = 2.0f * M_PI * i / sd.radial_symm[axis - 'X']; + for (int i = 1; i < mesh.radial_symmetry[axis - 'X']; i++) { + const float angle = 2.0f * M_PI * i / mesh.radial_symmetry[axis - 'X']; ss.cache->radial_symmetry_pass = i; SCULPT_cache_calc_brushdata_symm(*ss.cache, symm, axis, angle); do_tiled(depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action); @@ -3609,11 +3611,12 @@ static void do_symmetrical_brush_actions(const Depsgraph &depsgraph, PaintModeSettings &paint_mode_settings) { const Brush &brush = *BKE_paint_brush_for_read(&sd.paint); + const Mesh &mesh = *static_cast(ob.data); SculptSession &ss = *ob.sculpt; StrokeCache &cache = *ss.cache; const char symm = SCULPT_mesh_symmetry_xyz_get(ob); - float feather = calc_symmetry_feather(sd, *ss.cache); + float feather = calc_symmetry_feather(sd, mesh, *ss.cache); cache.bstrength = brush_strength(sd, cache, feather, ups, paint_mode_settings); cache.symmetry = symm; diff --git a/source/blender/makesdna/DNA_mesh_defaults.h b/source/blender/makesdna/DNA_mesh_defaults.h index 43271b0988b..53219ad7c18 100644 --- a/source/blender/makesdna/DNA_mesh_defaults.h +++ b/source/blender/makesdna/DNA_mesh_defaults.h @@ -23,7 +23,8 @@ .face_sets_color_seed = 0, \ .face_sets_color_default = 1, \ .flag = ME_REMESH_REPROJECT_VOLUME | ME_REMESH_REPROJECT_ATTRIBUTES, \ - .editflag = ME_EDIT_MIRROR_VERTEX_GROUPS \ + .editflag = ME_EDIT_MIRROR_VERTEX_GROUPS, \ + .radial_symmetry = {1, 1, 1} \ } /** \} */ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 6a5f15ad324..874af897b08 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -241,7 +241,8 @@ typedef struct Mesh { /* Deprecated size of #fdata. */ int totface_legacy; - char _pad1[4]; + char _pad1; + int8_t radial_symmetry[3]; /** * Data that isn't saved in files, including caches of derived data, temporary data to improve diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 0fd0f10b18f..0274230a670 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1340,7 +1340,7 @@ typedef struct Sculpt { // /* Control tablet input. */ // char tablet_size, tablet_strength; XXX not used? - int radial_symm[3]; + int radial_symm[3] DNA_DEPRECATED; /** Maximum edge length for dynamic topology sculpting (in pixels). */ float detail_size; @@ -1428,7 +1428,7 @@ typedef struct VPaint { char flag; char _pad[3]; /** For mirrored painting. */ - int radial_symm[3]; + int radial_symm[3] DNA_DEPRECATED; } VPaint; /** #VPaint::flag */ diff --git a/source/blender/makesrna/intern/rna_mesh.cc b/source/blender/makesrna/intern/rna_mesh.cc index e20fe4437fb..a457188f13a 100644 --- a/source/blender/makesrna/intern/rna_mesh.cc +++ b/source/blender/makesrna/intern/rna_mesh.cc @@ -3302,6 +3302,15 @@ static void rna_def_mesh(BlenderRNA *brna) "Mirror the left/right vertex groups when painting. The symmetry axis " "is determined by the symmetry settings."); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + + prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ); + RNA_def_property_int_sdna(prop, nullptr, "radial_symmetry"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_default(prop, 1); + RNA_def_property_range(prop, 1, 64); + RNA_def_property_ui_range(prop, 1, 32, 1, 1); + RNA_def_property_ui_text( + prop, "Radial Symmetry Count", "Number of mirrored regions around a central axis"); /* End Symmetry */ RNA_define_verify_sdna(false); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.cc b/source/blender/makesrna/intern/rna_sculpt_paint.cc index 8185713ac92..175df60b93d 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.cc +++ b/source/blender/makesrna/intern/rna_sculpt_paint.cc @@ -1006,14 +1006,6 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Sculpt", ""); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); - prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ); - RNA_def_property_int_sdna(prop, nullptr, "radial_symm"); - RNA_def_property_int_default(prop, 1); - RNA_def_property_range(prop, 1, 64); - RNA_def_property_ui_range(prop, 0, 32, 1, 1); - RNA_def_property_ui_text( - prop, "Radial Symmetry Count X Axis", "Number of times to copy strokes across the surface"); - prop = RNA_def_property(srna, "lock_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flags", SCULPT_LOCK_X); RNA_def_property_ui_text(prop, "Lock X", "Disallow changes to the X axis of vertices"); @@ -1312,15 +1304,6 @@ static void rna_def_vertex_paint(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, nullptr, "flag", VP_FLAG_VGROUP_RESTRICT); RNA_def_property_ui_text(prop, "Restrict", "Restrict painting to vertices in the group"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); - - /* Mirroring */ - prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ); - RNA_def_property_int_sdna(prop, nullptr, "radial_symm"); - RNA_def_property_int_default(prop, 1); - RNA_def_property_range(prop, 1, 64); - RNA_def_property_ui_range(prop, 1, 32, 1, 1); - RNA_def_property_ui_text( - prop, "Radial Symmetry Count X Axis", "Number of times to copy strokes across the surface"); } static void rna_def_paint_mode(BlenderRNA *brna)