| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							| 
									
										
										
										
											2020-05-09 17:14:35 +10:00
										 |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bke | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-06 12:08:39 +11:00
										 |  |  | #include <limits.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "DNA_brush_types.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | #include "DNA_modifier_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 08:42:15 +11:00
										 |  |  | #include "BKE_brush.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BKE_lib_id.h"
 | 
					
						
							|  |  |  | #include "BKE_main.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | #include "BKE_paint.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Tool Slot Initialization / Versioning
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * These functions run to update old files (while versioning), | 
					
						
							|  |  |  |  * take care only to perform low-level functions here. | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | void BKE_paint_toolslots_len_ensure(Paint *paint, int len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-06 12:08:39 +11:00
										 |  |  |   /* Tool slots are 'uchar'. */ | 
					
						
							|  |  |  |   BLI_assert(len <= UCHAR_MAX); | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |   if (paint->tool_slots_len < len) { | 
					
						
							|  |  |  |     paint->tool_slots = MEM_recallocN(paint->tool_slots, sizeof(*paint->tool_slots) * len); | 
					
						
							|  |  |  |     paint->tool_slots_len = len; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  | static void paint_toolslots_init(Main *bmain, Paint *paint) | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-05 07:15:47 +11:00
										 |  |  |   if (paint == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   const eObjectMode ob_mode = paint->runtime.ob_mode; | 
					
						
							| 
									
										
										
										
											2018-11-07 08:42:15 +11:00
										 |  |  |   BLI_assert(paint->runtime.tool_offset && ob_mode); | 
					
						
							| 
									
										
										
										
											2019-03-08 09:29:17 +11:00
										 |  |  |   for (Brush *brush = bmain->brushes.first; brush; brush = brush->id.next) { | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  |     if (brush->ob_mode & ob_mode) { | 
					
						
							| 
									
										
										
										
											2018-11-07 08:42:15 +11:00
										 |  |  |       const int slot_index = BKE_brush_tool_get(brush, paint); | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |       BKE_paint_toolslots_len_ensure(paint, slot_index + 1); | 
					
						
							|  |  |  |       if (paint->tool_slots[slot_index].brush == NULL) { | 
					
						
							|  |  |  |         paint->tool_slots[slot_index].brush = brush; | 
					
						
							|  |  |  |         id_us_plus(&brush->id); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Initialize runtime since this is called from versioning code. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void paint_toolslots_init_with_runtime(Main *bmain, ToolSettings *ts, Paint *paint) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (paint == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Needed so #Paint_Runtime is updated when versioning. */ | 
					
						
							|  |  |  |   BKE_paint_runtime_init(ts, paint); | 
					
						
							|  |  |  |   paint_toolslots_init(bmain, paint); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | void BKE_paint_toolslots_init_from_main(struct Main *bmain) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-08 09:29:17 +11:00
										 |  |  |   for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |     ToolSettings *ts = scene->toolsettings; | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |     paint_toolslots_init_with_runtime(bmain, ts, &ts->imapaint.paint); | 
					
						
							| 
									
										
										
										
											2019-08-01 09:03:50 +10:00
										 |  |  |     if (ts->sculpt) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->sculpt->paint); | 
					
						
							| 
									
										
										
										
											2019-08-01 09:03:50 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (ts->vpaint) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->vpaint->paint); | 
					
						
							| 
									
										
										
										
											2019-08-01 09:03:50 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (ts->wpaint) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->wpaint->paint); | 
					
						
							| 
									
										
										
										
											2019-08-01 09:03:50 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (ts->uvsculpt) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->uvsculpt->paint); | 
					
						
							| 
									
										
										
										
											2019-08-01 09:03:50 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (ts->gp_paint) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->gp_paint->paint); | 
					
						
							| 
									
										
										
										
											2019-08-01 09:03:50 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-09 16:27:24 +01:00
										 |  |  |     if (ts->gp_vertexpaint) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->gp_vertexpaint->paint); | 
					
						
							| 
									
										
										
										
											2020-03-09 16:27:24 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (ts->gp_sculptpaint) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->gp_sculptpaint->paint); | 
					
						
							| 
									
										
										
										
											2020-03-09 16:27:24 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (ts->gp_weightpaint) { | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  |       paint_toolslots_init_with_runtime(bmain, ts, &ts->gp_weightpaint->paint); | 
					
						
							| 
									
										
										
										
											2020-03-09 16:27:24 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-15 16:46:35 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  | void BKE_paint_toolslots_brush_update_ex(Paint *paint, Brush *brush) | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   const uint tool_offset = paint->runtime.tool_offset; | 
					
						
							| 
									
										
										
										
											2018-11-08 15:49:25 +01:00
										 |  |  |   UNUSED_VARS_NDEBUG(tool_offset); | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   BLI_assert(tool_offset != 0); | 
					
						
							| 
									
										
										
										
											2018-11-07 08:42:15 +11:00
										 |  |  |   const int slot_index = BKE_brush_tool_get(brush, paint); | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |   BKE_paint_toolslots_len_ensure(paint, slot_index + 1); | 
					
						
							|  |  |  |   PaintToolSlot *tslot = &paint->tool_slots[slot_index]; | 
					
						
							|  |  |  |   id_us_plus(&brush->id); | 
					
						
							| 
									
										
										
										
											2019-12-10 15:45:55 +01:00
										 |  |  |   if (tslot->brush) { | 
					
						
							|  |  |  |     id_us_min(&tslot->brush->id); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  |   tslot->brush = brush; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  | void BKE_paint_toolslots_brush_update(Paint *paint) | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   if (paint->brush == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   BKE_paint_toolslots_brush_update_ex(paint, paint->brush); | 
					
						
							| 
									
										
										
										
											2018-11-02 09:10:23 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Run this to ensure brush types are set for each slot on entering modes | 
					
						
							|  |  |  |  * (for new scenes for example). | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  | void BKE_paint_toolslots_brush_validate(Main *bmain, Paint *paint) | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   /* Clear slots with invalid slots or mode (unlikely but possible). */ | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   const uint tool_offset = paint->runtime.tool_offset; | 
					
						
							| 
									
										
										
										
											2018-11-08 15:49:25 +01:00
										 |  |  |   UNUSED_VARS_NDEBUG(tool_offset); | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   const eObjectMode ob_mode = paint->runtime.ob_mode; | 
					
						
							|  |  |  |   BLI_assert(tool_offset && ob_mode); | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  |   for (int i = 0; i < paint->tool_slots_len; i++) { | 
					
						
							|  |  |  |     PaintToolSlot *tslot = &paint->tool_slots[i]; | 
					
						
							|  |  |  |     if (tslot->brush) { | 
					
						
							| 
									
										
										
										
											2018-11-07 08:42:15 +11:00
										 |  |  |       if ((i != BKE_brush_tool_get(tslot->brush, paint)) || | 
					
						
							|  |  |  |           (tslot->brush->ob_mode & ob_mode) == 0) { | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  |         id_us_min(&tslot->brush->id); | 
					
						
							|  |  |  |         tslot->brush = NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  |   /* Unlikely but possible the active brush is not currently using a slot. */ | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   BKE_paint_toolslots_brush_update(paint); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  |   /* Fill slots from brushes. */ | 
					
						
							| 
									
										
										
										
											2018-11-05 16:18:43 +11:00
										 |  |  |   paint_toolslots_init(bmain, paint); | 
					
						
							| 
									
										
										
										
											2018-11-03 16:52:06 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-11-06 12:08:39 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | Brush *BKE_paint_toolslots_brush_get(Paint *paint, int slot_index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (slot_index < paint->tool_slots_len) { | 
					
						
							|  |  |  |     PaintToolSlot *tslot = &paint->tool_slots[slot_index]; | 
					
						
							|  |  |  |     return tslot->brush; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } |