Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not suppo...
[blender.git] / source / blender / blenkernel / intern / paint.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 by Nicholas Bishop
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/paint.c
29  *  \ingroup bke
30  */
31
32
33
34 #include "DNA_object_types.h"
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_brush_types.h"
39 #include "DNA_space_types.h"
40
41 #include "BLI_bitmap.h"
42 #include "BLI_utildefines.h"
43
44 #include "BKE_brush.h"
45 #include "BKE_context.h"
46 #include "BKE_global.h"
47 #include "BKE_library.h"
48 #include "BKE_paint.h"
49 #include "BKE_subsurf.h"
50
51 #include "bmesh.h"
52
53 #include <stdlib.h>
54 #include <string.h>
55
56 const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
57 const char PAINT_CURSOR_VERTEX_PAINT[3] = {255, 255, 255};
58 const char PAINT_CURSOR_WEIGHT_PAINT[3] = {200, 200, 255};
59 const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
60
61 Paint *paint_get_active(Scene *sce)
62 {
63         if (sce) {
64                 ToolSettings *ts = sce->toolsettings;
65                 
66                 if (sce->basact && sce->basact->object) {
67                         switch (sce->basact->object->mode) {
68                                 case OB_MODE_SCULPT:
69                                         return &ts->sculpt->paint;
70                                 case OB_MODE_VERTEX_PAINT:
71                                         return &ts->vpaint->paint;
72                                 case OB_MODE_WEIGHT_PAINT:
73                                         return &ts->wpaint->paint;
74                                 case OB_MODE_TEXTURE_PAINT:
75                                         return &ts->imapaint.paint;
76                                 case OB_MODE_EDIT:
77                                         if (ts->use_uv_sculpt)
78                                                 return &ts->uvsculpt->paint;
79                                         else
80                                                 return &ts->imapaint.paint;
81                         }
82                 }
83
84                 /* default to image paint */
85                 return &ts->imapaint.paint;
86         }
87
88         return NULL;
89 }
90
91 Paint *paint_get_active_from_context(const bContext *C)
92 {
93         Scene *sce = CTX_data_scene(C);
94         SpaceImage *sima;
95
96         if (sce) {
97                 ToolSettings *ts = sce->toolsettings;
98                 Object *obact = NULL;
99
100                 if (sce->basact && sce->basact->object)
101                         obact = sce->basact->object;
102
103                 if ((sima = CTX_wm_space_image(C)) != NULL) {
104                         if (obact && obact->mode == OB_MODE_EDIT) {
105                                 if (sima->mode == SI_MODE_PAINT)
106                                         return &ts->imapaint.paint;
107                                 else if (ts->use_uv_sculpt)
108                                         return &ts->uvsculpt->paint;
109                         }
110                         else {
111                                 return &ts->imapaint.paint;
112                         }
113                 }
114                 else if (obact) {
115                         switch (obact->mode) {
116                                 case OB_MODE_SCULPT:
117                                         return &ts->sculpt->paint;
118                                 case OB_MODE_VERTEX_PAINT:
119                                         return &ts->vpaint->paint;
120                                 case OB_MODE_WEIGHT_PAINT:
121                                         return &ts->wpaint->paint;
122                                 case OB_MODE_TEXTURE_PAINT:
123                                         return &ts->imapaint.paint;
124                                 case OB_MODE_EDIT:
125                                         if (ts->use_uv_sculpt)
126                                                 return &ts->uvsculpt->paint;
127                                         else
128                                                 return &ts->imapaint.paint;
129                         }
130                 }
131                 else {
132                         /* default to image paint */
133                         return &ts->imapaint.paint;
134                 }
135         }
136
137         return NULL;
138 }
139
140 PaintMode paintmode_get_active_from_context(const bContext *C)
141 {
142         Scene *sce = CTX_data_scene(C);
143         SpaceImage *sima;
144
145         if (sce) {
146                 ToolSettings *ts = sce->toolsettings;
147                 Object *obact = NULL;
148
149                 if (sce->basact && sce->basact->object)
150                         obact = sce->basact->object;
151
152                 if ((sima = CTX_wm_space_image(C)) != NULL) {
153                         if (obact && obact->mode == OB_MODE_EDIT) {
154                                 if (sima->mode == SI_MODE_PAINT)
155                                         return PAINT_TEXTURE_2D;
156                                 else if (ts->use_uv_sculpt)
157                                         return PAINT_SCULPT_UV;
158                         }
159                         else {
160                                 return PAINT_TEXTURE_2D;
161                         }
162                 }
163                 else if (obact) {
164                         switch (obact->mode) {
165                                 case OB_MODE_SCULPT:
166                                         return PAINT_SCULPT;
167                                 case OB_MODE_VERTEX_PAINT:
168                                         return PAINT_VERTEX;
169                                 case OB_MODE_WEIGHT_PAINT:
170                                         return PAINT_WEIGHT;
171                                 case OB_MODE_TEXTURE_PAINT:
172                                         return PAINT_TEXTURE_PROJECTIVE;
173                                 case OB_MODE_EDIT:
174                                         if (ts->use_uv_sculpt)
175                                                 return PAINT_SCULPT_UV;
176                                         else
177                                                 return PAINT_TEXTURE_2D;
178                         }
179                 }
180                 else {
181                         /* default to image paint */
182                         return PAINT_TEXTURE_2D;
183                 }
184         }
185
186         return PAINT_INVALID;
187 }
188
189 Brush *paint_brush(Paint *p)
190 {
191         return p ? p->brush : NULL;
192 }
193
194 void paint_brush_set(Paint *p, Brush *br)
195 {
196         if (p) {
197                 id_us_min((ID *)p->brush);
198                 id_us_plus((ID *)br);
199                 p->brush = br;
200         }
201 }
202
203 /* are we in vertex paint or weight pain face select mode? */
204 int paint_facesel_test(Object *ob)
205 {
206         return ( (ob != NULL) &&
207                  (ob->type == OB_MESH) &&
208                  (ob->data != NULL) &&
209                  (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
210                  (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
211                  );
212 }
213
214 /* are we in weight paint vertex select mode? */
215 int paint_vertsel_test(Object *ob)
216 {
217         return ( (ob != NULL) &&
218                  (ob->type == OB_MESH) &&
219                  (ob->data != NULL) &&
220                  (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
221                  (ob->mode & OB_MODE_WEIGHT_PAINT)
222                  );
223 }
224
225 void BKE_paint_init(Paint *p, const char col[3])
226 {
227         Brush *brush;
228
229         /* If there's no brush, create one */
230         brush = paint_brush(p);
231         if (brush == NULL)
232                 brush = BKE_brush_add(G.main, "Brush");
233         paint_brush_set(p, brush);
234
235         memcpy(p->paint_cursor_col, col, 3);
236         p->paint_cursor_col[3] = 128;
237
238         p->flags |= PAINT_SHOW_BRUSH;
239 }
240
241 void BKE_paint_free(Paint *paint)
242 {
243         id_us_min((ID *)paint->brush);
244 }
245
246 /* called when copying scene settings, so even if 'src' and 'tar' are the same
247  * still do a id_us_plus(), rather then if we were copying between 2 existing
248  * scenes where a matching value should decrease the existing user count as
249  * with paint_brush_set() */
250 void BKE_paint_copy(Paint *src, Paint *tar)
251 {
252         tar->brush = src->brush;
253         id_us_plus((ID *)tar->brush);
254 }
255
256 /* returns non-zero if any of the face's vertices
257  * are hidden, zero otherwise */
258 int paint_is_face_hidden(const MFace *f, const MVert *mvert)
259 {
260         return ((mvert[f->v1].flag & ME_HIDE) ||
261                 (mvert[f->v2].flag & ME_HIDE) ||
262                 (mvert[f->v3].flag & ME_HIDE) ||
263                 (f->v4 && (mvert[f->v4].flag & ME_HIDE)));
264 }
265
266 /* returns non-zero if any of the corners of the grid
267  * face whose inner corner is at (x, y) are hidden,
268  * zero otherwise */
269 int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
270                               int gridsize, int x, int y)
271 {
272         /* skip face if any of its corners are hidden */
273         return (BLI_BITMAP_GET(grid_hidden, y * gridsize + x) ||
274                 BLI_BITMAP_GET(grid_hidden, y * gridsize + x + 1) ||
275                 BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x + 1) ||
276                 BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x));
277 }
278
279 /* Return TRUE if all vertices in the face are visible, FALSE otherwise */
280 int paint_is_bmesh_face_hidden(BMFace *f)
281 {
282         BMLoop *l_iter;
283         BMLoop *l_first;
284
285         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
286         do {
287                 if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN)) {
288                         return true;
289                 }
290         } while ((l_iter = l_iter->next) != l_first);
291
292         return false;
293 }
294
295 float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
296                             unsigned x, unsigned y)
297 {
298         int factor = ccg_factor(level, gpm->level);
299         int gridsize = ccg_gridsize(gpm->level);
300         
301         return gpm->data[(y * factor) * gridsize + (x * factor)];
302 }