WIP: Snapping Redesign: Defaults | Navigation | Drawing | Removals #109062

Draft
Germano Cavalcante wants to merge 29 commits from mano-wii/blender:snap_defaults into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
10 changed files with 300 additions and 236 deletions
Showing only changes of commit 51df8b540e - Show all commits

View File

@ -36,232 +36,188 @@
#include "DNA_packedFile_types.h"
#include "DNA_vfont_types.h"
static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
static void freetype_outline_to_curves(FT_Outline ftoutline, ListBase *nurbsbase, const float scale)
{
const float scale = vfd->scale;
const float eps = 0.0001f;
const float eps_sq = eps * eps;
/* Blender */
Nurb *nu;
VChar *che;
BezTriple *bezt;
/* Freetype2 */
FT_GlyphSlot glyph;
FT_UInt glyph_index;
FT_Outline ftoutline;
float dx, dy;
int j, k, l, l_first = 0;
/*
* Generate the character 3D data
*
* Get the FT Glyph index and load the Glyph */
glyph_index = FT_Get_Char_Index(face, charcode);
FT_Error err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
/* initialize as -1 to add 1 on first loop each time */
int contour_prev;
/* If loading succeeded, convert the FT glyph to the internal format */
if (!err) {
/* initialize as -1 to add 1 on first loop each time */
int contour_prev;
int *onpoints;
/* Start converting the FT data */
int *onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
/* First we create entry for the new character to the character list */
che = (VChar *)MEM_callocN(sizeof(VChar), "objfnt_char");
/* Get number of on-curve points for bezier-triples (including conic virtual on-points). */
for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
const int n = ftoutline.contours[j] - contour_prev;
contour_prev = ftoutline.contours[j];
/* Take some data for modifying purposes */
glyph = face->glyph;
ftoutline = glyph->outline;
for (k = 0; k < n; k++) {
l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
if (k == 0) {
l_first = l;
}
/* Set the width and character code */
che->index = charcode;
che->width = glyph->advance.x * scale;
BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che);
/* Start converting the FT data */
onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
/* Get number of on-curve points for bezier-triples (including conic virtual on-points). */
for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
const int n = ftoutline.contours[j] - contour_prev;
contour_prev = ftoutline.contours[j];
for (k = 0; k < n; k++) {
l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
if (k == 0) {
l_first = l;
}
if (ftoutline.tags[l] == FT_Curve_Tag_On) {
onpoints[j]++;
}
if (ftoutline.tags[l] == FT_Curve_Tag_On) {
onpoints[j]++;
}
{
const int l_next = (k < n - 1) ? (l + 1) : l_first;
if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
ftoutline.tags[l_next] == FT_Curve_Tag_Conic)
{
const int l_next = (k < n - 1) ? (l + 1) : l_first;
if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
onpoints[j]++;
}
onpoints[j]++;
}
}
}
}
/* contour loop, bezier & conic styles merged */
for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
const int n = ftoutline.contours[j] - contour_prev;
contour_prev = ftoutline.contours[j];
/* contour loop, bezier & conic styles merged */
for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
const int n = ftoutline.contours[j] - contour_prev;
contour_prev = ftoutline.contours[j];
/* add new curve */
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "objfnt_nurb");
bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt");
BLI_addtail(&che->nurbsbase, nu);
/* add new curve */
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "objfnt_nurb");
bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt");
BLI_addtail(nurbsbase, nu);
nu->type = CU_BEZIER;
nu->pntsu = onpoints[j];
nu->resolu = 8;
nu->flagu = CU_NURB_CYCLIC;
nu->bezt = bezt;
nu->type = CU_BEZIER;
nu->pntsu = onpoints[j];
nu->resolu = 8;
nu->flagu = CU_NURB_CYCLIC;
nu->bezt = bezt;
/* individual curve loop, start-end */
for (k = 0; k < n; k++) {
l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
if (k == 0) {
l_first = l;
}
/* individual curve loop, start-end */
for (k = 0; k < n; k++) {
l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
if (k == 0) {
l_first = l;
}
/* virtual conic on-curve points */
/* virtual conic on-curve points */
{
const int l_next = (k < n - 1) ? (l + 1) : l_first;
if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
ftoutline.tags[l_next] == FT_Curve_Tag_Conic)
{
const int l_next = (k < n - 1) ? (l + 1) : l_first;
if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
dx = (ftoutline.points[l].x + ftoutline.points[l_next].x) * scale / 2.0f;
dy = (ftoutline.points[l].y + ftoutline.points[l_next].y) * scale / 2.0f;
/* left handle */
bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f;
bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f;
/* midpoint (virtual on-curve point) */
bezt->vec[1][0] = dx;
bezt->vec[1][1] = dy;
/* right handle */
bezt->vec[2][0] = (dx + (2 * ftoutline.points[l_next].x) * scale) / 3.0f;
bezt->vec[2][1] = (dy + (2 * ftoutline.points[l_next].y) * scale) / 3.0f;
bezt->h1 = bezt->h2 = HD_ALIGN;
bezt->radius = 1.0f;
bezt++;
}
}
/* on-curve points */
if (ftoutline.tags[l] == FT_Curve_Tag_On) {
const int l_prev = (k > 0) ? (l - 1) : ftoutline.contours[j];
const int l_next = (k < n - 1) ? (l + 1) : l_first;
dx = (ftoutline.points[l].x + ftoutline.points[l_next].x) * scale / 2.0f;
dy = (ftoutline.points[l].y + ftoutline.points[l_next].y) * scale / 2.0f;
/* left handle */
if (ftoutline.tags[l_prev] == FT_Curve_Tag_Cubic) {
bezt->vec[0][0] = ftoutline.points[l_prev].x * scale;
bezt->vec[0][1] = ftoutline.points[l_prev].y * scale;
bezt->h1 = HD_FREE;
}
else if (ftoutline.tags[l_prev] == FT_Curve_Tag_Conic) {
bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_prev].x)) * scale /
3.0f;
bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_prev].y)) * scale /
3.0f;
bezt->h1 = HD_FREE;
}
else {
bezt->vec[0][0] = ftoutline.points[l].x * scale -
(ftoutline.points[l].x - ftoutline.points[l_prev].x) * scale / 3.0f;
bezt->vec[0][1] = ftoutline.points[l].y * scale -
(ftoutline.points[l].y - ftoutline.points[l_prev].y) * scale / 3.0f;
bezt->h1 = HD_VECT;
}
bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f;
bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f;
/* midpoint (on-curve point) */
bezt->vec[1][0] = ftoutline.points[l].x * scale;
bezt->vec[1][1] = ftoutline.points[l].y * scale;
/* midpoint (virtual on-curve point) */
bezt->vec[1][0] = dx;
bezt->vec[1][1] = dy;
/* right handle */
if (ftoutline.tags[l_next] == FT_Curve_Tag_Cubic) {
bezt->vec[2][0] = ftoutline.points[l_next].x * scale;
bezt->vec[2][1] = ftoutline.points[l_next].y * scale;
bezt->h2 = HD_FREE;
}
else if (ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_next].x)) * scale /
3.0f;
bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_next].y)) * scale /
3.0f;
bezt->h2 = HD_FREE;
}
else {
bezt->vec[2][0] = ftoutline.points[l].x * scale -
(ftoutline.points[l].x - ftoutline.points[l_next].x) * scale / 3.0f;
bezt->vec[2][1] = ftoutline.points[l].y * scale -
(ftoutline.points[l].y - ftoutline.points[l_next].y) * scale / 3.0f;
bezt->h2 = HD_VECT;
}
bezt->vec[2][0] = (dx + (2 * ftoutline.points[l_next].x) * scale) / 3.0f;
bezt->vec[2][1] = (dy + (2 * ftoutline.points[l_next].y) * scale) / 3.0f;
/* get the handles that are aligned, tricky...
* - check if one of them is a vector handle.
* - dist_squared_to_line_v2, check if the three beztriple points are on one line
* - len_squared_v2v2, see if there's a distance between the three points
* - len_squared_v2v2 again, to check the angle between the handles
*/
if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) &&
(dist_squared_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) <
(0.001f * 0.001f)) &&
(len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > eps_sq) &&
(len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > eps_sq) &&
(len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > eps_sq) &&
(len_squared_v2v2(bezt->vec[0], bezt->vec[2]) >
max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]),
len_squared_v2v2(bezt->vec[1], bezt->vec[2]))))
{
bezt->h1 = bezt->h2 = HD_ALIGN;
}
bezt->h1 = bezt->h2 = HD_ALIGN;
bezt->radius = 1.0f;
bezt++;
}
}
/* on-curve points */
if (ftoutline.tags[l] == FT_Curve_Tag_On) {
const int l_prev = (k > 0) ? (l - 1) : ftoutline.contours[j];
const int l_next = (k < n - 1) ? (l + 1) : l_first;
/* left handle */
if (ftoutline.tags[l_prev] == FT_Curve_Tag_Cubic) {
bezt->vec[0][0] = ftoutline.points[l_prev].x * scale;
bezt->vec[0][1] = ftoutline.points[l_prev].y * scale;
bezt->h1 = HD_FREE;
}
else if (ftoutline.tags[l_prev] == FT_Curve_Tag_Conic) {
bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_prev].x)) * scale /
3.0f;
bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_prev].y)) * scale /
3.0f;
bezt->h1 = HD_FREE;
}
else {
bezt->vec[0][0] = ftoutline.points[l].x * scale -
(ftoutline.points[l].x - ftoutline.points[l_prev].x) * scale / 3.0f;
bezt->vec[0][1] = ftoutline.points[l].y * scale -
(ftoutline.points[l].y - ftoutline.points[l_prev].y) * scale / 3.0f;
bezt->h1 = HD_VECT;
}
/* midpoint (on-curve point) */
bezt->vec[1][0] = ftoutline.points[l].x * scale;
bezt->vec[1][1] = ftoutline.points[l].y * scale;
/* right handle */
if (ftoutline.tags[l_next] == FT_Curve_Tag_Cubic) {
bezt->vec[2][0] = ftoutline.points[l_next].x * scale;
bezt->vec[2][1] = ftoutline.points[l_next].y * scale;
bezt->h2 = HD_FREE;
}
else if (ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_next].x)) * scale /
3.0f;
bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_next].y)) * scale /
3.0f;
bezt->h2 = HD_FREE;
}
else {
bezt->vec[2][0] = ftoutline.points[l].x * scale -
(ftoutline.points[l].x - ftoutline.points[l_next].x) * scale / 3.0f;
bezt->vec[2][1] = ftoutline.points[l].y * scale -
(ftoutline.points[l].y - ftoutline.points[l_next].y) * scale / 3.0f;
bezt->h2 = HD_VECT;
}
/* get the handles that are aligned, tricky...
* - check if one of them is a vector handle.
* - dist_squared_to_line_v2, check if the three beztriple points are on one line
* - len_squared_v2v2, see if there's a distance between the three points
* - len_squared_v2v2 again, to check the angle between the handles
*/
if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) &&
(dist_squared_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) <
(0.001f * 0.001f)) &&
(len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > eps_sq) &&
(len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > eps_sq) &&
(len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > eps_sq) &&
(len_squared_v2v2(bezt->vec[0], bezt->vec[2]) >
max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]),
len_squared_v2v2(bezt->vec[1], bezt->vec[2]))))
{
bezt->h1 = bezt->h2 = HD_ALIGN;
}
bezt->radius = 1.0f;
bezt++;
}
}
MEM_freeN(onpoints);
return che;
}
return NULL;
MEM_freeN(onpoints);
}
static VChar *objchr_to_ftvfontdata(FT_Library library, VFont *vfont, FT_ULong charcode)
static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, const VFontData* vfd)
{
VChar *che;
/* Freetype2 */
FT_Face face;
/* Load the font to memory */
if (vfont->temp_pf) {
FT_Error err = FT_New_Memory_Face(
library, vfont->temp_pf->data, vfont->temp_pf->size, 0, &face);
if (err) {
return NULL;
}
}
else {
FT_UInt glyph_index = FT_Get_Char_Index(face, charcode);
if (FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP) != FT_Err_Ok) {
return NULL;
}
/* Read the char */
che = freetypechar_to_vchar(face, charcode, vfont->data);
VChar *che = (VChar *)MEM_callocN(sizeof(struct VChar), "objfnt_char");
freetype_outline_to_curves(face->glyph->outline, &che->nurbsbase, vfd->scale);
che->index = charcode;
che->width = face->glyph->advance.x * vfd->scale;
BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che);
/* And everything went ok */
return che;
}
@ -393,8 +349,6 @@ VFontData *BKE_vfontdata_copy(const VFontData *vfont_src, const int UNUSED(flag)
VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong character)
{
VChar *che = NULL;
if (!vfont) {
return NULL;
}
@ -407,10 +361,17 @@ VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong character)
return NULL;
}
FT_Face face = vfont_face_load_from_packed_file(library, vfont->temp_pf);
if (!face) {
FT_Done_FreeType(library);
return NULL;
}
/* Load the character */
che = objchr_to_ftvfontdata(library, vfont, character);
VChar *che = freetypechar_to_vchar(face, character, vfont->data);
/* Free Freetype */
FT_Done_Face(face);
FT_Done_FreeType(library);
return che;

