Math Lib: Add non-clamped round_* functions

Replace iroundf with round_fl_to_int, add other types
This commit is contained in:
Campbell Barton 2017-09-27 11:13:03 +10:00
parent 870dfb1b5a
commit 43b4913051
23 changed files with 83 additions and 55 deletions

View File

@ -149,10 +149,23 @@ MINLINE int power_of_2_min_i(int n);
MINLINE unsigned int power_of_2_max_u(unsigned int x);
MINLINE unsigned int power_of_2_min_u(unsigned int x);
MINLINE int iroundf(float a);
MINLINE int divide_round_i(int a, int b);
MINLINE int mod_i(int i, int n);
MINLINE signed char round_fl_to_char(float a);
MINLINE unsigned char round_fl_to_uchar(float a);
MINLINE short round_fl_to_short(float a);
MINLINE unsigned short round_fl_to_ushort(float a);
MINLINE int round_fl_to_int(float a);
MINLINE unsigned int round_fl_to_uint(float a);
MINLINE signed char round_db_to_char(double a);
MINLINE unsigned char round_db_to_uchar(double a);
MINLINE short round_db_to_short(double a);
MINLINE unsigned short round_db_to_ushort(double a);
MINLINE int round_db_to_int(double a);
MINLINE unsigned int round_db_to_uint(double a);
MINLINE signed char round_fl_to_char_clamp(float a);
MINLINE unsigned char round_fl_to_uchar_clamp(float a);
MINLINE short round_fl_to_short_clamp(float a);

View File

@ -184,11 +184,6 @@ MINLINE unsigned power_of_2_min_u(unsigned x)
/* rounding and clamping */
MINLINE int iroundf(float a)
{
return (int)floorf(a + 0.5f);
}
#define _round_clamp_fl_impl(arg, ty, min, max) { \
float r = floorf(arg + 0.5f); \
if (UNLIKELY(r <= (float)min)) return (ty)min; \
@ -203,6 +198,26 @@ MINLINE int iroundf(float a)
else return (ty)r; \
}
#define _round_fl_impl(arg, ty) { return (ty)floorf(arg + 0.5f); }
#define _round_db_impl(arg, ty) { return (ty)floor(arg + 0.5); }
MINLINE signed char round_fl_to_char(float a) { _round_fl_impl(a, signed char) }
MINLINE unsigned char round_fl_to_uchar(float a) { _round_fl_impl(a, unsigned char) }
MINLINE short round_fl_to_short(float a) { _round_fl_impl(a, short) }
MINLINE unsigned short round_fl_to_ushort(float a) { _round_fl_impl(a, unsigned short) }
MINLINE int round_fl_to_int(float a) { _round_fl_impl(a, int) }
MINLINE unsigned int round_fl_to_uint(float a) { _round_fl_impl(a, unsigned int) }
MINLINE signed char round_db_to_char(double a) { _round_db_impl(a, signed char) }
MINLINE unsigned char round_db_to_uchar(double a) { _round_db_impl(a, unsigned char) }
MINLINE short round_db_to_short(double a) { _round_db_impl(a, short) }
MINLINE unsigned short round_db_to_ushort(double a) { _round_db_impl(a, unsigned short) }
MINLINE int round_db_to_int(double a) { _round_db_impl(a, int) }
MINLINE unsigned int round_db_to_uint(double a) { _round_db_impl(a, unsigned int) }
#undef _round_fl_impl
#undef _round_db_impl
MINLINE signed char round_fl_to_char_clamp(float a) { _round_clamp_fl_impl(a, signed char, SCHAR_MIN, SCHAR_MAX) }
MINLINE unsigned char round_fl_to_uchar_clamp(float a) { _round_clamp_fl_impl(a, unsigned char, 0, UCHAR_MAX) }
MINLINE short round_fl_to_short_clamp(float a) { _round_clamp_fl_impl(a, short, SHRT_MIN, SHRT_MAX) }

View File

@ -94,11 +94,11 @@ size_t BLI_timecode_string_from_time(
* to cope with 'half' frames, etc., which should be fine in most cases
*/
seconds = (int)time;
frames = iroundf((float)(((double)time - (double)seconds) * fps));
frames = round_fl_to_int((float)(((double)time - (double)seconds) * fps));
}
else {
/* seconds (with pixel offset rounding) */
seconds = iroundf(time);
seconds = round_fl_to_int(time);
}
switch (timecode_style) {
@ -169,7 +169,7 @@ size_t BLI_timecode_string_from_time(
/* precision of decimal part */
const int ms_dp = (power <= 0) ? (1 - power) : 1;
const int ms = iroundf((time - (float)seconds) * 1000.0f);
const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f);
rlen = BLI_snprintf_rlen(
str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms);
@ -183,7 +183,7 @@ size_t BLI_timecode_string_from_time(
rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - power, time_seconds);
}
else {
rlen = BLI_snprintf_rlen(str, maxncpy, "%d", iroundf(time_seconds));
rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
}
break;
}
@ -250,7 +250,7 @@ size_t BLI_timecode_string_from_time_seconds(
rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - power, time_seconds);
}
else {
rlen = BLI_snprintf_rlen(str, maxncpy, "%d", iroundf(time_seconds));
rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
}
return rlen;

