WIP: Snapping Redesign: Defaults | Navigation | Drawing | Removals #109062
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(®ion->winrct) + 1;
|
||||
const int getsizey = BLI_rcti_size_y(®ion->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(®ion->winrct) + 1;
|
||||
const int getsizey = BLI_rcti_size_y(®ion->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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(®ion->v2d) *
|
||||
UI_PANEL_CATEGORY_MARGIN_WIDTH);
|
||||
}
|
||||
bool use_full_hide = false;
|
||||
if (region->overlap) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 -
|
||||
|
|
Loading…
Reference in New Issue