Blender V4.3
image_drawing.h
Go to the documentation of this file.
1// Copyright (c) 2009 libmv authors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to
5// deal in the Software without restriction, including without limitation the
6// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7// sell copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
21// Generic Image Processing Algorithm (GIPA)
22// Use an ImageModel class that must implement the following :
23//
24// ::Contains(int y, int x) <= Tell if a point is inside or not the image
25// ::operator(int y,int x) <= Modification accessor over the pixel (y,x)
26// ::Width()
27// ::Height()
28
29#ifndef LIBMV_IMAGE_IMAGE_DRAWING_H
30#define LIBMV_IMAGE_IMAGE_DRAWING_H
31
32namespace libmv {
33
36template <class Image, class Color>
37inline void safePutPixel(int yc, int xc, const Color& col, Image* pim) {
38 if (!pim) {
39 return;
40 }
41 if (pim->Contains(yc, xc)) {
42 (*pim)(yc, xc) = col;
43 }
44}
45
48template <class Image, class Color>
49inline void safePutPixel(int yc, int xc, const Color* col, Image* pim) {
50 if (!pim) {
51 return;
52 }
53 if (pim->Contains(yc, xc)) {
54 for (int i = 0; i < pim->Depth(); ++i) {
55 (*pim)(yc, xc, i) = *(col + i);
56 }
57 }
58}
59
60// Bresenham approach to draw ellipse.
61// http://raphaello.univ-fcomte.fr/ig/algorithme/ExemplesGLUt/BresenhamEllipse.htm
62// Add the rotation of the ellipse.
63// As the algo. use symmetry we must use 4 rotations.
64template <class Image, class Color>
65void DrawEllipse(int xc,
66 int yc,
67 int radiusA,
68 int radiusB,
69 const Color& col,
70 Image* pim,
71 double angle = 0.0) {
72 int a = radiusA;
73 int b = radiusB;
74
75 // Counter Clockwise rotation matrix.
76 double matXY[4] = {cos(angle), sin(angle), -sin(angle), cos(angle)};
77 int x, y;
78 double d1, d2;
79 x = 0;
80 y = b;
81 d1 = b * b - a * a * b + a * a / 4;
82
83 float rotX = (matXY[0] * x + matXY[1] * y);
84 float rotY = (matXY[2] * x + matXY[3] * y);
85 safePutPixel(yc + rotY, xc + rotX, col, pim);
86 rotX = (matXY[0] * x - matXY[1] * y);
87 rotY = (matXY[2] * x - matXY[3] * y);
88 safePutPixel(yc + rotY, xc + rotX, col, pim);
89 rotX = (-matXY[0] * x - matXY[1] * y);
90 rotY = (-matXY[2] * x - matXY[3] * y);
91 safePutPixel(yc + rotY, xc + rotX, col, pim);
92 rotX = (-matXY[0] * x + matXY[1] * y);
93 rotY = (-matXY[2] * x + matXY[3] * y);
94 safePutPixel(yc + rotY, xc + rotX, col, pim);
95
96 while (a * a * (y - .5) > b * b * (x + 1)) {
97 if (d1 < 0) {
98 d1 += b * b * (2 * x + 3);
99 ++x;
100 } else {
101 d1 += b * b * (2 * x + 3) + a * a * (-2 * y + 2);
102 ++x;
103 --y;
104 }
105 rotX = (matXY[0] * x + matXY[1] * y);
106 rotY = (matXY[2] * x + matXY[3] * y);
107 safePutPixel(yc + rotY, xc + rotX, col, pim);
108 rotX = (matXY[0] * x - matXY[1] * y);
109 rotY = (matXY[2] * x - matXY[3] * y);
110 safePutPixel(yc + rotY, xc + rotX, col, pim);
111 rotX = (-matXY[0] * x - matXY[1] * y);
112 rotY = (-matXY[2] * x - matXY[3] * y);
113 safePutPixel(yc + rotY, xc + rotX, col, pim);
114 rotX = (-matXY[0] * x + matXY[1] * y);
115 rotY = (-matXY[2] * x + matXY[3] * y);
116 safePutPixel(yc + rotY, xc + rotX, col, pim);
117 }
118 d2 = b * b * (x + .5) * (x + .5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
119 while (y > 0) {
120 if (d2 < 0) {
121 d2 += b * b * (2 * x + 2) + a * a * (-2 * y + 3);
122 --y;
123 ++x;
124 } else {
125 d2 += a * a * (-2 * y + 3);
126 --y;
127 }
128 rotX = (matXY[0] * x + matXY[1] * y);
129 rotY = (matXY[2] * x + matXY[3] * y);
130 safePutPixel(yc + rotY, xc + rotX, col, pim);
131 rotX = (matXY[0] * x - matXY[1] * y);
132 rotY = (matXY[2] * x - matXY[3] * y);
133 safePutPixel(yc + rotY, xc + rotX, col, pim);
134 rotX = (-matXY[0] * x - matXY[1] * y);
135 rotY = (-matXY[2] * x - matXY[3] * y);
136 safePutPixel(yc + rotY, xc + rotX, col, pim);
137 rotX = (-matXY[0] * x + matXY[1] * y);
138 rotY = (-matXY[2] * x + matXY[3] * y);
139 safePutPixel(yc + rotY, xc + rotX, col, pim);
140 }
141}
142
143// Bresenham approach do not allow to draw concentric circle without holes.
144// So it's better the use the Andres method.
145// http://fr.wikipedia.org/wiki/Algorithme_de_tracé_de_cercle_d'Andres.
146template <class Image, class Color>
147void DrawCircle(int x, int y, int radius, const Color& col, Image* pim) {
148 Image& im = *pim;
149 if (im.Contains(y + radius, x + radius) ||
150 im.Contains(y + radius, x - radius) ||
151 im.Contains(y - radius, x + radius) ||
152 im.Contains(y - radius, x - radius)) {
153 int x1 = 0;
154 int y1 = radius;
155 int d = radius - 1;
156 while (y1 >= x1) {
157 // Draw the point for each octant.
158 safePutPixel(y1 + y, x1 + x, col, pim);
159 safePutPixel(x1 + y, y1 + x, col, pim);
160 safePutPixel(y1 + y, -x1 + x, col, pim);
161 safePutPixel(x1 + y, -y1 + x, col, pim);
162 safePutPixel(-y1 + y, x1 + x, col, pim);
163 safePutPixel(-x1 + y, y1 + x, col, pim);
164 safePutPixel(-y1 + y, -x1 + x, col, pim);
165 safePutPixel(-x1 + y, -y1 + x, col, pim);
166 if (d >= 2 * x1) {
167 d = d - 2 * x1 - 1;
168 x1 += 1;
169 } else {
170 if (d <= 2 * (radius - y1)) {
171 d = d + 2 * y1 - 1;
172 y1 -= 1;
173 } else {
174 d = d + 2 * (y1 - x1 - 1);
175 y1 -= 1;
176 x1 += 1;
177 }
178 }
179 }
180 }
181}
182
183// Bresenham algorithm
184template <class Image, class Color>
185void DrawLine(int xa, int ya, int xb, int yb, const Color& col, Image* pim) {
186 Image& im = *pim;
187
188 // If one point is outside the image
189 // Replace the outside point by the intersection of the line and
190 // the limit (either x=width or y=height).
191 if (!im.Contains(ya, xa) || !im.Contains(yb, xb)) {
192 int width = pim->Width();
193 int height = pim->Height();
194 const bool xdir = xa < xb, ydir = ya < yb;
195 float nx0 = xa, nx1 = xb, ny0 = ya, ny1 = yb, &xleft = xdir ? nx0 : nx1,
196 &yleft = xdir ? ny0 : ny1, &xright = xdir ? nx1 : nx0,
197 &yright = xdir ? ny1 : ny0, &xup = ydir ? nx0 : nx1,
198 &yup = ydir ? ny0 : ny1, &xdown = ydir ? nx1 : nx0,
199 &ydown = ydir ? ny1 : ny0;
200
201 if (xright < 0 || xleft >= width) {
202 return;
203 }
204 if (xleft < 0) {
205 yleft -= xleft * (yright - yleft) / (xright - xleft);
206 xleft = 0;
207 }
208 if (xright >= width) {
209 yright -= (xright - width) * (yright - yleft) / (xright - xleft);
210 xright = width - 1;
211 }
212 if (ydown < 0 || yup >= height) {
213 return;
214 }
215 if (yup < 0) {
216 xup -= yup * (xdown - xup) / (ydown - yup);
217 yup = 0;
218 }
219 if (ydown >= height) {
220 xdown -= (ydown - height) * (xdown - xup) / (ydown - yup);
221 ydown = height - 1;
222 }
223
224 xa = (int)xleft;
225 xb = (int)xright;
226 ya = (int)yleft;
227 yb = (int)yright;
228 }
229
230 int xbas, xhaut, ybas, yhaut;
231 // Check the condition ybas < yhaut.
232 if (ya <= yb) {
233 xbas = xa;
234 ybas = ya;
235 xhaut = xb;
236 yhaut = yb;
237 } else {
238 xbas = xb;
239 ybas = yb;
240 xhaut = xa;
241 yhaut = ya;
242 }
243 // Initialize slope.
244 int x, y, dx, dy, incrmX, incrmY, dp, N, S;
245 dx = xhaut - xbas;
246 dy = yhaut - ybas;
247 if (dx > 0) { // If xhaut > xbas we will increment X.
248 incrmX = 1;
249 } else {
250 incrmX = -1; // else we will decrement X.
251 dx *= -1;
252 }
253 if (dy > 0) { // Positive slope will increment X.
254 incrmY = 1;
255 } else { // Negative slope.
256 incrmY = -1;
257 }
258 if (dx >= dy) {
259 dp = 2 * dy - dx;
260 S = 2 * dy;
261 N = 2 * (dy - dx);
262 y = ybas;
263 x = xbas;
264 while (x != xhaut) {
265 safePutPixel(y, x, col, pim);
266 x += incrmX;
267 if (dp <= 0) { // Go in direction of the South Pixel.
268 dp += S;
269 } else { // Go to the North.
270 dp += N;
271 y += incrmY;
272 }
273 }
274 } else {
275 dp = 2 * dx - dy;
276 S = 2 * dx;
277 N = 2 * (dx - dy);
278 x = xbas;
279 y = ybas;
280 while (y < yhaut) {
281 safePutPixel(y, x, col, pim);
282 y += incrmY;
283 if (dp <= 0) { // Go in direction of the South Pixel.
284 dp += S;
285 } else { // Go to the North.
286 dp += N;
287 x += incrmX;
288 }
289 }
290 }
291 safePutPixel(y, x, col, pim);
292}
293
294} // namespace libmv
295
296#endif // LIBMV_IMAGE_IMAGE_DRAWING_H
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Color
local_group_size(16, 16) .push_constant(Type b
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uint col
ccl_device_inline float3 cos(float3 v)
#define N
void safePutPixel(int yc, int xc, const Color &col, Image *pim)
void DrawEllipse(int xc, int yc, int radiusA, int radiusB, const Color &col, Image *pim, double angle=0.0)
void DrawLine(int xa, int ya, int xb, int yb, const Color &col, Image *pim)
void DrawCircle(int x, int y, int radius, const Color &col, Image *pim)