View File

@ -4458,8 +4458,8 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
* a callback available (e.g. broken F-Curve rename)
*/
if (acf->name_prop(ale, &ptr, &prop)) {
const short margin_x = 3 * iroundf(UI_DPI_FAC);
const short channel_height = iroundf(ymaxc - yminc);
const short margin_x = 3 * round_fl_to_int(UI_DPI_FAC);
const short channel_height = round_fl_to_int(ymaxc - yminc);
const short width = ac->ar->winx - offset - (margin_x * 2);
uiBut *but;

View File

@ -149,7 +149,7 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f
(side == 'L' && marker->frame < cfra) ||
(side == 'R' && marker->frame >= cfra))
{
marker->frame += iroundf(value);
marker->frame += round_fl_to_int(value);
changed_tot++;
}
break;
@ -157,7 +157,7 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f
case TFM_TIME_SCALE:
{
/* rescale the distance between the marker and the current frame */
marker->frame = cfra + iroundf((float)(marker->frame - cfra) * value);
marker->frame = cfra + round_fl_to_int((float)(marker->frame - cfra) * value);
changed_tot++;
break;
}
@ -195,7 +195,7 @@ TimeMarker *ED_markers_find_nearest_marker(ListBase *markers, float x)
int ED_markers_find_nearest_marker_time(ListBase *markers, float x)
{
TimeMarker *nearest = ED_markers_find_nearest_marker(markers, x);
return (nearest) ? (nearest->frame) : iroundf(x);
return (nearest) ? (nearest->frame) : round_fl_to_int(x);
}

View File

@ -108,7 +108,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = frame - (int)frame;
}
else {
CFRA = iroundf(frame);
CFRA = round_fl_to_int(frame);
SUBFRA = 0.0f;
}
FRAMENUMBER_MIN_CLAMP(CFRA);
@ -301,8 +301,8 @@ static int previewrange_define_exec(bContext *C, wmOperator *op)
if (efra < sfra) efra = sfra;
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = iroundf(sfra);
scene->r.pefra = iroundf(efra);
scene->r.psfra = round_fl_to_int(sfra);
scene->r.pefra = round_fl_to_int(efra);
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);

View File

