Fix assert in some cases when using DataTransfer modifier for custom normals.
[blender.git] / source / blender / blenlib / intern / rct.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bli
22  *
23  * A minimalist lib for functions doing stuff with rectangle structs.
24  */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <math.h>
29
30 #include <limits.h>
31 #include <float.h>
32
33 #include "BLI_rect.h"
34 #include "BLI_utildefines.h"
35
36 #include "DNA_vec_types.h"
37
38 /* avoid including BLI_math */
39 static void unit_m4(float m[4][4]);
40
41 /**
42  * Determine if a rect is empty. An empty
43  * rect is one with a zero (or negative)
44  * width or height.
45  *
46  * \return True if \a rect is empty.
47  */
48 bool BLI_rcti_is_empty(const rcti *rect)
49 {
50   return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
51 }
52
53 bool BLI_rctf_is_empty(const rctf *rect)
54 {
55   return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
56 }
57
58 bool BLI_rcti_isect_x(const rcti *rect, const int x)
59 {
60   if (x < rect->xmin) {
61     return false;
62   }
63   if (x > rect->xmax) {
64     return false;
65   }
66   return true;
67 }
68
69 bool BLI_rcti_isect_y(const rcti *rect, const int y)
70 {
71   if (y < rect->ymin) {
72     return false;
73   }
74   if (y > rect->ymax) {
75     return false;
76   }
77   return true;
78 }
79
80 bool BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
81 {
82   if (x < rect->xmin) {
83     return false;
84   }
85   if (x > rect->xmax) {
86     return false;
87   }
88   if (y < rect->ymin) {
89     return false;
90   }
91   if (y > rect->ymax) {
92     return false;
93   }
94   return true;
95 }
96
97 bool BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
98 {
99   if (xy[0] < rect->xmin) {
100     return false;
101   }
102   if (xy[0] > rect->xmax) {
103     return false;
104   }
105   if (xy[1] < rect->ymin) {
106     return false;
107   }
108   if (xy[1] > rect->ymax) {
109     return false;
110   }
111   return true;
112 }
113
114 bool BLI_rctf_isect_x(const rctf *rect, const float x)
115 {
116   if (x < rect->xmin) {
117     return false;
118   }
119   if (x > rect->xmax) {
120     return false;
121   }
122   return true;
123 }
124
125 bool BLI_rctf_isect_y(const rctf *rect, const float y)
126 {
127   if (y < rect->ymin) {
128     return false;
129   }
130   if (y > rect->ymax) {
131     return false;
132   }
133   return true;
134 }
135
136 bool BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
137 {
138   if (x < rect->xmin) {
139     return false;
140   }
141   if (x > rect->xmax) {
142     return false;
143   }
144   if (y < rect->ymin) {
145     return false;
146   }
147   if (y > rect->ymax) {
148     return false;
149   }
150   return true;
151 }
152
153 bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
154 {
155   if (xy[0] < rect->xmin) {
156     return false;
157   }
158   if (xy[0] > rect->xmax) {
159     return false;
160   }
161   if (xy[1] < rect->ymin) {
162     return false;
163   }
164   if (xy[1] > rect->ymax) {
165     return false;
166   }
167   return true;
168 }
169
170 /**
171  * \returns shortest distance from \a rect to x/y (0 if inside)
172  */
173
174 int BLI_rcti_length_x(const rcti *rect, const int x)
175 {
176   if (x < rect->xmin) {
177     return rect->xmin - x;
178   }
179   if (x > rect->xmax) {
180     return x - rect->xmax;
181   }
182   return 0;
183 }
184
185 int BLI_rcti_length_y(const rcti *rect, const int y)
186 {
187   if (y < rect->ymin) {
188     return rect->ymin - y;
189   }
190   if (y > rect->ymax) {
191     return y - rect->ymax;
192   }
193   return 0;
194 }
195
196 float BLI_rctf_length_x(const rctf *rect, const float x)
197 {
198   if (x < rect->xmin) {
199     return rect->xmin - x;
200   }
201   if (x > rect->xmax) {
202     return x - rect->xmax;
203   }
204   return 0.0f;
205 }
206
207 float BLI_rctf_length_y(const rctf *rect, const float y)
208 {
209   if (y < rect->ymin) {
210     return rect->ymin - y;
211   }
212   if (y > rect->ymax) {
213     return y - rect->ymax;
214   }
215   return 0.0f;
216 }
217
218 /**
219  * is \a rct_b inside \a rct_a
220  */
221 bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b)
222 {
223   return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) &&
224           (rct_a->ymin <= rct_b->ymin) && (rct_a->ymax >= rct_b->ymax));
225 }
226 bool BLI_rcti_inside_rcti(const rcti *rct_a, const rcti *rct_b)
227 {
228   return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) &&
229           (rct_a->ymin <= rct_b->ymin) && (rct_a->ymax >= rct_b->ymax));
230 }
231
232 /* based closely on 'isect_seg_seg_v2_int',
233  * but in modified so corner cases are treated as intersections */
234 static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
235 {
236   const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) -
237                               (v2[1] - v1[1]) * (v4[0] - v3[0]));
238   if (div == 0.0) {
239     return 1; /* co-linear */
240   }
241   else {
242     const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
243                                    (v1[0] - v3[0]) * (v4[1] - v3[1])) /
244                           div;
245     const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
246                                (v1[0] - v3[0]) * (v2[1] - v1[1])) /
247                       div;
248     return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
249   }
250 }
251 static int isect_segments_fl(const float v1[2],
252                              const float v2[2],
253                              const float v3[2],
254                              const float v4[2])
255 {
256   const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) -
257                               (v2[1] - v1[1]) * (v4[0] - v3[0]));
258   if (div == 0.0) {
259     return 1; /* co-linear */
260   }
261   else {
262     const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
263                                    (v1[0] - v3[0]) * (v4[1] - v3[1])) /
264                           div;
265     const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
266                                (v1[0] - v3[0]) * (v2[1] - v1[1])) /
267                       div;
268     return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
269   }
270 }
271
272 bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
273 {
274   /* first do outside-bounds check for both points of the segment */
275   if (s1[0] < rect->xmin && s2[0] < rect->xmin) {
276     return false;
277   }
278   if (s1[0] > rect->xmax && s2[0] > rect->xmax) {
279     return false;
280   }
281   if (s1[1] < rect->ymin && s2[1] < rect->ymin) {
282     return false;
283   }
284   if (s1[1] > rect->ymax && s2[1] > rect->ymax) {
285     return false;
286   }
287
288   /* if either points intersect then we definetly intersect */
289   if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
290     return true;
291   }
292   else {
293     /* both points are outside but may insersect the rect */
294     int tvec1[2];
295     int tvec2[2];
296     /* diagonal: [/] */
297     tvec1[0] = rect->xmin;
298     tvec1[1] = rect->ymin;
299     tvec2[0] = rect->xmin;
300     tvec2[1] = rect->ymax;
301     if (isect_segments_i(s1, s2, tvec1, tvec2)) {
302       return true;
303     }
304
305     /* diagonal: [\] */
306     tvec1[0] = rect->xmin;
307     tvec1[1] = rect->ymax;
308     tvec2[0] = rect->xmax;
309     tvec2[1] = rect->ymin;
310     if (isect_segments_i(s1, s2, tvec1, tvec2)) {
311       return true;
312     }
313
314     /* no intersection */
315     return false;
316   }
317 }
318
319 bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
320 {
321   /* first do outside-bounds check for both points of the segment */
322   if (s1[0] < rect->xmin && s2[0] < rect->xmin) {
323     return false;
324   }
325   if (s1[0] > rect->xmax && s2[0] > rect->xmax) {
326     return false;
327   }
328   if (s1[1] < rect->ymin && s2[1] < rect->ymin) {
329     return false;
330   }
331   if (s1[1] > rect->ymax && s2[1] > rect->ymax) {
332     return false;
333   }
334
335   /* if either points intersect then we definetly intersect */
336   if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
337     return true;
338   }
339   else {
340     /* both points are outside but may insersect the rect */
341     float tvec1[2];
342     float tvec2[2];
343     /* diagonal: [/] */
344     tvec1[0] = rect->xmin;
345     tvec1[1] = rect->ymin;
346     tvec2[0] = rect->xmin;
347     tvec2[1] = rect->ymax;
348     if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
349       return true;
350     }
351
352     /* diagonal: [\] */
353     tvec1[0] = rect->xmin;
354     tvec1[1] = rect->ymax;
355     tvec2[0] = rect->xmax;
356     tvec2[1] = rect->ymin;
357     if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
358       return true;
359     }
360
361     /* no intersection */
362     return false;
363   }
364 }
365
366 bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius)
367 {
368   float dx, dy;
369
370   if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
371     dx = 0;
372   }
373   else {
374     dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
375   }
376
377   if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
378     dy = 0;
379   }
380   else {
381     dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
382   }
383
384   return dx * dx + dy * dy <= radius * radius;
385 }
386
387 bool BLI_rctf_isect_circle(const rctf *rect, const float xy[2], const float radius)
388 {
389   float dx, dy;
390
391   if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
392     dx = 0;
393   }
394   else {
395     dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
396   }
397
398   if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
399     dy = 0;
400   }
401   else {
402     dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
403   }
404
405   return dx * dx + dy * dy <= radius * radius;
406 }
407
408 void BLI_rctf_union(rctf *rct1, const rctf *rct2)
409 {
410   if (rct1->xmin > rct2->xmin) {
411     rct1->xmin = rct2->xmin;
412   }
413   if (rct1->xmax < rct2->xmax) {
414     rct1->xmax = rct2->xmax;
415   }
416   if (rct1->ymin > rct2->ymin) {
417     rct1->ymin = rct2->ymin;
418   }
419   if (rct1->ymax < rct2->ymax) {
420     rct1->ymax = rct2->ymax;
421   }
422 }
423
424 void BLI_rcti_union(rcti *rct1, const rcti *rct2)
425 {
426   if (rct1->xmin > rct2->xmin) {
427     rct1->xmin = rct2->xmin;
428   }
429   if (rct1->xmax < rct2->xmax) {
430     rct1->xmax = rct2->xmax;
431   }
432   if (rct1->ymin > rct2->ymin) {
433     rct1->ymin = rct2->ymin;
434   }
435   if (rct1->ymax < rct2->ymax) {
436     rct1->ymax = rct2->ymax;
437   }
438 }
439
440 void BLI_rctf_init(rctf *rect, float xmin, float xmax, float ymin, float ymax)
441 {
442   if (xmin <= xmax) {
443     rect->xmin = xmin;
444     rect->xmax = xmax;
445   }
446   else {
447     rect->xmax = xmin;
448     rect->xmin = xmax;
449   }
450   if (ymin <= ymax) {
451     rect->ymin = ymin;
452     rect->ymax = ymax;
453   }
454   else {
455     rect->ymax = ymin;
456     rect->ymin = ymax;
457   }
458 }
459
460 void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
461 {
462   if (xmin <= xmax) {
463     rect->xmin = xmin;
464     rect->xmax = xmax;
465   }
466   else {
467     rect->xmax = xmin;
468     rect->xmin = xmax;
469   }
470   if (ymin <= ymax) {
471     rect->ymin = ymin;
472     rect->ymax = ymax;
473   }
474   else {
475     rect->ymax = ymin;
476     rect->ymin = ymax;
477   }
478 }
479
480 void BLI_rctf_init_pt_radius(rctf *rect, const float xy[2], float size)
481 {
482   rect->xmin = xy[0] - size;
483   rect->xmax = xy[0] + size;
484   rect->ymin = xy[1] - size;
485   rect->ymax = xy[1] + size;
486 }
487
488 void BLI_rcti_init_pt_radius(rcti *rect, const int xy[2], int size)
489 {
490   rect->xmin = xy[0] - size;
491   rect->xmax = xy[0] + size;
492   rect->ymin = xy[1] - size;
493   rect->ymax = xy[1] + size;
494 }
495
496 void BLI_rcti_init_minmax(rcti *rect)
497 {
498   rect->xmin = rect->ymin = INT_MAX;
499   rect->xmax = rect->ymax = INT_MIN;
500 }
501
502 void BLI_rctf_init_minmax(rctf *rect)
503 {
504   rect->xmin = rect->ymin = FLT_MAX;
505   rect->xmax = rect->ymax = -FLT_MAX;
506 }
507
508 void BLI_rcti_do_minmax_v(rcti *rect, const int xy[2])
509 {
510   if (xy[0] < rect->xmin) {
511     rect->xmin = xy[0];
512   }
513   if (xy[0] > rect->xmax) {
514     rect->xmax = xy[0];
515   }
516   if (xy[1] < rect->ymin) {
517     rect->ymin = xy[1];
518   }
519   if (xy[1] > rect->ymax) {
520     rect->ymax = xy[1];
521   }
522 }
523
524 void BLI_rctf_do_minmax_v(rctf *rect, const float xy[2])
525 {
526   if (xy[0] < rect->xmin) {
527     rect->xmin = xy[0];
528   }
529   if (xy[0] > rect->xmax) {
530     rect->xmax = xy[0];
531   }
532   if (xy[1] < rect->ymin) {
533     rect->ymin = xy[1];
534   }
535   if (xy[1] > rect->ymax) {
536     rect->ymax = xy[1];
537   }
538 }
539
540 /* given 2 rectangles - transform a point from one to another */
541 void BLI_rctf_transform_pt_v(const rctf *dst,
542                              const rctf *src,
543                              float xy_dst[2],
544                              const float xy_src[2])
545 {
546   xy_dst[0] = ((xy_src[0] - src->xmin) / (src->xmax - src->xmin));
547   xy_dst[0] = dst->xmin + ((dst->xmax - dst->xmin) * xy_dst[0]);
548
549   xy_dst[1] = ((xy_src[1] - src->ymin) / (src->ymax - src->ymin));
550   xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]);
551 }
552
553 /**
554  * Calculate a 4x4 matrix representing the transformation between two rectangles.
555  *
556  * \note Multiplying a vector by this matrix does *not*
557  * give the same value as #BLI_rctf_transform_pt_v.
558  */
559 void BLI_rctf_transform_calc_m4_pivot_min_ex(
560     const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y)
561 {
562   BLI_assert(x < 3 && y < 3);
563
564   unit_m4(matrix);
565
566   matrix[x][x] = BLI_rctf_size_x(src) / BLI_rctf_size_x(dst);
567   matrix[y][y] = BLI_rctf_size_y(src) / BLI_rctf_size_y(dst);
568   matrix[3][x] = (src->xmin - dst->xmin) * matrix[x][x];
569   matrix[3][y] = (src->ymin - dst->ymin) * matrix[y][y];
570 }
571
572 void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
573 {
574   BLI_rctf_transform_calc_m4_pivot_min_ex(dst, src, matrix, 0, 1);
575 }
576
577 void BLI_rcti_translate(rcti *rect, int x, int y)
578 {
579   rect->xmin += x;
580   rect->ymin += y;
581   rect->xmax += x;
582   rect->ymax += y;
583 }
584 void BLI_rctf_translate(rctf *rect, float x, float y)
585 {
586   rect->xmin += x;
587   rect->ymin += y;
588   rect->xmax += x;
589   rect->ymax += y;
590 }
591
592 void BLI_rcti_recenter(rcti *rect, int x, int y)
593 {
594   const int dx = x - BLI_rcti_cent_x(rect);
595   const int dy = y - BLI_rcti_cent_y(rect);
596   BLI_rcti_translate(rect, dx, dy);
597 }
598 void BLI_rctf_recenter(rctf *rect, float x, float y)
599 {
600   const float dx = x - BLI_rctf_cent_x(rect);
601   const float dy = y - BLI_rctf_cent_y(rect);
602   BLI_rctf_translate(rect, dx, dy);
603 }
604
605 /* change width & height around the central location */
606 void BLI_rcti_resize(rcti *rect, int x, int y)
607 {
608   rect->xmin = BLI_rcti_cent_x(rect) - (x / 2);
609   rect->ymin = BLI_rcti_cent_y(rect) - (y / 2);
610   rect->xmax = rect->xmin + x;
611   rect->ymax = rect->ymin + y;
612 }
613
614 void BLI_rctf_resize(rctf *rect, float x, float y)
615 {
616   rect->xmin = BLI_rctf_cent_x(rect) - (x * 0.5f);
617   rect->ymin = BLI_rctf_cent_y(rect) - (y * 0.5f);
618   rect->xmax = rect->xmin + x;
619   rect->ymax = rect->ymin + y;
620 }
621
622 void BLI_rcti_scale(rcti *rect, const float scale)
623 {
624   const int cent_x = BLI_rcti_cent_x(rect);
625   const int cent_y = BLI_rcti_cent_y(rect);
626   const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
627   const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
628   rect->xmin = cent_x - size_x_half;
629   rect->ymin = cent_y - size_y_half;
630   rect->xmax = cent_x + size_x_half;
631   rect->ymax = cent_y + size_y_half;
632 }
633
634 void BLI_rctf_scale(rctf *rect, const float scale)
635 {
636   const float cent_x = BLI_rctf_cent_x(rect);
637   const float cent_y = BLI_rctf_cent_y(rect);
638   const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
639   const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
640   rect->xmin = cent_x - size_x_half;
641   rect->ymin = cent_y - size_y_half;
642   rect->xmax = cent_x + size_x_half;
643   rect->ymax = cent_y + size_y_half;
644 }
645
646 void BLI_rctf_pad_y(rctf *rect,
647                     const float boundary_size,
648                     const float pad_min,
649                     const float pad_max)
650 {
651   BLI_assert(pad_max >= 0.0f);
652   BLI_assert(pad_min >= 0.0f);
653   BLI_assert(boundary_size > 0.0f);
654
655   float total_pad = pad_max + pad_min;
656   if (total_pad == 0.0f) {
657     return;
658   }
659
660   float total_extend = BLI_rctf_size_y(rect) * total_pad / (boundary_size - total_pad);
661   rect->ymax += total_extend * (pad_max / total_pad);
662   rect->ymin -= total_extend * (pad_min / total_pad);
663 }
664
665 void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
666 {
667   const float ifac = 1.0f - fac;
668   rect->xmin = (rect_a->xmin * ifac) + (rect_b->xmin * fac);
669   rect->xmax = (rect_a->xmax * ifac) + (rect_b->xmax * fac);
670   rect->ymin = (rect_a->ymin * ifac) + (rect_b->ymin * fac);
671   rect->ymax = (rect_a->ymax * ifac) + (rect_b->ymax * fac);
672 }
673
674 /* BLI_rcti_interp() not needed yet */
675
676 bool BLI_rctf_clamp_pt_v(const rctf *rect, float xy[2])
677 {
678   bool changed = false;
679   if (xy[0] < rect->xmin) {
680     xy[0] = rect->xmin;
681     changed = true;
682   }
683   if (xy[0] > rect->xmax) {
684     xy[0] = rect->xmax;
685     changed = true;
686   }
687   if (xy[1] < rect->ymin) {
688     xy[1] = rect->ymin;
689     changed = true;
690   }
691   if (xy[1] > rect->ymax) {
692     xy[1] = rect->ymax;
693     changed = true;
694   }
695   return changed;
696 }
697
698 bool BLI_rcti_clamp_pt_v(const rcti *rect, int xy[2])
699 {
700   bool changed = false;
701   if (xy[0] < rect->xmin) {
702     xy[0] = rect->xmin;
703     changed = true;
704   }
705   if (xy[0] > rect->xmax) {
706     xy[0] = rect->xmax;
707     changed = true;
708   }
709   if (xy[1] < rect->ymin) {
710     xy[1] = rect->ymin;
711     changed = true;
712   }
713   if (xy[1] > rect->ymax) {
714     xy[1] = rect->ymax;
715     changed = true;
716   }
717   return changed;
718 }
719
720 /**
721  * Clamp \a rect within \a rect_bounds, setting \a r_xy to the offset.
722  *
723  * Keeps the top left corner within the bounds, which for user interface
724  * elements is typically where the most important information is.
725  *
726  * \return true if a change is made.
727  */
728 bool BLI_rctf_clamp(rctf *rect, const rctf *rect_bounds, float r_xy[2])
729 {
730   bool changed = false;
731
732   r_xy[0] = 0.0f;
733   r_xy[1] = 0.0f;
734
735   if (rect->xmax > rect_bounds->xmax) {
736     float ofs = rect_bounds->xmax - rect->xmax;
737     rect->xmin += ofs;
738     rect->xmax += ofs;
739     r_xy[0] += ofs;
740     changed = true;
741   }
742
743   if (rect->xmin < rect_bounds->xmin) {
744     float ofs = rect_bounds->xmin - rect->xmin;
745     rect->xmin += ofs;
746     rect->xmax += ofs;
747     r_xy[0] += ofs;
748     changed = true;
749   }
750
751   if (rect->ymin < rect_bounds->ymin) {
752     float ofs = rect_bounds->ymin - rect->ymin;
753     rect->ymin += ofs;
754     rect->ymax += ofs;
755     r_xy[1] += ofs;
756     changed = true;
757   }
758
759   if (rect->ymax > rect_bounds->ymax) {
760     float ofs = rect_bounds->ymax - rect->ymax;
761     rect->ymin += ofs;
762     rect->ymax += ofs;
763     r_xy[1] += ofs;
764     changed = true;
765   }
766
767   return changed;
768 }
769
770 bool BLI_rcti_clamp(rcti *rect, const rcti *rect_bounds, int r_xy[2])
771 {
772   bool changed = false;
773
774   r_xy[0] = 0;
775   r_xy[1] = 0;
776
777   if (rect->xmax > rect_bounds->xmax) {
778     int ofs = rect_bounds->xmax - rect->xmax;
779     rect->xmin += ofs;
780     rect->xmax += ofs;
781     r_xy[0] += ofs;
782     changed = true;
783   }
784
785   if (rect->xmin < rect_bounds->xmin) {
786     int ofs = rect_bounds->xmin - rect->xmin;
787     rect->xmin += ofs;
788     rect->xmax += ofs;
789     r_xy[0] += ofs;
790     changed = true;
791   }
792
793   if (rect->ymin < rect_bounds->ymin) {
794     int ofs = rect_bounds->ymin - rect->ymin;
795     rect->ymin += ofs;
796     rect->ymax += ofs;
797     r_xy[1] += ofs;
798     changed = true;
799   }
800
801   if (rect->ymax > rect_bounds->ymax) {
802     int ofs = rect_bounds->ymax - rect->ymax;
803     rect->ymin += ofs;
804     rect->ymax += ofs;
805     r_xy[1] += ofs;
806     changed = true;
807   }
808
809   return changed;
810 }
811
812 bool BLI_rctf_compare(const rctf *rect_a, const rctf *rect_b, const float limit)
813 {
814   if (fabsf(rect_a->xmin - rect_b->xmin) < limit) {
815     if (fabsf(rect_a->xmax - rect_b->xmax) < limit) {
816       if (fabsf(rect_a->ymin - rect_b->ymin) < limit) {
817         if (fabsf(rect_a->ymax - rect_b->ymax) < limit) {
818           return true;
819         }
820       }
821     }
822   }
823
824   return false;
825 }
826
827 bool BLI_rcti_compare(const rcti *rect_a, const rcti *rect_b)
828 {
829   if (rect_a->xmin == rect_b->xmin) {
830     if (rect_a->xmax == rect_b->xmax) {
831       if (rect_a->ymin == rect_b->ymin) {
832         if (rect_a->ymax == rect_b->ymax) {
833           return true;
834         }
835       }
836     }
837   }
838
839   return false;
840 }
841
842 bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
843 {
844   float xmin, xmax;
845   float ymin, ymax;
846
847   xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
848   xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
849   ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
850   ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
851
852   if (xmax >= xmin && ymax >= ymin) {
853     if (dest) {
854       dest->xmin = xmin;
855       dest->xmax = xmax;
856       dest->ymin = ymin;
857       dest->ymax = ymax;
858     }
859     return true;
860   }
861   else {
862     if (dest) {
863       dest->xmin = 0;
864       dest->xmax = 0;
865       dest->ymin = 0;
866       dest->ymax = 0;
867     }
868     return false;
869   }
870 }
871
872 bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
873 {
874   int xmin, xmax;
875   int ymin, ymax;
876
877   xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
878   xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
879   ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
880   ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
881
882   if (xmax >= xmin && ymax >= ymin) {
883     if (dest) {
884       dest->xmin = xmin;
885       dest->xmax = xmax;
886       dest->ymin = ymin;
887       dest->ymax = ymax;
888     }
889     return true;
890   }
891   else {
892     if (dest) {
893       dest->xmin = 0;
894       dest->xmax = 0;
895       dest->ymin = 0;
896       dest->ymax = 0;
897     }
898     return false;
899   }
900 }
901
902 void BLI_rcti_rctf_copy(rcti *dst, const rctf *src)
903 {
904   dst->xmin = floorf(src->xmin + 0.5f);
905   dst->xmax = dst->xmin + floorf(BLI_rctf_size_x(src) + 0.5f);
906   dst->ymin = floorf(src->ymin + 0.5f);
907   dst->ymax = dst->ymin + floorf(BLI_rctf_size_y(src) + 0.5f);
908 }
909
910 void BLI_rcti_rctf_copy_floor(rcti *dst, const rctf *src)
911 {
912   dst->xmin = floorf(src->xmin);
913   dst->xmax = floorf(src->xmax);
914   dst->ymin = floorf(src->ymin);
915   dst->ymax = floorf(src->ymax);
916 }
917
918 void BLI_rcti_rctf_copy_round(rcti *dst, const rctf *src)
919 {
920   dst->xmin = floorf(src->xmin + 0.5f);
921   dst->xmax = floorf(src->xmax + 0.5f);
922   dst->ymin = floorf(src->ymin + 0.5f);
923   dst->ymax = floorf(src->ymax + 0.5f);
924 }
925
926 void BLI_rctf_rcti_copy(rctf *dst, const rcti *src)
927 {
928   dst->xmin = src->xmin;
929   dst->xmax = src->xmax;
930   dst->ymin = src->ymin;
931   dst->ymax = src->ymax;
932 }
933
934 void print_rctf(const char *str, const rctf *rect)
935 {
936   printf("%s: xmin %.8f, xmax %.8f, ymin %.8f, ymax %.8f (%.12fx%.12f)\n",
937          str,
938          rect->xmin,
939          rect->xmax,
940          rect->ymin,
941          rect->ymax,
942          BLI_rctf_size_x(rect),
943          BLI_rctf_size_y(rect));
944 }
945
946 void print_rcti(const char *str, const rcti *rect)
947 {
948   printf("%s: xmin %d, xmax %d, ymin %d, ymax %d (%dx%d)\n",
949          str,
950          rect->xmin,
951          rect->xmax,
952          rect->ymin,
953          rect->ymax,
954          BLI_rcti_size_x(rect),
955          BLI_rcti_size_y(rect));
956 }
957
958 /* -------------------------------------------------------------------- */
959 /* Comprehensive math (float only) */
960
961 /** \name Rect math functions
962  * \{ */
963
964 #define ROTATE_SINCOS(r_vec, mat2, vec) \
965   { \
966     (r_vec)[0] = (mat2)[1] * (vec)[0] + (+(mat2)[0]) * (vec)[1]; \
967     (r_vec)[1] = (mat2)[0] * (vec)[0] + (-(mat2)[1]) * (vec)[1]; \
968   } \
969   ((void)0)
970
971 /**
972  * Expand the rectangle to fit a rotated \a src.
973  */
974 void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle)
975 {
976   const float mat2[2] = {sinf(angle), cosf(angle)};
977   const float cent[2] = {BLI_rctf_cent_x(src), BLI_rctf_cent_y(src)};
978   float corner[2], corner_rot[2], corder_max[2];
979
980   /* x is same for both corners */
981   corner[0] = src->xmax - cent[0];
982   corner[1] = src->ymax - cent[1];
983   ROTATE_SINCOS(corner_rot, mat2, corner);
984   corder_max[0] = fabsf(corner_rot[0]);
985   corder_max[1] = fabsf(corner_rot[1]);
986
987   corner[1] *= -1;
988   ROTATE_SINCOS(corner_rot, mat2, corner);
989   corder_max[0] = MAX2(corder_max[0], fabsf(corner_rot[0]));
990   corder_max[1] = MAX2(corder_max[1], fabsf(corner_rot[1]));
991
992   dst->xmin = cent[0] - corder_max[0];
993   dst->xmax = cent[0] + corder_max[0];
994   dst->ymin = cent[1] - corder_max[1];
995   dst->ymax = cent[1] + corder_max[1];
996 }
997
998 #undef ROTATE_SINCOS
999
1000 /** \} */
1001
1002 static void unit_m4(float m[4][4])
1003 {
1004   m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
1005   m[0][1] = m[0][2] = m[0][3] = 0.0f;
1006   m[1][0] = m[1][2] = m[1][3] = 0.0f;
1007   m[2][0] = m[2][1] = m[2][3] = 0.0f;
1008   m[3][0] = m[3][1] = m[3][2] = 0.0f;
1009 }