Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonioya <blendergit@gmail.com>2019-03-25 19:02:42 +0300
committerAntonioya <blendergit@gmail.com>2019-03-25 19:06:07 +0300
commit7021bd527380b4d87cf48057f0039509326b03dd (patch)
tree55126437da17d736a789d236c8a98d199a1e6260 /source/blender/blenkernel/intern/gpencil.c
parent84240ebb3ebde58f6bfba256e49d37697fb6bc9f (diff)
GPencil: Only brushes with pinned materials have materials
Using GP_BRUSH_MATERIAL_PINNED to switch between active material and brush material, instead of updating all brushes on active material changes. This will allow brushes to have no material and therefore to not inflate the user count. This fix T62465. Patch contributed by @matc Reviewers: @brecht @antoniov @billreynish @mendio
Diffstat (limited to 'source/blender/blenkernel/intern/gpencil.c')
-rw-r--r--source/blender/blenkernel/intern/gpencil.c147
1 files changed, 135 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index eb6fc9ceeeb..263bf4e57e2 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -996,6 +996,136 @@ Material *BKE_gpencil_get_material_from_brush(Brush *brush)
return ma;
}
+void BKE_gpencil_brush_set_material(Brush *brush, Material *ma)
+{
+ BLI_assert(brush);
+ BLI_assert(brush->gpencil_settings);
+ if (brush->gpencil_settings->material != ma) {
+ if (brush->gpencil_settings->material) {
+ id_us_min(&brush->gpencil_settings->material->id);
+ }
+ if (ma) {
+ id_us_plus(&ma->id);
+ }
+ brush->gpencil_settings->material = ma;
+ }
+}
+
+/* Adds the pinned material to the object if necessary. */
+Material *BKE_gpencil_handle_brush_material(Main *bmain, Object *ob, Brush *brush)
+{
+ if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
+ Material *ma = BKE_gpencil_get_material_from_brush(brush);
+
+ /* check if the material is already on object material slots and add it if missing */
+ if (ma && BKE_gpencil_get_material_index(ob, ma) < 0) {
+ BKE_object_material_slot_add(bmain, ob);
+ assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+ }
+
+ return ma;
+ }
+ else {
+ /* using active material instead */
+ return give_current_material(ob, ob->actcol);
+ }
+}
+
+/* Assigns the material to object (if not already present) and returns its index (mat_nr). */
+int BKE_gpencil_handle_material(Main *bmain, Object *ob, Material *material)
+{
+ if (!material) {
+ return -1;
+ }
+ int index = BKE_gpencil_get_material_index(ob, material);
+ if (index < 0) {
+ BKE_object_material_slot_add(bmain, ob);
+ assign_material(bmain, ob, material, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+ return ob->totcol - 1;
+ }
+ return index;
+}
+
+/** Creates a new gpencil material and assigns it to object.
+ *
+ * \param *r_index: value is set to zero based index of the new material if r_index is not NULL
+ */
+Material *BKE_gpencil_handle_new_material(Main *bmain, Object *ob, const char *name, int *r_index)
+{
+ Material *ma = BKE_material_add_gpencil(bmain, name);
+ id_us_min(&ma->id); /* no users yet */
+
+ BKE_object_material_slot_add(bmain, ob);
+ assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
+
+ if (r_index) {
+ *r_index = ob->actcol - 1;
+ }
+ return ma;
+}
+
+/* Returns the material for a brush with respect to its pinned state. */
+Material *BKE_gpencil_get_material_for_brush(Object *ob, Brush *brush)
+{
+ if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
+ Material *ma = BKE_gpencil_get_material_from_brush(brush);
+ return ma;
+ }
+ else {
+ return give_current_material(ob, ob->actcol);
+ }
+}
+
+/* Returns the material index for a brush with respect to its pinned state. */
+int BKE_gpencil_get_material_index_for_brush(Object *ob, Brush *brush)
+{
+ if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
+ return BKE_gpencil_get_material_index(ob, brush->gpencil_settings->material);
+ }
+ else {
+ return ob->actcol - 1;
+ }
+}
+
+/* Guaranteed to return a material assigned to object. Returns never NULL. */
+Material *BKE_gpencil_current_input_toolsettings_material(Main *bmain, Object *ob, ToolSettings *ts)
+{
+ if (ts && ts->gp_paint && ts->gp_paint->paint.brush) {
+ return BKE_gpencil_current_input_brush_material(bmain, ob, ts->gp_paint->paint.brush);
+ }
+ else {
+ return BKE_gpencil_current_input_brush_material(bmain, ob, NULL);
+ }
+}
+
+/* Guaranteed to return a material assigned to object. Returns never NULL. */
+Material *BKE_gpencil_current_input_brush_material(Main *bmain, Object *ob, Brush *brush)
+{
+ Material *ma;
+ if (brush) {
+ ma = BKE_gpencil_handle_brush_material(bmain, ob, brush);
+ if (!ma && brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
+ /* it is easier to just unpin a NULL material, instead of setting a new one */
+ brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
+ }
+ }
+ if (ma) {
+ return ma;
+ }
+ return BKE_gpencil_current_input_material(bmain, ob);
+}
+
+/* Guaranteed to return a material assigned to object. Returns never NULL. Only use this for materials unrelated to user input */
+Material *BKE_gpencil_current_input_material(Main *bmain, Object *ob)
+{
+ Material *ma;
+ ma = give_current_material(ob, ob->actcol);
+ if (ma) {
+ return ma;
+ }
+ return BKE_gpencil_handle_new_material(bmain, ob, "Material", NULL);
+}
+
/* Get active color, and add all default settings if we don't find anything */
Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob)
{
@@ -1005,15 +1135,8 @@ Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob)
if (ELEM(NULL, bmain, ob))
return NULL;
- ma = give_current_material(ob, ob->actcol);
- if (ma == NULL) {
- if (ob->totcol == 0) {
- BKE_object_material_slot_add(bmain, ob);
- }
- ma = BKE_material_add_gpencil(bmain, DATA_("Material"));
- assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
- }
- else if (ma->gp_style == NULL) {
+ ma = BKE_gpencil_current_input_material(bmain, ob);
+ if (ma->gp_style == NULL) {
BKE_material_init_gpencil_settings(ma);
}
@@ -1538,7 +1661,7 @@ void BKE_gpencil_stats_update(bGPdata *gpd)
}
-/* get material index */
+/* get material index (0-based like mat_nr not actcol) */
int BKE_gpencil_get_material_index(Object *ob, Material *ma)
{
short *totcol = give_totcolp(ob);
@@ -1546,11 +1669,11 @@ int BKE_gpencil_get_material_index(Object *ob, Material *ma)
for (short i = 0; i < *totcol; i++) {
read_ma = give_current_material(ob, i + 1);
if (ma == read_ma) {
- return i + 1;
+ return i;
}
}
- return 0;
+ return -1;
}
/* Get points of stroke always flat to view not affected by camera view or view position */