Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-11-22 23:01:42 +0300
committerHans Goudey <h.goudey@me.com>2020-11-22 23:01:42 +0300
commit8aea0e8ac2fbc4486229a7cba5b8461ea6d8d7c1 (patch)
tree90bd7ebfe1055ecd304b3d39acdfc17a8c281ea2
parent2ce1b89d7561cca01f9b36a4b55d6c709c7e5d9d (diff)
parent4c01fbb564f5ada3f666af5ac36ca981667b3414 (diff)
Merge branch 'master' into geometry-nodes
-rw-r--r--source/blender/blenkernel/intern/displist.c310
-rw-r--r--source/blender/blenlib/BLI_double2.hh1
-rw-r--r--source/blender/blenlib/BLI_mpq2.hh1
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.cc354
-rw-r--r--source/blender/blenlib/intern/math_vec.cc16
-rw-r--r--source/blender/blenlib/tests/BLI_delaunay_2d_test.cc3
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c8
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c3
-rw-r--r--source/blender/editors/interface/interface_widgets.c271
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c6
10 files changed, 569 insertions, 404 deletions
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index f5257eb12ab..5220d5be2ca 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1290,20 +1290,18 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
BKE_nurbList_free(&nubase);
}
-static void rotateBevelPiece(Curve *cu,
- BevPoint *bevp,
- BevPoint *nbevp,
- DispList *dlb,
- float bev_blend,
- float widfac,
- float fac,
+static void rotateBevelPiece(const Curve *cu,
+ const BevPoint *bevp,
+ const BevPoint *nbevp,
+ const DispList *dlb,
+ const float bev_blend,
+ const float widfac,
+ const float radius_factor,
float **r_data)
{
- float *fp, *data = *r_data;
- int b;
-
- fp = dlb->verts;
- for (b = 0; b < dlb->nr; b++, fp += 3, data += 3) {
+ float *data = *r_data;
+ const float *fp = dlb->verts;
+ for (int b = 0; b < dlb->nr; b++, fp += 3, data += 3) {
if (cu->flag & CU_3D) {
float vec[3], quat[4];
@@ -1322,9 +1320,9 @@ static void rotateBevelPiece(Curve *cu,
mul_qt_v3(quat, vec);
- data[0] += fac * vec[0];
- data[1] += fac * vec[1];
- data[2] += fac * vec[2];
+ data[0] += radius_factor * vec[0];
+ data[1] += radius_factor * vec[1];
+ data[2] += radius_factor * vec[2];
}
else {
float sina, cosa;
@@ -1344,9 +1342,9 @@ static void rotateBevelPiece(Curve *cu,
cosa = nbevp->cosa * bev_blend + bevp->cosa * (1.0f - bev_blend);
}
- data[0] += fac * (widfac + fp[1]) * sina;
- data[1] += fac * (widfac + fp[1]) * cosa;
- data[2] += fac * fp[2];
+ data[0] += radius_factor * (widfac + fp[1]) * sina;
+ data[1] += radius_factor * (widfac + fp[1]) * cosa;
+ data[2] += radius_factor * fp[2];
}
}
@@ -1568,184 +1566,176 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
curve_to_displist(cu, &nubase, dispbase, for_render);
}
else {
- float widfac = cu->width - 1.0f;
+ const float widfac = cu->width - 1.0f;
BevList *bl = ob->runtime.curve_cache->bev.first;
Nurb *nu = nubase.first;
for (; bl && nu; bl = bl->next, nu = nu->next) {
- DispList *dl;
float *data;
- int a;
-
- if (bl->nr) { /* blank bevel lists can happen */
- /* exception handling; curve without bevel or extrude, with width correction */
- if (BLI_listbase_is_empty(&dlbev)) {
- BevPoint *bevp;
- dl = MEM_callocN(sizeof(DispList), "makeDispListbev");
- dl->verts = MEM_mallocN(sizeof(float[3]) * bl->nr, "dlverts");
- BLI_addtail(dispbase, dl);
+ if (bl->nr == 0) { /* blank bevel lists can happen */
+ continue;
+ }
- if (bl->poly != -1) {
- dl->type = DL_POLY;
- }
- else {
- dl->type = DL_SEGM;
- }
+ /* exception handling; curve without bevel or extrude, with width correction */
+ if (BLI_listbase_is_empty(&dlbev)) {
+ DispList *dl = MEM_callocN(sizeof(DispList), "makeDispListbev");
+ dl->verts = MEM_mallocN(sizeof(float[3]) * bl->nr, "dlverts");
+ BLI_addtail(dispbase, dl);
- if (dl->type == DL_SEGM) {
- dl->flag = (DL_FRONT_CURVE | DL_BACK_CURVE);
- }
+ if (bl->poly != -1) {
+ dl->type = DL_POLY;
+ }
+ else {
+ dl->type = DL_SEGM;
+ dl->flag = (DL_FRONT_CURVE | DL_BACK_CURVE);
+ }
- dl->parts = 1;
- dl->nr = bl->nr;
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
+ dl->parts = 1;
+ dl->nr = bl->nr;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
- /* dl->rt will be used as flag for render face and */
- /* CU_2D conflicts with R_NOPUNOFLIP */
- dl->rt = nu->flag & ~CU_2D;
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt = nu->flag & ~CU_2D;
- a = dl->nr;
- bevp = bl->bevpoints;
- data = dl->verts;
- while (a--) {
- data[0] = bevp->vec[0] + widfac * bevp->sina;
- data[1] = bevp->vec[1] + widfac * bevp->cosa;
- data[2] = bevp->vec[2];
- bevp++;
- data += 3;
- }
+ int a = dl->nr;
+ BevPoint *bevp = bl->bevpoints;
+ data = dl->verts;
+ while (a--) {
+ data[0] = bevp->vec[0] + widfac * bevp->sina;
+ data[1] = bevp->vec[1] + widfac * bevp->cosa;
+ data[2] = bevp->vec[2];
+ bevp++;
+ data += 3;
+ }
+ }
+ else {
+ ListBase bottom_capbase = {NULL, NULL};
+ ListBase top_capbase = {NULL, NULL};
+ float bottom_no[3] = {0.0f};
+ float top_no[3] = {0.0f};
+ float first_blend = 0.0f, last_blend = 0.0f;
+ int start, steps = 0;
+
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ calc_bevfac_mapping_default(bl, &start, &first_blend, &steps, &last_blend);
}
else {
- DispList *dlb;
- ListBase bottom_capbase = {NULL, NULL};
- ListBase top_capbase = {NULL, NULL};
- float bottom_no[3] = {0.0f};
- float top_no[3] = {0.0f};
- float firstblend = 0.0f, lastblend = 0.0f;
- int i, start, steps = 0;
-
- if (nu->flagu & CU_NURB_CYCLIC) {
- calc_bevfac_mapping_default(bl, &start, &firstblend, &steps, &lastblend);
+ if (fabsf(cu->bevfac2 - cu->bevfac1) < FLT_EPSILON) {
+ continue;
}
- else {
- if (fabsf(cu->bevfac2 - cu->bevfac1) < FLT_EPSILON) {
- continue;
- }
- calc_bevfac_mapping(cu, bl, nu, &start, &firstblend, &steps, &lastblend);
- }
+ calc_bevfac_mapping(cu, bl, nu, &start, &first_blend, &steps, &last_blend);
+ }
- for (dlb = dlbev.first; dlb; dlb = dlb->next) {
- BevPoint *bevp_first, *bevp_last;
- BevPoint *bevp;
+ LISTBASE_FOREACH (DispList *, dlb, &dlbev) {
+ /* for each part of the bevel use a separate displblock */
+ DispList *dl = MEM_callocN(sizeof(DispList), "makeDispListbev1");
+ dl->verts = data = MEM_mallocN(sizeof(float[3]) * dlb->nr * steps, "dlverts");
+ BLI_addtail(dispbase, dl);
- /* for each part of the bevel use a separate displblock */
- dl = MEM_callocN(sizeof(DispList), "makeDispListbev1");
- dl->verts = data = MEM_mallocN(sizeof(float[3]) * dlb->nr * steps, "dlverts");
- BLI_addtail(dispbase, dl);
+ dl->type = DL_SURF;
- dl->type = DL_SURF;
+ dl->flag = dlb->flag & (DL_FRONT_CURVE | DL_BACK_CURVE);
+ if (dlb->type == DL_POLY) {
+ dl->flag |= DL_CYCL_U;
+ }
+ if ((bl->poly >= 0) && (steps > 2)) {
+ dl->flag |= DL_CYCL_V;
+ }
- dl->flag = dlb->flag & (DL_FRONT_CURVE | DL_BACK_CURVE);
- if (dlb->type == DL_POLY) {
- dl->flag |= DL_CYCL_U;
- }
- if ((bl->poly >= 0) && (steps > 2)) {
- dl->flag |= DL_CYCL_V;
- }
+ dl->parts = steps;
+ dl->nr = dlb->nr;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
- dl->parts = steps;
- dl->nr = dlb->nr;
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt = nu->flag & ~CU_2D;
- /* dl->rt will be used as flag for render face and */
- /* CU_2D conflicts with R_NOPUNOFLIP */
- dl->rt = nu->flag & ~CU_2D;
+ dl->bevel_split = BLI_BITMAP_NEW(steps, "bevel_split");
- dl->bevel_split = BLI_BITMAP_NEW(steps, "bevel_split");
+ /* for each point of poly make a bevel piece */
+ BevPoint *bevp_first = bl->bevpoints;
+ BevPoint *bevp_last = &bl->bevpoints[bl->nr - 1];
+ BevPoint *bevp = &bl->bevpoints[start];
+ for (int i = start, a = 0; a < steps; i++, bevp++, a++) {
+ float radius_factor = 1.0;
+ float *cur_data = data;
- /* for each point of poly make a bevel piece */
- bevp_first = bl->bevpoints;
- bevp_last = &bl->bevpoints[bl->nr - 1];
- bevp = &bl->bevpoints[start];
- for (i = start, a = 0; a < steps; i++, bevp++, a++) {
- float fac = 1.0;
- float *cur_data = data;
+ if (cu->taperobj == NULL) {
+ radius_factor = bevp->radius;
+ }
+ else {
+ float taper_factor;
+ if (cu->flag & CU_MAP_TAPER) {
+ float len = (steps - 3) + first_blend + last_blend;
- if (cu->taperobj == NULL) {
- fac = bevp->radius;
- }
- else {
- float len, taper_fac;
-
- if (cu->flag & CU_MAP_TAPER) {
- len = (steps - 3) + firstblend + lastblend;
-
- if (a == 0) {
- taper_fac = 0.0f;
- }
- else if (a == steps - 1) {
- taper_fac = 1.0f;
- }
- else {
- taper_fac = ((float)a - (1.0f - firstblend)) / len;
- }
+ if (a == 0) {
+ taper_factor = 0.0f;
+ }
+ else if (a == steps - 1) {
+ taper_factor = 1.0f;
}
else {
- len = bl->nr - 1;
- taper_fac = (float)i / len;
-
- if (a == 0) {
- taper_fac += (1.0f - firstblend) / len;
- }
- else if (a == steps - 1) {
- taper_fac -= (1.0f - lastblend) / len;
- }
+ taper_factor = ((float)a - (1.0f - first_blend)) / len;
}
-
- fac = displist_calc_taper(depsgraph, scene, cu->taperobj, taper_fac);
- }
-
- if (bevp->split_tag) {
- BLI_BITMAP_ENABLE(dl->bevel_split, a);
- }
-
- /* rotate bevel piece and write in data */
- if ((a == 0) && (bevp != bevp_last)) {
- rotateBevelPiece(cu, bevp, bevp + 1, dlb, 1.0f - firstblend, widfac, fac, &data);
- }
- else if ((a == steps - 1) && (bevp != bevp_first)) {
- rotateBevelPiece(cu, bevp, bevp - 1, dlb, 1.0f - lastblend, widfac, fac, &data);
}
else {
- rotateBevelPiece(cu, bevp, NULL, dlb, 0.0f, widfac, fac, &data);
- }
+ float len = bl->nr - 1;
+ taper_factor = (float)i / len;
- if ((cu->flag & CU_FILL_CAPS) && !(nu->flagu & CU_NURB_CYCLIC)) {
- if (a == 1) {
- fillBevelCap(nu, dlb, cur_data - 3 * dlb->nr, &bottom_capbase);
- copy_v3_v3(bottom_no, bevp->dir);
+ if (a == 0) {
+ taper_factor += (1.0f - first_blend) / len;
}
- if (a == steps - 1) {
- fillBevelCap(nu, dlb, cur_data, &top_capbase);
- negate_v3_v3(top_no, bevp->dir);
+ else if (a == steps - 1) {
+ taper_factor -= (1.0f - last_blend) / len;
}
}
+
+ radius_factor = displist_calc_taper(depsgraph, scene, cu->taperobj, taper_factor);
}
- /* gl array drawing: using indices */
- displist_surf_indices(dl);
- }
+ if (bevp->split_tag) {
+ BLI_BITMAP_ENABLE(dl->bevel_split, a);
+ }
+
+ /* rotate bevel piece and write in data */
+ if ((a == 0) && (bevp != bevp_last)) {
+ rotateBevelPiece(
+ cu, bevp, bevp + 1, dlb, 1.0f - first_blend, widfac, radius_factor, &data);
+ }
+ else if ((a == steps - 1) && (bevp != bevp_first)) {
+ rotateBevelPiece(
+ cu, bevp, bevp - 1, dlb, 1.0f - last_blend, widfac, radius_factor, &data);
+ }
+ else {
+ rotateBevelPiece(cu, bevp, NULL, dlb, 0.0f, widfac, radius_factor, &data);
+ }
- if (bottom_capbase.first) {
- BKE_displist_fill(&bottom_capbase, dispbase, bottom_no, false);
- BKE_displist_fill(&top_capbase, dispbase, top_no, false);
- BKE_displist_free(&bottom_capbase);
- BKE_displist_free(&top_capbase);
+ if ((cu->flag & CU_FILL_CAPS) && !(nu->flagu & CU_NURB_CYCLIC)) {
+ if (a == 1) {
+ fillBevelCap(nu, dlb, cur_data - 3 * dlb->nr, &bottom_capbase);
+ copy_v3_v3(bottom_no, bevp->dir);
+ }
+ if (a == steps - 1) {
+ fillBevelCap(nu, dlb, cur_data, &top_capbase);
+ negate_v3_v3(top_no, bevp->dir);
+ }
+ }
}
+
+ /* gl array drawing: using indices */
+ displist_surf_indices(dl);
+ }
+
+ if (bottom_capbase.first) {
+ BKE_displist_fill(&bottom_capbase, dispbase, bottom_no, false);
+ BKE_displist_fill(&top_capbase, dispbase, top_no, false);
+ BKE_displist_free(&bottom_capbase);
+ BKE_displist_free(&top_capbase);
}
}
}
@@ -1761,9 +1751,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) {
calc_curvepath(ob, &nubase);
}
- }
- if (!for_orco) {
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
curve_calc_modifiers_post(
depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, force_mesh_conversion);
diff --git a/source/blender/blenlib/BLI_double2.hh b/source/blender/blenlib/BLI_double2.hh
index 313afd06d1b..621ac4d01fc 100644
--- a/source/blender/blenlib/BLI_double2.hh
+++ b/source/blender/blenlib/BLI_double2.hh
@@ -131,7 +131,6 @@ struct double2 {
LINE_LINE_CROSS = 2,
} kind;
double lambda;
- double mu;
};
static isect_result isect_seg_seg(const double2 &v1,
diff --git a/source/blender/blenlib/BLI_mpq2.hh b/source/blender/blenlib/BLI_mpq2.hh
index 6261b50466b..40e227019ce 100644
--- a/source/blender/blenlib/BLI_mpq2.hh
+++ b/source/blender/blenlib/BLI_mpq2.hh
@@ -167,7 +167,6 @@ struct mpq2 {
LINE_LINE_CROSS = 2,
} kind;
mpq_class lambda;
- mpq_class mu;
};
static isect_result isect_seg_seg(const mpq2 &v1,
diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc
index daa006fd5cc..f0b65a55816 100644
--- a/source/blender/blenlib/intern/delaunay_2d.cc
+++ b/source/blender/blenlib/intern/delaunay_2d.cc
@@ -117,11 +117,84 @@ template<typename T> inline SymEdge<T> *prev(const SymEdge<T> *se)
return se->rot->next->rot;
}
-template<typename Arith_t> struct CDTVert {
+/** A coordinate class with extra information for fast filtered orient tests. */
+
+template<typename T> struct FatCo {
+ vec2<T> exact;
+ vec2<double> approx;
+ vec2<double> abs_approx;
+
+ FatCo();
+#ifdef WITH_GMP
+ FatCo(const vec2<mpq_class> &v);
+#endif
+ FatCo(const vec2<double> &v);
+};
+
+#ifdef WITH_GMP
+template<> struct FatCo<mpq_class> {
+ vec2<mpq_class> exact;
+ vec2<double> approx;
+ vec2<double> abs_approx;
+
+ FatCo()
+ : exact(vec2<mpq_class>(0, 0)), approx(vec2<double>(0, 0)), abs_approx(vec2<double>(0, 0))
+ {
+ }
+
+ FatCo(const vec2<mpq_class> &v)
+ {
+ exact = v;
+ approx = vec2<double>(v.x.get_d(), v.y.get_d());
+ abs_approx = vec2<double>(fabs(approx.x), fabs(approx.y));
+ }
+
+ FatCo(const vec2<double> &v)
+ {
+ exact = vec2<mpq_class>(v.x, v.y);
+ approx = v;
+ abs_approx = vec2<double>(fabs(approx.x), fabs(approx.y));
+ }
+};
+#endif
+
+template<> struct FatCo<double> {
+ vec2<double> exact;
+ vec2<double> approx;
+ vec2<double> abs_approx;
+
+ FatCo() : exact(vec2<double>(0, 0)), approx(vec2<double>(0, 0)), abs_approx(vec2<double>(0, 0))
+ {
+ }
+
+#ifdef WITH_GMP
+ FatCo(const vec2<mpq_class> &v)
+ {
+ exact = vec2<double>(v.x.get_d(), v.y.get_d());
+ approx = exact;
+ abs_approx = vec2<double>(fabs(approx.x), fabs(approx.y));
+ }
+#endif
+
+ FatCo(const vec2<double> &v)
+ {
+ exact = v;
+ approx = v;
+ abs_approx = vec2<double>(fabs(approx.x), fabs(approx.y));
+ }
+};
+
+template<typename T> std::ostream &operator<<(std::ostream &stream, const FatCo<T> &co)
+{
+ stream << "(" << co.approx.x << ", " << co.approx.y << ")";
+ return stream;
+}
+
+template<typename T> struct CDTVert {
/** Coordinate. */
- vec2<Arith_t> co;
+ FatCo<T> co;
/** Some edge attached to it. */
- SymEdge<Arith_t> *symedge{nullptr};
+ SymEdge<T> *symedge{nullptr};
/** List of corresponding vertex input ids. */
LinkNode *input_ids{nullptr};
/** Index into array that #CDTArrangement keeps. */
@@ -132,7 +205,7 @@ template<typename Arith_t> struct CDTVert {
int visit_index{0};
CDTVert() = default;
- explicit CDTVert(const vec2<Arith_t> &pt);
+ explicit CDTVert(const vec2<T> &pt);
};
template<typename Arith_t> struct CDTEdge {
@@ -431,7 +504,7 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
vec2<double> vmax(-DBL_MAX, -DBL_MAX);
for (const CDTVert<T> *v : cdt.verts) {
for (int i = 0; i < 2; ++i) {
- double dvi = math_to_double(v->co[i]);
+ double dvi = v->co.approx[i];
if (dvi < vmin[i]) {
vmin[i] = dvi;
}
@@ -457,8 +530,8 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
}
double scale = view_width / width;
-# define SX(x) ((math_to_double(x) - minx) * scale)
-# define SY(y) ((maxy - math_to_double(y)) * scale)
+# define SX(x) (((x)-minx) * scale)
+# define SY(y) ((maxy - (y)) * scale)
std::ofstream f;
if (append) {
@@ -485,8 +558,8 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
}
const CDTVert<T> *u = e->symedges[0].vert;
const CDTVert<T> *v = e->symedges[1].vert;
- const vec2<T> &uco = u->co;
- const vec2<T> &vco = v->co;
+ const vec2<double> &uco = u->co.approx;
+ const vec2<double> &vco = v->co.approx;
int strokew = e->input_ids == nullptr ? thin_line : thick_line;
f << "<line fill=\"none\" stroke=\"black\" stroke-width=\"" << strokew << "\" x1=\""
<< SX(uco[0]) << "\" y1=\"" << SY(uco[1]) << "\" x2=\"" << SX(vco[0]) << "\" y2=\""
@@ -503,13 +576,13 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
int i = 0;
for (const CDTVert<T> *v : cdt.verts) {
- f << "<circle fill=\"black\" cx=\"" << SX(v->co[0]) << "\" cy=\"" << SY(v->co[1]) << "\" r=\""
- << vert_radius << "\">\n";
- f << " <title>[" << i << "]" << v->co << "</title>\n";
+ f << "<circle fill=\"black\" cx=\"" << SX(v->co.approx[0]) << "\" cy=\"" << SY(v->co.approx[1])
+ << "\" r=\"" << vert_radius << "\">\n";
+ f << " <title>[" << i << "]" << v->co.approx << "</title>\n";
f << "</circle>\n";
if (draw_vert_labels) {
- f << "<text x=\"" << SX(v->co[0]) + vert_radius << "\" y=\"" << SY(v->co[1]) - vert_radius
- << "\" font-size=\"small\">[" << i << "]</text>\n";
+ f << "<text x=\"" << SX(v->co.approx[0]) + vert_radius << "\" y=\""
+ << SY(v->co.approx[1]) - vert_radius << "\" font-size=\"small\">[" << i << "]</text>\n";
}
++i;
}
@@ -521,24 +594,167 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
#endif
/**
+ * A filtered version of orient2d, which will usually be much faster when using exact arithmetic.
+ * See EXACT GEOMETRIC COMPUTATION USING CASCADING, by Burnikel, Funke, and Seel.
+ */
+template<typename T>
+static int filtered_orient2d(const FatCo<T> &a, const FatCo<T> &b, const FatCo<T> &c);
+
+#ifdef WITH_GMP
+template<>
+int filtered_orient2d<mpq_class>(const FatCo<mpq_class> &a,
+ const FatCo<mpq_class> &b,
+ const FatCo<mpq_class> &c)
+{
+ double det = (a.approx[0] - c.approx[0]) * (b.approx[1] - c.approx[1]) -
+ (a.approx[1] - c.approx[1]) * (b.approx[0] - c.approx[0]);
+ double supremum = (a.abs_approx[0] + c.abs_approx[0]) * (b.abs_approx[1] + c.abs_approx[1]) +
+ (a.abs_approx[1] + c.abs_approx[1]) * (b.abs_approx[0] + c.abs_approx[0]);
+ constexpr double index_orient2d = 6;
+ double err_bound = supremum * index_orient2d * DBL_EPSILON;
+ if (fabs(det) > err_bound) {
+ return det > 0 ? 1 : -1;
+ }
+ return orient2d(a.exact, b.exact, c.exact);
+}
+#endif
+
+template<>
+int filtered_orient2d<double>(const FatCo<double> &a,
+ const FatCo<double> &b,
+ const FatCo<double> &c)
+{
+ return orient2d(a.approx, b.approx, c.approx);
+}
+
+/**
+ * A filtered version of incircle.
+ */
+template<typename T>
+static int filtered_incircle(const FatCo<T> &a,
+ const FatCo<T> &b,
+ const FatCo<T> &c,
+ const FatCo<T> &d);
+
+#ifdef WITH_GMP
+template<>
+int filtered_incircle<mpq_class>(const FatCo<mpq_class> &a,
+ const FatCo<mpq_class> &b,
+ const FatCo<mpq_class> &c,
+ const FatCo<mpq_class> &d)
+{
+ double adx = a.approx[0] - d.approx[0];
+ double bdx = b.approx[0] - d.approx[0];
+ double cdx = c.approx[0] - d.approx[0];
+ double ady = a.approx[1] - d.approx[1];
+ double bdy = b.approx[1] - d.approx[1];
+ double cdy = c.approx[1] - d.approx[1];
+ double bdxcdy = bdx * cdy;
+ double cdxbdy = cdx * bdy;
+ double alift = adx * adx + ady * ady;
+ double cdxady = cdx * ady;
+ double adxcdy = adx * cdy;
+ double blift = bdx * bdx + bdy * bdy;
+ double adxbdy = adx * bdy;
+ double bdxady = bdx * ady;
+ double clift = cdx * cdx + cdy * cdy;
+ double det = alift * (bdxcdy - cdxbdy) + blift * (cdxady - adxcdy) + clift * (adxbdy - bdxady);
+
+ double sup_adx = a.abs_approx[0] + d.abs_approx[0]; /* index 2. */
+ double sup_bdx = b.abs_approx[0] + d.abs_approx[0];
+ double sup_cdx = c.abs_approx[0] + d.abs_approx[0];
+ double sup_ady = a.abs_approx[1] + d.abs_approx[1];
+ double sup_bdy = b.abs_approx[1] + d.abs_approx[1];
+ double sup_cdy = c.abs_approx[1] + d.abs_approx[1];
+ double sup_bdxcdy = sup_bdx * sup_cdy; /* index 5. */
+ double sup_cdxbdy = sup_cdx * sup_bdy;
+ double sup_alift = sup_adx * sup_adx + sup_ady * sup_ady; /* index 6. */
+ double sup_cdxady = sup_cdx * sup_ady;
+ double sup_adxcdy = sup_adx * sup_cdy;
+ double sup_blift = sup_bdx * sup_bdx + sup_bdy * sup_bdy;
+ double sup_adxbdy = sup_adx * sup_bdy;
+ double sup_bdxady = sup_bdx * sup_ady;
+ double sup_clift = sup_cdx * sup_cdx + sup_cdy * sup_cdy;
+ double sup_det = sup_alift * (sup_bdxcdy + sup_cdxbdy) + sup_blift * (sup_cdxady + sup_adxcdy) +
+ sup_clift * (sup_adxbdy + sup_bdxady);
+ int index = 14;
+ double err_bound = sup_det * index * DBL_EPSILON;
+ if (fabs(det) > err_bound) {
+ return det < 0.0 ? -1 : (det > 0.0 ? 1 : 0);
+ }
+ return incircle(a.exact, b.exact, c.exact, d.exact);
+}
+#endif
+
+template<>
+int filtered_incircle<double>(const FatCo<double> &a,
+ const FatCo<double> &b,
+ const FatCo<double> &c,
+ const FatCo<double> &d)
+{
+ return incircle(a.approx, b.approx, c.approx, d.approx);
+}
+
+/**
* Return true if `a -- b -- c` are in that order, assuming they are on a straight line according
* to #orient2d and we know the order is either `abc` or `bac`.
* This means `ab . ac` and `bc . ac` must both be non-negative.
+ * Use filtering to speed this up when using exact arithmetic.
*/
-template<typename T> bool in_line(const vec2<T> &a, const vec2<T> &b, const vec2<T> &c)
+template<typename T> static bool in_line(const FatCo<T> &a, const FatCo<T> &b, const FatCo<T> &c);
+
+#ifdef WITH_GMP
+template<>
+bool in_line<mpq_class>(const FatCo<mpq_class> &a,
+ const FatCo<mpq_class> &b,
+ const FatCo<mpq_class> &c)
+{
+ vec2<double> ab = b.approx - a.approx;
+ vec2<double> bc = c.approx - b.approx;
+ vec2<double> ac = c.approx - a.approx;
+ vec2<double> supremum_ab = b.abs_approx + a.abs_approx;
+ vec2<double> supremum_bc = c.abs_approx + b.abs_approx;
+ vec2<double> supremum_ac = c.abs_approx + a.abs_approx;
+ double dot_ab_ac = ab.x * ac.x + ab.y * ac.y;
+ double supremum_dot_ab_ac = supremum_ab.x * supremum_ac.x + supremum_ab.y * supremum_ac.y;
+ constexpr double index = 6;
+ double err_bound = supremum_dot_ab_ac * index * DBL_EPSILON;
+ if (dot_ab_ac < -err_bound) {
+ return false;
+ }
+ double dot_bc_ac = bc.x * ac.x + bc.y * ac.y;
+ double supremum_dot_bc_ac = supremum_bc.x * supremum_ac.x + supremum_bc.y * supremum_ac.y;
+ err_bound = supremum_dot_bc_ac * index * DBL_EPSILON;
+ if (dot_bc_ac < -err_bound) {
+ return false;
+ }
+ vec2<mpq_class> exact_ab = b.exact - a.exact;
+ vec2<mpq_class> exact_ac = c.exact - a.exact;
+ if (vec2<mpq_class>::dot(exact_ab, exact_ac) < 0) {
+ return false;
+ }
+ vec2<mpq_class> exact_bc = c.exact - b.exact;
+ return vec2<mpq_class>::dot(exact_bc, exact_ac) >= 0;
+}
+#endif
+
+template<>
+bool in_line<double>(const FatCo<double> &a, const FatCo<double> &b, const FatCo<double> &c)
{
- vec2<T> ab = b - a;
- vec2<T> bc = c - b;
- vec2<T> ac = c - a;
- if (vec2<T>::dot(ab, ac) < 0) {
+ vec2<double> ab = b.approx - a.approx;
+ vec2<double> ac = c.approx - a.approx;
+ if (vec2<double>::dot(ab, ac) < 0) {
return false;
}
- return vec2<T>::dot(bc, ac) >= 0;
+ vec2<double> bc = c.approx - b.approx;
+ return vec2<double>::dot(bc, ac) >= 0;
}
-template<typename T> CDTVert<T>::CDTVert(const vec2<T> &pt)
+template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
{
- this->co = pt;
+ this->co.exact = pt;
+ this->co.approx = pt;
+ this->co.abs_approx = pt; /* Not used, so does't matter. */
this->input_ids = nullptr;
this->symedge = nullptr;
this->index = -1;
@@ -546,6 +762,20 @@ template<typename T> CDTVert<T>::CDTVert(const vec2<T> &pt)
this->visit_index = 0;
}
+#ifdef WITH_GMP
+template<> CDTVert<mpq_class>::CDTVert(const vec2<mpq_class> &pt)
+{
+ this->co.exact = pt;
+ this->co.approx = double2(pt.x.get_d(), pt.y.get_d());
+ this->co.abs_approx = double2(fabs(this->co.approx.x), fabs(this->co.approx.y));
+ this->input_ids = nullptr;
+ this->symedge = nullptr;
+ this->index = -1;
+ this->merge_to_index = -1;
+ this->visit_index = 0;
+}
+#endif
+
template<typename T> CDTVert<T> *CDTArrangement<T>::add_vert(const vec2<T> &pt)
{
CDTVert<T> *v = new CDTVert<T>(pt);
@@ -805,8 +1035,8 @@ CDTEdge<T> *CDTArrangement<T>::connect_separate_parts(SymEdge<T> *se1, SymEdge<T
template<typename T> CDTEdge<T> *CDTArrangement<T>::split_edge(SymEdge<T> *se, T lambda)
{
/* Split e at lambda. */
- const vec2<T> *a = &se->vert->co;
- const vec2<T> *b = &se->next->vert->co;
+ const vec2<T> *a = &se->vert->co.exact;
+ const vec2<T> *b = &se->next->vert->co.exact;
SymEdge<T> *sesym = sym(se);
SymEdge<T> *sesymprev = prev(sesym);
SymEdge<T> *sesymprevsym = sym(sesymprev);
@@ -918,8 +1148,8 @@ template<typename T> class SiteInfo {
*/
template<typename T> bool site_lexicographic_sort(const SiteInfo<T> &a, const SiteInfo<T> &b)
{
- const vec2<T> &co_a = a.v->co;
- const vec2<T> &co_b = b.v->co;
+ const vec2<T> &co_a = a.v->co.exact;
+ const vec2<T> &co_b = b.v->co.exact;
if (co_a[0] < co_b[0]) {
return true;
}
@@ -945,7 +1175,7 @@ template<typename T> void find_site_merges(Array<SiteInfo<T>> &sites)
int n = sites.size();
for (int i = 0; i < n - 1; ++i) {
int j = i + 1;
- while (j < n && sites[j].v->co == sites[i].v->co) {
+ while (j < n && sites[j].v->co.exact == sites[i].v->co.exact) {
sites[j].v->merge_to_index = sites[i].orig_index;
++j;
}
@@ -957,19 +1187,19 @@ template<typename T> void find_site_merges(Array<SiteInfo<T>> &sites)
template<typename T> inline bool vert_left_of_symedge(CDTVert<T> *v, SymEdge<T> *se)
{
- return orient2d(v->co, se->vert->co, se->next->vert->co) > 0;
+ return filtered_orient2d(v->co, se->vert->co, se->next->vert->co) > 0;
}
template<typename T> inline bool vert_right_of_symedge(CDTVert<T> *v, SymEdge<T> *se)
{
- return orient2d(v->co, se->next->vert->co, se->vert->co) > 0;
+ return filtered_orient2d(v->co, se->next->vert->co, se->vert->co) > 0;
}
/* Is se above basel? */
template<typename T>
inline bool dc_tri_valid(SymEdge<T> *se, SymEdge<T> *basel, SymEdge<T> *basel_sym)
{
- return orient2d(se->next->vert->co, basel_sym->vert->co, basel->vert->co) > 0;
+ return filtered_orient2d(se->next->vert->co, basel_sym->vert->co, basel->vert->co) > 0;
}
/**
@@ -1013,7 +1243,7 @@ void dc_tri(CDTArrangement<T> *cdt,
}
CDTVert<T> *v3 = sites[start + 2].v;
CDTEdge<T> *eb = cdt->add_vert_to_symedge_edge(v3, &ea->symedges[1]);
- int orient = orient2d(v1->co, v2->co, v3->co);
+ int orient = filtered_orient2d(v1->co, v2->co, v3->co);
if (orient > 0) {
cdt->add_diagonal(&eb->symedges[0], &ea->symedges[0]);
*r_le = &ea->symedges[0];
@@ -1101,10 +1331,10 @@ void dc_tri(CDTArrangement<T> *cdt,
std::cout << "found valid lcand\n";
std::cout << " lcand" << lcand << "\n";
}
- while (incircle(basel_sym->vert->co,
- basel->vert->co,
- lcand->next->vert->co,
- lcand->rot->next->vert->co) > 0.0) {
+ while (filtered_incircle(basel_sym->vert->co,
+ basel->vert->co,
+ lcand->next->vert->co,
+ lcand->rot->next->vert->co) > 0.0) {
if (dbg_level > 1) {
std::cout << "incircle says to remove lcand\n";
std::cout << " lcand" << lcand << "\n";
@@ -1120,10 +1350,10 @@ void dc_tri(CDTArrangement<T> *cdt,
std::cout << "found valid rcand\n";
std::cout << " rcand" << rcand << "\n";
}
- while (incircle(basel_sym->vert->co,
- basel->vert->co,
- rcand->next->vert->co,
- sym(rcand)->next->next->vert->co) > 0.0) {
+ while (filtered_incircle(basel_sym->vert->co,
+ basel->vert->co,
+ rcand->next->vert->co,
+ sym(rcand)->next->next->vert->co) > 0.0) {
if (dbg_level > 0) {
std::cout << "incircle says to remove rcand\n";
std::cout << " rcand" << rcand << "\n";
@@ -1147,10 +1377,10 @@ void dc_tri(CDTArrangement<T> *cdt,
}
/* The next cross edge to be connected is to either `lcand->next->vert` or `rcand->next->vert`;
* if both are valid, choose the appropriate one using the #incircle test. */
- if (!valid_lcand ||
- (valid_rcand &&
- incircle(lcand->next->vert->co, lcand->vert->co, rcand->vert->co, rcand->next->vert->co) >
- 0)) {
+ if (!valid_lcand || (valid_rcand && filtered_incircle(lcand->next->vert->co,
+ lcand->vert->co,
+ rcand->vert->co,
+ rcand->next->vert->co) > 0)) {
if (dbg_level > 0) {
std::cout << "connecting rcand\n";
std::cout << " se1=basel_sym" << basel_sym << "\n";
@@ -1265,7 +1495,7 @@ template<typename T> static void re_delaunay_triangulate(CDTArrangement<T> *cdt,
SymEdge<T> *cse = first;
for (SymEdge<T> *ss = first->next; ss != se; ss = ss->next) {
CDTVert<T> *v = ss->vert;
- if (incircle(a->co, b->co, c->co, v->co) > 0) {
+ if (filtered_incircle(a->co, b->co, c->co, v->co) > 0) {
c = v;
cse = ss;
}
@@ -1290,7 +1520,7 @@ template<typename T> static void re_delaunay_triangulate(CDTArrangement<T> *cdt,
template<typename T> inline int tri_orient(const SymEdge<T> *t)
{
- return orient2d(t->vert->co, t->next->vert->co, t->next->next->vert->co);
+ return filtered_orient2d(t->vert->co, t->next->vert->co, t->next->next->vert->co);
}
/**
@@ -1419,7 +1649,7 @@ void fill_crossdata_for_through_vert(CDTVert<T> *v,
* case. We need to fill in cd's 'out' edge if it was a vert case.
*/
template<typename T>
-void fill_crossdata_for_intersect(const vec2<T> &curco,
+void fill_crossdata_for_intersect(const FatCo<T> &curco,
const CDTVert<T> *v2,
SymEdge<T> *t,
CrossData<T> *cd,
@@ -1434,7 +1664,7 @@ void fill_crossdata_for_intersect(const vec2<T> &curco,
BLI_assert(se_vcva->vert == vc && se_vcva->next->vert == va);
BLI_assert(se_vcvb->vert == vc && se_vcvb->next->vert == vb);
UNUSED_VARS_NDEBUG(vc);
- auto isect = vec2<T>::isect_seg_seg(va->co, vb->co, curco, v2->co);
+ auto isect = vec2<T>::isect_seg_seg(va->co.exact, vb->co.exact, curco.exact, v2->co.exact);
T &lambda = isect.lambda;
switch (isect.kind) {
case vec2<T>::isect_result::LINE_LINE_CROSS: {
@@ -1443,7 +1673,7 @@ void fill_crossdata_for_intersect(const vec2<T> &curco,
#else
if (true) {
#endif
- T len_ab = vec2<T>::distance(va->co, vb->co);
+ double len_ab = vec2<double>::distance(va->co.approx, vb->co.approx);
if (lambda * len_ab <= epsilon) {
fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
}
@@ -1497,7 +1727,8 @@ void fill_crossdata_for_intersect(const vec2<T> &curco,
break;
}
case vec2<T>::isect_result::LINE_LINE_COLINEAR: {
- if (vec2<T>::distance_squared(va->co, v2->co) <= vec2<T>::distance_squared(vb->co, v2->co)) {
+ if (vec2<double>::distance_squared(va->co.approx, v2->co.approx) <=
+ vec2<double>::distance_squared(vb->co.approx, v2->co.approx)) {
fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
}
else {
@@ -1537,14 +1768,14 @@ bool get_next_crossing_from_vert(CDT_state<T> *cdt_state,
}
CDTVert<T> *va = t->next->vert;
CDTVert<T> *vb = t->next->next->vert;
- int orient1 = orient2d(t->vert->co, va->co, v2->co);
+ int orient1 = filtered_orient2d(t->vert->co, va->co, v2->co);
if (orient1 == 0 && in_line<T>(vcur->co, va->co, v2->co)) {
fill_crossdata_for_through_vert(va, t, cd, cd_next);
ok = true;
break;
}
if (t->face != cdt_state->cdt.outer_face) {
- int orient2 = orient2d(vcur->co, vb->co, v2->co);
+ int orient2 = filtered_orient2d(vcur->co, vb->co, v2->co);
/* Don't handle orient2 == 0 case here: next rotation will get it. */
if (orient1 > 0 && orient2 < 0) {
/* Segment intersection. */
@@ -1574,15 +1805,16 @@ void get_next_crossing_from_edge(CrossData<T> *cd,
{
CDTVert<T> *va = cd->in->vert;
CDTVert<T> *vb = cd->in->next->vert;
- vec2<T> curco = vec2<T>::interpolate(va->co, vb->co, cd->lambda);
+ vec2<T> curco = vec2<T>::interpolate(va->co.exact, vb->co.exact, cd->lambda);
+ FatCo<T> fat_curco(curco);
SymEdge<T> *se_ac = sym(cd->in)->next;
CDTVert<T> *vc = se_ac->next->vert;
- int orient = orient2d(curco, v2->co, vc->co);
+ int orient = filtered_orient2d(fat_curco, v2->co, vc->co);
if (orient < 0) {
- fill_crossdata_for_intersect<T>(curco, v2, se_ac->next, cd, cd_next, epsilon);
+ fill_crossdata_for_intersect<T>(fat_curco, v2, se_ac->next, cd, cd_next, epsilon);
}
else if (orient > 0.0) {
- fill_crossdata_for_intersect(curco, v2, se_ac, cd, cd_next, epsilon);
+ fill_crossdata_for_intersect(fat_curco, v2, se_ac, cd, cd_next, epsilon);
}
else {
*cd_next = CrossData<T>{0.0, vc, se_ac->next, nullptr};
@@ -1682,7 +1914,7 @@ void add_edge_constraint(
ok = get_next_crossing_from_vert(cdt_state, cd, cd_next, v2);
}
else {
- get_next_crossing_from_edge(cd, cd_next, v2, cdt_state->epsilon);
+ get_next_crossing_from_edge<T>(cd, cd_next, v2, cdt_state->epsilon);
ok = true;
}
constexpr int unreasonably_large_crossings = 100000;
@@ -2057,7 +2289,7 @@ template<typename T> void remove_non_constraint_edges(CDT_state<T> *cdt_state)
* For sorting edges by decreasing length (squared).
*/
template<typename T> struct EdgeToSort {
- T len_squared = T(0);
+ double len_squared = 0.0;
CDTEdge<T> *e{nullptr};
EdgeToSort() = default;
@@ -2098,9 +2330,9 @@ template<typename T> void remove_non_constraint_edges_leave_valid_bmesh(CDT_stat
if (!is_deleted_edge(e) && !is_constrained_edge(e)) {
dissolvable_edges.append(EdgeToSort<T>());
dissolvable_edges[i].e = e;
- const vec2<T> &co1 = e->symedges[0].vert->co;
- const vec2<T> &co2 = e->symedges[1].vert->co;
- dissolvable_edges[i].len_squared = vec2<T>::distance_squared(co1, co2);
+ const vec2<double> &co1 = e->symedges[0].vert->co.approx;
+ const vec2<double> &co2 = e->symedges[1].vert->co.approx;
+ dissolvable_edges[i].len_squared = vec2<double>::distance_squared(co1, co2);
i++;
}
}
@@ -2268,7 +2500,7 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
for (int i = 0; i < verts_size; ++i) {
CDTVert<T> *v = cdt->verts[i];
if (v->merge_to_index == -1) {
- result.vert[i_out] = v->co;
+ result.vert[i_out] = v->co.exact;
if (i < cdt_state->input_vert_tot) {
result.vert_orig[i_out].append(i);
}
diff --git a/source/blender/blenlib/intern/math_vec.cc b/source/blender/blenlib/intern/math_vec.cc
index 54926f84eb9..84fa6c69d17 100644
--- a/source/blender/blenlib/intern/math_vec.cc
+++ b/source/blender/blenlib/intern/math_vec.cc
@@ -70,14 +70,13 @@ double2::isect_result double2::isect_seg_seg(const double2 &v1,
double div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
if (div == 0.0) {
ans.lambda = 0.0;
- ans.mu = 0.0;
ans.kind = double2::isect_result::LINE_LINE_COLINEAR;
}
else {
ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- ans.mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (ans.lambda >= 0.0 && ans.lambda <= 1.0 && ans.mu >= 0.0 && ans.mu <= 1.0) {
- if (ans.lambda == 0.0 || ans.lambda == 1.0 || ans.mu == 0.0 || ans.mu == 1.0) {
+ double mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
+ if (ans.lambda >= 0.0 && ans.lambda <= 1.0 && mu >= 0.0 && mu <= 1.0) {
+ if (ans.lambda == 0.0 || ans.lambda == 1.0 || mu == 0.0 || mu == 1.0) {
ans.kind = double2::isect_result::LINE_LINE_EXACT;
}
else {
@@ -101,14 +100,15 @@ mpq2::isect_result mpq2::isect_seg_seg(const mpq2 &v1,
mpq_class div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
if (div == 0.0) {
ans.lambda = 0.0;
- ans.mu = 0.0;
ans.kind = mpq2::isect_result::LINE_LINE_COLINEAR;
}
else {
ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- ans.mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (ans.lambda >= 0 && ans.lambda <= 1 && ans.mu >= 0 && ans.mu <= 1) {
- if (ans.lambda == 0 || ans.lambda == 1 || ans.mu == 0 || ans.mu == 1) {
+ /* Avoid dividing mu by div: it is expensive in multiprecision. */
+ mpq_class mudiv = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1]));
+ if (ans.lambda >= 0 && ans.lambda <= 1 &&
+ ((div > 0 && mudiv >= 0 && mudiv <= div) || (div < 0 && mudiv <= 0 && mudiv >= div))) {
+ if (ans.lambda == 0 || ans.lambda == 1 || mudiv == 0 || mudiv == div) {
ans.kind = mpq2::isect_result::LINE_LINE_EXACT;
}
else {
diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
index 338d6f96bef..487afc095f9 100644
--- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
@@ -21,6 +21,7 @@ extern "C" {
#include "BLI_array.hh"
#include "BLI_double2.hh"
+#include "BLI_math_boolean.hh"
#include "BLI_math_mpq.hh"
#include "BLI_mpq2.hh"
#include "BLI_vector.hh"
@@ -1696,7 +1697,7 @@ void rand_delaunay_test(int test_kind,
in.vert[ic][1] = T((param * sin(angle3)));
/* Put the coordinates in ccw order. */
in.face[i].append(ia);
- int orient = vec2<T>::orient2d(in.vert[ia], in.vert[ib], in.vert[ic]);
+ int orient = orient2d(in.vert[ia], in.vert[ib], in.vert[ic]);
if (orient >= 0) {
in.face[i].append(ib);
in.face[i].append(ic);
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 5188d338183..4533a321909 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -555,6 +555,11 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_extra_blend_draw(vedata);
OVERLAY_volume_draw(vedata);
+ if (pd->ctx_mode == CTX_MODE_SCULPT) {
+ /* Sculpt overlays are drawn here to avoid artifacts with wireframe opacity. */
+ OVERLAY_sculpt_draw(vedata);
+ }
+
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_line_fb);
}
@@ -633,9 +638,6 @@ static void OVERLAY_draw_scene(void *vedata)
case CTX_MODE_PARTICLE:
OVERLAY_edit_particle_draw(vedata);
break;
- case CTX_MODE_SCULPT:
- OVERLAY_sculpt_draw(vedata);
- break;
case CTX_MODE_EDIT_GPENCIL:
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index af63c5ca3b2..e8e25a55796 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -2343,6 +2343,9 @@ int ED_gpencil_select_stroke_segment(bGPdata *gpd,
float r_hita[3],
float r_hitb[3])
{
+ if (gps->totpoints < 2) {
+ return 0;
+ }
const float min_factor = 0.0015f;
bGPDspoint *pta1 = NULL;
bGPDspoint *pta2 = NULL;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 5c1eb4224a7..893ffd5c914 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -519,8 +519,8 @@ void UI_draw_anti_tria(
float x1, float y1, float x2, float y2, float x3, float y3, const float color[4])
{
const float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}};
- float draw_color[4];
+ float draw_color[4];
copy_v4_v4(draw_color, color);
/* Note: This won't give back the original color. */
draw_color[3] *= 1.0f / WIDGET_AA_JITTER;
@@ -645,8 +645,7 @@ static int round_box_shadow_edges(
float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step)
{
float vec[WIDGET_CURVE_RESOLU][2];
- float minx, miny, maxx, maxy;
- int a, tot = 0;
+ int tot = 0;
rad += step;
@@ -654,65 +653,65 @@ static int round_box_shadow_edges(
rad = 0.5f * BLI_rcti_size_y(rect);
}
- minx = rect->xmin - step;
- miny = rect->ymin - step;
- maxx = rect->xmax + step;
- maxy = rect->ymax + step;
+ const float minx = rect->xmin - step;
+ const float miny = rect->ymin - step;
+ const float maxx = rect->xmax + step;
+ const float maxy = rect->ymax + step;
/* mult */
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
vec[a][0] = rad * cornervec[a][0];
vec[a][1] = rad * cornervec[a][1];
}
/* start with left-top, anti clockwise */
if (roundboxalign & UI_CNR_TOP_LEFT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = minx + rad - vec[a][0];
vert[tot][1] = maxy - vec[a][1];
}
}
else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = minx;
vert[tot][1] = maxy;
}
}
if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = minx + vec[a][1];
vert[tot][1] = miny + rad - vec[a][0];
}
}
else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = minx;
vert[tot][1] = miny;
}
}
if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = maxx - rad + vec[a][0];
vert[tot][1] = miny + vec[a][1];
}
}
else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = maxx;
vert[tot][1] = miny;
}
}
if (roundboxalign & UI_CNR_TOP_RIGHT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = maxx - vec[a][1];
vert[tot][1] = maxy - rad + vec[a][0];
}
}
else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
vert[tot][0] = maxx;
vert[tot][1] = maxy;
}
@@ -733,7 +732,7 @@ static void round_box__edges(
/* for uv, can divide by zero */
const float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f;
const float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f;
- int a, tot = 0, minsize;
+ int tot = 0;
const int hnum = ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT)) ==
(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT) ||
(roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)) ==
@@ -747,7 +746,7 @@ static void round_box__edges(
1 :
2;
- minsize = min_ii(BLI_rcti_size_x(rect) * hnum, BLI_rcti_size_y(rect) * vnum);
+ int minsize = min_ii(BLI_rcti_size_x(rect) * hnum, BLI_rcti_size_y(rect) * vnum);
if (2.0f * rad > minsize) {
rad = 0.5f * minsize;
@@ -769,7 +768,7 @@ static void round_box__edges(
BLI_rctf_init(&wt->uniform_params.recti, minxi, maxxi, minyi, maxyi);
/* mult */
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
veci[a][0] = radi * cornervec[a][0];
veci[a][1] = radi * cornervec[a][1];
vec[a][0] = rad * cornervec[a][0];
@@ -778,8 +777,7 @@ static void round_box__edges(
/* corner left-bottom */
if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
wt->inner_v[tot][0] = minxi + veci[a][1];
wt->inner_v[tot][1] = minyi + radi - veci[a][0];
@@ -805,8 +803,7 @@ static void round_box__edges(
/* corner right-bottom */
if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
wt->inner_v[tot][0] = maxxi - radi + veci[a][0];
wt->inner_v[tot][1] = minyi + veci[a][1];
@@ -834,8 +831,7 @@ static void round_box__edges(
/* corner right-top */
if (roundboxalign & UI_CNR_TOP_RIGHT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
wt->inner_v[tot][0] = maxxi - veci[a][1];
wt->inner_v[tot][1] = maxyi - radi + veci[a][0];
@@ -861,8 +857,7 @@ static void round_box__edges(
/* corner left-top */
if (roundboxalign & UI_CNR_TOP_LEFT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
wt->inner_v[tot][0] = minxi + radi - veci[a][0];
wt->inner_v[tot][1] = maxyi - veci[a][1];
@@ -874,7 +869,6 @@ static void round_box__edges(
}
}
else {
-
wt->inner_v[tot][0] = minxi;
wt->inner_v[tot][1] = maxyi;
@@ -914,19 +908,14 @@ static void shape_preset_init_trias_ex(uiWidgetTrias *tria,
const uint tris[][3],
const int tris_tot)
{
- float centx, centy, sizex, sizey, minsize;
- int a, i1 = 0, i2 = 1;
+ float sizex, sizey;
+ int i1 = 0, i2 = 1;
- if (ELEM(where, 'r', 'l')) {
- minsize = BLI_rcti_size_y(rect);
- }
- else {
- minsize = BLI_rcti_size_x(rect);
- }
+ float minsize = ELEM(where, 'r', 'l') ? BLI_rcti_size_y(rect) : BLI_rcti_size_x(rect);
/* center position and size */
- centx = (float)rect->xmin + 0.4f * minsize;
- centy = (float)rect->ymin + 0.5f * minsize;
+ float centx = (float)rect->xmin + 0.4f * minsize;
+ float centy = (float)rect->ymin + 0.5f * minsize;
tria->size = sizex = sizey = -0.5f * triasize * minsize;
if (where == 'r') {
@@ -947,7 +936,7 @@ static void shape_preset_init_trias_ex(uiWidgetTrias *tria,
i1 = 1;
}
- for (a = 0; a < verts_tot; a++) {
+ for (int a = 0; a < verts_tot; a++) {
tria->vec[a][0] = sizex * verts[a][i1] + centx;
tria->vec[a][1] = sizey * verts[a][i2] + centy;
}
@@ -1367,16 +1356,13 @@ static float widget_alpha_factor(const int state)
static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
{
- int w, h, size;
-
if (icon == ICON_NONE) {
return;
}
- w = BLI_rcti_size_x(rect);
- h = BLI_rcti_size_y(rect);
- size = MIN2(w, h);
- size -= PREVIEW_PAD * 2; /* padding */
+ const int w = BLI_rcti_size_x(rect);
+ const int h = BLI_rcti_size_y(rect);
+ const int size = MIN2(w, h) - PREVIEW_PAD * 2;
if (size > 0) {
const int x = rect->xmin + w / 2 - size / 2;
@@ -1397,7 +1383,6 @@ static void widget_draw_icon(
const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const uchar mono_color[4])
{
float xs = 0.0f, ys = 0.0f;
- float aspect, height;
if (but->flag & UI_BUT_ICON_PREVIEW) {
GPU_blend(GPU_BLEND_ALPHA);
@@ -1411,8 +1396,8 @@ static void widget_draw_icon(
return;
}
- aspect = but->block->aspect * U.inv_dpi_fac;
- height = ICON_DEFAULT_HEIGHT / aspect;
+ float aspect = but->block->aspect * U.inv_dpi_fac;
+ float height = ICON_DEFAULT_HEIGHT / aspect;
/* calculate blend color */
if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) {
@@ -1501,12 +1486,12 @@ static void widget_draw_submenu_tria(const uiBut *but,
const int tria_width = (int)(ICON_DEFAULT_WIDTH / aspect) - 2 * U.pixelsize;
const int xs = rect->xmax - tria_width;
const int ys = (rect->ymin + rect->ymax - tria_height) / 2.0f;
- float col[4];
- rctf tria_rect;
+ float col[4];
rgba_uchar_to_float(col, wcol->text);
col[3] *= 0.8f;
+ rctf tria_rect;
BLI_rctf_init(&tria_rect, xs, xs + tria_width, ys, ys + tria_height);
BLI_rctf_scale(&tria_rect, 0.4f);
@@ -1546,9 +1531,6 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
const float sep_strwidth,
size_t *r_final_len)
{
- float tmp;
- int l_end;
-
BLI_assert(str[0]);
/* If the trailing ellipsis takes more than 20% of all available width, just cut the string
@@ -1556,14 +1538,17 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
* already!).
*/
if (sep_strwidth / okwidth > 0.2f) {
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
+ float tmp;
+ const int l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
str[l_end] = '\0';
if (r_final_len) {
*r_final_len = (size_t)l_end;
}
}
else {
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
+ float tmp;
+ const int l_end = BLF_width_to_strlen(
+ fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
if (r_final_len) {
*r_final_len = (size_t)(l_end) + sep_len;
@@ -1589,8 +1574,6 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
const size_t max_len,
const char rpart_sep)
{
- float strwidth;
-
/* Add some epsilon to OK width, avoids 'ellipsing' text that nearly fits!
* Better to have a small piece of the last char cut out,
* than two remaining chars replaced by an ellipsis... */
@@ -1606,15 +1589,13 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
}
- strwidth = BLF_width(fstyle->uifont_id, str, max_len);
+ float strwidth = BLF_width(fstyle->uifont_id, str, max_len);
if ((okwidth > 0.0f) && (strwidth > okwidth)) {
/* Ellipsis. Some compilers complain with real literal string. */
const char sep[] = {0xe2, 0x80, 0xA6, 0x0};
const int sep_len = sizeof(sep) - 1;
const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sep_len + 1);
- float parts_strwidth;
- size_t l_end;
char *rpart = NULL, rpart_buf[UI_MAX_DRAW_STR];
float rpart_width = 0.0f;
@@ -1641,7 +1622,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
}
}
- parts_strwidth = (okwidth - sep_strwidth) / 2.0f;
+ float parts_strwidth = (okwidth - sep_strwidth) / 2.0f;
if (rpart) {
strcpy(rpart_buf, rpart);
@@ -1649,7 +1630,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
rpart = rpart_buf;
}
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
+ size_t l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
if (l_end < 10 || min_ff(parts_strwidth, strwidth - okwidth) < minwidth) {
/* If we really have no place, or we would clip a very small piece of string in the middle,
* only show start of string.
@@ -1826,7 +1807,6 @@ static void ui_text_clip_right_label(const uiFontStyle *fstyle, uiBut *but, cons
{
const int border = UI_TEXT_CLIP_MARGIN + 1;
const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
- char *cpoin = NULL;
int drawstr_len = strlen(but->drawstr);
const char *cpend = but->drawstr + drawstr_len;
@@ -1848,7 +1828,7 @@ static void ui_text_clip_right_label(const uiFontStyle *fstyle, uiBut *but, cons
*/
/* find the space after ':' separator */
- cpoin = strrchr(but->drawstr, ':');
+ char *cpoin = strrchr(but->drawstr, ':');
if (cpoin && (cpoin < cpend - 2)) {
char *cp2 = cpoin;
@@ -2775,8 +2755,6 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
bTheme *btheme = UI_GetTheme();
uiWidgetBase wtb;
rcti rect1 = *rect;
- float alphastep;
- int step, totvert;
float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2];
const float radout = UI_ThemeMenuShadowWidth();
@@ -2794,21 +2772,22 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
}
/* inner part */
- totvert = round_box_shadow_edges(wtb.inner_v,
- &rect1,
- radin,
- roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT),
- 0.0f);
+ const int totvert = round_box_shadow_edges(wtb.inner_v,
+ &rect1,
+ radin,
+ roundboxalign &
+ (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT),
+ 0.0f);
/* we draw a number of increasing size alpha quad strips */
- alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
+ const float alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
const uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- for (step = 1; step <= (int)radout; step++) {
+ for (int step = 1; step <= (int)radout; step++) {
const float expfac = sqrtf(step / radout);
round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
@@ -2896,10 +2875,10 @@ void ui_hsvcircle_pos_from_vals(
const float centx = BLI_rcti_cent_x_fl(rect);
const float centy = BLI_rcti_cent_y_fl(rect);
float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
- float ang, radius_t;
- ang = 2.0f * (float)M_PI * hsv[0] + (float)M_PI_2;
+ const float ang = 2.0f * (float)M_PI * hsv[0] + (float)M_PI_2;
+ float radius_t;
if (cpicker->use_color_cubic && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
radius_t = (1.0f - pow3f(1.0f - hsv[1]));
}
@@ -2907,9 +2886,9 @@ void ui_hsvcircle_pos_from_vals(
radius_t = hsv[1];
}
- radius = clamp_f(radius_t, 0.0f, 1.0f) * radius;
- *r_xpos = centx + cosf(-ang) * radius;
- *r_ypos = centy + sinf(-ang) * radius;
+ float rad = clamp_f(radius_t, 0.0f, 1.0f) * radius;
+ *r_xpos = centx + cosf(-ang) * rad;
+ *r_ypos = centy + sinf(-ang) * rad;
}
static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
@@ -3354,7 +3333,6 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol)
static void widget_numbut_draw(
uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
{
- uiWidgetBase wtb;
const float rad = wcol->roundness * BLI_rcti_size_y(rect);
const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f);
@@ -3362,6 +3340,7 @@ static void widget_numbut_draw(
SWAP(short, wcol->shadetop, wcol->shadedown);
}
+ uiWidgetBase wtb;
widget_init(&wtb);
if (!emboss) {
@@ -3461,11 +3440,9 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
- float rad;
-
widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
@@ -3489,7 +3466,6 @@ static void widget_menubut_embossn(uiBut *UNUSED(but),
int UNUSED(roundboxalign))
{
uiWidgetBase wtb;
-
widget_init(&wtb);
wtb.draw_inner = false;
wtb.draw_outline = false;
@@ -3515,21 +3491,15 @@ static void widget_numbut_embossn(
void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
{
uiWidgetBase wtb;
- int horizontal;
- float rad;
bool outline = false;
widget_init(&wtb);
/* determine horizontal/vertical */
- horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
+ bool horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
- if (horizontal) {
- rad = wcol->roundness * BLI_rcti_size_y(rect);
- }
- else {
- rad = wcol->roundness * BLI_rcti_size_x(rect);
- }
+ const float rad = (horizontal) ? wcol->roundness * BLI_rcti_size_y(rect) :
+ wcol->roundness * BLI_rcti_size_x(rect);
wtb.uniform_params.shade_dir = (horizontal) ? 1.0f : 0.0;
@@ -3608,30 +3578,24 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s
static void widget_scroll(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
{
- rcti rect1;
- double value;
- float fac, size, min;
- int horizontal;
-
/* calculate slider part */
- value = ui_but_value_get(but);
+ const float value = (float)ui_but_value_get(but);
- size = (but->softmax + but->a1 - but->softmin);
- size = max_ff(size, 2.0f);
+ const float size = max_ff((but->softmax + but->a1 - but->softmin), 2.0f);
/* position */
- rect1 = *rect;
+ rcti rect1 = *rect;
/* determine horizontal/vertical */
- horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
+ const bool horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
if (horizontal) {
- fac = BLI_rcti_size_x(rect) / size;
- rect1.xmin = rect1.xmin + ceilf(fac * ((float)value - but->softmin));
+ const float fac = BLI_rcti_size_x(rect) / size;
+ rect1.xmin = rect1.xmin + ceilf(fac * (value - but->softmin));
rect1.xmax = rect1.xmin + ceilf(fac * (but->a1 - but->softmin));
/* ensure minimium size */
- min = BLI_rcti_size_y(rect);
+ const float min = BLI_rcti_size_y(rect);
if (BLI_rcti_size_x(&rect1) < min) {
rect1.xmax = rect1.xmin + min;
@@ -3643,12 +3607,12 @@ static void widget_scroll(
}
}
else {
- fac = BLI_rcti_size_y(rect) / size;
- rect1.ymax = rect1.ymax - ceilf(fac * ((float)value - but->softmin));
+ const float fac = BLI_rcti_size_y(rect) / size;
+ rect1.ymax = rect1.ymax - ceilf(fac * (value - but->softmin));
rect1.ymin = rect1.ymax - ceilf(fac * (but->a1 - but->softmin));
/* ensure minimium size */
- min = BLI_rcti_size_x(rect);
+ float min = BLI_rcti_size_x(rect);
if (BLI_rcti_size_y(&rect1) < min) {
rect1.ymax = rect1.ymin + min;
@@ -3673,9 +3637,9 @@ static void widget_progressbar(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiButProgressbar *but_progressbar = (uiButProgressbar *)but;
- uiWidgetBase wtb, wtb_bar;
rcti rect_prog = *rect, rect_bar = *rect;
+ uiWidgetBase wtb, wtb_bar;
widget_init(&wtb);
widget_init(&wtb_bar);
@@ -3707,12 +3671,12 @@ static void widget_progressbar(
static void widget_nodesocket(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
- uiWidgetBase wtb;
const int radi = 5;
- uchar old_inner[3], old_outline[3];
+ uiWidgetBase wtb;
widget_init(&wtb);
+ uchar old_inner[3], old_outline[3];
copy_v3_v3_uchar(old_inner, wcol->inner);
copy_v3_v3_uchar(old_outline, wcol->outline);
@@ -3743,16 +3707,12 @@ static void widget_numslider(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb, wtb1;
- rcti rect1;
- float offs, toffs;
- uchar outline[3];
-
widget_init(&wtb);
widget_init(&wtb1);
/* Backdrop first. */
- offs = wcol->roundness * BLI_rcti_size_y(rect);
- toffs = offs * 0.75f;
+ const float offs = wcol->roundness * BLI_rcti_size_y(rect);
+ const float toffs = offs * 0.75f;
round_box_edges(&wtb, roundboxalign, rect, offs);
wtb.draw_outline = false;
@@ -3762,6 +3722,7 @@ static void widget_numslider(
if (!(state & UI_STATE_TEXT_INPUT)) {
int roundboxalign_slider = roundboxalign;
+ uchar outline[3];
copy_v3_v3_uchar(outline, wcol->outline);
copy_v3_v3_uchar(wcol->outline, wcol->item);
copy_v3_v3_uchar(wcol->inner, wcol->item);
@@ -3770,7 +3731,7 @@ static void widget_numslider(
SWAP(short, wcol->shadetop, wcol->shadedown);
}
- rect1 = *rect;
+ rcti rect1 = *rect;
float factor, factor_ui;
float factor_discard = 1.0f; /* No discard. */
const float value = (float)ui_but_value_get(but);
@@ -3834,8 +3795,7 @@ static void widget_swatch(
{
BLI_assert(but->type == UI_BTYPE_COLOR);
uiButColor *color_but = (uiButColor *)but;
- uiWidgetBase wtb;
- float rad, col[4];
+ float col[4];
col[3] = 1.0f;
@@ -3847,9 +3807,10 @@ static void widget_swatch(
}
}
+ uiWidgetBase wtb;
widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
ui_but_v3_get(but, col);
@@ -3926,12 +3887,10 @@ static void widget_icon_has_anim(
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT) &&
but->emboss != UI_EMBOSS_NONE) {
uiWidgetBase wtb;
- float rad;
-
widget_init(&wtb);
wtb.draw_outline = false;
- rad = wcol->roundness * BLI_rcti_size_y(rect);
+ const float rad = wcol->roundness * BLI_rcti_size_y(rect);
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
@@ -3948,16 +3907,14 @@ static void widget_icon_has_anim(
static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
-
if (state & UI_SELECT) {
SWAP(short, wcol->shadetop, wcol->shadedown);
}
+ uiWidgetBase wtb;
widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -3969,11 +3926,9 @@ static void widget_menuiconbut(uiWidgetColors *wcol,
int roundboxalign)
{
uiWidgetBase wtb;
- float rad;
-
widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
@@ -4014,7 +3969,6 @@ static void widget_menu_itembut(uiWidgetColors *wcol,
int UNUSED(roundboxalign))
{
uiWidgetBase wtb;
-
widget_init(&wtb);
/* not rounded, no outline */
@@ -4027,15 +3981,14 @@ static void widget_menu_itembut(uiWidgetColors *wcol,
static void widget_menu_radial_itembut(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
- uiWidgetBase wtb;
- float rad;
const float fac = but->block->pie_data.alphafac;
+ uiWidgetBase wtb;
widget_init(&wtb);
wtb.draw_emboss = false;
- rad = wcol->roundness * BLI_rcti_size_y(rect);
+ const float rad = wcol->roundness * BLI_rcti_size_y(rect);
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
wcol->inner[3] *= fac;
@@ -4054,13 +4007,11 @@ static void widget_list_itembut(uiWidgetColors *wcol,
int UNUSED(roundboxalign))
{
uiWidgetBase wtb;
- float rad;
-
widget_init(&wtb);
/* no outline */
wtb.draw_outline = false;
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -4072,11 +4023,9 @@ static void widget_optionbut(uiWidgetColors *wcol,
int UNUSED(roundboxalign))
{
const bool text_before_widget = (state & UI_STATE_TEXT_BEFORE_WIDGET);
- uiWidgetBase wtb;
rcti recttemp = *rect;
- float rad;
- int delta;
+ uiWidgetBase wtb;
widget_init(&wtb);
/* square */
@@ -4088,13 +4037,13 @@ static void widget_optionbut(uiWidgetColors *wcol,
}
/* smaller */
- delta = (BLI_rcti_size_y(&recttemp) - 2 * U.pixelsize) / 6;
+ const int delta = (BLI_rcti_size_y(&recttemp) - 2 * U.pixelsize) / 6;
BLI_rcti_resize(
&recttemp, BLI_rcti_size_x(&recttemp) - delta * 2, BLI_rcti_size_y(&recttemp) - delta * 2);
/* Keep one edge in place. */
BLI_rcti_translate(&recttemp, text_before_widget ? delta : -delta, 0);
- rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
+ const float rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
/* decoration */
@@ -4144,11 +4093,9 @@ static void widget_state_label(uiWidgetType *wt, int state, int drawflag, char e
static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
- float rad;
-
widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -4158,11 +4105,9 @@ static void widget_box(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
- float rad;
- uchar old_col[3];
-
widget_init(&wtb);
+ uchar old_col[3];
copy_v3_v3_uchar(old_col, wcol->inner);
/* abuse but->hsv - if it's non-zero, use this color as the box's background */
@@ -4173,7 +4118,7 @@ static void widget_box(
wcol->inner[3] = but->col[3];
}
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -4184,11 +4129,9 @@ static void widget_box(
static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
- float rad;
-
widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -4211,9 +4154,9 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_roundbut_exec(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- uiWidgetBase wtb;
const float rad = wcol->roundness * U.widget_unit;
+ uiWidgetBase wtb;
widget_init(&wtb);
if (state & UI_STATE_HOLD_ACTION) {
@@ -4236,7 +4179,6 @@ static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundbox
* seems incorrect and also looks nicer without it imho ;) */
// #define USE_TAB_SHADED_HIGHLIGHT
- uiWidgetBase wtb;
uchar theme_col_tab_highlight[3];
#ifdef USE_TAB_SHADED_HIGHLIGHT
@@ -4249,6 +4191,7 @@ static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundbox
}
#endif
+ uiWidgetBase wtb;
widget_init(&wtb);
/* half rounded */
@@ -4279,13 +4222,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
{
bTheme *btheme = UI_GetTheme();
uiWidgetColors *wcol = &btheme->tui.wcol_radio;
- uiWidgetBase wtb;
const float rad = wcol->roundness * U.widget_unit;
- uchar col[4];
/* state copy! */
wt->wcol = *(wt->wcol_theme);
+ uiWidgetBase wtb;
widget_init(&wtb);
if (but->block->drawextra) {
@@ -4298,6 +4240,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* make mask to draw over image */
+ uchar col[4];
UI_GetThemeColor3ubv(TH_BACK, col);
immUniformColor3ubv(col);
@@ -4317,9 +4260,9 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
static uiWidgetType *widget_type(uiWidgetTypeEnum type)
{
bTheme *btheme = UI_GetTheme();
- static uiWidgetType wt;
/* defaults */
+ static uiWidgetType wt;
wt.wcol_theme = &btheme->tui.wcol_regular;
wt.wcol_state = &btheme->tui.wcol_state;
wt.state = widget_state;
@@ -4820,13 +4763,12 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
if (wt) {
// rcti disablerect = *rect; /* rect gets clipped smaller for text */
- int roundboxalign, state, drawflag;
- roundboxalign = widget_roundbox_set(but, rect);
+ const int roundboxalign = widget_roundbox_set(but, rect);
/* Mask out flags re-used for local state. */
- state = but->flag & ~UI_STATE_FLAGS_ALL;
- drawflag = but->drawflag;
+ int state = but->flag & ~UI_STATE_FLAGS_ALL;
+ const int drawflag = but->drawflag;
if (state & UI_SELECT_DRAW) {
state |= UI_SELECT;
@@ -5056,10 +4998,9 @@ static void draw_disk_shaded(float start,
{
const float radius_ext_scale = (0.5f / radius_ext); /* 1 / (2 * radius_ext) */
- uint pos, col;
-
+ uint col;
GPUVertFormat *format = immVertexFormat();
- pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (shaded) {
col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 774187d18b7..1c84be5907b 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -2510,7 +2510,7 @@ static void rna_def_constraint_location_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", LIMIT_TRANSFORM);
RNA_def_property_ui_text(
- prop, "Affect Transform", "Transforms are affected by this constraint as well");
+ prop, "Affect Transform", "Transform tools are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);
@@ -2583,7 +2583,7 @@ static void rna_def_constraint_rotation_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", LIMIT_TRANSFORM);
RNA_def_property_ui_text(
- prop, "Affect Transform", "Transforms are affected by this constraint as well");
+ prop, "Affect Transform", "Transform tools are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);
@@ -2671,7 +2671,7 @@ static void rna_def_constraint_size_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", LIMIT_TRANSFORM);
RNA_def_property_ui_text(
- prop, "Affect Transform", "Transforms are affected by this constraint as well");
+ prop, "Affect Transform", "Transform tools are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);