@ -1481,7 +1481,7 @@ static void pose_propagate_fcurve(wmOperator *op, Object *ob, FCurve *fcu,
/* stop on matching marker if there is one */
for (ce = modeData.sel_markers.first; ce; ce = ce->next) {
if (ce->cfra == iroundf(bezt->vec[1][0]))
if (ce->cfra == round_fl_to_int(bezt->vec[1][0]))
break;
}

View File

@ -1732,10 +1732,10 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm, Scene *scene, View3D *v3d, AReg
rctf rectf;
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, true); /* no shift */
offsx = iroundf(rectf.xmin);
offsy = iroundf(rectf.ymin);
winx = iroundf(rectf.xmax - rectf.xmin);
winy = iroundf(rectf.ymax - rectf.ymin);
offsx = round_fl_to_int(rectf.xmin);
offsy = round_fl_to_int(rectf.ymin);
winx = round_fl_to_int(rectf.xmax - rectf.xmin);
winy = round_fl_to_int(rectf.ymax - rectf.ymin);
}
else {
offsx = 0;

View File

@ -4295,7 +4295,7 @@ static bool ui_numedit_but_NUM(
if (!is_float) {
temp = iroundf(tempf);
temp = round_fl_to_int(tempf);
temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
@ -4580,7 +4580,7 @@ static bool ui_numedit_but_SLI(
tempf = softmin + f * softrange;
temp = iroundf(tempf);
temp = round_fl_to_int(tempf);
if (snap) {
if (tempf == softmin || tempf == softmax) {

View File

@ -496,14 +496,14 @@ static void ui_draw_panel_dragwidget(const rctf *rect)
const int col_tint = 84;
const int px = (int)U.pixelsize;
const int px_zoom = max_ii(iroundf(BLI_rctf_size_y(rect) / 22.0f), 1);
const int px_zoom = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 22.0f), 1);
const int box_margin = max_ii(iroundf((float)(px_zoom * 2.0f)), px);
const int box_size = max_ii(iroundf((BLI_rctf_size_y(rect) / 8.0f) - px), px);
const int box_margin = max_ii(round_fl_to_int((float)(px_zoom * 2.0f)), px);
const int box_size = max_ii(round_fl_to_int((BLI_rctf_size_y(rect) / 8.0f) - px), px);
const int x_min = rect->xmin;
const int y_min = rect->ymin;
const int y_ofs = max_ii(iroundf(BLI_rctf_size_y(rect) / 3.0f), px);
const int y_ofs = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 3.0f), px);
const int x_ofs = y_ofs;
int i_x, i_y;
@ -877,8 +877,8 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
for (a = 0; a < tot; a++, ps++) {
if ((ps->pa->flag & PNL_SELECT) == 0) {
if ((ps->orig->ofsx != ps->pa->ofsx) || (ps->orig->ofsy != ps->pa->ofsy)) {
ps->orig->ofsx = iroundf(fac * (float)ps->pa->ofsx + (1.0f - fac) * (float)ps->orig->ofsx);
ps->orig->ofsy = iroundf(fac * (float)ps->pa->ofsy + (1.0f - fac) * (float)ps->orig->ofsy);
ps->orig->ofsx = round_fl_to_int(fac * (float)ps->pa->ofsx + (1.0f - fac) * (float)ps->orig->ofsx);
ps->orig->ofsy = round_fl_to_int(fac * (float)ps->pa->ofsy + (1.0f - fac) * (float)ps->orig->ofsy);
done = true;
}
}
@ -1615,11 +1615,11 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
PanelCategoryDyn *pc_dyn;
const float aspect = ((uiBlock *)ar->uiblocks.first)->aspect;
const float zoom = 1.0f / aspect;
const int px = max_ii(1, iroundf(U.pixelsize));
const int category_tabs_width = iroundf(UI_PANEL_CATEGORY_MARGIN_WIDTH * zoom);
const int px = max_ii(1, round_fl_to_int(U.pixelsize));
const int category_tabs_width = round_fl_to_int(UI_PANEL_CATEGORY_MARGIN_WIDTH * zoom);
const float dpi_fac = UI_DPI_FAC;
const int tab_v_pad_text = iroundf((2 + ((px * 3) * dpi_fac)) * zoom); /* pading of tabs around text */
const int tab_v_pad = iroundf((4 + (2 * px * dpi_fac)) * zoom); /* padding between tabs */
const int tab_v_pad_text = round_fl_to_int((2 + ((px * 3) * dpi_fac)) * zoom); /* pading of tabs around text */
const int tab_v_pad = round_fl_to_int((4 + (2 * px * dpi_fac)) * zoom); /* padding between tabs */
const float tab_curve_radius = ((px * 3) * dpi_fac) * zoom;
const int roundboxtype = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
bool is_alpha;

View File

@ -2841,7 +2841,7 @@ static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
uiListDyn *dyn_data = ui_list->dyn_data;
/* This way we get diff in number of additional items to show (positive) or hide (negative). */
const int diff = iroundf((float)(dyn_data->resize - dyn_data->resize_prev) / (float)UI_UNIT_Y);
const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) / (float)UI_UNIT_Y);
if (diff != 0) {
ui_list->list_grip += diff;

View File

@ -1522,7 +1522,7 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
/* set the new current frame value, based on the average time */
if (ked.i1) {
Scene *scene = ac.scene;
CFRA = iroundf(ked.f1 / ked.i1);
CFRA = round_fl_to_int(ked.f1 / ked.i1);
SUBFRA = 0.f;
}

View File

@ -941,7 +941,7 @@ static int frame_from_event(bContext *C, const wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
framenr = iroundf(viewx);
framenr = round_fl_to_int(viewx);
}
return framenr;

View File

@ -195,8 +195,8 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
/* set the range directly */
get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, false, false);
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = iroundf(min);
scene->r.pefra = iroundf(max);
scene->r.psfra = round_fl_to_int(min);
scene->r.pefra = round_fl_to_int(max);
/* set notifier that things have changed */
// XXX err... there's nothing for frame ranges yet, but this should do fine too
@ -2036,7 +2036,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
/* Animation Mode - Affects current frame (int) */
CFRA = iroundf(ked.f1 / ked.i1);
CFRA = round_fl_to_int(ked.f1 / ked.i1);
SUBFRA = 0.f;
sipo->cursorVal = ked.f2 / (float)ked.i1;
}

View File

