Merge branch 'blender-v4.5-release'
This commit is contained in:
@@ -1004,22 +1004,37 @@ static inline void sort_points(int2 &p1, int2 &p2)
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensures that the x and y distance to from p1 to p2 is equal. The two points can be in any
|
||||
* spacial relation to each other i.e. if p1 was top left, it remains top left. */
|
||||
static inline void square_points(const int2 &p1, int2 &p2)
|
||||
/* Clamps the point to the window bounds. */
|
||||
static inline int2 clamp_point_to_window(const int2 &point, const wmWindow *window)
|
||||
{
|
||||
int2 delta = p2 - p1;
|
||||
return {clamp_i(point.x, 0, window->sizex - 1), clamp_i(point.y, 0, window->sizey - 1)};
|
||||
}
|
||||
|
||||
/* Ensures that the x and y distance to from p1 to p2 is equal and the resulting square remains
|
||||
* fully within the window bounds. The two points can be in any spacial relation to each other i.e.
|
||||
* if p1 was top left, it remains top left. */
|
||||
static inline void square_points_clamp_to_window(const int2 &p1, int2 &p2, const wmWindow *window)
|
||||
{
|
||||
const int2 delta = p2 - p1;
|
||||
|
||||
/* Determine the drag direction for each axis. */
|
||||
const int dir_x = (delta.x >= 0) ? 1 : -1;
|
||||
const int dir_y = (delta.y >= 0) ? 1 : -1;
|
||||
|
||||
const int size_x = std::abs(delta.x);
|
||||
const int size_y = std::abs(delta.y);
|
||||
if (size_x < size_y) {
|
||||
delta.x = std::copysignf(size_y, delta.x);
|
||||
}
|
||||
else if (size_y < size_x) {
|
||||
delta.y = std::copysign(size_x, delta.y);
|
||||
}
|
||||
p2.x = p1.x + delta.x;
|
||||
p2.y = p1.y + delta.y;
|
||||
int square_size = std::max(size_x, size_y);
|
||||
|
||||
/* Compute maximum size that fits within window bounds in the drag direction. */
|
||||
const int max_size_x = (dir_x > 0) ? window->sizex - p1.x - 1 : p1.x;
|
||||
const int max_size_y = (dir_y > 0) ? window->sizey - p1.y - 1 : p1.y;
|
||||
|
||||
/* Clamp the square size so it does not exceed window bounds. */
|
||||
square_size = std::min(square_size, std::min(max_size_x, max_size_y));
|
||||
|
||||
/* Update p2 to form a clamped square in the same direction as the drag. */
|
||||
p2.x = p1.x + dir_x * square_size;
|
||||
p2.y = p1.y + dir_y * square_size;
|
||||
}
|
||||
|
||||
static void generate_previewimg_from_buffer(ID *id, const ImBuf *image_buffer)
|
||||
@@ -1105,13 +1120,18 @@ static ImBuf *take_screenshot_crop(bContext *C, const rcti &crop_rect)
|
||||
static wmOperatorStatus screenshot_preview_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int2 p1, p2;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
RNA_int_get_array(op->ptr, "p1", p1);
|
||||
RNA_int_get_array(op->ptr, "p2", p2);
|
||||
|
||||
/* Clamp points to window bounds, so the screenshot area is always valid. */
|
||||
p1 = clamp_point_to_window(p1, win);
|
||||
p2 = clamp_point_to_window(p2, win);
|
||||
|
||||
/* Squaring has to happen before sorting so the area is squared from the point where
|
||||
* dragging started. */
|
||||
if (RNA_boolean_get(op->ptr, "force_square")) {
|
||||
square_points(p1, p2);
|
||||
square_points_clamp_to_window(p1, p2, win);
|
||||
}
|
||||
|
||||
sort_points(p1, p2);
|
||||
@@ -1207,9 +1227,16 @@ static void screenshot_preview_draw(const wmWindow *window, void *operator_data)
|
||||
int2 p1 = data->p1;
|
||||
int2 p2 = data->p2;
|
||||
|
||||
/* Clamp points to window bounds, so the screenshot area is always valid. */
|
||||
p1 = clamp_point_to_window(p1, window);
|
||||
p2 = clamp_point_to_window(p2, window);
|
||||
|
||||
/* Squaring has to happen before sorting so the area is squared from the point where
|
||||
* dragging started. */
|
||||
if (data->force_square) {
|
||||
square_points(p1, p2);
|
||||
square_points_clamp_to_window(p1, p2, window);
|
||||
}
|
||||
|
||||
sort_points(p1, p2);
|
||||
|
||||
/* Drawing rect just out of the screenshot area to not capture the box in the picture. */
|
||||
@@ -1254,7 +1281,7 @@ static inline void screenshot_area_transfer_to_rna(wmOperator *op, ScreenshotOpe
|
||||
static wmOperatorStatus screenshot_preview_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ScreenshotOperatorData *data = static_cast<ScreenshotOperatorData *>(op->customdata);
|
||||
|
||||
const int2 screen_space_cursor = {
|
||||
@@ -1271,7 +1298,7 @@ static wmOperatorStatus screenshot_preview_modal(bContext *C, wmOperator *op, co
|
||||
break;
|
||||
case KM_RELEASE:
|
||||
data->is_mouse_down = false;
|
||||
data->drag_end = screen_space_cursor;
|
||||
data->drag_end = clamp_point_to_window(screen_space_cursor, win);
|
||||
screenshot_area_transfer_to_rna(op, data);
|
||||
screenshot_preview_exec(C, op);
|
||||
screenshot_preview_exit(C, op);
|
||||
@@ -1327,27 +1354,39 @@ static wmOperatorStatus screenshot_preview_modal(bContext *C, wmOperator *op, co
|
||||
}
|
||||
|
||||
case MOUSEMOVE: {
|
||||
if (!data->crossed_threshold) {
|
||||
const int2 delta = data->drag_end - data->drag_start;
|
||||
if (std::abs(delta.x) > DRAG_THRESHOLD && std::abs(delta.y) > DRAG_THRESHOLD) {
|
||||
/* Only set the points once the threshold has been crossed. This allows to just
|
||||
* click to confirm using a potentially existing screenshot rect. */
|
||||
data->crossed_threshold = true;
|
||||
data->p1 = data->drag_start;
|
||||
if (data->shift_area) {
|
||||
const int2 delta = screen_space_cursor - data->last_cursor;
|
||||
const int2 new_p1 = data->p1 + delta;
|
||||
const int2 new_p2 = data->p2 + delta;
|
||||
|
||||
auto is_within_window = [win](const int2 &pt) -> bool {
|
||||
return pt.x >= 0 && pt.x < win->sizex && pt.y >= 0 && pt.y < win->sizey;
|
||||
};
|
||||
|
||||
/* Apply movement only if the entire rectangle stays within window bounds. */
|
||||
if (is_within_window(new_p1) && is_within_window(new_p2)) {
|
||||
data->p1 = new_p1;
|
||||
data->p2 = new_p2;
|
||||
}
|
||||
}
|
||||
else if (data->is_mouse_down) {
|
||||
data->drag_end = clamp_point_to_window(screen_space_cursor, win);
|
||||
|
||||
if (!data->crossed_threshold) {
|
||||
const int2 delta = data->drag_end - data->drag_start;
|
||||
if (std::abs(delta.x) > DRAG_THRESHOLD && std::abs(delta.y) > DRAG_THRESHOLD) {
|
||||
/* Only set the points once the threshold has been crossed. This allows to just
|
||||
* click to confirm using a potentially existing screenshot rect. */
|
||||
data->crossed_threshold = true;
|
||||
data->p1 = data->drag_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->crossed_threshold) {
|
||||
data->p2 = data->drag_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->shift_area) {
|
||||
const int2 delta = screen_space_cursor - data->last_cursor;
|
||||
data->p1 += delta;
|
||||
data->p2 += delta;
|
||||
}
|
||||
else if (data->is_mouse_down) {
|
||||
data->drag_end = screen_space_cursor;
|
||||
if (data->crossed_threshold) {
|
||||
data->p2 = screen_space_cursor;
|
||||
}
|
||||
}
|
||||
CTX_wm_screen(C)->do_draw = true;
|
||||
data->last_cursor = screen_space_cursor;
|
||||
break;
|
||||
|
||||
@@ -91,12 +91,10 @@ deform_tests = RunTest(tests)
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
deform_tests.apply_modifiers = True
|
||||
deform_tests.do_compare = True
|
||||
deform_tests.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
deform_tests.apply_modifiers = False
|
||||
deform_tests.do_compare = False
|
||||
name = command[i + 1]
|
||||
deform_tests.run_test(name)
|
||||
|
||||
@@ -342,12 +342,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
modifiers_test.apply_modifiers = True
|
||||
modifiers_test.do_compare = True
|
||||
modifiers_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
modifiers_test.apply_modifiers = False
|
||||
modifiers_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
modifiers_test.run_test(name)
|
||||
|
||||
@@ -814,7 +814,7 @@ class RunTest:
|
||||
>>> modifiers_test.run_all_tests()
|
||||
"""
|
||||
|
||||
def __init__(self, tests, apply_modifiers=False, do_compare=False):
|
||||
def __init__(self, tests, do_compare=False):
|
||||
"""
|
||||
Construct a test suite.
|
||||
|
||||
@@ -825,10 +825,11 @@ class RunTest:
|
||||
2) expected_object_name: bpy.Types.Object - expected object
|
||||
3) modifiers or operators: list - list of mesh_test.ModifierSpec objects or
|
||||
mesh_test.OperatorSpecEditMode objects
|
||||
:arg do_compare: bool - Whether the result mesh will be compared with the provided golden mesh. When set to False
|
||||
the modifier is not applied so the result can be examined inside Blender.
|
||||
"""
|
||||
self.tests = tests
|
||||
self._ensure_unique_test_name_or_raise_error()
|
||||
self.apply_modifiers = apply_modifiers
|
||||
self.do_compare = do_compare
|
||||
self.verbose = os.environ.get("BLENDER_VERBOSE") is not None
|
||||
self._failed_tests_list = []
|
||||
@@ -895,7 +896,9 @@ class RunTest:
|
||||
raise Exception('No test called {} found!'.format(test_name))
|
||||
|
||||
test = case
|
||||
test.apply_modifier = self.apply_modifiers
|
||||
if not self.do_compare:
|
||||
test.apply_modifier = False
|
||||
|
||||
test.do_compare = self.do_compare
|
||||
|
||||
success = test.run_test()
|
||||
|
||||
@@ -35,12 +35,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
cloth_test.apply_modifiers = True
|
||||
cloth_test.do_compare = True
|
||||
cloth_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
cloth_test.apply_modifiers = False
|
||||
cloth_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
cloth_test.run_test(name)
|
||||
|
||||
@@ -26,12 +26,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
dynamic_paint_test.apply_modifiers = True
|
||||
dynamic_paint_test.do_compare = True
|
||||
dynamic_paint_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
dynamic_paint_test.apply_modifiers = False
|
||||
dynamic_paint_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
dynamic_paint_test.run_test(name)
|
||||
|
||||
@@ -22,12 +22,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
ocean_test.apply_modifiers = True
|
||||
ocean_test.do_compare = True
|
||||
ocean_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
ocean_test.apply_modifiers = False
|
||||
ocean_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
ocean_test.run_test(name)
|
||||
|
||||
@@ -24,12 +24,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
particle_instance_test.apply_modifiers = True
|
||||
particle_instance_test.do_compare = True
|
||||
particle_instance_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
particle_instance_test.apply_modifiers = False
|
||||
particle_instance_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
particle_instance_test.run_test(name)
|
||||
|
||||
@@ -27,12 +27,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
particle_test.apply_modifiers = True
|
||||
particle_test.do_compare = True
|
||||
particle_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
particle_test.apply_modifiers = False
|
||||
particle_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
particle_test.run_test(name)
|
||||
|
||||
@@ -24,12 +24,10 @@ def main():
|
||||
command = list(sys.argv)
|
||||
for i, cmd in enumerate(command):
|
||||
if cmd == "--run-all-tests":
|
||||
soft_body_test.apply_modifiers = True
|
||||
soft_body_test.do_compare = True
|
||||
soft_body_test.run_all_tests()
|
||||
break
|
||||
elif cmd == "--run-test":
|
||||
soft_body_test.apply_modifiers = False
|
||||
soft_body_test.do_compare = False
|
||||
name = command[i + 1]
|
||||
soft_body_test.run_test(name)
|
||||
|
||||
Reference in New Issue
Block a user