Commit: 3c5d358d892f6216137d77262a1bf7482f19f0d8
Author: Joshua Leung
Date:   Fri Dec 22 17:04:22 2017 +1300
Branches: greasepencil-object
https://developer.blender.org/rB3c5d358d892f6216137d77262a1bf7482f19f0d8

Joining GP objects also merges + fixes animation data for the merged datablocks

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

M       source/blender/editors/gpencil/gpencil_data.c

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

diff --git a/source/blender/editors/gpencil/gpencil_data.c 
b/source/blender/editors/gpencil/gpencil_data.c
index ac0362fc0b5..1c20aea4695 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -46,6 +46,7 @@
 
 #include "BLT_translation.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -58,6 +59,7 @@
 #include "BKE_main.h"
 #include "BKE_animsys.h"
 #include "BKE_context.h"
+#include "BKE_fcurve.h"
 #include "BKE_global.h"
 #include "BKE_gpencil.h"
 #include "BKE_paint.h"
@@ -1881,6 +1883,80 @@ void GPENCIL_OT_vertex_group_deselect(wmOperatorType *ot)
 
 /****************************** Join ***********************************/
 
+/* userdata for joined_gpencil_fix_animdata_cb() */
+typedef struct tJoinGPencil_AdtFixData {
+       bGPdata *src_gpd;
+       bGPdata *tar_gpd;
+       
+       GHash *names_map;
+} tJoinGPencil_AdtFixData;
+
+/* Callback to pass to BKE_fcurves_main_cb() for RNA Paths attached to each 
F-Curve used in the AnimData */
+static void joined_gpencil_fix_animdata_cb(ID *id, FCurve *fcu, void 
*user_data)
+{
+       tJoinGPencil_AdtFixData *afd = (tJoinGPencil_AdtFixData *)user_data;
+       ID *src_id = &afd->src_gpd->id;
+       ID *dst_id = &afd->tar_gpd->id;
+       
+       GHashIterator gh_iter;
+       
+       /* Fix paths - If this is the target datablock, it will have some 
"dirty" paths */
+       if ((id == src_id) && fcu->rna_path && strstr(fcu->rna_path, 
"layers[")) {
+               GHASH_ITER(gh_iter, afd->names_map) {
+                       const char *old_name = 
BLI_ghashIterator_getKey(&gh_iter);
+                       const char *new_name = 
BLI_ghashIterator_getValue(&gh_iter);
+                       
+                       /* only remap if changed; this still means there will 
be some waste if there aren't many drivers/keys */
+                       if (!STREQ(old_name, new_name) && strstr(fcu->rna_path, 
old_name)) {
+                               fcu->rna_path = 
BKE_animsys_fix_rna_path_rename(id, fcu->rna_path, "layers",
+                                                                               
old_name, new_name, 0, 0, false);
+                               
+                               /* we don't want to apply a second remapping on 
this F-Curve now, 
+                                * so stop trying to fix names names
+                                */
+                               break;
+                       }
+               }
+       }
+       
+       /* Fix driver targets */
+       if (fcu->driver) {
+               /* Fix driver references to invalid ID's */
+               for (DriverVar *dvar = fcu->driver->variables.first; dvar; dvar 
= dvar->next) {
+                       /* only change the used targets, since the others will 
need fixing manually anyway */
+                       DRIVER_TARGETS_USED_LOOPER(dvar)
+                       {
+                               /* change the ID's used... */
+                               if (dtar->id == src_id) {
+                                       dtar->id = dst_id;
+                                       
+                                       /* also check on the subtarget...
+                                        * XXX: We duplicate the logic from 
drivers_path_rename_fix() here, with our own
+                                        *      little twists so that we know 
that it isn't going to clobber the wrong data
+                                        */
+                                       if (dtar->rna_path && 
strstr(dtar->rna_path, "layers[")) {
+                                               GHASH_ITER(gh_iter, 
afd->names_map) {
+                                                       const char *old_name = 
BLI_ghashIterator_getKey(&gh_iter);
+                                                       const char *new_name = 
BLI_ghashIterator_getValue(&gh_iter);
+                                                       
+                                                       /* only remap if 
changed */
+                                                       if (!STREQ(old_name, 
new_name)) {
+                                                               if 
((dtar->rna_path) && strstr(dtar->rna_path, old_name)) {
+                                                                       /* Fix 
up path */
+                                                                       
dtar->rna_path = BKE_animsys_fix_rna_path_rename(id, dtar->rna_path, "layers",
+                                                                               
                                         old_name, new_name, 0, 0, false);
+                                                                       break; 
/* no need to try any more names for layer path */
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       DRIVER_TARGETS_LOOPER_END
+               }
+       }
+}
+
 /* join objects called from OBJECT_OT_join */
 int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
 {
@@ -1983,6 +2059,11 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator 
*op)
                                }
 
                                /* duplicate bGPDlayers  */
+                               tJoinGPencil_AdtFixData afd = {0};
+                               afd.src_gpd = gpd_src;
+                               afd.tar_gpd = gpd_dst;
+                               afd.names_map = 
BLI_ghash_str_new("joined_gp_layers_map");
+                               
                                float imat[3][3], bmat[3][3];
                                float offset_global[3];
                                float offset_local[3];
@@ -1993,6 +2074,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator 
*op)
                                mul_m3_v3(imat, offset_global);
                                mul_v3_m3v3(offset_local, imat, offset_global);
 
+
                                for (bGPDlayer *gpl_src = 
gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
                                        bGPDlayer *gpl_new = 
BKE_gpencil_layer_duplicate(gpl_src);
                                        float diff_mat[4][4];
@@ -2014,13 +2096,44 @@ int ED_gpencil_join_objects_exec(bContext *C, 
wmOperator *op)
                                                        }
                                                }
                                        }
+                                       
                                        /* be sure name is unique in new object 
*/
                                        BLI_uniquename(&gpd_dst->layers, 
gpl_new, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), 
sizeof(gpl_new->info));
+                                       BLI_ghash_insert(afd.names_map, 
BLI_strdup(gpl_src->info), gpl_new->info);
+                                       
                                        /* add to destination datablock */
                                        BLI_addtail(&gpd_dst->layers, gpl_new);
                                }
