Fix #34040: Moving Normal Node with enabled Cycles Material Preview crashes
[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 Brush *paint_brush(Paint *p)
141 {
142         return p ? p->brush : NULL;
143 }
144
145 void paint_brush_set(Paint *p, Brush *br)
146 {
147         if (p) {
148                 id_us_min((ID *)p->brush);
149                 id_us_plus((ID *)br);
150                 p->brush = br;
151         }
152 }
153
154 /* are we in vertex paint or weight pain face select mode? */
155 int paint_facesel_test(Object *ob)
156 {
157         return ( (ob != NULL) &&
158                  (ob->type == OB_MESH) &&
159                  (ob->data != NULL) &&
160                  (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
161                  (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
162                  );
163 }
164
165 /* are we in weight paint vertex select mode? */
166 int paint_vertsel_test(Object *ob)
167 {
168         return ( (ob != NULL) &&
169                  (ob->type == OB_MESH) &&
170                  (ob->data != NULL) &&
171                  (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
172                  (ob->mode & OB_MODE_WEIGHT_PAINT)
173                  );
174 }
175
176 void BKE_paint_init(Paint *p, const char col[3])
177 {
178         Brush *brush;
179
180         /* If there's no brush, create one */
181         brush = paint_brush(p);
182         if (brush == NULL)
183                 brush = BKE_brush_add(G.main, "Brush");
184         paint_brush_set(p, brush);
185
186         memcpy(p->paint_cursor_col, col, 3);
187         p->paint_cursor_col[3] = 128;
188
189         p->flags |= PAINT_SHOW_BRUSH;
190 }
191
192 void BKE_paint_free(Paint *paint)
193 {
194         id_us_min((ID *)paint->brush);
195 }
196
197 /* called when copying scene settings, so even if 'src' and 'tar' are the same
198  * still do a id_us_plus(), rather then if we were copying between 2 existing
199  * scenes where a matching value should decrease the existing user count as
200  * with paint_brush_set() */
201 void BKE_paint_copy(Paint *src, Paint *tar)
202 {
203         tar->brush = src->brush;
204         id_us_plus((ID *)tar->brush);
205 }
206
207 /* returns non-zero if any of the face's vertices
208  * are hidden, zero otherwise */
209 int paint_is_face_hidden(const MFace *f, const MVert *mvert)
210 {
211         return ((mvert[f->v1].flag & ME_HIDE) ||
212                 (mvert[f->v2].flag & ME_HIDE) ||
213                 (mvert[f->v3].flag & ME_HIDE) ||
214                 (f->v4 && (mvert[f->v4].flag & ME_HIDE)));
215 }
216
217 /* returns non-zero if any of the corners of the grid
218  * face whose inner corner is at (x, y) are hidden,
219  * zero otherwise */
220 int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
221                               int gridsize, int x, int y)
222 {
223         /* skip face if any of its corners are hidden */
224         return (BLI_BITMAP_GET(grid_hidden, y * gridsize + x) ||
225                 BLI_BITMAP_GET(grid_hidden, y * gridsize + x + 1) ||
226                 BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x + 1) ||
227                 BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x));
228 }
229
230 /* Return TRUE if all vertices in the face are visible, FALSE otherwise */
231 int paint_is_bmesh_face_hidden(BMFace *f)
232 {
233         BMLoop *l_iter;
234         BMLoop *l_first;
235
236         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
237         do {
238                 if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN)) {
239                         return true;
240                 }
241         } while ((l_iter = l_iter->next) != l_first);
242
243         return false;
244 }
245
246 float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
247                             unsigned x, unsigned y)
248 {
249         int factor = ccg_factor(level, gpm->level);
250         int gridsize = ccg_gridsize(gpm->level);
251         
252         return gpm->data[(y * factor) * gridsize + (x * factor)];
253 }