[Bf-blender-cvs] [e0a07700bfb] master: GPencil: Prevent RNA assignment of invalid materials in modifiers

Philipp Oeser noreply at git.blender.org
Fri Apr 2 21:27:11 CEST 2021


Commit: e0a07700bfbe3a4d64e65d0d51adb8c44ef105d7
Author: Philipp Oeser
Date:   Wed Mar 31 15:54:41 2021 +0200
Branches: master
https://developer.blender.org/rBe0a07700bfbe3a4d64e65d0d51adb8c44ef105d7

GPencil: Prevent RNA assignment of invalid materials in modifiers

Materials used in grease pencil modifiers have the requirement that they
are already used on the object. In the UI dropdown, this restriction is
ensured by calling uiItemPointerR with appropriate searchptr and
searchpropname, so only giving the user the choice of materials already
used on the object.

>From python though, it was still possible to assign materials outside of
this this restriction. This led to reports like T86981 [which have been
partially solved by clamping the material index in the modifier code to
be in the valid range].

Now make sure we dont assign "invalid" materials through RNA by
appropriate RNA pointer functions.

This also adds a proper warning (red, alert) in case of the LineArt
modifier if such a invalid material is still in the file [same as other
modifiers already do].

Differential Revision: https://developer.blender.org/D10873

===================================================================

M	source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
M	source/blender/makesrna/intern/rna_gpencil_modifier.c

===================================================================

diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index eca82f4cb90..d6e151fd262 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -33,6 +33,7 @@
 #include "DNA_defaults.h"
 #include "DNA_gpencil_modifier_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_material_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -275,8 +276,25 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
   uiItemR(sub, ptr, "crease_threshold", UI_ITEM_R_SLIDER, " ", ICON_NONE);
 
   uiItemPointerR(layout, ptr, "target_layer", &obj_data_ptr, "layers", NULL, ICON_GREASEPENCIL);
