Commit: d92bc7d09ad0b90aa0b80449fb407ce5720c98aa
Author: Antonio Vazquez
Date:   Thu Dec 21 12:52:17 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rBd92bc7d09ad0b90aa0b80449fb407ce5720c98aa

WIP: Basic Join object operator for grease pencil

Still pending:

- Modifiers
- Animation data

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

M       source/blender/editors/gpencil/gpencil_data.c
M       source/blender/editors/include/ED_gpencil.h
M       source/blender/editors/object/object_add.c

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

diff --git a/source/blender/editors/gpencil/gpencil_data.c 
b/source/blender/editors/gpencil/gpencil_data.c
index 2566dda3b3d..7287f485d66 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -55,6 +55,7 @@
 #include "DNA_brush_types.h"
 
 #include "BKE_main.h"
+#include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_gpencil.h"
@@ -76,8 +77,11 @@
 #include "RNA_define.h"
 #include "RNA_enum_types.h"
 
+#include "ED_object.h"
 #include "ED_gpencil.h"
 
+#include "DEG_depsgraph_build.h"
+
 #include "gpencil_intern.h"
 
 /* ************************************************ */
@@ -1870,3 +1874,124 @@ void GPENCIL_OT_vertex_group_deselect(wmOperatorType 
*ot)
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/* join objects called from OBJECT_OT_join */
+int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
+{
+       Main *bmain = CTX_data_main(C);
+       Scene *scene = CTX_data_scene(C);
+       Object  *obact = CTX_data_active_object(C);
+       bGPdata *gpd_act = NULL;
+       bool ok = false;
+
+       /* Ensure we're in right mode and that the active object is correct */
+       if (!obact || obact->type != OB_GPENCIL)
+               return OPERATOR_CANCELLED;
+
+       /* Ensure all rotations are applied before */
+       CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+       {
+               if (base->object->type == OB_GPENCIL) {
+                       if ((base->object->rot[0] != 0) || 
+                               (base->object->rot[1] != 0) || 
+                               (base->object->rot[2] != 0)) 
+                       {
+                               BKE_report(op->reports, RPT_ERROR, "Apply all 
rotations before join objects");
+                               return OPERATOR_CANCELLED;
+                       }
+               }
+       }
+       CTX_DATA_END;
+
+       bGPdata *gpd = (bGPdata *)obact->data;
+       if ((!gpd) || GPENCIL_ANY_MODE(gpd)) {
+               return OPERATOR_CANCELLED;
+       }
+
+       CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+       {
+               if (base->object == obact) {
+                       ok = true;
+                       break;
+               }
+       }
+       CTX_DATA_END;
+
+       /* that way the active object is always selected */
+       if (ok == false) {
+               BKE_report(op->reports, RPT_WARNING, "Active object is not a 
selected grease pencil");
+               return OPERATOR_CANCELLED;
+       }
+
+       gpd_act = obact->data;
+
+       /* loop and join */
+       CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+       {
+               if ((base->object->type == OB_GPENCIL) && (base->object != 
obact)) {
+                       /* we assume that each datablock is not already used in 
active object */
+                       if (obact->data != base->object->data) {
+                               bGPdata *gpd = base->object->data;
+
+                               /* TODO: Apply all modifiers */
+
+                               /* add missing paletteslots */
+                               bGPDpaletteref *palslot;
+                               for (palslot = gpd->palette_slots.first; 
palslot; palslot = palslot->next) {
+                                       if 
(!BKE_gpencil_paletteslot_find(gpd_act, palslot->palette)) {
+                                               
BKE_gpencil_paletteslot_add(gpd_act, palslot->palette);
+                                       }
+                               }
+
+                               /* duplicate layers */
+                               bGPDspoint *pt;
+                               float imat[3][3], bmat[3][3];
+                               float offset_global[3];
+                               float offset_local[3];
+                               int i;
+
+                               sub_v3_v3v3(offset_global, obact->loc, 
base->object->obmat[3]);
+                               copy_m3_m4(bmat, obact->obmat);
+                               invert_m3_m3(imat, bmat);
+                               mul_m3_v3(imat, offset_global);
+                               mul_v3_m3v3(offset_local, imat, offset_global);
+
+                               float diff_mat[4][4];
+                               float inverse_diff_mat[4][4];
+
+                               for (bGPDlayer *gpl_src = gpd->layers.first; 
gpl_src; gpl_src = gpl_src->next) {
+                                       bGPDlayer *gpl_new = 
BKE_gpencil_layer_duplicate(gpl_src);
+                                       /* recalculate all strokes */
+                                       
ED_gpencil_parent_location(base->object, gpd, gpl_src, diff_mat);
+                                       /* undo matrix */
+                                       invert_m4_m4(inverse_diff_mat, 
diff_mat);
+                                       
+                                       for (bGPDframe *gpf = 
gpl_new->frames.first; gpf; gpf = gpf->next) {
+                                               for (bGPDstroke *gps = 
gpf->strokes.first; gps; gps = gps->next) {
+                                                       for (i = 0, pt = 
gps->points; i < gps->totpoints; i++, pt++) {
+                                                               float mpt[3];
+                                                               
mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x);
+                                                               sub_v3_v3(mpt, 
offset_local);
+                                                               
mul_v3_m4v3(&pt->x, diff_mat, mpt);
+                                                       }
+                                               }
+                                       }
+
+                                       /* add to datablock */
+                                       BLI_addtail(&gpd_act->layers, gpl_new);
+                               }
+
+                               /* TODO: copy animdata */
+                       }
+
+                       /* Free the old object */
+                       ED_object_base_free_and_unlink(bmain, scene, 
base->object);
+               }
+       }
+       CTX_DATA_END;
+
+       DEG_relations_tag_update(bmain);  /* because we removed object(s) */
+
+       WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+
+       return OPERATOR_FINISHED;
+}
\ No newline at end of file
diff --git a/source/blender/editors/include/ED_gpencil.h 
b/source/blender/editors/include/ED_gpencil.h
index b80a310e1d4..408844cc6c4 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -35,6 +35,7 @@
 struct ARegion;
 struct bAnimContext;
 struct bContext;
+struct wmOperator;
 struct bGPdata;
 struct bGPDlayer;
 struct bGPDframe;
@@ -284,4 +285,6 @@ void ED_gpencil_vgroup_remove(struct bContext *C, struct 
Object *ob);
 void ED_gpencil_vgroup_select(struct bContext *C, struct Object *ob);
 void ED_gpencil_vgroup_deselect(struct bContext *C, struct Object *ob);
 
+/* join objects */
+int ED_gpencil_join_objects_exec(struct bContext *C, struct wmOperator *op);
 #endif /*  __ED_GPENCIL_H__ */
diff --git a/source/blender/editors/object/object_add.c 
b/source/blender/editors/object/object_add.c
index 96208241a3f..ed66d5ae109 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2592,7 +2592,7 @@ static int join_poll(bContext *C)
 
        if (!ob || ID_IS_LINKED(ob)) return 0;
 
-       if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE))
+       if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL))
                return ED_operator_screenactive(C);
        else
                return 0;
@@ -2611,6 +2611,13 @@ static int join_exec(bContext *C, wmOperator *op)
                BKE_report(op->reports, RPT_ERROR, "Cannot edit external 
libdata");
                return OPERATOR_CANCELLED;
        }
+       else if (ob->type == OB_GPENCIL) {
+               bGPdata *gpd = (bGPdata *)ob->data;
+               if ((!gpd) || GPENCIL_ANY_MODE(gpd)) {
+                       BKE_report(op->reports, RPT_ERROR, "This data does not 
support joining in this mode");
+                       return OPERATOR_CANCELLED;
+               }
+       }
 
        if (ob->type == OB_MESH)
                return join_mesh_exec(C, op);
@@ -2618,6 +2625,8 @@ static int join_exec(bContext *C, wmOperator *op)
                return join_curve_exec(C, op);
        else if (ob->type == OB_ARMATURE)
                return join_armature_exec(C, op);
+       else if (ob->type == OB_GPENCIL)
+               return ED_gpencil_join_objects_exec(C, op);
 
        return OPERATOR_CANCELLED;
 }

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

Reply via email to