[Bf-blender-cvs] [3437cf155e7] master: LibOverride: Add full support for camera's background images.

Bastien Montagne noreply at git.blender.org
Mon May 30 17:43:27 CEST 2022


Commit: 3437cf155e7ca73cb96882ed5372f5baf2eac78a
Author: Bastien Montagne
Date:   Mon May 30 17:24:16 2022 +0200
Branches: master
https://developer.blender.org/rB3437cf155e7ca73cb96882ed5372f5baf2eac78a

LibOverride: Add full support for camera's background images.

Add support for adding (inserting) new background images into an
override of a linked Camera ID.

Request from the Blender studio.

This ended up being more involved than expected as it uncovered some
latent issues with existing background images code. Noticiably, a new
`BKE_camera_background_image_copy` had to be added to handle copying
of background images in a proper, generic ID-management way.

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

M	source/blender/blenkernel/BKE_camera.h
M	source/blender/blenkernel/intern/camera.c
M	source/blender/editors/space_view3d/view3d_edit.c
M	source/blender/makesdna/DNA_camera_types.h
M	source/blender/makesrna/intern/rna_access_compare_override.c
M	source/blender/makesrna/intern/rna_camera.c

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

diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index e55b8b1a2da..b7aa1c09e04 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -164,6 +164,14 @@ bool BKE_camera_multiview_spherical_stereo(const struct RenderData *rd,
 /* Camera background image API */
 
 struct CameraBGImage *BKE_camera_background_image_new(struct Camera *cam);
+/**
+ * Duplicate a background image, in a ID management compatible way.
+ *
+ * \param copy_flag The usual ID copying flags, see `LIB_ID_CREATE_`/`LIB_ID_COPY_` enums in
+ * `BKE_lib_id.h`.
+ */
+struct CameraBGImage *BKE_camera_background_image_copy(struct CameraBGImage *bgpic_src,
+                                                            const int copy_flag);
 void BKE_camera_background_image_remove(struct Camera *cam, struct CameraBGImage *bgpic);
 void BKE_camera_background_image_clear(struct Camera *cam);
 
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index b59e44aae8a..6325251647b 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -66,14 +66,19 @@ static void camera_init_data(ID *id)
  *
  * \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more).
  */
-static void camera_copy_data(Main *UNUSED(bmain),
-                             ID *id_dst,
-                             const ID *id_src,
-                             const int UNUSED(flag))
+static void camera_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
 {
   Camera *cam_dst = (Camera *)id_dst;
   const Camera *cam_src = (const Camera *)id_src;
-  BLI_duplicatelist(&cam_dst->bg_images, &cam_src->bg_images);
+
+  /* We never handle usercount here for own data. */
+  const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+  BLI_listbase_clear(&cam_dst->bg_images);
+  LISTBASE_FOREACH (CameraBGImage *, bgpic_src, &cam_src->bg_images) {
+    CameraBGImage *bgpic_dst = BKE_camera_background_image_copy(bgpic_src, flag_subdata);
+    BLI_addtail(&cam_dst->bg_images, bgpic_dst);
+  }
 }
 
 /** Free (or release) any data used by this camera (does not free the camera itself). */
@@ -125,6 +130,11 @@ static void camera_blend_read_data(BlendDataReader *reader, ID *id)
 
   LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
     bgpic->iuser.scene = NULL;
+
+    /* If linking from a library, clear 'local' library override flag. */
+    if (ID_IS_LINKED(ca)) {
+      bgpic->flag &= ~CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL;
+    }
   }
 }
 
@@ -1119,13 +1129,31 @@ CameraBGImage *BKE_camera_background_image_new(Camera *cam)
   bgpic->scale = 1.0f;
   bgpic->alpha = 0.5f;
   bgpic->iuser.flag |= IMA_ANIM_ALWAYS;
-  bgpic->flag |= CAM_BGIMG_FLAG_EXPANDED;
+  bgpic->flag |= CAM_BGIMG_FLAG_EXPANDED | CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL;
 
   BLI_addtail(&cam->bg_images, bgpic);
 
   return bgpic;
 }
 