View File

@ -94,10 +94,15 @@ float avg(vec2 v) { return dot(vec2(1.0 / 2.0), v); }
float avg(vec3 v) { return dot(vec3(1.0 / 3.0), v); }
float avg(vec4 v) { return dot(vec4(1.0 / 4.0), v); }
/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */
#ifndef GPU_SHADER_MATH_BASE_LIB_GLSL
float safe_rcp(float a) { return (a != 0.0) ? (1.0 / a) : 0.0; }
#endif
#ifndef GPU_SHADER_MATH_VECTOR_LIB_GLSL
vec2 safe_rcp(vec2 a) { return select(vec2(0.0), (1.0 / a), notEqual(a, vec2(0.0))); }
vec3 safe_rcp(vec3 a) { return select(vec3(0.0), (1.0 / a), notEqual(a, vec3(0.0))); }
vec4 safe_rcp(vec4 a) { return select(vec4(0.0), (1.0 / a), notEqual(a, vec4(0.0))); }
#endif
float safe_sqrt(float a) { return sqrt(max(a, 0.0)); }
@ -206,7 +211,6 @@ float distance_squared(vec3 a, vec3 b)
a -= b;
return dot(a, a);
}
#endif
vec3 safe_normalize(vec3 v)
{
@ -216,6 +220,7 @@ vec3 safe_normalize(vec3 v)
}
return v / len;
}
#endif
vec2 safe_normalize_len(vec2 v, out float len)
{
@ -226,11 +231,14 @@ vec2 safe_normalize_len(vec2 v, out float len)
return v / len;
}
/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */
#ifndef GPU_SHADER_MATH_VECTOR_LIB_GLSL
vec2 safe_normalize(vec2 v)
{
float len;
return safe_normalize_len(v, len);
}
#endif
vec3 normalize_len(vec3 v, out float len)
{

View File

@ -122,7 +122,7 @@ static bool ui_but_is_unit_radians(const uiBut *but)
/* ************* window matrix ************** */
void ui_block_to_region_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
void ui_block_to_region_fl(const ARegion *region, const uiBlock *block, float *r_x, float *r_y)
{
const int getsizex = BLI_rcti_size_x(&region->winrct) + 1;
const int getsizey = BLI_rcti_size_y(&region->winrct) + 1;
@ -141,14 +141,14 @@ void ui_block_to_region_fl(const ARegion *region, uiBlock *block, float *r_x, fl
block->winmat[3][1]));
}
void ui_block_to_window_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
void ui_block_to_window_fl(const ARegion *region, const uiBlock *block, float *r_x, float *r_y)
{
ui_block_to_region_fl(region, block, r_x, r_y);
*r_x += region->winrct.xmin;
*r_y += region->winrct.ymin;
}
void ui_block_to_window(const ARegion *region, uiBlock *block, int *r_x, int *r_y)
void ui_block_to_window(const ARegion *region, const uiBlock *block, int *r_x, int *r_y)
{
float fx = *r_x;
float fy = *r_y;
@ -160,7 +160,7 @@ void ui_block_to_window(const ARegion *region, uiBlock *block, int *r_x, int *r_
}
void ui_block_to_region_rctf(const ARegion *region,
uiBlock *block,
const uiBlock *block,
rctf *rct_dst,
const rctf *rct_src)
{
@ -170,7 +170,7 @@ void ui_block_to_region_rctf(const ARegion *region,
}
void ui_block_to_window_rctf(const ARegion *region,
uiBlock *block,
const uiBlock *block,
rctf *rct_dst,
const rctf *rct_src)
{
@ -179,7 +179,7 @@ void ui_block_to_window_rctf(const ARegion *region,
ui_block_to_window_fl(region, block, &rct_dst->xmax, &rct_dst->ymax);
}
float ui_block_to_window_scale(const ARegion *region, uiBlock *block)
float ui_block_to_window_scale(const ARegion *region, const uiBlock *block)
{
/* We could have function for this to avoid dummy arg. */
float min_y = 0, max_y = 1;
@ -190,7 +190,7 @@ float ui_block_to_window_scale(const ARegion *region, uiBlock *block)
return max_y - min_y;
}
void ui_window_to_block_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
void ui_window_to_block_fl(const ARegion *region, const uiBlock *block, float *r_x, float *r_y)
{
const int getsizex = BLI_rcti_size_x(&region->winrct) + 1;
const int getsizey = BLI_rcti_size_y(&region->winrct) + 1;
@ -218,7 +218,7 @@ void ui_window_to_block_fl(const ARegion *region, uiBlock *block, float *r_x, fl
}
void ui_window_to_block_rctf(const ARegion *region,
uiBlock *block,
const uiBlock *block,
rctf *rct_dst,
const rctf *rct_src)
{
@ -227,7 +227,7 @@ void ui_window_to_block_rctf(const ARegion *region,
ui_window_to_block_fl(region, block, &rct_dst->xmax, &rct_dst->ymax);
}
void ui_window_to_block(const ARegion *region, uiBlock *block, int *r_x, int *r_y)
void ui_window_to_block(const ARegion *region, const uiBlock *block, int *r_x, int *r_y)
{
float fx = *r_x;
float fy = *r_y;

View File

@ -595,25 +595,25 @@ struct uiSafetyRct {
void ui_fontscale(float *points, float aspect);
void ui_block_to_region_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y);
void ui_block_to_window_fl(const ARegion *region, uiBlock *block, float *x, float *y);
void ui_block_to_window(const ARegion *region, uiBlock *block, int *x, int *y);
void ui_block_to_region_fl(const ARegion *region, const uiBlock *block, float *r_x, float *r_y);
void ui_block_to_window_fl(const ARegion *region, const uiBlock *block, float *x, float *y);
void ui_block_to_window(const ARegion *region, const uiBlock *block, int *x, int *y);
void ui_block_to_region_rctf(const ARegion *region,
uiBlock *block,
const uiBlock *block,
rctf *rct_dst,
const rctf *rct_src);
void ui_block_to_window_rctf(const ARegion *region,
uiBlock *block,
const uiBlock *block,
rctf *rct_dst,
const rctf *rct_src);
float ui_block_to_window_scale(const ARegion *region, uiBlock *block);
float ui_block_to_window_scale(const ARegion *region, const uiBlock *block);
/**
* For mouse cursor.
*/
void ui_window_to_block_fl(const ARegion *region, uiBlock *block, float *x, float *y);
void ui_window_to_block(const ARegion *region, uiBlock *block, int *x, int *y);
void ui_window_to_block_fl(const ARegion *region, const uiBlock *block, float *x, float *y);
void ui_window_to_block(const ARegion *region, const uiBlock *block, int *x, int *y);
void ui_window_to_block_rctf(const ARegion *region,
uiBlock *block,
const uiBlock *block,
rctf *rct_dst,
const rctf *rct_src);
void ui_window_to_region(const ARegion *region, int *x, int *y);

View File

@ -1061,9 +1061,7 @@ static void region_azone_scrollbar_init(ScrArea *area,
ARegion *region,
AZScrollDirection direction)
{
rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? region->v2d.vert : region->v2d.hor;
AZone *az = static_cast<AZone *>(MEM_callocN(sizeof(*az), __func__));
float hide_width;
BLI_addtail(&area->actionzones, az);
az->type = AZONE_REGION_SCROLL;
@ -1072,20 +1070,13 @@ static void region_azone_scrollbar_init(ScrArea *area,
if (direction == AZ_SCROLL_VERT) {
az->region->v2d.alpha_vert = 0;
hide_width = V2D_SCROLL_HIDE_HEIGHT;
}
else if (direction == AZ_SCROLL_HOR) {
az->region->v2d.alpha_hor = 0;
hide_width = V2D_SCROLL_HIDE_WIDTH;
}
BLI_rcti_translate(&scroller_vert, region->winrct.xmin, region->winrct.ymin);
az->x1 = scroller_vert.xmin - ((direction == AZ_SCROLL_VERT) ? hide_width : 0);
az->y1 = scroller_vert.ymin - ((direction == AZ_SCROLL_HOR) ? hide_width : 0);
az->x2 = scroller_vert.xmax + ((direction == AZ_SCROLL_VERT) ? hide_width : 0);
az->y2 = scroller_vert.ymax + ((direction == AZ_SCROLL_HOR) ? hide_width : 0);
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
/* No need to specify rect for scrollbar az. For intersection we'll test against the area around
* the region's scroller instead, in `area_actionzone_get_rect`. */
}
static void region_azones_scrollbars_init(ScrArea *area, ARegion *region)
@ -3131,11 +3122,14 @@ void ED_region_panels_draw(const bContext *C, ARegion *region)
/* scrollers */
bool use_mask = false;
rcti mask;
if (region->runtime.category && (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_RIGHT))
if (region->runtime.category &&
(RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_RIGHT) &&
UI_panel_category_is_visible(region))
{
use_mask = true;
UI_view2d_mask_from_win(v2d, &mask);
mask.xmax -= UI_PANEL_CATEGORY_MARGIN_WIDTH;
mask.xmax -= round_fl_to_int(UI_view2d_scale_get_x(&region->v2d) *
UI_PANEL_CATEGORY_MARGIN_WIDTH);
}
bool use_full_hide = false;
if (region->overlap) {

View File

@ -817,15 +817,35 @@ static bool azone_clipped_rect_calc(const AZone *az, rcti *r_rect_clip)
return false;
}
/* Return the azone's calculated rect. */
static void area_actionzone_get_rect(AZone *az, rcti *rect)
{
if (az->type == AZONE_REGION_SCROLL) {
/* For scroll azones use the area around the region's scrollbar location. */
rcti scroller_vert = (az->direction == AZ_SCROLL_HOR) ? az->region->v2d.hor :
az->region->v2d.vert;
BLI_rcti_translate(&scroller_vert, az->region->winrct.xmin, az->region->winrct.ymin);
rect->xmin = scroller_vert.xmin - ((az->direction == AZ_SCROLL_VERT) ? V2D_SCROLL_HIDE_HEIGHT : 0);
rect->ymin = scroller_vert.ymin -
((az->direction == AZ_SCROLL_HOR) ? V2D_SCROLL_HIDE_WIDTH : 0);
rect->xmax = scroller_vert.xmax +
((az->direction == AZ_SCROLL_VERT) ? V2D_SCROLL_HIDE_HEIGHT : 0);
rect->ymax = scroller_vert.ymax +
((az->direction == AZ_SCROLL_HOR) ? V2D_SCROLL_HIDE_WIDTH : 0);
}
else {
azone_clipped_rect_calc(az, rect);
}
}
static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const bool test_only)
{
AZone *az = NULL;
for (az = area->actionzones.first; az; az = az->next) {
rcti az_rect_clip;
if (BLI_rcti_isect_pt_v(&az->rect, xy) &&
/* Check clipping if this is clipped */
(!azone_clipped_rect_calc(az, &az_rect_clip) || BLI_rcti_isect_pt_v(&az_rect_clip, xy)))
rcti az_rect;
area_actionzone_get_rect(az, &az_rect);
if (BLI_rcti_isect_pt_v(&az_rect, xy))
{
if (az->type == AZONE_AREA) {
@ -915,16 +935,14 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b
float dist_fac = 0.0f, alpha = 0.0f;
if (az->direction == AZ_SCROLL_HOR) {
float hide_width = (az->y2 - az->y1) / 2.0f;
dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / hide_width;
dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / V2D_SCROLL_HIDE_WIDTH;
CLAMP(dist_fac, 0.0f, 1.0f);
alpha = 1.0f - dist_fac;
v2d->alpha_hor = alpha * 255;
}
else if (az->direction == AZ_SCROLL_VERT) {
float hide_width = (az->x2 - az->x1) / 2.0f;
dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / hide_width;
dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / V2D_SCROLL_HIDE_HEIGHT;
CLAMP(dist_fac, 0.0f, 1.0f);
alpha = 1.0f - dist_fac;

View File

@ -346,15 +346,6 @@ void split_edges(Mesh &mesh,
});
/* Step 1: Split the edges. */
threading::parallel_for(mask.index_range(), 512, [&](IndexRange range) {
for (const int mask_i : range) {
const int edge_i = mask[mask_i];
split_edge_per_poly(edge_i, edge_offsets[edge_i], edge_to_loop_map, corner_edges);
}
});
/* Step 1: Split the edges. */
mask.foreach_index([&](const int edge_i) {
split_edge_per_poly(edge_i, edge_offsets[edge_i], edge_to_loop_map, corner_edges);
});

View File

@ -139,6 +139,15 @@ float safe_divide(float a, float b)
return (b != 0.0) ? (a / b) : 0.0;
}
/**
* Safe reciprocal function. Returns `1/a`.
* If `a` equal 0 the result will be 0.
*/
float safe_rcp(float a)
{
return (a != 0.0) ? (1.0 / a) : 0.0;
}
/**
* Return true if the difference between`a` and `b` is below the `epsilon` value.
*/

View File

@ -123,6 +123,21 @@ vec2 normalize_and_get_length(vec2 vector, out float out_length);
vec3 normalize_and_get_length(vec3 vector, out float out_length);
vec4 normalize_and_get_length(vec4 vector, out float out_length);
/**
* Return normalized version of the `vector` or a default normalized vector if `vector` is invalid.
*/
vec2 safe_normalize(vec2 vector);
vec3 safe_normalize(vec3 vector);
vec4 safe_normalize(vec4 vector);
/**
* Safe reciprocal function. Returns `1/a`.
* If `a` equal 0 the result will be 0.
*/
vec2 safe_rcp(vec2 a);
vec3 safe_rcp(vec3 a);
vec4 safe_rcp(vec4 a);
/**
* Per component linear interpolation.
*/
@ -443,6 +458,72 @@ vec4 normalize_and_get_length(vec4 vector, out float out_length)
return vec4(0.0);
}
vec2 safe_normalize_and_get_length(vec2 vector, out float out_length)
{
out_length = length_squared(vector);
const float threshold = 1e-35f;
if (out_length > threshold) {
out_length = sqrt(out_length);
return vector / out_length;
}
/* Either the vector is small or one of it's values contained `nan`. */
out_length = 1.0;
return vec2(1.0, 0.0);
}
vec3 safe_normalize_and_get_length(vec3 vector, out float out_length)
{
out_length = length_squared(vector);
const float threshold = 1e-35f;
if (out_length > threshold) {
out_length = sqrt(out_length);
return vector / out_length;
}
/* Either the vector is small or one of it's values contained `nan`. */
out_length = 1.0;
return vec3(1.0, 0.0, 0.0);
}
vec4 safe_normalize_and_get_length(vec4 vector, out float out_length)
{
out_length = length_squared(vector);
const float threshold = 1e-35f;
if (out_length > threshold) {
out_length = sqrt(out_length);
return vector / out_length;
}
/* Either the vector is small or one of it's values contained `nan`. */
out_length = 1.0;
return vec4(1.0, 0.0, 0.0, 0.0);
}
vec2 safe_normalize(vec2 vector)
{
float unused_length;
return safe_normalize_and_get_length(vector, unused_length);
}
vec3 safe_normalize(vec3 vector)
{
float unused_length;
return safe_normalize_and_get_length(vector, unused_length);
}
vec4 safe_normalize(vec4 vector)
{
float unused_length;
return safe_normalize_and_get_length(vector, unused_length);
}
vec2 safe_rcp(vec2 a)
{
return select(vec2(0.0), (1.0 / a), notEqual(a, vec2(0.0)));
}
vec3 safe_rcp(vec3 a)
{
return select(vec3(0.0), (1.0 / a), notEqual(a, vec3(0.0)));
}
vec4 safe_rcp(vec4 a)
{
return select(vec4(0.0), (1.0 / a), notEqual(a, vec4(0.0)));
}
vec2 interpolate(vec2 a, vec2 b, float t)
{
return mix(a, b, t);

View File

@ -305,7 +305,9 @@ static void seq_retiming_offset_linear_handle(const Scene *scene,
* length.
* Alternative solution is to find where in arc segment the `y` value is closest to `handle`
* retiming factor, then trim transition to that point. This would change transition length. */
if (SEQ_retiming_handle_is_transition_type(handle - 2)) {
if (SEQ_retiming_handle_index_get(seq, handle) > 1 &&
SEQ_retiming_handle_is_transition_type(handle - 2))
{
SeqRetimingHandle *transition_handle = handle - 2;
const int transition_offset = transition_handle->strip_frame_index -