-
-                               /* TODO: copy animdata */
+                               
+                               /* Fix all the animation data */
+                               BKE_fcurves_main_cb(bmain, 
joined_gpencil_fix_animdata_cb, &afd);
+                               BLI_ghash_free(afd.names_map, MEM_freeN, NULL);
+                               
+                               /* Only copy over animdata now, after all the 
remapping has been done, 
+                                * so that we don't have to worry about 
ambiguities re which datablock
+                                * a layer came from!
+                                */
+                               if (base->object->adt) {
+                                       if (obact->adt == NULL) {
+                                               /* no animdata, so just use a 
copy of the whole thing */
+                                               obact->adt = 
BKE_animdata_copy(bmain, base->object->adt, false);
+                                       }
+                                       else {
+                                               /* merge in data - we'll fix 
the drivers manually */
+                                               
BKE_animdata_merge_copy(&obact->id, &base->object->id, ADT_MERGECOPY_KEEP_DST, 
false);
+                                       }
+                               }
+                               
+                               if (gpd_src->adt) {
+                                       if (gpd_dst->adt == NULL) {
+                                               /* no animdata, so just use a 
copy of the whole thing */
+                                               gpd_dst->adt = 
BKE_animdata_copy(bmain, gpd_src->adt, false);
+                                       }
+                                       else {
+                                               /* merge in data - we'll fix 
the drivers manually */
+                                               
BKE_animdata_merge_copy(&gpd_dst->id, &gpd_src->id, ADT_MERGECOPY_KEEP_DST, 
false);
+                                       }
+                               }
                        }
 
                        /* Free the old object */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to