[Bf-blender-cvs] [d92bc7d09ad] greasepencil-object: WIP: Basic Join object operator for grease pencil
Antonio Vazquez
noreply at git.blender.org
Thu Dec 21 12:52:37 CET 2017
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;
}
More information about the Bf-blender-cvs
mailing list