-  uiItemPointerR(
-      layout, ptr, "target_material", &obj_data_ptr, "materials", NULL, ICON_SHADING_TEXTURE);
+
+  /* Material has to be used by grease pencil object already, it was possible to assign materials
+   * without this requirement in earlier versions of blender. */
+  bool material_valid = false;
+  PointerRNA material_ptr = RNA_pointer_get(ptr, "target_material");
+  if (!RNA_pointer_is_null(&material_ptr)) {
+    Material *current_material = material_ptr.data;
+    Object *ob = ob_ptr.data;
+    material_valid = BKE_gpencil_object_material_index_get(ob, current_material) != -1;
+  }
+  uiLayout *row = uiLayoutRow(layout, true);
+  uiLayoutSetRedAlert(row, !material_valid);
+  uiItemPointerR(row,
+                 ptr,
+                 "target_material",
+                 &obj_data_ptr,
+                 "materials",
+                 NULL,
+                 material_valid ? ICON_SHADING_TEXTURE : ICON_ERROR);
 
   uiItemR(layout, ptr, "use_remove_doubles", 0, NULL, ICON_NONE);
   uiItemR(layout, ptr, "use_edge_overlap", 0, IFACE_("Overlapping Edges As Contour"), ICON_NONE);
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index b13dada6bdf..b118adea14f 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -194,6 +194,7 @@ static const EnumPropertyItem gpencil_tint_type_items[] = {
 
 #  include "DNA_curve_types.h"
 #  include "DNA_fluid_types.h"
+#  include "DNA_material_types.h"
 #  include "DNA_particle_types.h"
 
 #  include "BKE_cachefile.h"
@@ -434,6 +435,195 @@ static void rna_GpencilModifier_opacity_update(Main *bmain, Scene *scene, Pointe
   rna_GpencilModifier_update(bmain, scene, ptr);
 }
 
+bool rna_GpencilModifier_material_poll(PointerRNA *ptr, PointerRNA value)
+{
+  Object *ob = (Object *)ptr->owner_id;
+  Material *ma = (Material *)value.owner_id;
+
+  return BKE_gpencil_object_material_index_get(ob, ma) != -1;
+}
+
+static void rna_GpencilModifier_material_set(PointerRNA *ptr,
+                                             PointerRNA value,
+                                             Material **ma_target,
+                                             struct ReportList *reports)
+{
+  Object *ob = (Object *)ptr->owner_id;
+  Material *ma = (Material *)value.owner_id;
+
+  if (ma == NULL || BKE_gpencil_object_material_index_get(ob, ma) != -1) {
+    id_lib_extern((ID *)ob);
+    *ma_target = ma;
+  }
+  else {
+    BKE_reportf(
+        reports,
+        RPT_ERROR,
+        "Cannot assign material '%s', it has to be used by the grease pencil object already",
+        ma->id.name);
+  }
+}
+
+static void rna_LineartGpencilModifier_material_set(PointerRNA *ptr,
+                                                    PointerRNA value,
+                                                    struct ReportList *reports)
+{
+  LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)ptr->data;
+  Material **ma_target = &lmd->target_material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_NoiseGpencilModifier_material_set(PointerRNA *ptr,
+                                                  PointerRNA value,
+                                                  struct ReportList *reports)
+{
+  NoiseGpencilModifierData *nmd = (NoiseGpencilModifierData *)ptr->data;
+  Material **ma_target = &nmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_SmoothGpencilModifier_material_set(PointerRNA *ptr,
+                                                   PointerRNA value,
+                                                   struct ReportList *reports)
+{
+  SmoothGpencilModifierData *smd = (SmoothGpencilModifierData *)ptr->data;
+  Material **ma_target = &smd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_SubdivGpencilModifier_material_set(PointerRNA *ptr,
+                                                   PointerRNA value,
+                                                   struct ReportList *reports)
+{
+  SubdivGpencilModifierData *smd = (SubdivGpencilModifierData *)ptr->data;
+  Material **ma_target = &smd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_SimplifyGpencilModifier_material_set(PointerRNA *ptr,
+                                                     PointerRNA value,
+                                                     struct ReportList *reports)
+{
+  SimplifyGpencilModifierData *smd = (SimplifyGpencilModifierData *)ptr->data;
+  Material **ma_target = &smd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_ThickGpencilModifier_material_set(PointerRNA *ptr,
+                                                  PointerRNA value,
+                                                  struct ReportList *reports)
+{
+  ThickGpencilModifierData *tmd = (ThickGpencilModifierData *)ptr->data;
+  Material **ma_target = &tmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_OffsetGpencilModifier_material_set(PointerRNA *ptr,
+                                                   PointerRNA value,
+                                                   struct ReportList *reports)
+{
+  OffsetGpencilModifierData *omd = (OffsetGpencilModifierData *)ptr->data;
+  Material **ma_target = &omd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_TintGpencilModifier_material_set(PointerRNA *ptr,
+                                                 PointerRNA value,
+                                                 struct ReportList *reports)
+{
+  TintGpencilModifierData *tmd = (TintGpencilModifierData *)ptr->data;
+  Material **ma_target = &tmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_ColorGpencilModifier_material_set(PointerRNA *ptr,
+                                                  PointerRNA value,
+                                                  struct ReportList *reports)
+{
+  ColorGpencilModifierData *cmd = (ColorGpencilModifierData *)ptr->data;
+  Material **ma_target = &cmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_ArrayGpencilModifier_material_set(PointerRNA *ptr,
+                                                  PointerRNA value,
+                                                  struct ReportList *reports)
+{
+  ArrayGpencilModifierData *amd = (ArrayGpencilModifierData *)ptr->data;
+  Material **ma_target = &amd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_OpacityGpencilModifier_material_set(PointerRNA *ptr,
+                                                    PointerRNA value,
+                                                    struct ReportList *reports)
+{
+  OpacityGpencilModifierData *omd = (OpacityGpencilModifierData *)ptr->data;
+  Material **ma_target = &omd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_LatticeGpencilModifier_material_set(PointerRNA *ptr,
+                                                    PointerRNA value,
+                                                    struct ReportList *reports)
+{
+  LatticeGpencilModifierData *lmd = (LatticeGpencilModifierData *)ptr->data;
+  Material **ma_target = &lmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_MirrorGpencilModifier_material_set(PointerRNA *ptr,
+                                                   PointerRNA value,
+                                                   struct ReportList *reports)
+{
+  MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)ptr->data;
+  Material **ma_target = &mmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_HookGpencilModifier_material_set(PointerRNA *ptr,
+                                                 PointerRNA value,
+                                                 struct ReportList *reports)
+{
+  HookGpencilModifierData *hmd = (HookGpencilModifierData *)ptr->data;
+  Material **ma_target = &hmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_MultiplyGpencilModifier_material_set(PointerRNA *ptr,
+                                                     PointerRNA value,
+                                                     struct ReportList *reports)
+{
+  MultiplyGpencilModifierData *mmd = (MultiplyGpencilModifierData *)ptr->data;
+  Material **ma_target = &mmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_TextureGpencilModifier_material_set(PointerRNA *ptr,
+                                                    PointerRNA value,
+                                                    struct ReportList *reports)
+{
+  TextureGpencilModifierData *tmd = (TextureGpencilModifierData *)ptr->data;
+  Material **ma_target = &tmd->material;
+
+  rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
 #else
 
 static void rna_def_modifier_gpenc

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list