@ -94,7 +94,7 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
* NOTE: sync this part of the code with ANIM_OT_change_frame
*/
/* 1) frame is rounded to the nearest int, since frames are ints */
CFRA = iroundf(frame);
CFRA = round_fl_to_int(frame);
if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
/* Clip to preview range

View File

@ -3526,7 +3526,7 @@ static int frame_from_event(bContext *C, const wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
framenr = iroundf(viewx);
framenr = round_fl_to_int(viewx);
}
return framenr;

View File

@ -365,8 +365,8 @@ static int nlaedit_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
/* set the range directly */
get_nlastrip_extents(&ac, &min, &max, true);
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = iroundf(min);
scene->r.pefra = iroundf(max);
scene->r.psfra = round_fl_to_int(min);
scene->r.pefra = round_fl_to_int(max);
/* set notifier that things have changed */
// XXX err... there's nothing for frame ranges yet, but this should do fine too

View File

@ -1091,7 +1091,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname,
iroundf(rct->xmin + NODE_MARGIN_X), iroundf(centy - NODE_DY * 0.5f),
round_fl_to_int(rct->xmin + NODE_MARGIN_X), round_fl_to_int(centy - NODE_DY * 0.5f),
(short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY,
NULL, 0, 0, 0, 0, "");
}

View File

@ -2801,7 +2801,7 @@ void flushTransSeq(TransInfo *t)
tdsq = (TransDataSeq *)td->extra;
seq = tdsq->seq;
old_start = seq->start;
new_frame = iroundf(td2d->loc[0]);
new_frame = round_fl_to_int(td2d->loc[0]);
switch (tdsq->sel_flag) {
case SELECT:
@ -2813,7 +2813,7 @@ void flushTransSeq(TransInfo *t)
seq->start = new_frame - tdsq->start_offset;
#endif
if (seq->depth == 0) {
seq->machine = iroundf(td2d->loc[1]);
seq->machine = round_fl_to_int(td2d->loc[1]);
CLAMP(seq->machine, 1, MAXSEQ);
}
break;
@ -3761,7 +3761,7 @@ void flushTransIntFrameActionData(TransInfo *t)
/* flush data! */
for (i = 0; i < t->total; i++, tfd++) {
*(tfd->sdata) = iroundf(tfd->val);
*(tfd->sdata) = round_fl_to_int(tfd->val);
}
}

View File

@ -1467,7 +1467,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2])
/* convert to frame range */
UI_view2d_region_to_view(&t->ar->v2d, mval[0], mval[1], &xmouse, &ymouse);
mframe = iroundf(xmouse);
mframe = round_fl_to_int(xmouse);
/* now find the closest sequence */
frame = BKE_sequencer_find_next_prev_edit(t->scene, mframe, SEQ_SIDE_BOTH, true, false, true);

View File

@ -36,7 +36,7 @@ void MOD_meshcache_calc_range(const float frame, const char interp,
int r_index_range[2], float *r_factor)
{
if (interp == MOD_MESHCACHE_INTERP_NONE) {
r_index_range[0] = r_index_range[1] = max_ii(0, min_ii(frame_tot - 1, iroundf(frame)));
r_index_range[0] = r_index_range[1] = max_ii(0, min_ii(frame_tot - 1, round_fl_to_int(frame)));
*r_factor = 1.0f; /* dummy */
}
else {

View File

@ -1172,7 +1172,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
a = max_ff(a, 1.0f);
b = max_ff(b, 1.0f);
fProbes = 2.f*(a / b) - 1.f;
AFD.iProbes = iroundf(fProbes);
AFD.iProbes = round_fl_to_int(fProbes);
AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
if (AFD.iProbes < fProbes)
b = 2.f*a / (float)(AFD.iProbes + 1);
@ -1277,7 +1277,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
b = max_ff(b, 1.0f);
fProbes = 2.f*(a / b) - 1.f;
/* no limit to number of Probes here */
AFD.iProbes = iroundf(fProbes);
AFD.iProbes = round_fl_to_int(fProbes);
if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
AFD.majrad = a/ff;
AFD.minrad = b/ff;

View File

@ -137,7 +137,7 @@ int wm_gesture_evaluate(wmGesture *gesture)
int dx = BLI_rcti_size_x(rect);
int dy = BLI_rcti_size_y(rect);
if (abs(dx) + abs(dy) > U.tweak_threshold) {
int theta = iroundf(4.0f * atan2f((float)dy, (float)dx) / (float)M_PI);
int theta = round_fl_to_int(4.0f * atan2f((float)dy, (float)dx) / (float)M_PI);
int val = EVT_GESTURE_W;
if (theta == 0) val = EVT_GESTURE_E;