GPencil: Remove ID from operators to fix T82597

Instead to use the ID of the object, now the parameter is an Enum with Selected object or New.

If use selected mode, the first grease pencil object selected is used. If none of the selected objects is a grease pencil object, a new object is created.

Small cleanup changes to the original patch.

Differential Revision: https://developer.blender.org/D9529
This commit is contained in:
Antonio Vazquez 2020-11-13 13:17:17 +01:00
parent 50ccf346f0
commit e9b955b99c
Notes: blender-bot 2023-02-14 10:21:10 +01:00
Referenced by issue #82597, Crash running with --debug-wm and pressing F3
5 changed files with 70 additions and 30 deletions

View File

@ -377,6 +377,10 @@ 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);
#define BKE_view_layer_array_selected_objects(view_layer, v3d, r_len, ...) \
BKE_view_layer_array_selected_objects_params( \
view_layer, v3d, r_len, &(const struct ObjectsInViewLayerParams)__VA_ARGS__)

View File

@ -192,4 +192,19 @@ 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)
{
Object *ob_result = NULL;
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob_iter) {
if (ob_iter->type == ob_type) {
ob_result = ob_iter;
break;
}
}
FOREACH_SELECTED_OBJECT_END;
return ob_result;
}
/** \} */

View File

@ -39,6 +39,7 @@
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_object.h"
@ -191,7 +192,6 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Object *ob_gpencil = NULL;
ListBase ob_selected_list = {NULL, NULL};
gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list);
@ -222,10 +222,16 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
const float offset = RNA_float_get(op->ptr, "offset");
const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start;
const int project_type = RNA_enum_get(op->ptr, "project_type");
ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data;
eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
/* Create a new grease pencil object in origin. */
/* Create a new grease pencil object in origin or resuse 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);
}
if (ob_gpencil == NULL) {
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
const float loc[3] = {0.0f, 0.0f, 0.0f};
@ -244,6 +250,9 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
if (project_type != GP_REPROJECT_KEEP) {
/* Init space conversion stuff. */
gpencil_point_conversion_init(C, &gsc);
/* Move the grease pencil object to conversion data. */
gsc.ob = ob_gpencil;
/* Init snap context for geometry projection. */
sctx = ED_transform_snap_object_context_create_view3d(scene, 0, region, CTX_wm_view3d(C));
@ -383,10 +392,6 @@ static int gpencil_bake_mesh_animation_invoke(bContext *C,
return WM_operator_props_dialog_popup(C, op, 250);
}
static bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
return ((Object *)value.owner_id)->type == OB_GPENCIL;
}
void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
{
static const EnumPropertyItem reproject_type[] = {
@ -408,6 +413,12 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem target_object_modes[] = {
{GP_TARGET_OB_NEW, "NEW", 0, "New Object", ""},
{GP_TARGET_OB_SELECTED, "SELECTED", 0, "Selected Object", ""},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
/* identifiers */
@ -424,12 +435,12 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
ot->prop = RNA_def_pointer_runtime(ot->srna,
"target",
&RNA_Object,
"Target Object",
"Target grease pencil object. Leave empty for new object");
RNA_def_property_poll_runtime(ot->prop, rna_GPencil_object_poll);
ot->prop = RNA_def_enum(ot->srna,
"target",
target_object_modes,
GP_TARGET_OB_NEW,
"Target Object",
"Target grease pencil");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
prop = RNA_def_int(

View File

@ -38,6 +38,7 @@
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
@ -320,7 +321,13 @@ static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
job->image = (Image *)job->ob_active->data;
job->frame_target = CFRA;
job->ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data;
/* Create a new grease pencil object or resuse 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->was_ob_created = false;
job->threshold = RNA_float_get(op->ptr, "threshold");
@ -368,15 +375,8 @@ static int gpencil_trace_image_invoke(bContext *C, wmOperator *op, const wmEvent
return WM_operator_props_dialog_popup(C, op, 250);
}
static bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
return ((Object *)value.owner_id)->type == OB_GPENCIL;
}
void GPENCIL_OT_trace_image(wmOperatorType *ot)
{
PropertyRNA *prop;
static const EnumPropertyItem turnpolicy_type[] = {
{POTRACE_TURNPOLICY_BLACK,
"BLACK",
@ -412,6 +412,12 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem target_object_modes[] = {
{GP_TARGET_OB_NEW, "NEW", 0, "New Object", ""},
{GP_TARGET_OB_SELECTED, "SELECTED", 0, "Selected Object", ""},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
ot->name = "Trace Image to Grease Pencil";
ot->idname = "GPENCIL_OT_trace_image";
@ -426,15 +432,13 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_pointer_runtime(
ot->srna,
"target",
&RNA_Object,
"Target Object",
"Target grease pencil object name. Leave empty to create a new object");
RNA_def_property_poll_runtime(prop, rna_GPencil_object_poll);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
ot->prop = RNA_def_enum(ot->srna,
"target",
target_object_modes,
GP_TARGET_OB_NEW,
"Target Object",
"Target grease pencil");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
RNA_def_int(ot->srna, "thickness", 10, 1, 1000, "Thickness", "", 1, 1000);
RNA_def_int(

View File

@ -79,6 +79,12 @@ typedef enum eGP_ReprojectModes {
GP_REPROJECT_KEEP,
} eGP_ReprojectModes;
/* Target object modes. */
typedef enum eGP_TargetObjectMode {
GP_TARGET_OB_NEW = 0,
GP_TARGET_OB_SELECTED = 1,
} eGP_TargetObjectMode;
/* ------------- Grease-Pencil Runtime Data ---------------- */
/* Temporary 'Stroke Point' data (2D / screen-space)