Grease Pencil: adjust behavior of target object detection

First detect the other selected object, then check it can be written to.

Otherwise the target object could be the first one found when
looping over objects which is random from the user perspective.

Move the type check to the operator, which also checks the data isn't
library data which was being ignored.
This commit is contained in:
Campbell Barton 2020-11-16 16:48:44 +11:00
parent a3a6d6a670
commit 64ab084ca5
4 changed files with 48 additions and 16 deletions

View File

@ -377,9 +377,8 @@ struct Object **BKE_view_layer_array_selected_objects_params(
uint *r_len,
const struct ObjectsInViewLayerParams *params);
struct Object *BKE_view_layer_first_selected_object_by_type(struct ViewLayer *view_layer,
const struct View3D *v3d,
const short ob_type);
struct Object *BKE_view_layer_non_active_selected_object(struct ViewLayer *view_layer,
const struct View3D *v3d);
#define BKE_view_layer_array_selected_objects(view_layer, v3d, r_len, ...) \
BKE_view_layer_array_selected_objects_params( \

View File

@ -192,15 +192,28 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(Object *ob, void *UNUSED(user_dat
return false;
}
/** Select first selected object of the type specified. */
Object *BKE_view_layer_first_selected_object_by_type(struct ViewLayer *view_layer,
const struct View3D *v3d,
const short ob_type)
/**
* Use this in rare cases we need to detect a pair of objects (active, selected).
* This returns the other non-active selected object.
*
* Returns NULL with it finds multiple other selected objects
* as behavior in this case would be random from the user perspective.
*/
Object *BKE_view_layer_non_active_selected_object(struct ViewLayer *view_layer,
const struct View3D *v3d)
{
Object *ob_active = OBACT(view_layer);
Object *ob_result = NULL;
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob_iter) {
if (ob_iter->type == ob_type) {
if (ob_iter == ob_active) {
continue;
}
if (ob_result == NULL) {
ob_result = ob_iter;
}
else {
ob_result = NULL;
break;
}
}

View File

@ -224,12 +224,22 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
const int project_type = RNA_enum_get(op->ptr, "project_type");
eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
/* Create a new grease pencil object in origin or resuse selected. */
/* Create a new grease pencil object in origin or reuse selected. */
Object *ob_gpencil = NULL;
bool newob = false;
if (target == GP_TARGET_OB_SELECTED) {
ob_gpencil = BKE_view_layer_first_selected_object_by_type(
CTX_data_view_layer(C), v3d, OB_GPENCIL);
ob_gpencil = BKE_view_layer_non_active_selected_object(CTX_data_view_layer(C), v3d);
if (ob_gpencil != NULL) {
if (ob_gpencil->type != OB_GPENCIL) {
BKE_report(op->reports, RPT_WARNING, "Target object not a grease pencil, ignoring!");
ob_gpencil = NULL;
}
else if (BKE_object_obdata_is_libdata(ob_gpencil)) {
BKE_report(op->reports, RPT_WARNING, "Target object library-data, ignoring!");
ob_gpencil = NULL;
}
}
}
if (ob_gpencil == NULL) {

View File

@ -321,12 +321,22 @@ static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
job->image = (Image *)job->ob_active->data;
job->frame_target = CFRA;
/* Create a new grease pencil object or resuse selected. */
/* Create a new grease pencil object or reuse selected. */
eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
job->ob_gpencil = (target == GP_TARGET_OB_SELECTED) ?
BKE_view_layer_first_selected_object_by_type(
CTX_data_view_layer(C), job->v3d, OB_GPENCIL) :
NULL;
job->ob_gpencil = (target == GP_TARGET_OB_SELECTED) ? BKE_view_layer_non_active_selected_object(
CTX_data_view_layer(C), job->v3d) :
NULL;
if (job->ob_gpencil != NULL) {
if (job->ob_gpencil->type != OB_GPENCIL) {
BKE_report(op->reports, RPT_WARNING, "Target object not a grease pencil, ignoring!");
job->ob_gpencil = NULL;
}
else if (BKE_object_obdata_is_libdata(job->ob_gpencil)) {
BKE_report(op->reports, RPT_WARNING, "Target object library-data, ignoring!");
job->ob_gpencil = NULL;
}
}
job->was_ob_created = false;