Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / paint_toolslots.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
17 /** \file
18  * \ingroup bke
19  */
20
21 #include <limits.h>
22
23 #include "MEM_guardedalloc.h"
24
25 #include "DNA_modifier_types.h"
26 #include "DNA_scene_types.h"
27 #include "DNA_brush_types.h"
28
29 #include "BLI_utildefines.h"
30
31 #include "BKE_main.h"
32 #include "BKE_library.h"
33 #include "BKE_brush.h"
34 #include "BKE_paint.h"
35
36 void BKE_paint_toolslots_len_ensure(Paint *paint, int len)
37 {
38   /* Tool slots are 'uchar'. */
39   BLI_assert(len <= UCHAR_MAX);
40   if (paint->tool_slots_len < len) {
41     paint->tool_slots = MEM_recallocN(paint->tool_slots, sizeof(*paint->tool_slots) * len);
42     paint->tool_slots_len = len;
43   }
44 }
45
46 static void paint_toolslots_init(Main *bmain, Paint *paint)
47 {
48   if (paint == NULL) {
49     return;
50   }
51   const eObjectMode ob_mode = paint->runtime.ob_mode;
52   BLI_assert(paint->runtime.tool_offset && ob_mode);
53   for (Brush *brush = bmain->brushes.first; brush; brush = brush->id.next) {
54     if (brush->ob_mode & ob_mode) {
55       const int slot_index = BKE_brush_tool_get(brush, paint);
56       BKE_paint_toolslots_len_ensure(paint, slot_index + 1);
57       if (paint->tool_slots[slot_index].brush == NULL) {
58         paint->tool_slots[slot_index].brush = brush;
59         id_us_plus(&brush->id);
60       }
61     }
62   }
63 }
64
65 void BKE_paint_toolslots_init_from_main(struct Main *bmain)
66 {
67   for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
68     ToolSettings *ts = scene->toolsettings;
69     paint_toolslots_init(bmain, &ts->imapaint.paint);
70     paint_toolslots_init(bmain, &ts->sculpt->paint);
71     paint_toolslots_init(bmain, &ts->vpaint->paint);
72     paint_toolslots_init(bmain, &ts->wpaint->paint);
73     paint_toolslots_init(bmain, &ts->gp_paint->paint);
74   }
75 }
76
77 void BKE_paint_toolslots_brush_update_ex(Paint *paint, Brush *brush)
78 {
79   const uint tool_offset = paint->runtime.tool_offset;
80   UNUSED_VARS_NDEBUG(tool_offset);
81   BLI_assert(tool_offset != 0);
82   const int slot_index = BKE_brush_tool_get(brush, paint);
83   BKE_paint_toolslots_len_ensure(paint, slot_index + 1);
84   PaintToolSlot *tslot = &paint->tool_slots[slot_index];
85   id_us_plus(&brush->id);
86   id_us_min(&tslot->brush->id);
87   tslot->brush = brush;
88 }
89
90 void BKE_paint_toolslots_brush_update(Paint *paint)
91 {
92   if (paint->brush == NULL) {
93     return;
94   }
95   BKE_paint_toolslots_brush_update_ex(paint, paint->brush);
96 }
97
98 /**
99  * Run this to ensure brush types are set for each slot on entering modes
100  * (for new scenes for example).
101  */
102 void BKE_paint_toolslots_brush_validate(Main *bmain, Paint *paint)
103 {
104   /* Clear slots with invalid slots or mode (unlikely but possible). */
105   const uint tool_offset = paint->runtime.tool_offset;
106   UNUSED_VARS_NDEBUG(tool_offset);
107   const eObjectMode ob_mode = paint->runtime.ob_mode;
108   BLI_assert(tool_offset && ob_mode);
109   for (int i = 0; i < paint->tool_slots_len; i++) {
110     PaintToolSlot *tslot = &paint->tool_slots[i];
111     if (tslot->brush) {
112       if ((i != BKE_brush_tool_get(tslot->brush, paint)) ||
113           (tslot->brush->ob_mode & ob_mode) == 0) {
114         id_us_min(&tslot->brush->id);
115         tslot->brush = NULL;
116       }
117     }
118   }
119
120   /* Unlikely but possible the active brush is not currently using a slot. */
121   BKE_paint_toolslots_brush_update(paint);
122
123   /* Fill slots from brushes. */
124   paint_toolslots_init(bmain, paint);
125 }
126
127 Brush *BKE_paint_toolslots_brush_get(Paint *paint, int slot_index)
128 {
129   if (slot_index < paint->tool_slots_len) {
130     PaintToolSlot *tslot = &paint->tool_slots[slot_index];
131     return tslot->brush;
132   }
133   return NULL;
134 }