Merge branch 'blender-v3.6-release'

This commit is contained in:
Chris Blackbourn
2023-05-24 11:30:01 +12:00
4 changed files with 53 additions and 13 deletions

View File

@@ -1507,7 +1507,8 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
}
pack_island_params.setFromUnwrapOptions(options);
pack_island_params.rotate = RNA_boolean_get(op->ptr, "rotate");
pack_island_params.rotate_method = eUVPackIsland_RotationMethod(
RNA_enum_get(op->ptr, "rotate_method"));
pack_island_params.scale_to_fit = RNA_boolean_get(op->ptr, "scale");
pack_island_params.merge_overlap = RNA_boolean_get(op->ptr, "merge_overlap");
pack_island_params.pin_method = eUVPackIsland_PinMethod(RNA_enum_get(op->ptr, "pin_method"));
@@ -1564,6 +1565,23 @@ static const EnumPropertyItem pack_margin_method_items[] = {
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem pack_rotate_method_items[] = {
{ED_UVPACK_ROTATION_NONE, "NONE", 0, "No rotation", "No rotation is applied to the islands"},
RNA_ENUM_ITEM_SEPR,
{ED_UVPACK_ROTATION_AXIS_ALIGNED,
"AXIS_ALIGNED",
0,
"Axis-aligned",
"Rotated to a minimal rectangle, either vertical or horizontal"},
{ED_UVPACK_ROTATION_CARDINAL,
"CARDINAL",
0,
"Cardinal",
"Only 90 degree rotations are allowed"},
{ED_UVPACK_ROTATION_ANY, "ANY", 0, "Any", "Any angle is allowed for rotation"},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem pack_shape_method_items[] = {
{ED_UVPACK_SHAPE_CONCAVE, "CONCAVE", 0, "Exact shape (Concave)", "Uses exact geometry"},
{ED_UVPACK_SHAPE_CONVEX, "CONVEX", 0, "Boundary shape (Convex)", "Uses convex hull"},
@@ -1627,7 +1645,12 @@ void UV_OT_pack_islands(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "udim_source", pack_target, PACK_UDIM_SRC_CLOSEST, "Pack to", "");
RNA_def_boolean(ot->srna, "rotate", true, "Rotate", "Rotate islands for best fit");
RNA_def_enum(ot->srna,
"rotate_method",
pack_rotate_method_items,
ED_UVPACK_ROTATION_ANY,
"Rotation Method",
"");
RNA_def_boolean(ot->srna, "scale", true, "Scale", "Scale islands to fill unit square");
RNA_def_boolean(
ot->srna, "merge_overlap", false, "Merge Overlapped", "Overlapping islands stick together");
@@ -2360,7 +2383,7 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len
blender::geometry::UVPackIsland_Params pack_island_params;
pack_island_params.setFromUnwrapOptions(options);
pack_island_params.rotate = true;
pack_island_params.rotate_method = ED_UVPACK_ROTATION_ANY;
pack_island_params.pin_method = ED_UVPACK_PIN_IGNORED;
pack_island_params.margin_method = ED_UVPACK_MARGIN_SCALED;
pack_island_params.margin = scene->toolsettings->uvcalc_margin;
@@ -2502,7 +2525,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
blender::geometry::UVPackIsland_Params pack_island_params;
pack_island_params.setFromUnwrapOptions(options);
pack_island_params.rotate = true;
pack_island_params.rotate_method = ED_UVPACK_ROTATION_ANY;
pack_island_params.pin_method = ED_UVPACK_PIN_IGNORED;
pack_island_params.margin_method = eUVPackIsland_MarginMethod(
RNA_enum_get(op->ptr, "margin_method"));
@@ -2882,7 +2905,7 @@ static int smart_project_exec(bContext *C, wmOperator *op)
const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
blender::geometry::UVPackIsland_Params params;
params.rotate = true;
params.rotate_method = ED_UVPACK_ROTATION_ANY;
params.only_selected_uvs = only_selected_uvs;
params.only_selected_faces = true;
params.correct_aspect = correct_aspect;
@@ -3871,7 +3894,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
/* Pack UVs. */
blender::geometry::UVPackIsland_Params params;
params.rotate = true;
params.rotate_method = ED_UVPACK_ROTATION_ANY;
params.only_selected_uvs = false;
params.only_selected_faces = false;
params.correct_aspect = false;

View File

@@ -26,6 +26,17 @@ enum eUVPackIsland_MarginMethod {
ED_UVPACK_MARGIN_FRACTION,
};
enum eUVPackIsland_RotationMethod {
/** No rotation. */
ED_UVPACK_ROTATION_NONE = 0,
/** Rotated to a minimal rectangle, either vertical or horizontal. */
ED_UVPACK_ROTATION_AXIS_ALIGNED,
/** Only 90 degree rotations are allowed. */
ED_UVPACK_ROTATION_CARDINAL,
/** Any angle. */
ED_UVPACK_ROTATION_ANY,
};
enum eUVPackIsland_ShapeMethod {
/** Use Axis-Aligned Bounding-Boxes. */
ED_UVPACK_SHAPE_AABB = 0,
@@ -57,8 +68,8 @@ class UVPackIsland_Params {
void setUDIMOffsetFromSpaceImage(const SpaceImage *sima);
bool isCancelled() const;
/** Islands can be rotated to improve packing. */
bool rotate;
/** Restrictions around island rotation. */
eUVPackIsland_RotationMethod rotate_method;
/** Resize islands to fill the unit square. */
bool scale_to_fit;
/** (In UV Editor) only pack islands which have one or more selected UVs. */

View File

@@ -211,6 +211,12 @@ void PackIsland::calculate_pre_rotation_(const UVPackIsland_Params &params)
if (!can_rotate_(params)) {
return; /* Nothing to do. */
}
if (params.rotate_method == ED_UVPACK_ROTATION_CARDINAL) {
/* Arbitrary rotations are not allowed. */
return;
}
BLI_assert(params.rotate_method == ED_UVPACK_ROTATION_ANY ||
params.rotate_method == ED_UVPACK_ROTATION_AXIS_ALIGNED);
/* As a heuristic to improve layout efficiency, #PackIsland's are first rotated by an arbitrary
* angle to minimize the area of the enclosing AABB. This angle is stored in the `pre_rotate_`
@@ -325,7 +331,7 @@ void PackIsland::place_(const float scale, const uv_phi phi)
UVPackIsland_Params::UVPackIsland_Params()
{
rotate = false;
rotate_method = ED_UVPACK_ROTATION_NONE;
scale_to_fit = true;
only_selected_uvs = false;
only_selected_faces = false;
@@ -1095,8 +1101,8 @@ static bool rotate_inside_square(const Span<UVAABBIsland *> island_indices,
if (island_indices.size() == 0) {
return false; /* Nothing to do. */
}
if (!params.rotate) {
return false; /* Unable to rotate. */
if (params.rotate_method != ED_UVPACK_ROTATION_ANY) {
return false; /* Unable to rotate by arbitrary angle. */
}
if (params.shape_method == ED_UVPACK_SHAPE_AABB) {
/* AABB margin calculations are not preserved under rotations. */
@@ -1927,7 +1933,7 @@ void PackIsland::build_inverse_transformation(const float scale,
bool PackIsland::can_rotate_(const UVPackIsland_Params &params) const
{
if (!params.rotate) {
if (params.rotate_method == ED_UVPACK_ROTATION_NONE) {
return false;
}
if (!pinned) {

View File

@@ -4113,7 +4113,7 @@ void uv_parametrizer_pack(ParamHandle *handle, float margin, bool do_rotate, boo
Vector<PackIsland *> pack_island_vector;
UVPackIsland_Params params;
params.rotate = do_rotate;
params.rotate_method = do_rotate ? ED_UVPACK_ROTATION_ANY : ED_UVPACK_ROTATION_NONE;
params.margin = margin;
params.margin_method = ED_UVPACK_MARGIN_SCALED;