+CameraBGImage *BKE_camera_background_image_copy(CameraBGImage *bgpic_src, const int flag)
+{
+  CameraBGImage *bgpic_dst = MEM_dupallocN(bgpic_src);
+
+  bgpic_dst->next = bgpic_dst->prev = NULL;
+
+  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+    id_us_plus((ID *)bgpic_dst->ima);
+    id_us_plus((ID *)bgpic_dst->clip);
+  }
+
+  if ((flag & LIB_ID_COPY_NO_LIB_OVERRIDE_LOCAL_DATA_FLAG) == 0) {
+    bgpic_dst->flag |= CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL;
+  }
+
+  return bgpic_dst;
+}
+
 void BKE_camera_background_image_remove(Camera *cam, CameraBGImage *bgpic)
 {
   BLI_remlink(&cam->bg_images, bgpic);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index fb5e7e58d33..a65e9a8d506 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -631,6 +631,17 @@ static int background_image_remove_exec(bContext *C, wmOperator *op)
   CameraBGImage *bgpic_rem = BLI_findlink(&cam->bg_images, index);
 
   if (bgpic_rem) {
+    if (ID_IS_OVERRIDE_LIBRARY(cam) &&
+        (bgpic_rem->flag & CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL) == 0) {
+      BKE_reportf(op->reports,
+                  RPT_WARNING,
+                  "Cannot remove background image %d from camera '%s', as it is from the linked "
+                  "reference data",
+                  index,
+                  cam->id.name + 2);
+      return OPERATOR_CANCELLED;
+    }
+
     id_us_min((ID *)bgpic_rem->ima);
     id_us_min((ID *)bgpic_rem->clip);
 
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index 9b3adc4c8dd..e0aec298cd0 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -194,6 +194,9 @@ enum {
   /* Axis flip options */
   CAM_BGIMG_FLAG_FLIP_X = (1 << 7),
   CAM_BGIMG_FLAG_FLIP_Y = (1 << 8),
+
+  /* That background image has been inserted in local override (i.e. it can be fully edited!). */
+  CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL = (1 << 9),
 };
 
 /* CameraBGImage->source */
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index aea4467c162..17c00923efa 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -12,6 +12,7 @@
 
 #include "DNA_ID.h"
 #include "DNA_anim_types.h"
+#include "DNA_camera_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_gpencil_modifier_types.h"
 #include "DNA_key_types.h"
@@ -145,6 +146,12 @@ bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop)
         return true;
       }
     }
+    else if (RNA_struct_is_a(ptr->type, &RNA_CameraBackgroundImage)) {
+      CameraBGImage *bgpic = ptr->data;
+      if (bgpic->flag & CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL) {
+        return true;
+      }
+    }
     /* If this is a RNA-defined property (real or 'virtual' IDProp),
      * we want to use RNA prop flag. */
     return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) &&
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 52ec2bee128..dcf0647392e 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -125,6 +125,49 @@ static char *rna_Camera_background_image_path(const PointerRNA *ptr)
   return NULL;
 }
 
+static bool rna_Camera_background_images_override_apply(Main *bmain,
+                                                        PointerRNA *ptr_dst,
+                                                        PointerRNA *ptr_src,
+                                                        PointerRNA *UNUSED(ptr_storage),
+                                                        PropertyRNA *prop_dst,
+                                                        PropertyRNA *UNUSED(prop_src),
+                                                        PropertyRNA *UNUSED(prop_storage),
+                                                        const int UNUSED(len_dst),
+                                                        const int UNUSED(len_src),
+                                                        const int UNUSED(len_storage),
+                                                        PointerRNA *UNUSED(ptr_item_dst),
+                                                        PointerRNA *UNUSED(ptr_item_src),
+                                                        PointerRNA *UNUSED(ptr_item_storage),
+                                                        IDOverrideLibraryPropertyOperation *opop)
+{
+  BLI_assert_msg(opop->operation == IDOVERRIDE_LIBRARY_OP_INSERT_AFTER,
+                 "Unsupported RNA override operation on background images collection");
+
+  Camera *cam_dst = (Camera *)ptr_dst->owner_id;
+  Camera *cam_src = (Camera *)ptr_src->owner_id;
+
+  /* Remember that insertion operations are defined and stored in correct order, which means that
+   * even if we insert several items in a row, we always insert first one, then second one, etc.
+   * So we should always find 'anchor' constraint in both _src *and* _dst. */
+  CameraBGImage *bgpic_anchor = BLI_findlink(&cam_dst->bg_images, opop->subitem_reference_index);
+
+  /* If `bgpic_anchor` is NULL, `bgpic_src` will be inserted in first position. */
+  CameraBGImage *bgpic_src = BLI_findlink(&cam_src->bg_images, opop->subitem_local_index);
+
+  if (bgpic_src == NULL) {
+    BLI_assert(bgpic_src != NULL);
+    return false;
+  }
+
+  CameraBGImage *bgpic_dst = BKE_camera_background_image_copy(bgpic_src, 0);
+
+  /* This handles NULL anchor as expected by adding at head of list. */
+  BLI_insertlinkafter(&cam_dst->bg_images, bgpic_anchor, bgpic_dst);
+
+  RNA_property_update_main(bmain, NULL, ptr_dst, prop_dst);
+  return true;
+}
+
 static void rna_Camera_dof_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
 {
   SEQ_relations_invalidate_scene_strips(bmain, scene);
@@ -195,6 +238,16 @@ static void rna_def_camera_background_image(BlenderRNA *brna)
       srna, "Background Image", "Image and settings for display in the 3D View background");
   RNA_def_struct_path_func(srna, "rna_Camera_background_image_path");
 
+  prop = RNA_def_boolean(srna,
+                         "is_override_data",
+                         false,
+                         "Override Background Image",
+                         "In a local override camera, whether this background image comes from "
+                         "the linked reference camera, or is local to the override");
+  RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+  RNA_def_property_boolean_negative_sdna(
+      prop, NULL, "flag", CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL);
+
   RNA_define_lib_overridable(true);
 
   prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
@@ -751,6 +804,8 @@ void RNA_def_camera(BlenderRNA *brna)
   RNA_def_property_collection_sdna(prop, NULL, "bg_images", NULL);
   RNA_def_property_struct_type(prop, "CameraBackgroundImage");
   RNA_def_property_ui_text(prop, "Background Images", "List of background images");
+  R

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list