Cleanup: Use std::string for some RNA function return values
This significantly simplifies memory management, mostly by avoiding the need to free the memory manually. It may also improve performance, since std::string has an inline buffer that can prevent heap allocations and it stores the size. Pull Request: https://projects.blender.org/blender/blender/pulls/117695
This commit is contained in:
parent
c180486c83
commit
f04bc75f8c
|
@ -948,19 +948,18 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
||||||
rna_path.c_str());
|
rna_path.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char *rna_path_id_to_prop = RNA_path_from_ID_to_property(&ptr, prop);
|
const std::optional<std::string> rna_path_id_to_prop = RNA_path_from_ID_to_property(&ptr,
|
||||||
|
prop);
|
||||||
Vector<float> rna_values = get_keyframe_values(&ptr, prop, visual_keyframing);
|
Vector<float> rna_values = get_keyframe_values(&ptr, prop, visual_keyframing);
|
||||||
|
|
||||||
insert_key_count += insert_key_action(bmain,
|
insert_key_count += insert_key_action(bmain,
|
||||||
action,
|
action,
|
||||||
rna_pointer,
|
rna_pointer,
|
||||||
rna_path_id_to_prop,
|
rna_path_id_to_prop->c_str(),
|
||||||
nla_frame,
|
nla_frame,
|
||||||
rna_values.as_span(),
|
rna_values.as_span(),
|
||||||
insert_key_flags,
|
insert_key_flags,
|
||||||
key_type);
|
key_type);
|
||||||
|
|
||||||
MEM_freeN(rna_path_id_to_prop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insert_key_count == 0) {
|
if (insert_key_count == 0) {
|
||||||
|
|
|
@ -353,7 +353,7 @@ bool autokeyframe_property(bContext *C,
|
||||||
ReportList *reports = CTX_wm_reports(C);
|
ReportList *reports = CTX_wm_reports(C);
|
||||||
ToolSettings *ts = scene->toolsettings;
|
ToolSettings *ts = scene->toolsettings;
|
||||||
const eInsertKeyFlags flag = get_autokey_flags(scene);
|
const eInsertKeyFlags flag = get_autokey_flags(scene);
|
||||||
char *path = RNA_path_from_ID_to_property(ptr, prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
|
|
||||||
if (only_if_property_keyed) {
|
if (only_if_property_keyed) {
|
||||||
/* NOTE: We use rnaindex instead of fcu->array_index,
|
/* NOTE: We use rnaindex instead of fcu->array_index,
|
||||||
|
@ -366,14 +366,12 @@ bool autokeyframe_property(bContext *C,
|
||||||
id,
|
id,
|
||||||
action,
|
action,
|
||||||
(fcu && fcu->grp) ? fcu->grp->name : nullptr,
|
(fcu && fcu->grp) ? fcu->grp->name : nullptr,
|
||||||
fcu ? fcu->rna_path : path,
|
fcu ? fcu->rna_path : (path ? path->c_str() : nullptr),
|
||||||
rnaindex,
|
rnaindex,
|
||||||
&anim_eval_context,
|
&anim_eval_context,
|
||||||
eBezTriple_KeyframeType(ts->keyframe_type),
|
eBezTriple_KeyframeType(ts->keyframe_type),
|
||||||
flag) != 0;
|
flag) != 0;
|
||||||
if (path) {
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, nullptr);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
@ -101,7 +104,7 @@ void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src);
|
||||||
* Get RNA-Path for 'value' setting of the given shape-key.
|
* Get RNA-Path for 'value' setting of the given shape-key.
|
||||||
* \note the user needs to free the returned string once they're finished with it.
|
* \note the user needs to free the returned string once they're finished with it.
|
||||||
*/
|
*/
|
||||||
char *BKE_keyblock_curval_rnapath_get(const Key *key, const KeyBlock *kb);
|
std::optional<std::string> BKE_keyblock_curval_rnapath_get(const Key *key, const KeyBlock *kb);
|
||||||
|
|
||||||
/* conversion functions */
|
/* conversion functions */
|
||||||
/* NOTE: 'update_from' versions do not (re)allocate mem in kb, while 'convert_from' do. */
|
/* NOTE: 'update_from' versions do not (re)allocate mem in kb, while 'convert_from' do. */
|
||||||
|
|
|
@ -1480,7 +1480,6 @@ eAction_TransformFlags BKE_action_get_item_transform_flags(bAction *act,
|
||||||
ListBase *curves)
|
ListBase *curves)
|
||||||
{
|
{
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
char *basePath = nullptr;
|
|
||||||
short flags = 0;
|
short flags = 0;
|
||||||
|
|
||||||
/* build PointerRNA from provided data to obtain the paths to use */
|
/* build PointerRNA from provided data to obtain the paths to use */
|
||||||
|
@ -1495,8 +1494,8 @@ eAction_TransformFlags BKE_action_get_item_transform_flags(bAction *act,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the basic path to the properties of interest */
|
/* get the basic path to the properties of interest */
|
||||||
basePath = RNA_path_from_ID_to_struct(&ptr);
|
const std::optional<std::string> basePath = RNA_path_from_ID_to_struct(&ptr);
|
||||||
if (basePath == nullptr) {
|
if (!basePath) {
|
||||||
return eAction_TransformFlags(0);
|
return eAction_TransformFlags(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,13 +1517,13 @@ eAction_TransformFlags BKE_action_get_item_transform_flags(bAction *act,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* step 1: check for matching base path */
|
/* step 1: check for matching base path */
|
||||||
bPtr = strstr(fcu->rna_path, basePath);
|
bPtr = strstr(fcu->rna_path, basePath->c_str());
|
||||||
|
|
||||||
if (bPtr) {
|
if (bPtr) {
|
||||||
/* we must add len(basePath) bytes to the match so that we are at the end of the
|
/* we must add len(basePath) bytes to the match so that we are at the end of the
|
||||||
* base path so that we don't get false positives with these strings in the names
|
* base path so that we don't get false positives with these strings in the names
|
||||||
*/
|
*/
|
||||||
bPtr += strlen(basePath);
|
bPtr += strlen(basePath->c_str());
|
||||||
|
|
||||||
/* step 2: check for some property with transforms
|
/* step 2: check for some property with transforms
|
||||||
* - to speed things up, only check for the ones not yet found
|
* - to speed things up, only check for the ones not yet found
|
||||||
|
@ -1597,9 +1596,6 @@ eAction_TransformFlags BKE_action_get_item_transform_flags(bAction *act,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free basePath */
|
|
||||||
MEM_freeN(basePath);
|
|
||||||
|
|
||||||
/* return flags found */
|
/* return flags found */
|
||||||
return eAction_TransformFlags(flags);
|
return eAction_TransformFlags(flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,15 +238,16 @@ FCurve *id_data_find_fcurve(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *path = RNA_path_from_ID_to_property(&ptr, prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop);
|
||||||
if (path == nullptr) {
|
if (!path) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: The way drivers are handled here (always nullptr-ifying `fcu`) is very weird, this
|
/* FIXME: The way drivers are handled here (always nullptr-ifying `fcu`) is very weird, this
|
||||||
* needs to be re-checked I think?. */
|
* needs to be re-checked I think?. */
|
||||||
bool is_driven = false;
|
bool is_driven = false;
|
||||||
FCurve *fcu = BKE_animadata_fcurve_find_by_rna_path(adt, path, index, nullptr, &is_driven);
|
FCurve *fcu = BKE_animadata_fcurve_find_by_rna_path(
|
||||||
|
adt, path->c_str(), index, nullptr, &is_driven);
|
||||||
if (is_driven) {
|
if (is_driven) {
|
||||||
if (r_driven != nullptr) {
|
if (r_driven != nullptr) {
|
||||||
*r_driven = is_driven;
|
*r_driven = is_driven;
|
||||||
|
@ -254,8 +255,6 @@ FCurve *id_data_find_fcurve(
|
||||||
fcu = nullptr;
|
fcu = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
|
|
||||||
return fcu;
|
return fcu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,19 +453,19 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext * /*C*/,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX This function call can become a performance bottleneck. */
|
/* XXX This function call can become a performance bottleneck. */
|
||||||
char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
|
const std::optional<std::string> rna_path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
if (rna_path == nullptr) {
|
if (!rna_path) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Standard F-Curve from animdata - Animation (Action) or Drivers. */
|
/* Standard F-Curve from animdata - Animation (Action) or Drivers. */
|
||||||
FCurve *fcu = BKE_animadata_fcurve_find_by_rna_path(adt, rna_path, rnaindex, r_action, r_driven);
|
FCurve *fcu = BKE_animadata_fcurve_find_by_rna_path(
|
||||||
|
adt, rna_path->c_str(), rnaindex, r_action, r_driven);
|
||||||
|
|
||||||
if (fcu != nullptr && r_animdata != nullptr) {
|
if (fcu != nullptr && r_animdata != nullptr) {
|
||||||
*r_animdata = adt;
|
*r_animdata = adt;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
return fcu;
|
return fcu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1946,21 +1946,13 @@ void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
|
||||||
kb_dst->slidermax = kb_src->slidermax;
|
kb_dst->slidermax = kb_src->slidermax;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *BKE_keyblock_curval_rnapath_get(const Key *key, const KeyBlock *kb)
|
std::optional<std::string> BKE_keyblock_curval_rnapath_get(const Key *key, const KeyBlock *kb)
|
||||||
{
|
{
|
||||||
PropertyRNA *prop;
|
|
||||||
|
|
||||||
/* sanity checks */
|
|
||||||
if (ELEM(nullptr, key, kb)) {
|
if (ELEM(nullptr, key, kb)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the RNA pointer */
|
|
||||||
PointerRNA ptr = RNA_pointer_create((ID *)&key->id, &RNA_ShapeKey, (KeyBlock *)kb);
|
PointerRNA ptr = RNA_pointer_create((ID *)&key->id, &RNA_ShapeKey, (KeyBlock *)kb);
|
||||||
/* get pointer to the property too */
|
PropertyRNA *prop = RNA_struct_find_property(&ptr, "value");
|
||||||
prop = RNA_struct_find_property(&ptr, "value");
|
|
||||||
|
|
||||||
/* return the path */
|
|
||||||
return RNA_path_from_ID_to_property(&ptr, prop);
|
return RNA_path_from_ID_to_property(&ptr, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,15 +254,14 @@ void DEG_get_evaluated_rna_pointer(const Depsgraph *depsgraph,
|
||||||
* given the COW ID pointer as the new lookup point */
|
* given the COW ID pointer as the new lookup point */
|
||||||
/* TODO: Find a faster alternative, or implement support for other
|
/* TODO: Find a faster alternative, or implement support for other
|
||||||
* common types too above (e.g. modifiers) */
|
* common types too above (e.g. modifiers) */
|
||||||
char *path = RNA_path_from_ID_to_struct(ptr);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_struct(ptr)) {
|
||||||
if (path) {
|
|
||||||
PointerRNA cow_id_ptr = RNA_id_pointer_create(cow_id);
|
PointerRNA cow_id_ptr = RNA_id_pointer_create(cow_id);
|
||||||
if (!RNA_path_resolve(&cow_id_ptr, path, r_ptr_eval, nullptr)) {
|
if (!RNA_path_resolve(&cow_id_ptr, path->c_str(), r_ptr_eval, nullptr)) {
|
||||||
/* Couldn't find COW copy of data */
|
/* Couldn't find COW copy of data */
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: Couldn't resolve RNA path ('%s') relative to COW ID (%p) for '%s'\n",
|
"%s: Couldn't resolve RNA path ('%s') relative to COW ID (%p) for '%s'\n",
|
||||||
__func__,
|
__func__,
|
||||||
path,
|
path->c_str(),
|
||||||
(void *)cow_id,
|
(void *)cow_id,
|
||||||
orig_id->name);
|
orig_id->name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5080,7 +5080,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
Key *key = (Key *)key_poin;
|
Key *key = (Key *)key_poin;
|
||||||
KeyBlock *kb = (KeyBlock *)kb_poin;
|
KeyBlock *kb = (KeyBlock *)kb_poin;
|
||||||
char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
|
std::optional<std::string> rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
|
||||||
|
|
||||||
ReportList *reports = CTX_wm_reports(C);
|
ReportList *reports = CTX_wm_reports(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
|
@ -5109,11 +5109,12 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
|
||||||
flag = ANIM_get_keyframing_flags(scene);
|
flag = ANIM_get_keyframing_flags(scene);
|
||||||
|
|
||||||
/* try to resolve the path stored in the F-Curve */
|
/* try to resolve the path stored in the F-Curve */
|
||||||
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
|
if (RNA_path_resolve_property(&id_ptr, rna_path ? rna_path->c_str() : nullptr, &ptr, &prop)) {
|
||||||
/* find or create new F-Curve */
|
/* find or create new F-Curve */
|
||||||
/* XXX is the group name for this ok? */
|
/* XXX is the group name for this ok? */
|
||||||
bAction *act = blender::animrig::id_action_ensure(bmain, (ID *)key);
|
bAction *act = blender::animrig::id_action_ensure(bmain, (ID *)key);
|
||||||
FCurve *fcu = blender::animrig::action_fcurve_ensure(bmain, act, nullptr, &ptr, rna_path, 0);
|
FCurve *fcu = blender::animrig::action_fcurve_ensure(
|
||||||
|
bmain, act, nullptr, &ptr, rna_path->c_str(), 0);
|
||||||
|
|
||||||
/* set the special 'replace' flag if on a keyframe */
|
/* set the special 'replace' flag if on a keyframe */
|
||||||
if (fcurve_frame_has_keyframe(fcu, remapped_frame)) {
|
if (fcurve_frame_has_keyframe(fcu, remapped_frame)) {
|
||||||
|
@ -5137,11 +5138,6 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the path */
|
|
||||||
if (rna_path) {
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
|
BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5478,8 +5474,11 @@ static void draw_grease_pencil_layer_widgets(bAnimListElem *ale,
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||||
PropertyRNA *onion_skinning_prop = RNA_struct_find_property(&ptr, "use_onion_skinning");
|
PropertyRNA *onion_skinning_prop = RNA_struct_find_property(&ptr, "use_onion_skinning");
|
||||||
|
|
||||||
char *onion_skinning_rna_path = RNA_path_from_ID_to_property(&ptr, onion_skinning_prop);
|
const std::optional<std::string> onion_skinning_rna_path = RNA_path_from_ID_to_property(
|
||||||
if (RNA_path_resolve_property(&id_ptr, onion_skinning_rna_path, &ptr, &onion_skinning_prop)) {
|
&ptr, onion_skinning_prop);
|
||||||
|
if (RNA_path_resolve_property(
|
||||||
|
&id_ptr, onion_skinning_rna_path->c_str(), &ptr, &onion_skinning_prop))
|
||||||
|
{
|
||||||
const int icon = layer->use_onion_skinning() ? ICON_ONIONSKIN_ON : ICON_ONIONSKIN_OFF;
|
const int icon = layer->use_onion_skinning() ? ICON_ONIONSKIN_ON : ICON_ONIONSKIN_OFF;
|
||||||
uiDefAutoButR(block,
|
uiDefAutoButR(block,
|
||||||
&ptr,
|
&ptr,
|
||||||
|
@ -5492,15 +5491,15 @@ static void draw_grease_pencil_layer_widgets(bAnimListElem *ale,
|
||||||
ICON_WIDTH,
|
ICON_WIDTH,
|
||||||
channel_height);
|
channel_height);
|
||||||
}
|
}
|
||||||
MEM_freeN(onion_skinning_rna_path);
|
|
||||||
|
|
||||||
/* Layer opacity. */
|
/* Layer opacity. */
|
||||||
const short width = SLIDER_WIDTH * 0.6;
|
const short width = SLIDER_WIDTH * 0.6;
|
||||||
offset -= width;
|
offset -= width;
|
||||||
UI_block_emboss_set(block, UI_EMBOSS);
|
UI_block_emboss_set(block, UI_EMBOSS);
|
||||||
PropertyRNA *opacity_prop = RNA_struct_find_property(&ptr, "opacity");
|
PropertyRNA *opacity_prop = RNA_struct_find_property(&ptr, "opacity");
|
||||||
char *opacity_rna_path = RNA_path_from_ID_to_property(&ptr, opacity_prop);
|
const std::optional<std::string> opacity_rna_path = RNA_path_from_ID_to_property(&ptr,
|
||||||
if (RNA_path_resolve_property(&id_ptr, opacity_rna_path, &ptr, &opacity_prop)) {
|
opacity_prop);
|
||||||
|
if (RNA_path_resolve_property(&id_ptr, opacity_rna_path->c_str(), &ptr, &opacity_prop)) {
|
||||||
uiDefAutoButR(block,
|
uiDefAutoButR(block,
|
||||||
&ptr,
|
&ptr,
|
||||||
opacity_prop,
|
opacity_prop,
|
||||||
|
@ -5512,7 +5511,6 @@ static void draw_grease_pencil_layer_widgets(bAnimListElem *ale,
|
||||||
width,
|
width,
|
||||||
channel_height);
|
channel_height);
|
||||||
}
|
}
|
||||||
MEM_freeN(opacity_rna_path);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5836,9 +5834,8 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
||||||
else if (ale->id) { /* Slider using RNA Access --------------- */
|
else if (ale->id) { /* Slider using RNA Access --------------- */
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
char *rna_path = nullptr;
|
std::optional<std::string> rna_path;
|
||||||
int array_index = 0;
|
int array_index = 0;
|
||||||
short free_path = 0;
|
|
||||||
|
|
||||||
/* get destination info */
|
/* get destination info */
|
||||||
if (ale->type == ANIMTYPE_FCURVE) {
|
if (ale->type == ANIMTYPE_FCURVE) {
|
||||||
|
@ -5852,7 +5849,6 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
||||||
Key *key = (Key *)ale->id;
|
Key *key = (Key *)ale->id;
|
||||||
|
|
||||||
rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
|
rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
|
||||||
free_path = 1;
|
|
||||||
}
|
}
|
||||||
/* Special for Grease Pencil Layer. */
|
/* Special for Grease Pencil Layer. */
|
||||||
else if (ale->type == ANIMTYPE_GPLAYER) {
|
else if (ale->type == ANIMTYPE_GPLAYER) {
|
||||||
|
@ -5861,7 +5857,6 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
||||||
/* Reset slider offset, in order to add special gp icons. */
|
/* Reset slider offset, in order to add special gp icons. */
|
||||||
offset += SLIDER_WIDTH;
|
offset += SLIDER_WIDTH;
|
||||||
|
|
||||||
char *gp_rna_path = nullptr;
|
|
||||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||||
|
|
||||||
/* Create the RNA pointers. */
|
/* Create the RNA pointers. */
|
||||||
|
@ -5873,67 +5868,73 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
||||||
offset -= ICON_WIDTH;
|
offset -= ICON_WIDTH;
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||||
prop = RNA_struct_find_property(&ptr, "use_onion_skinning");
|
prop = RNA_struct_find_property(&ptr, "use_onion_skinning");
|
||||||
gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> gp_rna_path = RNA_path_from_ID_to_property(&ptr,
|
||||||
if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
|
prop))
|
||||||
icon = (gpl->onion_flag & GP_LAYER_ONIONSKIN) ? ICON_ONIONSKIN_ON :
|
{
|
||||||
ICON_ONIONSKIN_OFF;
|
if (RNA_path_resolve_property(&id_ptr, gp_rna_path->c_str(), &ptr, &prop)) {
|
||||||
uiDefAutoButR(block,
|
icon = (gpl->onion_flag & GP_LAYER_ONIONSKIN) ? ICON_ONIONSKIN_ON :
|
||||||
&ptr,
|
ICON_ONIONSKIN_OFF;
|
||||||
prop,
|
uiDefAutoButR(block,
|
||||||
array_index,
|
&ptr,
|
||||||
"",
|
prop,
|
||||||
icon,
|
array_index,
|
||||||
offset,
|
"",
|
||||||
rect->ymin,
|
icon,
|
||||||
ICON_WIDTH,
|
offset,
|
||||||
channel_height);
|
rect->ymin,
|
||||||
|
ICON_WIDTH,
|
||||||
|
channel_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MEM_freeN(gp_rna_path);
|
|
||||||
|
|
||||||
/* Mask Layer. */
|
/* Mask Layer. */
|
||||||
offset -= ICON_WIDTH;
|
offset -= ICON_WIDTH;
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||||
prop = RNA_struct_find_property(&ptr, "use_mask_layer");
|
prop = RNA_struct_find_property(&ptr, "use_mask_layer");
|
||||||
gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> gp_rna_path = RNA_path_from_ID_to_property(&ptr,
|
||||||
if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
|
prop))
|
||||||
if (gpl->flag & GP_LAYER_USE_MASK) {
|
{
|
||||||
icon = ICON_MOD_MASK;
|
if (RNA_path_resolve_property(&id_ptr, gp_rna_path->c_str(), &ptr, &prop)) {
|
||||||
|
if (gpl->flag & GP_LAYER_USE_MASK) {
|
||||||
|
icon = ICON_MOD_MASK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
icon = ICON_LAYER_ACTIVE;
|
||||||
|
}
|
||||||
|
uiDefAutoButR(block,
|
||||||
|
&ptr,
|
||||||
|
prop,
|
||||||
|
array_index,
|
||||||
|
"",
|
||||||
|
icon,
|
||||||
|
offset,
|
||||||
|
rect->ymin,
|
||||||
|
ICON_WIDTH,
|
||||||
|
channel_height);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
icon = ICON_LAYER_ACTIVE;
|
|
||||||
}
|
|
||||||
uiDefAutoButR(block,
|
|
||||||
&ptr,
|
|
||||||
prop,
|
|
||||||
array_index,
|
|
||||||
"",
|
|
||||||
icon,
|
|
||||||
offset,
|
|
||||||
rect->ymin,
|
|
||||||
ICON_WIDTH,
|
|
||||||
channel_height);
|
|
||||||
}
|
}
|
||||||
MEM_freeN(gp_rna_path);
|
|
||||||
|
|
||||||
/* Layer opacity. */
|
/* Layer opacity. */
|
||||||
const short width = SLIDER_WIDTH * 0.6;
|
const short width = SLIDER_WIDTH * 0.6;
|
||||||
offset -= width;
|
offset -= width;
|
||||||
UI_block_emboss_set(block, UI_EMBOSS);
|
UI_block_emboss_set(block, UI_EMBOSS);
|
||||||
prop = RNA_struct_find_property(&ptr, "opacity");
|
prop = RNA_struct_find_property(&ptr, "opacity");
|
||||||
gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> gp_rna_path = RNA_path_from_ID_to_property(&ptr,
|
||||||
if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
|
prop))
|
||||||
uiDefAutoButR(block,
|
{
|
||||||
&ptr,
|
if (RNA_path_resolve_property(&id_ptr, gp_rna_path->c_str(), &ptr, &prop)) {
|
||||||
prop,
|
uiDefAutoButR(block,
|
||||||
array_index,
|
&ptr,
|
||||||
"",
|
prop,
|
||||||
ICON_NONE,
|
array_index,
|
||||||
offset,
|
"",
|
||||||
rect->ymin,
|
ICON_NONE,
|
||||||
width,
|
offset,
|
||||||
channel_height);
|
rect->ymin,
|
||||||
|
width,
|
||||||
|
channel_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MEM_freeN(gp_rna_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WITH_GREASE_PENCIL_V3
|
#ifdef WITH_GREASE_PENCIL_V3
|
||||||
|
@ -5948,7 +5949,9 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
||||||
PointerRNA id_ptr = RNA_id_pointer_create(ale->id);
|
PointerRNA id_ptr = RNA_id_pointer_create(ale->id);
|
||||||
|
|
||||||
/* try to resolve the path */
|
/* try to resolve the path */
|
||||||
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
|
if (RNA_path_resolve_property(
|
||||||
|
&id_ptr, rna_path ? rna_path->c_str() : nullptr, &ptr, &prop))
|
||||||
|
{
|
||||||
uiBut *but;
|
uiBut *but;
|
||||||
|
|
||||||
/* Create the slider button,
|
/* Create the slider button,
|
||||||
|
@ -5972,11 +5975,6 @@ void ANIM_channel_draw_widgets(const bContext *C,
|
||||||
UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
|
UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the path if necessary */
|
|
||||||
if (free_path) {
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* Special Slider for stuff without RNA Access ---------- */
|
else { /* Special Slider for stuff without RNA Access ---------- */
|
||||||
|
|
|
@ -4533,7 +4533,7 @@ static rctf calculate_selection_fcurve_bounds_and_unhide(
|
||||||
bContext *C,
|
bContext *C,
|
||||||
ListBase /* CollectionPointerLink */ *selection,
|
ListBase /* CollectionPointerLink */ *selection,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
char *id_to_prop_path,
|
const blender::StringRefNull id_to_prop_path,
|
||||||
const int index,
|
const int index,
|
||||||
const bool whole_array)
|
const bool whole_array)
|
||||||
{
|
{
|
||||||
|
@ -4560,9 +4560,9 @@ static rctf calculate_selection_fcurve_bounds_and_unhide(
|
||||||
}
|
}
|
||||||
PointerRNA resolved_ptr;
|
PointerRNA resolved_ptr;
|
||||||
PropertyRNA *resolved_prop;
|
PropertyRNA *resolved_prop;
|
||||||
if (id_to_prop_path != nullptr) {
|
if (!id_to_prop_path.is_empty()) {
|
||||||
const bool resolved = RNA_path_resolve_property(
|
const bool resolved = RNA_path_resolve_property(
|
||||||
&selected->ptr, id_to_prop_path, &resolved_ptr, &resolved_prop);
|
&selected->ptr, id_to_prop_path.c_str(), &resolved_ptr, &resolved_prop);
|
||||||
if (!resolved) {
|
if (!resolved) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -4571,7 +4571,8 @@ static rctf calculate_selection_fcurve_bounds_and_unhide(
|
||||||
resolved_ptr = selected->ptr;
|
resolved_ptr = selected->ptr;
|
||||||
resolved_prop = prop;
|
resolved_prop = prop;
|
||||||
}
|
}
|
||||||
char *path = RNA_path_from_ID_to_property(&resolved_ptr, resolved_prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(&resolved_ptr,
|
||||||
|
resolved_prop);
|
||||||
|
|
||||||
AnimData *anim_data = BKE_animdata_from_id(selected_id);
|
AnimData *anim_data = BKE_animdata_from_id(selected_id);
|
||||||
blender::Vector<FCurve *> fcurves;
|
blender::Vector<FCurve *> fcurves;
|
||||||
|
@ -4579,7 +4580,7 @@ static rctf calculate_selection_fcurve_bounds_and_unhide(
|
||||||
const int length = RNA_property_array_length(&selected->ptr, prop);
|
const int length = RNA_property_array_length(&selected->ptr, prop);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
FCurve *fcurve = BKE_animadata_fcurve_find_by_rna_path(
|
FCurve *fcurve = BKE_animadata_fcurve_find_by_rna_path(
|
||||||
anim_data, path, i, nullptr, nullptr);
|
anim_data, path->c_str(), i, nullptr, nullptr);
|
||||||
if (fcurve != nullptr) {
|
if (fcurve != nullptr) {
|
||||||
fcurves.append(fcurve);
|
fcurves.append(fcurve);
|
||||||
}
|
}
|
||||||
|
@ -4587,14 +4588,12 @@ static rctf calculate_selection_fcurve_bounds_and_unhide(
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FCurve *fcurve = BKE_animadata_fcurve_find_by_rna_path(
|
FCurve *fcurve = BKE_animadata_fcurve_find_by_rna_path(
|
||||||
anim_data, path, index, nullptr, nullptr);
|
anim_data, path->c_str(), index, nullptr, nullptr);
|
||||||
if (fcurve != nullptr) {
|
if (fcurve != nullptr) {
|
||||||
fcurves.append(fcurve);
|
fcurves.append(fcurve);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
|
|
||||||
for (FCurve *fcurve : fcurves) {
|
for (FCurve *fcurve : fcurves) {
|
||||||
fcurve->flag |= (FCURVE_SELECTED | FCURVE_VISIBLE);
|
fcurve->flag |= (FCURVE_SELECTED | FCURVE_VISIBLE);
|
||||||
rctf fcu_bounds;
|
rctf fcu_bounds;
|
||||||
|
@ -4633,7 +4632,7 @@ static int view_curve_in_graph_editor_exec(bContext *C, wmOperator *op)
|
||||||
ListBase selection = {nullptr, nullptr};
|
ListBase selection = {nullptr, nullptr};
|
||||||
|
|
||||||
bool path_from_id;
|
bool path_from_id;
|
||||||
char *id_to_prop_path;
|
std::optional<std::string> id_to_prop_path;
|
||||||
const bool selected_list_success = UI_context_copy_to_selected_list(
|
const bool selected_list_success = UI_context_copy_to_selected_list(
|
||||||
C, &ptr, prop, &selection, &path_from_id, &id_to_prop_path);
|
C, &ptr, prop, &selection, &path_from_id, &id_to_prop_path);
|
||||||
|
|
||||||
|
@ -4663,14 +4662,10 @@ static int view_curve_in_graph_editor_exec(bContext *C, wmOperator *op)
|
||||||
const bool whole_array = RNA_boolean_get(op->ptr, "all");
|
const bool whole_array = RNA_boolean_get(op->ptr, "all");
|
||||||
|
|
||||||
rctf bounds = calculate_selection_fcurve_bounds_and_unhide(
|
rctf bounds = calculate_selection_fcurve_bounds_and_unhide(
|
||||||
C, &selection, prop, id_to_prop_path, index, whole_array);
|
C, &selection, prop, id_to_prop_path.value_or(""), index, whole_array);
|
||||||
|
|
||||||
BLI_freelistN(&selection);
|
BLI_freelistN(&selection);
|
||||||
|
|
||||||
if (id_to_prop_path != nullptr) {
|
|
||||||
MEM_freeN(id_to_prop_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!BLI_rctf_is_valid(&bounds)) {
|
if (!BLI_rctf_is_valid(&bounds)) {
|
||||||
WM_report(RPT_ERROR, "F-Curves have no valid size");
|
WM_report(RPT_ERROR, "F-Curves have no valid size");
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
|
|
|
@ -942,14 +942,9 @@ static bAnimListElem *make_new_animlistelem(void *data,
|
||||||
/* the corresponding keyframes are from the animdata */
|
/* the corresponding keyframes are from the animdata */
|
||||||
if (ale->adt && ale->adt->action) {
|
if (ale->adt && ale->adt->action) {
|
||||||
bAction *act = ale->adt->action;
|
bAction *act = ale->adt->action;
|
||||||
char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
|
/* Try to find the F-Curve which corresponds to this exactly. */
|
||||||
|
if (std::optional<std::string> rna_path = BKE_keyblock_curval_rnapath_get(key, kb)) {
|
||||||
/* try to find the F-Curve which corresponds to this exactly,
|
ale->key_data = (void *)BKE_fcurve_find(&act->curves, rna_path->c_str(), 0);
|
||||||
* then free the MEM_alloc'd string
|
|
||||||
*/
|
|
||||||
if (rna_path) {
|
|
||||||
ale->key_data = (void *)BKE_fcurve_find(&act->curves, rna_path, 0);
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ale->datatype = (ale->key_data) ? ALE_FCURVE : ALE_NONE;
|
ale->datatype = (ale->key_data) ? ALE_FCURVE : ALE_NONE;
|
||||||
|
|
|
@ -953,13 +953,11 @@ static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_typ
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
||||||
char *path = RNA_path_from_ID_to_property(&ptr, prop);
|
|
||||||
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
||||||
|
|
||||||
if (path) {
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
success += ANIM_add_driver(
|
success += ANIM_add_driver(
|
||||||
op->reports, ptr.owner_id, path, index, flags, DRIVER_TYPE_PYTHON);
|
op->reports, ptr.owner_id, path->c_str(), index, flags, DRIVER_TYPE_PYTHON);
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,14 +1045,13 @@ static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
||||||
/* 1) Create a new "empty" driver for this property */
|
/* 1) Create a new "empty" driver for this property */
|
||||||
char *path = RNA_path_from_ID_to_property(&ptr, prop);
|
|
||||||
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
if (path) {
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
changed |= (ANIM_add_driver(
|
changed |=
|
||||||
op->reports, ptr.owner_id, path, index, flags, DRIVER_TYPE_PYTHON) != 0);
|
(ANIM_add_driver(
|
||||||
MEM_freeN(path);
|
op->reports, ptr.owner_id, path->c_str(), index, flags, DRIVER_TYPE_PYTHON) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
@ -1106,12 +1103,8 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop) {
|
if (ptr.owner_id && ptr.data && prop) {
|
||||||
char *path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
changed = ANIM_remove_driver(op->reports, ptr.owner_id, path->c_str(), index, 0);
|
||||||
if (path) {
|
|
||||||
changed = ANIM_remove_driver(op->reports, ptr.owner_id, path, index, 0);
|
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1189,15 +1182,11 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
|
||||||
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
||||||
char *path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
/* only copy the driver for the button that this was involved for */
|
/* only copy the driver for the button that this was involved for */
|
||||||
changed = ANIM_copy_driver(op->reports, ptr.owner_id, path, index, 0);
|
changed = ANIM_copy_driver(op->reports, ptr.owner_id, path->c_str(), index, 0);
|
||||||
|
|
||||||
UI_context_update_anim_flag(C);
|
UI_context_update_anim_flag(C);
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,11 +1221,9 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
|
||||||
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
||||||
char *path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
/* only copy the driver for the button that this was involved for */
|
/* only copy the driver for the button that this was involved for */
|
||||||
changed = ANIM_paste_driver(op->reports, ptr.owner_id, path, index, 0);
|
changed = ANIM_paste_driver(op->reports, ptr.owner_id, path->c_str(), index, 0);
|
||||||
|
|
||||||
UI_context_update_anim_flag(C);
|
UI_context_update_anim_flag(C);
|
||||||
|
|
||||||
|
@ -1245,8 +1232,6 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
|
||||||
DEG_id_tag_update(ptr.owner_id, ID_RECALC_ANIMATION);
|
DEG_id_tag_update(ptr.owner_id, ID_RECALC_ANIMATION);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, nullptr); /* XXX */
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, nullptr); /* XXX */
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -870,7 +870,6 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
|
||||||
ToolSettings *ts = scene->toolsettings;
|
ToolSettings *ts = scene->toolsettings;
|
||||||
PointerRNA ptr = {nullptr};
|
PointerRNA ptr = {nullptr};
|
||||||
PropertyRNA *prop = nullptr;
|
PropertyRNA *prop = nullptr;
|
||||||
char *path;
|
|
||||||
uiBut *but;
|
uiBut *but;
|
||||||
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
|
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
|
||||||
CTX_data_depsgraph_pointer(C), BKE_scene_frame_get(scene));
|
CTX_data_depsgraph_pointer(C), BKE_scene_frame_get(scene));
|
||||||
|
@ -938,9 +937,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* standard properties */
|
/* standard properties */
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
const char *identifier = RNA_property_identifier(prop);
|
const char *identifier = RNA_property_identifier(prop);
|
||||||
const char *group = nullptr;
|
const char *group = nullptr;
|
||||||
|
|
||||||
|
@ -975,13 +972,11 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
|
||||||
ptr.owner_id,
|
ptr.owner_id,
|
||||||
nullptr,
|
nullptr,
|
||||||
group,
|
group,
|
||||||
path,
|
path->c_str(),
|
||||||
index,
|
index,
|
||||||
&anim_eval_context,
|
&anim_eval_context,
|
||||||
eBezTriple_KeyframeType(ts->keyframe_type),
|
eBezTriple_KeyframeType(ts->keyframe_type),
|
||||||
flag) != 0);
|
flag) != 0);
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_report(op->reports,
|
BKE_report(op->reports,
|
||||||
|
@ -1052,7 +1047,6 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
|
||||||
PointerRNA ptr = {nullptr};
|
PointerRNA ptr = {nullptr};
|
||||||
PropertyRNA *prop = nullptr;
|
PropertyRNA *prop = nullptr;
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
char *path;
|
|
||||||
const float cfra = BKE_scene_frame_get(scene);
|
const float cfra = BKE_scene_frame_get(scene);
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
int index;
|
int index;
|
||||||
|
@ -1104,17 +1098,14 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* standard properties */
|
/* standard properties */
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
if (all) {
|
if (all) {
|
||||||
/* -1 indicates operating on the entire array (or the property itself otherwise) */
|
/* -1 indicates operating on the entire array (or the property itself otherwise) */
|
||||||
index = -1;
|
index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed = blender::animrig::delete_keyframe(
|
changed = blender::animrig::delete_keyframe(
|
||||||
bmain, op->reports, ptr.owner_id, nullptr, path, index, cfra) != 0;
|
bmain, op->reports, ptr.owner_id, nullptr, path->c_str(), index, cfra) != 0;
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
else if (G.debug & G_DEBUG) {
|
else if (G.debug & G_DEBUG) {
|
||||||
printf("Button Delete-Key: no path to property\n");
|
printf("Button Delete-Key: no path to property\n");
|
||||||
|
@ -1161,7 +1152,6 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
|
||||||
PointerRNA ptr = {nullptr};
|
PointerRNA ptr = {nullptr};
|
||||||
PropertyRNA *prop = nullptr;
|
PropertyRNA *prop = nullptr;
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
char *path;
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
int index;
|
int index;
|
||||||
const bool all = RNA_boolean_get(op->ptr, "all");
|
const bool all = RNA_boolean_get(op->ptr, "all");
|
||||||
|
@ -1172,18 +1162,19 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop) {
|
if (ptr.owner_id && ptr.data && prop) {
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
if (all) {
|
if (all) {
|
||||||
/* -1 indicates operating on the entire array (or the property itself otherwise) */
|
/* -1 indicates operating on the entire array (or the property itself otherwise) */
|
||||||
index = -1;
|
index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed |=
|
changed |= (blender::animrig::clear_keyframe(bmain,
|
||||||
(blender::animrig::clear_keyframe(
|
op->reports,
|
||||||
bmain, op->reports, ptr.owner_id, nullptr, path, index, eInsertKeyFlags(0)) != 0);
|
ptr.owner_id,
|
||||||
MEM_freeN(path);
|
nullptr,
|
||||||
|
path->c_str(),
|
||||||
|
index,
|
||||||
|
eInsertKeyFlags(0)) != 0);
|
||||||
}
|
}
|
||||||
else if (G.debug & G_DEBUG) {
|
else if (G.debug & G_DEBUG) {
|
||||||
printf("Button Clear-Key: no path to property\n");
|
printf("Button Clear-Key: no path to property\n");
|
||||||
|
|
|
@ -304,12 +304,9 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
|
||||||
|
|
||||||
/* Check if property is able to be added. */
|
/* Check if property is able to be added. */
|
||||||
const bool all = RNA_boolean_get(op->ptr, "all");
|
const bool all = RNA_boolean_get(op->ptr, "all");
|
||||||
char *path = nullptr;
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
if (all) {
|
if (all) {
|
||||||
pflag |= KSP_FLAG_WHOLE_ARRAY;
|
pflag |= KSP_FLAG_WHOLE_ARRAY;
|
||||||
|
|
||||||
|
@ -322,11 +319,9 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
|
||||||
|
|
||||||
/* Add path to this setting. */
|
/* Add path to this setting. */
|
||||||
BKE_keyingset_add_path(
|
BKE_keyingset_add_path(
|
||||||
keyingset, ptr.owner_id, nullptr, path, index, pflag, KSP_GROUP_KSNAME);
|
keyingset, ptr.owner_id, nullptr, path->c_str(), index, pflag, KSP_GROUP_KSNAME);
|
||||||
keyingset->active_path = BLI_listbase_count(&keyingset->paths);
|
keyingset->active_path = BLI_listbase_count(&keyingset->paths);
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,21 +385,16 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
|
||||||
BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1));
|
BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1));
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
char *path = nullptr;
|
|
||||||
if (ptr.owner_id && ptr.data && prop) {
|
if (ptr.owner_id && ptr.data && prop) {
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
/* Try to find a path matching this description. */
|
/* Try to find a path matching this description. */
|
||||||
KS_Path *keyingset_path = BKE_keyingset_find_path(
|
KS_Path *keyingset_path = BKE_keyingset_find_path(
|
||||||
keyingset, ptr.owner_id, keyingset->name, path, index, KSP_GROUP_KSNAME);
|
keyingset, ptr.owner_id, keyingset->name, path->c_str(), index, KSP_GROUP_KSNAME);
|
||||||
|
|
||||||
if (keyingset_path) {
|
if (keyingset_path) {
|
||||||
BKE_keyingset_free_path(keyingset, keyingset_path);
|
BKE_keyingset_free_path(keyingset, keyingset_path);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks,
|
||||||
|
|
||||||
/* get the RNA path to this pchan - this needs to be freed! */
|
/* get the RNA path to this pchan - this needs to be freed! */
|
||||||
PointerRNA ptr = RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan);
|
PointerRNA ptr = RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan);
|
||||||
pfl->pchan_path = RNA_path_from_ID_to_struct(&ptr);
|
pfl->pchan_path = BLI_strdup(RNA_path_from_ID_to_struct(&ptr).value_or("").c_str());
|
||||||
|
|
||||||
/* add linkage data to operator data */
|
/* add linkage data to operator data */
|
||||||
BLI_addtail(pfLinks, pfl);
|
BLI_addtail(pfLinks, pfl);
|
||||||
|
|
|
@ -3102,7 +3102,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
ListBase *r_lb,
|
ListBase *r_lb,
|
||||||
bool *r_use_path_from_id,
|
bool *r_use_path_from_id,
|
||||||
char **r_path);
|
std::optional<std::string> *r_path);
|
||||||
bool UI_context_copy_to_selected_check(PointerRNA *ptr,
|
bool UI_context_copy_to_selected_check(PointerRNA *ptr,
|
||||||
PointerRNA *ptr_link,
|
PointerRNA *ptr_link,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
|
|
|
@ -91,19 +91,20 @@ static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *eve
|
||||||
PropertyRNA *target_prop = but->rnaprop;
|
PropertyRNA *target_prop = but->rnaprop;
|
||||||
const int target_index = but->rnaindex;
|
const int target_index = but->rnaindex;
|
||||||
|
|
||||||
char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop);
|
const std::optional<std::string> target_path = RNA_path_from_ID_to_property(target_ptr,
|
||||||
|
target_prop);
|
||||||
|
|
||||||
/* Get paths for the destination. */
|
/* Get paths for the destination. */
|
||||||
char *dst_path = RNA_path_from_ID_to_property(&ddr->ptr, ddr->prop);
|
const std::optional<std::string> dst_path = RNA_path_from_ID_to_property(&ddr->ptr, ddr->prop);
|
||||||
|
|
||||||
/* Now create driver(s) */
|
/* Now create driver(s) */
|
||||||
if (target_path && dst_path) {
|
if (target_path && dst_path) {
|
||||||
int success = ANIM_add_driver_with_target(op->reports,
|
int success = ANIM_add_driver_with_target(op->reports,
|
||||||
ddr->ptr.owner_id,
|
ddr->ptr.owner_id,
|
||||||
dst_path,
|
dst_path->c_str(),
|
||||||
ddr->index,
|
ddr->index,
|
||||||
target_ptr->owner_id,
|
target_ptr->owner_id,
|
||||||
target_path,
|
target_path->c_str(),
|
||||||
target_index,
|
target_index,
|
||||||
flag,
|
flag,
|
||||||
DRIVER_TYPE_PYTHON,
|
DRIVER_TYPE_PYTHON,
|
||||||
|
@ -117,14 +118,6 @@ static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *eve
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, nullptr); /* XXX */
|
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, nullptr); /* XXX */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup */
|
|
||||||
if (target_path) {
|
|
||||||
MEM_freeN(target_path);
|
|
||||||
}
|
|
||||||
if (dst_path) {
|
|
||||||
MEM_freeN(dst_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void driverdropper_cancel(bContext *C, wmOperator *op)
|
static void driverdropper_cancel(bContext *C, wmOperator *op)
|
||||||
|
|
|
@ -237,7 +237,6 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str)
|
||||||
bContext *C = static_cast<bContext *>(but->block->evil_C);
|
bContext *C = static_cast<bContext *>(but->block->evil_C);
|
||||||
ID *id;
|
ID *id;
|
||||||
FCurve *fcu;
|
FCurve *fcu;
|
||||||
char *path;
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
/* button must have RNA-pointer to a numeric-capable property */
|
/* button must have RNA-pointer to a numeric-capable property */
|
||||||
|
@ -269,13 +268,14 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get path */
|
/* get path */
|
||||||
path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(&but->rnapoin,
|
||||||
if (path == nullptr) {
|
but->rnaprop);
|
||||||
|
if (!path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create driver */
|
/* create driver */
|
||||||
fcu = verify_driver_fcurve(id, path, but->rnaindex, DRIVER_FCURVE_KEYFRAMES);
|
fcu = verify_driver_fcurve(id, path->c_str(), but->rnaindex, DRIVER_FCURVE_KEYFRAMES);
|
||||||
if (fcu) {
|
if (fcu) {
|
||||||
ChannelDriver *driver = fcu->driver;
|
ChannelDriver *driver = fcu->driver;
|
||||||
|
|
||||||
|
@ -295,8 +295,6 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,11 +354,11 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/* Ignore the actual array index [pass -1] since the index is handled separately. */
|
/* Ignore the actual array index [pass -1] since the index is handled separately. */
|
||||||
const char *prop_id = RNA_property_is_idprop(but->rnaprop) ?
|
const std::string prop_id = RNA_property_is_idprop(but->rnaprop) ?
|
||||||
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
|
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
|
||||||
RNA_property_identifier(but->rnaprop);
|
RNA_property_identifier(but->rnaprop);
|
||||||
bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
|
bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
|
||||||
&um->items, member_id_data_path.value().c_str(), prop_id, but->rnaindex);
|
&um->items, member_id_data_path->c_str(), prop_id.c_str(), but->rnaindex);
|
||||||
return umi;
|
return umi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,12 +436,12 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Ignore the actual array index [pass -1] since the index is handled separately. */
|
/* Ignore the actual array index [pass -1] since the index is handled separately. */
|
||||||
const char *prop_id = RNA_property_is_idprop(but->rnaprop) ?
|
const std::string prop_id = RNA_property_is_idprop(but->rnaprop) ?
|
||||||
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
|
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
|
||||||
RNA_property_identifier(but->rnaprop);
|
RNA_property_identifier(but->rnaprop);
|
||||||
/* NOTE: ignore 'drawstr', use property idname always. */
|
/* NOTE: ignore 'drawstr', use property idname always. */
|
||||||
ED_screen_user_menu_item_add_prop(
|
ED_screen_user_menu_item_add_prop(
|
||||||
&um->items, "", member_id_data_path.value().c_str(), prop_id, but->rnaindex);
|
&um->items, "", member_id_data_path->c_str(), prop_id.c_str(), but->rnaindex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((mt = UI_but_menutype_get(but))) {
|
else if ((mt = UI_but_menutype_get(but))) {
|
||||||
|
|
|
@ -1824,7 +1824,6 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
|
||||||
PropertyRNA *lprop;
|
PropertyRNA *lprop;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
char *path = nullptr;
|
|
||||||
ListBase lb = {nullptr};
|
ListBase lb = {nullptr};
|
||||||
|
|
||||||
PointerRNA ptr = but->rnapoin;
|
PointerRNA ptr = but->rnapoin;
|
||||||
|
@ -1844,6 +1843,7 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
|
||||||
const bool is_array = RNA_property_array_check(prop);
|
const bool is_array = RNA_property_array_check(prop);
|
||||||
const int rna_type = RNA_property_type(prop);
|
const int rna_type = RNA_property_type(prop);
|
||||||
|
|
||||||
|
std::optional<std::string> path;
|
||||||
if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
|
if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
|
||||||
!BLI_listbase_is_empty(&lb))
|
!BLI_listbase_is_empty(&lb))
|
||||||
{
|
{
|
||||||
|
@ -1856,8 +1856,13 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UI_context_copy_to_selected_check(
|
if (!UI_context_copy_to_selected_check(&ptr,
|
||||||
&ptr, &link->ptr, prop, path, use_path_from_id, &lptr, &lprop))
|
&link->ptr,
|
||||||
|
prop,
|
||||||
|
path.has_value() ? path->c_str() : nullptr,
|
||||||
|
use_path_from_id,
|
||||||
|
&lptr,
|
||||||
|
&lprop))
|
||||||
{
|
{
|
||||||
selctx_data->elems_len -= 1;
|
selctx_data->elems_len -= 1;
|
||||||
i -= 1;
|
i -= 1;
|
||||||
|
@ -1906,7 +1911,6 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
|
||||||
MEM_SAFE_FREE(selctx_data->elems);
|
MEM_SAFE_FREE(selctx_data->elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_SAFE_FREE(path);
|
|
||||||
BLI_freelistN(&lb);
|
BLI_freelistN(&lb);
|
||||||
|
|
||||||
/* caller can clear */
|
/* caller can clear */
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "DNA_armature_types.h"
|
#include "DNA_armature_types.h"
|
||||||
|
@ -105,16 +107,12 @@ static bool copy_data_path_button_poll(bContext *C)
|
||||||
{
|
{
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
char *path;
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
||||||
|
|
||||||
if (ptr.owner_id && ptr.data && prop) {
|
if (ptr.owner_id && ptr.data && prop) {
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
MEM_freeN(path);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +125,6 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *op)
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
char *path;
|
|
||||||
int index;
|
int index;
|
||||||
ID *id;
|
ID *id;
|
||||||
|
|
||||||
|
@ -136,6 +133,7 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *op)
|
||||||
/* try to create driver using property retrieved from UI */
|
/* try to create driver using property retrieved from UI */
|
||||||
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
||||||
|
|
||||||
|
std::optional<std::string> path;
|
||||||
if (ptr.owner_id != nullptr) {
|
if (ptr.owner_id != nullptr) {
|
||||||
if (full_path) {
|
if (full_path) {
|
||||||
if (prop) {
|
if (prop) {
|
||||||
|
@ -155,8 +153,7 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
WM_clipboard_text_set(path, false);
|
WM_clipboard_text_set(path->c_str(), false);
|
||||||
MEM_freeN(path);
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +192,6 @@ static bool copy_as_driver_button_poll(bContext *C)
|
||||||
{
|
{
|
||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
char *path;
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
||||||
|
@ -204,10 +200,7 @@ static bool copy_as_driver_button_poll(bContext *C)
|
||||||
ELEM(RNA_property_type(prop), PROP_BOOLEAN, PROP_INT, PROP_FLOAT, PROP_ENUM) &&
|
ELEM(RNA_property_type(prop), PROP_BOOLEAN, PROP_INT, PROP_FLOAT, PROP_ENUM) &&
|
||||||
(index >= 0 || !RNA_property_array_check(prop)))
|
(index >= 0 || !RNA_property_array_check(prop)))
|
||||||
{
|
{
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop)) {
|
||||||
|
|
||||||
if (path) {
|
|
||||||
MEM_freeN(path);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,11 +221,10 @@ static int copy_as_driver_button_exec(bContext *C, wmOperator *op)
|
||||||
if (ptr.owner_id && ptr.data && prop) {
|
if (ptr.owner_id && ptr.data && prop) {
|
||||||
ID *id;
|
ID *id;
|
||||||
const int dim = RNA_property_array_dimension(&ptr, prop, nullptr);
|
const int dim = RNA_property_array_dimension(&ptr, prop, nullptr);
|
||||||
char *path = RNA_path_from_real_ID_to_property_index(bmain, &ptr, prop, dim, index, &id);
|
if (const std::optional<std::string> path = RNA_path_from_real_ID_to_property_index(
|
||||||
|
bmain, &ptr, prop, dim, index, &id))
|
||||||
if (path) {
|
{
|
||||||
ANIM_copy_as_driver(id, path, RNA_property_identifier(prop));
|
ANIM_copy_as_driver(id, path->c_str(), RNA_property_identifier(prop));
|
||||||
MEM_freeN(path);
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,12 +1069,11 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
ListBase *r_lb,
|
ListBase *r_lb,
|
||||||
bool *r_use_path_from_id,
|
bool *r_use_path_from_id,
|
||||||
char **r_path)
|
std::optional<std::string> *r_path)
|
||||||
{
|
{
|
||||||
*r_use_path_from_id = false;
|
*r_use_path_from_id = false;
|
||||||
*r_path = nullptr;
|
*r_path = std::nullopt;
|
||||||
/* special case for bone constraints */
|
/* special case for bone constraints */
|
||||||
char *path_from_bone = nullptr;
|
|
||||||
const bool is_rna = !RNA_property_is_idprop(prop);
|
const bool is_rna = !RNA_property_is_idprop(prop);
|
||||||
/* Remove links from the collection list which don't contain 'prop'. */
|
/* Remove links from the collection list which don't contain 'prop'. */
|
||||||
bool ensure_list_items_contain_prop = false;
|
bool ensure_list_items_contain_prop = false;
|
||||||
|
@ -1097,34 +1088,34 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
*/
|
*/
|
||||||
if (is_rna && RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) {
|
if (is_rna && RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) {
|
||||||
PointerRNA owner_ptr;
|
PointerRNA owner_ptr;
|
||||||
char *idpath = nullptr;
|
std::optional<std::string> idpath;
|
||||||
|
|
||||||
/* First, check the active PoseBone and PoseBone->Bone. */
|
/* First, check the active PoseBone and PoseBone->Bone. */
|
||||||
if (NOT_RNA_NULL(owner_ptr = CTX_data_pointer_get_type(C, "active_pose_bone", &RNA_PoseBone)))
|
if (NOT_RNA_NULL(owner_ptr = CTX_data_pointer_get_type(C, "active_pose_bone", &RNA_PoseBone)))
|
||||||
{
|
{
|
||||||
if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(
|
idpath = RNA_path_from_struct_to_idproperty(&owner_ptr,
|
||||||
&owner_ptr, static_cast<const IDProperty *>(ptr->data))))
|
static_cast<const IDProperty *>(ptr->data));
|
||||||
{
|
if (idpath) {
|
||||||
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
|
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bPoseChannel *pchan = static_cast<bPoseChannel *>(owner_ptr.data);
|
bPoseChannel *pchan = static_cast<bPoseChannel *>(owner_ptr.data);
|
||||||
owner_ptr = RNA_pointer_create(owner_ptr.owner_id, &RNA_Bone, pchan->bone);
|
owner_ptr = RNA_pointer_create(owner_ptr.owner_id, &RNA_Bone, pchan->bone);
|
||||||
|
idpath = RNA_path_from_struct_to_idproperty(&owner_ptr,
|
||||||
if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(
|
static_cast<const IDProperty *>(ptr->data));
|
||||||
&owner_ptr, static_cast<const IDProperty *>(ptr->data))))
|
if (idpath) {
|
||||||
{
|
|
||||||
ui_context_selected_bones_via_pose(C, r_lb);
|
ui_context_selected_bones_via_pose(C, r_lb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idpath == nullptr) {
|
if (!idpath) {
|
||||||
/* Check the active EditBone if in edit mode. */
|
/* Check the active EditBone if in edit mode. */
|
||||||
|
idpath = RNA_path_from_struct_to_idproperty(&owner_ptr,
|
||||||
|
static_cast<const IDProperty *>(ptr->data));
|
||||||
if (NOT_RNA_NULL(
|
if (NOT_RNA_NULL(
|
||||||
owner_ptr = CTX_data_pointer_get_type_silent(C, "active_bone", &RNA_EditBone)) &&
|
owner_ptr = CTX_data_pointer_get_type_silent(C, "active_bone", &RNA_EditBone)) &&
|
||||||
NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(
|
idpath)
|
||||||
&owner_ptr, static_cast<const IDProperty *>(ptr->data))))
|
|
||||||
{
|
{
|
||||||
*r_lb = CTX_data_collection_get(C, "selected_editable_bones");
|
*r_lb = CTX_data_collection_get(C, "selected_editable_bones");
|
||||||
}
|
}
|
||||||
|
@ -1133,8 +1124,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idpath) {
|
if (idpath) {
|
||||||
*r_path = BLI_sprintfN("%s.%s", idpath, RNA_property_identifier(prop));
|
*r_path = fmt::format("{}.{}", *idpath, RNA_property_identifier(prop));
|
||||||
MEM_freeN(idpath);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1221,16 +1211,16 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
else if (RNA_struct_is_a(ptr->type, &RNA_MovieTrackingTrack)) {
|
else if (RNA_struct_is_a(ptr->type, &RNA_MovieTrackingTrack)) {
|
||||||
*r_lb = CTX_data_collection_get(C, "selected_movieclip_tracks");
|
*r_lb = CTX_data_collection_get(C, "selected_movieclip_tracks");
|
||||||
}
|
}
|
||||||
else if (RNA_struct_is_a(ptr->type, &RNA_Constraint) &&
|
else if (const std::optional<std::string> path_from_bone =
|
||||||
(path_from_bone = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_PoseBone)) !=
|
RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_PoseBone);
|
||||||
nullptr)
|
RNA_struct_is_a(ptr->type, &RNA_Constraint) && path_from_bone)
|
||||||
{
|
{
|
||||||
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
|
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
|
||||||
*r_path = path_from_bone;
|
*r_path = path_from_bone;
|
||||||
}
|
}
|
||||||
else if (RNA_struct_is_a(ptr->type, &RNA_Node) || RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
|
else if (RNA_struct_is_a(ptr->type, &RNA_Node) || RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
|
||||||
ListBase lb = {nullptr, nullptr};
|
ListBase lb = {nullptr, nullptr};
|
||||||
char *path = nullptr;
|
std::optional<std::string> path;
|
||||||
bNode *node = nullptr;
|
bNode *node = nullptr;
|
||||||
|
|
||||||
/* Get the node we're editing */
|
/* Get the node we're editing */
|
||||||
|
@ -1238,7 +1228,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||||
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
|
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
|
||||||
if (nodeFindNodeTry(ntree, sock, &node, nullptr)) {
|
if (nodeFindNodeTry(ntree, sock, &node, nullptr)) {
|
||||||
if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != nullptr) {
|
path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node);
|
||||||
|
if (path) {
|
||||||
/* we're good! */
|
/* we're good! */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1279,7 +1270,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
/* check we're using the active object */
|
/* check we're using the active object */
|
||||||
const short id_code = GS(id->name);
|
const short id_code = GS(id->name);
|
||||||
ListBase lb = CTX_data_collection_get(C, "selected_editable_objects");
|
ListBase lb = CTX_data_collection_get(C, "selected_editable_objects");
|
||||||
char *path = RNA_path_from_ID_to_property(ptr, prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
|
|
||||||
/* de-duplicate obdata */
|
/* de-duplicate obdata */
|
||||||
if (!BLI_listbase_is_empty(&lb)) {
|
if (!BLI_listbase_is_empty(&lb)) {
|
||||||
|
@ -1319,8 +1310,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
/* Sequencer's ID is scene :/ */
|
/* Sequencer's ID is scene :/ */
|
||||||
/* Try to recursively find an RNA_Sequence ancestor,
|
/* Try to recursively find an RNA_Sequence ancestor,
|
||||||
* to handle situations like #41062... */
|
* to handle situations like #41062... */
|
||||||
if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != nullptr)
|
*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence);
|
||||||
{
|
if (r_path->has_value()) {
|
||||||
/* Special case when we do this for 'Sequence.lock'.
|
/* Special case when we do this for 'Sequence.lock'.
|
||||||
* (if the sequence is locked, it won't be in "selected_editable_sequences"). */
|
* (if the sequence is locked, it won't be in "selected_editable_sequences"). */
|
||||||
const char *prop_id = RNA_property_identifier(prop);
|
const char *prop_id = RNA_property_identifier(prop);
|
||||||
|
@ -1337,14 +1328,14 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (*r_path != nullptr);
|
return r_path->has_value();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RNA_property_is_idprop(prop)) {
|
if (RNA_property_is_idprop(prop)) {
|
||||||
if (*r_path == nullptr) {
|
if (!r_path->has_value()) {
|
||||||
*r_path = RNA_path_from_ptr_to_property_index(ptr, prop, 0, -1);
|
*r_path = RNA_path_from_ptr_to_property_index(ptr, prop, 0, -1);
|
||||||
BLI_assert(*r_path);
|
BLI_assert(*r_path);
|
||||||
}
|
}
|
||||||
|
@ -1371,7 +1362,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||||
LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, r_lb) {
|
LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, r_lb) {
|
||||||
PointerRNA lptr;
|
PointerRNA lptr;
|
||||||
PropertyRNA *lprop = nullptr;
|
PropertyRNA *lprop = nullptr;
|
||||||
RNA_path_resolve_property(&link->ptr, *r_path, &lptr, &lprop);
|
RNA_path_resolve_property(
|
||||||
|
&link->ptr, r_path->has_value() ? r_path->value().c_str() : nullptr, &lptr, &lprop);
|
||||||
|
|
||||||
bool remove = false;
|
bool remove = false;
|
||||||
if (lprop == nullptr) {
|
if (lprop == nullptr) {
|
||||||
|
@ -1517,7 +1509,7 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
char *path = nullptr;
|
std::optional<std::string> path;
|
||||||
bool use_path_from_id;
|
bool use_path_from_id;
|
||||||
ListBase lb = {nullptr};
|
ListBase lb = {nullptr};
|
||||||
|
|
||||||
|
@ -1527,8 +1519,13 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UI_context_copy_to_selected_check(
|
if (!UI_context_copy_to_selected_check(&ptr,
|
||||||
&ptr, &link->ptr, prop, path, use_path_from_id, &lptr, &lprop))
|
&link->ptr,
|
||||||
|
prop,
|
||||||
|
path.has_value() ? path->c_str() : nullptr,
|
||||||
|
use_path_from_id,
|
||||||
|
&lptr,
|
||||||
|
&lprop))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1544,7 +1541,6 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_SAFE_FREE(path);
|
|
||||||
BLI_freelistN(&lb);
|
BLI_freelistN(&lb);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
|
|
@ -1042,11 +1042,10 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (but->rnapoin.owner_id) {
|
if (but->rnapoin.owner_id) {
|
||||||
char *str = rnaprop ?
|
std::optional<std::string> str = rnaprop ? RNA_path_full_property_py_ex(
|
||||||
RNA_path_full_property_py_ex(&but->rnapoin, rnaprop, but->rnaindex, true) :
|
&but->rnapoin, rnaprop, but->rnaindex, true) :
|
||||||
RNA_path_full_struct_py(&but->rnapoin);
|
RNA_path_full_struct_py(&but->rnapoin);
|
||||||
UI_tooltip_text_field_add(data, str, {}, UI_TIP_STYLE_MONO, UI_TIP_LC_PYTHON);
|
UI_tooltip_text_field_add(data, str.value_or(""), {}, UI_TIP_STYLE_MONO, UI_TIP_LC_PYTHON);
|
||||||
MEM_freeN(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1089,28 +1089,22 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op)
|
||||||
else {
|
else {
|
||||||
/* animate constraint's "fixed offset" */
|
/* animate constraint's "fixed offset" */
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
char *path;
|
|
||||||
|
|
||||||
/* get RNA pointer to constraint's "offset_factor" property - to build RNA path */
|
/* get RNA pointer to constraint's "offset_factor" property - to build RNA path */
|
||||||
PointerRNA ptr = RNA_pointer_create(&ob->id, &RNA_FollowPathConstraint, con);
|
PointerRNA ptr = RNA_pointer_create(&ob->id, &RNA_FollowPathConstraint, con);
|
||||||
prop = RNA_struct_find_property(&ptr, "offset_factor");
|
prop = RNA_struct_find_property(&ptr, "offset_factor");
|
||||||
|
|
||||||
path = RNA_path_from_ID_to_property(&ptr, prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop);
|
||||||
|
|
||||||
/* create F-Curve for constraint */
|
/* create F-Curve for constraint */
|
||||||
act = blender::animrig::id_action_ensure(bmain, &ob->id);
|
act = blender::animrig::id_action_ensure(bmain, &ob->id);
|
||||||
fcu = blender::animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, path, 0);
|
fcu = blender::animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, path->c_str(), 0);
|
||||||
|
|
||||||
/* standard vertical range - 0.0 to 1.0 */
|
/* standard vertical range - 0.0 to 1.0 */
|
||||||
standardRange = 1.0f;
|
standardRange = 1.0f;
|
||||||
|
|
||||||
/* enable "Use Fixed Position" so that animating this has effect */
|
/* enable "Use Fixed Position" so that animating this has effect */
|
||||||
data->followflag |= FOLLOWPATH_STATIC;
|
data->followflag |= FOLLOWPATH_STATIC;
|
||||||
|
|
||||||
/* path needs to be freed */
|
|
||||||
if (path) {
|
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup dummy 'generator' modifier here to get 1-1 correspondence still working
|
/* setup dummy 'generator' modifier here to get 1-1 correspondence still working
|
||||||
|
|
|
@ -161,9 +161,8 @@ static void id_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
|
||||||
ID *id = WM_drag_get_local_ID(drag, 0);
|
ID *id = WM_drag_get_local_ID(drag, 0);
|
||||||
|
|
||||||
/* copy drag path to properties */
|
/* copy drag path to properties */
|
||||||
char *text = RNA_path_full_ID_py(id);
|
std::string text = RNA_path_full_ID_py(id);
|
||||||
RNA_string_set(drop->ptr, "text", text);
|
RNA_string_set(drop->ptr, "text", text.c_str());
|
||||||
MEM_freeN(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool path_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
|
static bool path_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
|
||||||
|
|
|
@ -221,13 +221,13 @@ void NODE_OT_group_edit(wmOperatorType *ot)
|
||||||
* The given paths will be owned by the returned instance.
|
* The given paths will be owned by the returned instance.
|
||||||
* Both pointers are allowed to point to the same string.
|
* Both pointers are allowed to point to the same string.
|
||||||
*/
|
*/
|
||||||
static AnimationBasePathChange *animation_basepath_change_new(const char *src_basepath,
|
static AnimationBasePathChange *animation_basepath_change_new(const StringRef src_basepath,
|
||||||
const char *dst_basepath)
|
const StringRef dst_basepath)
|
||||||
{
|
{
|
||||||
AnimationBasePathChange *basepath_change = (AnimationBasePathChange *)MEM_callocN(
|
AnimationBasePathChange *basepath_change = (AnimationBasePathChange *)MEM_callocN(
|
||||||
sizeof(*basepath_change), AT);
|
sizeof(*basepath_change), AT);
|
||||||
basepath_change->src_basepath = src_basepath;
|
basepath_change->src_basepath = BLI_strdupn(src_basepath.data(), src_basepath.size());
|
||||||
basepath_change->dst_basepath = dst_basepath;
|
basepath_change->dst_basepath = BLI_strdupn(dst_basepath.data(), dst_basepath.size());
|
||||||
return basepath_change;
|
return basepath_change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ static void node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
|
||||||
|
|
||||||
/* Keep track of this node's RNA "base" path (the part of the path identifying the node)
|
/* Keep track of this node's RNA "base" path (the part of the path identifying the node)
|
||||||
* if the old node-tree has animation data which potentially covers this node. */
|
* if the old node-tree has animation data which potentially covers this node. */
|
||||||
const char *old_animation_basepath = nullptr;
|
std::optional<std::string> old_animation_basepath;
|
||||||
if (wgroup->adt) {
|
if (wgroup->adt) {
|
||||||
PointerRNA ptr = RNA_pointer_create(&wgroup->id, &RNA_Node, node);
|
PointerRNA ptr = RNA_pointer_create(&wgroup->id, &RNA_Node, node);
|
||||||
old_animation_basepath = RNA_path_from_ID_to_struct(&ptr);
|
old_animation_basepath = RNA_path_from_ID_to_struct(&ptr);
|
||||||
|
@ -313,9 +313,9 @@ static void node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
|
||||||
|
|
||||||
if (wgroup->adt) {
|
if (wgroup->adt) {
|
||||||
PointerRNA ptr = RNA_pointer_create(&ntree->id, &RNA_Node, node);
|
PointerRNA ptr = RNA_pointer_create(&ntree->id, &RNA_Node, node);
|
||||||
const char *new_animation_basepath = RNA_path_from_ID_to_struct(&ptr);
|
const std::optional<std::string> new_animation_basepath = RNA_path_from_ID_to_struct(&ptr);
|
||||||
BLI_addtail(&anim_basepaths,
|
BLI_addtail(&anim_basepaths,
|
||||||
animation_basepath_change_new(old_animation_basepath, new_animation_basepath));
|
animation_basepath_change_new(*old_animation_basepath, *new_animation_basepath));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->parent) {
|
if (!node->parent) {
|
||||||
|
@ -538,13 +538,9 @@ static bool node_group_separate_selected(
|
||||||
/* Keep track of this node's RNA "base" path (the part of the path identifying the node)
|
/* Keep track of this node's RNA "base" path (the part of the path identifying the node)
|
||||||
* if the old node-tree has animation data which potentially covers this node. */
|
* if the old node-tree has animation data which potentially covers this node. */
|
||||||
if (ngroup.adt) {
|
if (ngroup.adt) {
|
||||||
char *path;
|
|
||||||
|
|
||||||
PointerRNA ptr = RNA_pointer_create(&ngroup.id, &RNA_Node, newnode);
|
PointerRNA ptr = RNA_pointer_create(&ngroup.id, &RNA_Node, newnode);
|
||||||
path = RNA_path_from_ID_to_struct(&ptr);
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_struct(&ptr)) {
|
||||||
|
BLI_addtail(&anim_basepaths, animation_basepath_change_new(*path, *path));
|
||||||
if (path) {
|
|
||||||
BLI_addtail(&anim_basepaths, animation_basepath_change_new(path, path));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,8 +1084,8 @@ static void node_group_make_insert_selected(const bContext &C,
|
||||||
ListBase anim_basepaths = {nullptr, nullptr};
|
ListBase anim_basepaths = {nullptr, nullptr};
|
||||||
for (bNode *node : nodes_to_move) {
|
for (bNode *node : nodes_to_move) {
|
||||||
PointerRNA ptr = RNA_pointer_create(&ntree.id, &RNA_Node, node);
|
PointerRNA ptr = RNA_pointer_create(&ntree.id, &RNA_Node, node);
|
||||||
if (char *path = RNA_path_from_ID_to_struct(&ptr)) {
|
if (const std::optional<std::string> path = RNA_path_from_ID_to_struct(&ptr)) {
|
||||||
BLI_addtail(&anim_basepaths, animation_basepath_change_new(path, path));
|
BLI_addtail(&anim_basepaths, animation_basepath_change_new(*path, *path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BKE_animdata_transfer_by_basepath(bmain, &ntree.id, &group.id, &anim_basepaths);
|
BKE_animdata_transfer_by_basepath(bmain, &ntree.id, &group.id, &anim_basepaths);
|
||||||
|
|
|
@ -327,13 +327,11 @@ static bool text_drop_paste_poll(bContext * /*C*/, wmDrag *drag, const wmEvent *
|
||||||
|
|
||||||
static void text_drop_paste(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
|
static void text_drop_paste(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
|
||||||
{
|
{
|
||||||
char *text;
|
|
||||||
ID *id = WM_drag_get_local_ID(drag, 0);
|
ID *id = WM_drag_get_local_ID(drag, 0);
|
||||||
|
|
||||||
/* copy drag path to properties */
|
/* copy drag path to properties */
|
||||||
text = RNA_path_full_ID_py(id);
|
std::string text = RNA_path_full_ID_py(id);
|
||||||
RNA_string_set(drop->ptr, "text", text);
|
RNA_string_set(drop->ptr, "text", text.c_str());
|
||||||
MEM_freeN(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this region dropbox definition */
|
/* this region dropbox definition */
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
* \ingroup RNA
|
* \ingroup RNA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "RNA_types.hh"
|
#include "RNA_types.hh"
|
||||||
|
|
||||||
|
@ -636,34 +638,34 @@ void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier);
|
||||||
/**
|
/**
|
||||||
* Python compatible string representation of this property, (must be freed!).
|
* Python compatible string representation of this property, (must be freed!).
|
||||||
*/
|
*/
|
||||||
char *RNA_property_as_string(
|
std::string RNA_property_as_string(
|
||||||
bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length);
|
bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length);
|
||||||
/**
|
/**
|
||||||
* String representation of a property, Python compatible but can be used for display too.
|
* String representation of a property, Python compatible but can be used for display too.
|
||||||
* \param C: can be NULL.
|
* \param C: can be NULL.
|
||||||
*/
|
*/
|
||||||
char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr);
|
std::string RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr);
|
||||||
char *RNA_pointer_as_string(bContext *C,
|
std::optional<std::string> RNA_pointer_as_string(bContext *C,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
PropertyRNA *prop_ptr,
|
PropertyRNA *prop_ptr,
|
||||||
PointerRNA *ptr_prop);
|
PointerRNA *ptr_prop);
|
||||||
/**
|
/**
|
||||||
* \param C: can be NULL.
|
* \param C: can be NULL.
|
||||||
*/
|
*/
|
||||||
char *RNA_pointer_as_string_keywords_ex(bContext *C,
|
std::string RNA_pointer_as_string_keywords_ex(bContext *C,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
bool as_function,
|
bool as_function,
|
||||||
bool all_args,
|
bool all_args,
|
||||||
bool nested_args,
|
bool nested_args,
|
||||||
int max_prop_length,
|
int max_prop_length,
|
||||||
PropertyRNA *iterprop);
|
PropertyRNA *iterprop);
|
||||||
char *RNA_pointer_as_string_keywords(bContext *C,
|
std::string RNA_pointer_as_string_keywords(bContext *C,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
bool as_function,
|
bool as_function,
|
||||||
bool all_args,
|
bool all_args,
|
||||||
bool nested_args,
|
bool nested_args,
|
||||||
int max_prop_length);
|
int max_prop_length);
|
||||||
char *RNA_function_as_string_keywords(
|
std::string RNA_function_as_string_keywords(
|
||||||
bContext *C, FunctionRNA *func, bool as_function, bool all_args, int max_prop_length);
|
bContext *C, FunctionRNA *func, bool as_function, bool all_args, int max_prop_length);
|
||||||
|
|
||||||
/* Function */
|
/* Function */
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
* UI code or Actions, though efficiency is a concern.
|
* UI code or Actions, though efficiency is a concern.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "RNA_types.hh"
|
#include "RNA_types.hh"
|
||||||
|
|
||||||
struct ListBase;
|
struct ListBase;
|
||||||
|
@ -177,7 +180,8 @@ bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, ListBase *r_el
|
||||||
* \param needle: Custom property object to find.
|
* \param needle: Custom property object to find.
|
||||||
* \return Relative path or NULL.
|
* \return Relative path or NULL.
|
||||||
*/
|
*/
|
||||||
char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, const IDProperty *needle);
|
std::optional<std::string> RNA_path_from_struct_to_idproperty(PointerRNA *ptr,
|
||||||
|
const IDProperty *needle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the actual ID pointer and path from it to the given ID.
|
* Find the actual ID pointer and path from it to the given ID.
|
||||||
|
@ -188,67 +192,73 @@ char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, const IDProperty *need
|
||||||
*/
|
*/
|
||||||
ID *RNA_find_real_ID_and_path(ID *id, const char **r_path);
|
ID *RNA_find_real_ID_and_path(ID *id, const char **r_path);
|
||||||
|
|
||||||
char *RNA_path_from_ID_to_struct(const PointerRNA *ptr);
|
std::optional<std::string> RNA_path_from_ID_to_struct(const PointerRNA *ptr);
|
||||||
|
|
||||||
char *RNA_path_from_real_ID_to_struct(Main *bmain, const PointerRNA *ptr, ID **r_real);
|
std::optional<std::string> RNA_path_from_real_ID_to_struct(Main *bmain,
|
||||||
|
const PointerRNA *ptr,
|
||||||
|
ID **r_real);
|
||||||
|
|
||||||
char *RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop);
|
std::optional<std::string> RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop);
|
||||||
|
|
||||||
char *RNA_path_from_ptr_to_property_index(const PointerRNA *ptr,
|
std::string RNA_path_from_ptr_to_property_index(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index_dim,
|
int index_dim,
|
||||||
int index);
|
int index);
|
||||||
/**
|
/**
|
||||||
* \param index_dim: The dimension to show, 0 disables. 1 for 1d array, 2 for 2d. etc.
|
* \param index_dim: The dimension to show, 0 disables. 1 for 1d array, 2 for 2d. etc.
|
||||||
* \param index: The *flattened* index to use when \a `index_dim > 0`,
|
* \param index: The *flattened* index to use when \a `index_dim > 0`,
|
||||||
* this is expanded when used with multi-dimensional arrays.
|
* this is expanded when used with multi-dimensional arrays.
|
||||||
*/
|
*/
|
||||||
char *RNA_path_from_ID_to_property_index(const PointerRNA *ptr,
|
std::optional<std::string> RNA_path_from_ID_to_property_index(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index_dim,
|
int index_dim,
|
||||||
int index);
|
int index);
|
||||||
|
|
||||||
char *RNA_path_from_real_ID_to_property_index(Main *bmain,
|
std::optional<std::string> RNA_path_from_real_ID_to_property_index(Main *bmain,
|
||||||
const PointerRNA *ptr,
|
const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index_dim,
|
int index_dim,
|
||||||
int index,
|
int index,
|
||||||
ID **r_real_id);
|
ID **r_real_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \return the path to given ptr/prop from the closest ancestor of given type,
|
* \return the path to given ptr/prop from the closest ancestor of given type,
|
||||||
* if any (else return NULL).
|
* if any (else return NULL).
|
||||||
*/
|
*/
|
||||||
char *RNA_path_resolve_from_type_to_property(const PointerRNA *ptr,
|
std::optional<std::string> RNA_path_resolve_from_type_to_property(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
const StructRNA *type);
|
const StructRNA *type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ID as a python representation, eg:
|
* Get the ID as a python representation, eg:
|
||||||
* bpy.data.foo["bar"]
|
* bpy.data.foo["bar"]
|
||||||
*/
|
*/
|
||||||
char *RNA_path_full_ID_py(ID *id);
|
std::string RNA_path_full_ID_py(ID *id);
|
||||||
/**
|
/**
|
||||||
* Get the ID.struct as a python representation, eg:
|
* Get the ID.struct as a python representation, eg:
|
||||||
* bpy.data.foo["bar"].some_struct
|
* bpy.data.foo["bar"].some_struct
|
||||||
*/
|
*/
|
||||||
char *RNA_path_full_struct_py(const PointerRNA *ptr);
|
std::optional<std::string> RNA_path_full_struct_py(const PointerRNA *ptr);
|
||||||
/**
|
/**
|
||||||
* Get the ID.struct.property as a python representation, eg:
|
* Get the ID.struct.property as a python representation, eg:
|
||||||
* bpy.data.foo["bar"].some_struct.some_prop[10]
|
* bpy.data.foo["bar"].some_struct.some_prop[10]
|
||||||
*/
|
*/
|
||||||
char *RNA_path_full_property_py_ex(const PointerRNA *ptr,
|
std::optional<std::string> RNA_path_full_property_py_ex(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index,
|
int index,
|
||||||
bool use_fallback);
|
bool use_fallback);
|
||||||
char *RNA_path_full_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index);
|
std::optional<std::string> RNA_path_full_property_py(const PointerRNA *ptr,
|
||||||
|
PropertyRNA *prop,
|
||||||
|
int index);
|
||||||
/**
|
/**
|
||||||
* Get the struct.property as a python representation, eg:
|
* Get the struct.property as a python representation, eg:
|
||||||
* some_struct.some_prop[10]
|
* some_struct.some_prop[10]
|
||||||
*/
|
*/
|
||||||
char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index);
|
std::optional<std::string> RNA_path_struct_property_py(PointerRNA *ptr,
|
||||||
|
PropertyRNA *prop,
|
||||||
|
int index);
|
||||||
/**
|
/**
|
||||||
* Get the struct.property as a python representation, eg:
|
* Get the struct.property as a python representation, eg:
|
||||||
* some_prop[10]
|
* some_prop[10]
|
||||||
*/
|
*/
|
||||||
char *RNA_path_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index);
|
std::string RNA_path_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index);
|
||||||
|
|
|
@ -257,6 +257,7 @@ set(INC
|
||||||
../../render
|
../../render
|
||||||
../../../../intern/clog
|
../../../../intern/clog
|
||||||
../../../../intern/cycles/blender
|
../../../../intern/cycles/blender
|
||||||
|
../../../../extern/fmtlib/include
|
||||||
../../../../intern/memutil
|
../../../../intern/memutil
|
||||||
../../../../intern/mantaflow/extern
|
../../../../intern/mantaflow/extern
|
||||||
|
|
||||||
|
@ -487,6 +488,7 @@ set(SRC
|
||||||
set(LIB
|
set(LIB
|
||||||
PRIVATE bf::animrig
|
PRIVATE bf::animrig
|
||||||
PRIVATE bf::dna
|
PRIVATE bf::dna
|
||||||
|
PRIVATE extern_fmtlib
|
||||||
bf_editor_space_api
|
bf_editor_space_api
|
||||||
|
|
||||||
bf_editor_animation
|
bf_editor_animation
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -2217,7 +2220,7 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
|
||||||
}
|
}
|
||||||
bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
|
bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
|
||||||
{
|
{
|
||||||
char *path = RNA_path_from_ID_to_property(ptr, prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
|
@ -2225,10 +2228,9 @@ bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
|
||||||
PropertyRNA *r_prop;
|
PropertyRNA *r_prop;
|
||||||
|
|
||||||
PointerRNA id_ptr = RNA_id_pointer_create(ptr->owner_id);
|
PointerRNA id_ptr = RNA_id_pointer_create(ptr->owner_id);
|
||||||
if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == true) {
|
if (RNA_path_resolve(&id_ptr, path->c_str(), &r_ptr, &r_prop) == true) {
|
||||||
ret = (prop == r_prop);
|
ret = (prop == r_prop);
|
||||||
}
|
}
|
||||||
MEM_freeN(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -5713,15 +5715,14 @@ bool RNA_property_is_unlink(PropertyRNA *prop)
|
||||||
return (flag & (PROP_NEVER_UNLINK | PROP_NEVER_NULL)) == 0;
|
return (flag & (PROP_NEVER_UNLINK | PROP_NEVER_NULL)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
|
std::string RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
DynStr *dynstr = BLI_dynstr_new();
|
std::stringstream ss;
|
||||||
char *cstring;
|
|
||||||
|
|
||||||
const char *propname;
|
const char *propname;
|
||||||
int first_time = 1;
|
int first_time = 1;
|
||||||
|
|
||||||
BLI_dynstr_append(dynstr, "{");
|
ss << '{';
|
||||||
|
|
||||||
RNA_STRUCT_BEGIN (ptr, prop) {
|
RNA_STRUCT_BEGIN (ptr, prop) {
|
||||||
propname = RNA_property_identifier(prop);
|
propname = RNA_property_identifier(prop);
|
||||||
|
@ -5731,27 +5732,24 @@ char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_time == 0) {
|
if (first_time == 0) {
|
||||||
BLI_dynstr_append(dynstr, ", ");
|
ss << ", ";
|
||||||
}
|
}
|
||||||
first_time = 0;
|
first_time = 0;
|
||||||
|
|
||||||
cstring = RNA_property_as_string(C, ptr, prop, -1, INT_MAX);
|
const std::string str = RNA_property_as_string(C, ptr, prop, -1, INT_MAX);
|
||||||
BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
|
ss << fmt::format("\"{}\":{}", propname, str);
|
||||||
MEM_freeN(cstring);
|
|
||||||
}
|
}
|
||||||
RNA_STRUCT_END;
|
RNA_STRUCT_END;
|
||||||
|
|
||||||
BLI_dynstr_append(dynstr, "}");
|
ss << '}';
|
||||||
|
|
||||||
cstring = BLI_dynstr_get_cstring(dynstr);
|
return ss.str();
|
||||||
BLI_dynstr_free(dynstr);
|
|
||||||
return cstring;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *rna_pointer_as_string__bldata(PointerRNA *ptr)
|
static std::optional<std::string> rna_pointer_as_string__bldata(PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
if (ptr->type == nullptr || ptr->owner_id == nullptr) {
|
if (ptr->type == nullptr || ptr->owner_id == nullptr) {
|
||||||
return BLI_strdup("None");
|
return "None";
|
||||||
}
|
}
|
||||||
if (RNA_struct_is_ID(ptr->type)) {
|
if (RNA_struct_is_ID(ptr->type)) {
|
||||||
return RNA_path_full_ID_py(ptr->owner_id);
|
return RNA_path_full_ID_py(ptr->owner_id);
|
||||||
|
@ -5759,14 +5757,14 @@ static char *rna_pointer_as_string__bldata(PointerRNA *ptr)
|
||||||
return RNA_path_full_struct_py(ptr);
|
return RNA_path_full_struct_py(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_pointer_as_string(bContext *C,
|
std::optional<std::string> RNA_pointer_as_string(bContext *C,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
PropertyRNA *prop_ptr,
|
PropertyRNA *prop_ptr,
|
||||||
PointerRNA *ptr_prop)
|
PointerRNA *ptr_prop)
|
||||||
{
|
{
|
||||||
IDProperty *prop;
|
IDProperty *prop;
|
||||||
if (ptr_prop->data == nullptr) {
|
if (ptr_prop->data == nullptr) {
|
||||||
return BLI_strdup("None");
|
return "None";
|
||||||
}
|
}
|
||||||
if ((prop = rna_idproperty_check(&prop_ptr, ptr)) && prop->type != IDP_ID) {
|
if ((prop = rna_idproperty_check(&prop_ptr, ptr)) && prop->type != IDP_ID) {
|
||||||
return RNA_pointer_as_string_id(C, ptr_prop);
|
return RNA_pointer_as_string_id(C, ptr_prop);
|
||||||
|
@ -5774,20 +5772,20 @@ char *RNA_pointer_as_string(bContext *C,
|
||||||
return rna_pointer_as_string__bldata(ptr_prop);
|
return rna_pointer_as_string__bldata(ptr_prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_pointer_as_string_keywords_ex(bContext *C,
|
std::string RNA_pointer_as_string_keywords_ex(bContext *C,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
const bool as_function,
|
const bool as_function,
|
||||||
const bool all_args,
|
const bool all_args,
|
||||||
const bool nested_args,
|
const bool nested_args,
|
||||||
const int max_prop_length,
|
const int max_prop_length,
|
||||||
PropertyRNA *iterprop)
|
PropertyRNA *iterprop)
|
||||||
{
|
{
|
||||||
const char *arg_name = nullptr;
|
const char *arg_name = nullptr;
|
||||||
|
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|
||||||
DynStr *dynstr = BLI_dynstr_new();
|
std::stringstream ss;
|
||||||
char *cstring, *buf;
|
|
||||||
bool first_iter = true;
|
bool first_iter = true;
|
||||||
int flag, flag_parameter;
|
int flag, flag_parameter;
|
||||||
|
|
||||||
|
@ -5813,7 +5811,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C,
|
||||||
|
|
||||||
if (as_function && (prop->flag_parameter & PARM_REQUIRED)) {
|
if (as_function && (prop->flag_parameter & PARM_REQUIRED)) {
|
||||||
/* required args don't have useful defaults */
|
/* required args don't have useful defaults */
|
||||||
BLI_dynstr_appendf(dynstr, first_iter ? "%s" : ", %s", arg_name);
|
ss << fmt::format(first_iter ? "{}" : ", {}", arg_name);
|
||||||
first_iter = false;
|
first_iter = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -5827,39 +5825,37 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
std::string buf;
|
||||||
if (as_function && RNA_property_type(prop) == PROP_POINTER) {
|
if (as_function && RNA_property_type(prop) == PROP_POINTER) {
|
||||||
/* don't expand pointers for functions */
|
/* don't expand pointers for functions */
|
||||||
if (flag & PROP_NEVER_NULL) {
|
if (flag & PROP_NEVER_NULL) {
|
||||||
/* we can't really do the right thing here. arg=arg?, hrmf! */
|
/* we can't really do the right thing here. arg=arg?, hrmf! */
|
||||||
buf = BLI_strdup(arg_name);
|
buf = arg_name;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buf = BLI_strdup("None");
|
buf = "None";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buf = RNA_property_as_string(C, ptr, prop, -1, max_prop_length);
|
buf = RNA_property_as_string(C, ptr, prop, -1, max_prop_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_dynstr_appendf(dynstr, first_iter ? "%s=%s" : ", %s=%s", arg_name, buf);
|
ss << fmt::format(first_iter ? "{}={}" : ", {}={}", arg_name, buf);
|
||||||
first_iter = false;
|
first_iter = false;
|
||||||
MEM_freeN(buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RNA_PROP_END;
|
RNA_PROP_END;
|
||||||
|
|
||||||
cstring = BLI_dynstr_get_cstring(dynstr);
|
return ss.str();
|
||||||
BLI_dynstr_free(dynstr);
|
|
||||||
return cstring;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_pointer_as_string_keywords(bContext *C,
|
std::string RNA_pointer_as_string_keywords(bContext *C,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
const bool as_function,
|
const bool as_function,
|
||||||
const bool all_args,
|
const bool all_args,
|
||||||
const bool nested_args,
|
const bool nested_args,
|
||||||
const int max_prop_length)
|
const int max_prop_length)
|
||||||
{
|
{
|
||||||
PropertyRNA *iterprop;
|
PropertyRNA *iterprop;
|
||||||
|
|
||||||
|
@ -5869,17 +5865,15 @@ char *RNA_pointer_as_string_keywords(bContext *C,
|
||||||
C, ptr, as_function, all_args, nested_args, max_prop_length, iterprop);
|
C, ptr, as_function, all_args, nested_args, max_prop_length, iterprop);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_function_as_string_keywords(bContext *C,
|
std::string RNA_function_as_string_keywords(bContext *C,
|
||||||
FunctionRNA *func,
|
FunctionRNA *func,
|
||||||
const bool as_function,
|
const bool as_function,
|
||||||
const bool all_args,
|
const bool all_args,
|
||||||
const int max_prop_length)
|
const int max_prop_length)
|
||||||
{
|
{
|
||||||
PropertyRNA *iterprop;
|
|
||||||
|
|
||||||
PointerRNA funcptr = RNA_pointer_create(nullptr, &RNA_Function, func);
|
PointerRNA funcptr = RNA_pointer_create(nullptr, &RNA_Function, func);
|
||||||
|
|
||||||
iterprop = RNA_struct_find_property(&funcptr, "parameters");
|
PropertyRNA *iterprop = RNA_struct_find_property(&funcptr, "parameters");
|
||||||
|
|
||||||
RNA_struct_iterator_property(funcptr.type);
|
RNA_struct_iterator_property(funcptr.type);
|
||||||
|
|
||||||
|
@ -5920,7 +5914,7 @@ static void *rna_array_as_string_alloc(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_array_as_string_elem(int type, void **buf_p, int len, DynStr *dynstr)
|
static void rna_array_as_string_elem(int type, void **buf_p, int len, std::stringstream &ss)
|
||||||
{
|
{
|
||||||
/* This will print a comma separated string of the array elements from
|
/* This will print a comma separated string of the array elements from
|
||||||
* buf start to len. We will add a comma if len == 1 to preserve tuples. */
|
* buf start to len. We will add a comma if len == 1 to preserve tuples. */
|
||||||
|
@ -5929,7 +5923,7 @@ static void rna_array_as_string_elem(int type, void **buf_p, int len, DynStr *dy
|
||||||
case PROP_BOOLEAN: {
|
case PROP_BOOLEAN: {
|
||||||
bool *buf = static_cast<bool *>(*buf_p);
|
bool *buf = static_cast<bool *>(*buf_p);
|
||||||
for (int i = 0; i < len; i++, buf++) {
|
for (int i = 0; i < len; i++, buf++) {
|
||||||
BLI_dynstr_appendf(dynstr, (i < end || !end) ? "%s, " : "%s", bool_as_py_string(*buf));
|
ss << fmt::format((i < end || !end) ? "{}, " : "{}", bool_as_py_string(*buf));
|
||||||
}
|
}
|
||||||
*buf_p = buf;
|
*buf_p = buf;
|
||||||
break;
|
break;
|
||||||
|
@ -5937,7 +5931,7 @@ static void rna_array_as_string_elem(int type, void **buf_p, int len, DynStr *dy
|
||||||
case PROP_INT: {
|
case PROP_INT: {
|
||||||
int *buf = static_cast<int *>(*buf_p);
|
int *buf = static_cast<int *>(*buf_p);
|
||||||
for (int i = 0; i < len; i++, buf++) {
|
for (int i = 0; i < len; i++, buf++) {
|
||||||
BLI_dynstr_appendf(dynstr, (i < end || !end) ? "%d, " : "%d", *buf);
|
ss << fmt::format((i < end || !end) ? "{}, " : "{}", *buf);
|
||||||
}
|
}
|
||||||
*buf_p = buf;
|
*buf_p = buf;
|
||||||
break;
|
break;
|
||||||
|
@ -5945,7 +5939,7 @@ static void rna_array_as_string_elem(int type, void **buf_p, int len, DynStr *dy
|
||||||
case PROP_FLOAT: {
|
case PROP_FLOAT: {
|
||||||
float *buf = static_cast<float *>(*buf_p);
|
float *buf = static_cast<float *>(*buf_p);
|
||||||
for (int i = 0; i < len; i++, buf++) {
|
for (int i = 0; i < len; i++, buf++) {
|
||||||
BLI_dynstr_appendf(dynstr, (i < end || !end) ? "%g, " : "%g", *buf);
|
ss << fmt::format((i < end || !end) ? "%g, " : "%g", *buf);
|
||||||
}
|
}
|
||||||
*buf_p = buf;
|
*buf_p = buf;
|
||||||
break;
|
break;
|
||||||
|
@ -5956,27 +5950,27 @@ static void rna_array_as_string_elem(int type, void **buf_p, int len, DynStr *dy
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_array_as_string_recursive(
|
static void rna_array_as_string_recursive(
|
||||||
int type, void **buf_p, int totdim, const int *dim_size, DynStr *dynstr)
|
int type, void **buf_p, int totdim, const int *dim_size, std::stringstream &ss)
|
||||||
{
|
{
|
||||||
BLI_dynstr_append(dynstr, "(");
|
ss << '(';
|
||||||
if (totdim > 1) {
|
if (totdim > 1) {
|
||||||
totdim--;
|
totdim--;
|
||||||
const int end = dim_size[totdim] - 1;
|
const int end = dim_size[totdim] - 1;
|
||||||
for (int i = 0; i <= end; i++) {
|
for (int i = 0; i <= end; i++) {
|
||||||
rna_array_as_string_recursive(type, buf_p, totdim, dim_size, dynstr);
|
rna_array_as_string_recursive(type, buf_p, totdim, dim_size, ss);
|
||||||
if (i < end || !end) {
|
if (i < end || !end) {
|
||||||
BLI_dynstr_append(dynstr, ", ");
|
ss << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rna_array_as_string_elem(type, buf_p, dim_size[0], dynstr);
|
rna_array_as_string_elem(type, buf_p, dim_size[0], ss);
|
||||||
}
|
}
|
||||||
BLI_dynstr_append(dynstr, ")");
|
ss << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_array_as_string(
|
static void rna_array_as_string(
|
||||||
int type, int len, PointerRNA *ptr, PropertyRNA *prop, DynStr *dynstr)
|
int type, int len, PointerRNA *ptr, PropertyRNA *prop, std::stringstream &ss)
|
||||||
{
|
{
|
||||||
void *buf_end;
|
void *buf_end;
|
||||||
void *buf = rna_array_as_string_alloc(type, len, ptr, prop, &buf_end);
|
void *buf = rna_array_as_string_alloc(type, len, ptr, prop, &buf_end);
|
||||||
|
@ -5985,59 +5979,57 @@ static void rna_array_as_string(
|
||||||
|
|
||||||
totdim = RNA_property_array_dimension(ptr, prop, dim_size);
|
totdim = RNA_property_array_dimension(ptr, prop, dim_size);
|
||||||
|
|
||||||
rna_array_as_string_recursive(type, &buf_step, totdim, dim_size, dynstr);
|
rna_array_as_string_recursive(type, &buf_step, totdim, dim_size, ss);
|
||||||
BLI_assert(buf_step == buf_end);
|
BLI_assert(buf_step == buf_end);
|
||||||
MEM_freeN(buf);
|
MEM_freeN(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_property_as_string(
|
std::string RNA_property_as_string(
|
||||||
bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length)
|
bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length)
|
||||||
{
|
{
|
||||||
int type = RNA_property_type(prop);
|
int type = RNA_property_type(prop);
|
||||||
int len = RNA_property_array_length(ptr, prop);
|
int len = RNA_property_array_length(ptr, prop);
|
||||||
|
|
||||||
DynStr *dynstr = BLI_dynstr_new();
|
std::stringstream ss;
|
||||||
char *cstring;
|
|
||||||
|
|
||||||
/* see if we can coerce into a python type - PropertyType */
|
/* see if we can coerce into a python type - PropertyType */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PROP_BOOLEAN:
|
case PROP_BOOLEAN:
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get(ptr, prop)));
|
ss << bool_as_py_string(RNA_property_boolean_get(ptr, prop));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
BLI_dynstr_append(dynstr,
|
ss << bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, index));
|
||||||
bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, index)));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rna_array_as_string(type, len, ptr, prop, dynstr);
|
rna_array_as_string(type, len, ptr, prop, ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_INT:
|
case PROP_INT:
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
|
ss << RNA_property_int_get(ptr, prop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get_index(ptr, prop, index));
|
ss << RNA_property_int_get_index(ptr, prop, index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rna_array_as_string(type, len, ptr, prop, dynstr);
|
rna_array_as_string(type, len, ptr, prop, ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_FLOAT:
|
case PROP_FLOAT:
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
|
ss << fmt::format("{:g}", RNA_property_float_get(ptr, prop));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get_index(ptr, prop, index));
|
ss << fmt::format("{:g}", RNA_property_float_get_index(ptr, prop, index));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rna_array_as_string(type, len, ptr, prop, dynstr);
|
rna_array_as_string(type, len, ptr, prop, ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -6054,7 +6046,7 @@ char *RNA_property_as_string(
|
||||||
RNA_property_string_get(ptr, prop, buf);
|
RNA_property_string_get(ptr, prop, buf);
|
||||||
BLI_str_escape(buf_esc, buf, length * 2 + 1);
|
BLI_str_escape(buf_esc, buf, length * 2 + 1);
|
||||||
MEM_freeN(buf);
|
MEM_freeN(buf);
|
||||||
BLI_dynstr_appendf(dynstr, "\"%s\"", buf_esc);
|
ss << fmt::format("\"{}\"", buf_esc);
|
||||||
MEM_freeN(buf_esc);
|
MEM_freeN(buf_esc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6069,7 +6061,7 @@ char *RNA_property_as_string(
|
||||||
const EnumPropertyItem *item_array;
|
const EnumPropertyItem *item_array;
|
||||||
bool free;
|
bool free;
|
||||||
|
|
||||||
BLI_dynstr_append(dynstr, "{");
|
ss << "{";
|
||||||
|
|
||||||
RNA_property_enum_items(C, ptr, prop, &item_array, nullptr, &free);
|
RNA_property_enum_items(C, ptr, prop, &item_array, nullptr, &free);
|
||||||
if (item_array) {
|
if (item_array) {
|
||||||
|
@ -6077,7 +6069,7 @@ char *RNA_property_as_string(
|
||||||
bool is_first = true;
|
bool is_first = true;
|
||||||
for (; item->identifier; item++) {
|
for (; item->identifier; item++) {
|
||||||
if (item->identifier[0] && item->value & val) {
|
if (item->identifier[0] && item->value & val) {
|
||||||
BLI_dynstr_appendf(dynstr, is_first ? "'%s'" : ", '%s'", item->identifier);
|
ss << fmt::format(is_first ? "'%s'" : ", '%s'", item->identifier);
|
||||||
is_first = false;
|
is_first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6087,32 +6079,30 @@ char *RNA_property_as_string(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_dynstr_append(dynstr, "}");
|
ss << "}";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* annoying exception, don't confuse with dictionary syntax above: {} */
|
/* annoying exception, don't confuse with dictionary syntax above: {} */
|
||||||
BLI_dynstr_append(dynstr, "set()");
|
ss << "set()";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
|
else if (RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
|
||||||
BLI_dynstr_appendf(dynstr, "'%s'", identifier);
|
ss << fmt::format("'{}'", identifier);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BLI_dynstr_append(dynstr, "'<UNKNOWN ENUM>'");
|
return "'<UNKNOWN ENUM>'";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROP_POINTER: {
|
case PROP_POINTER: {
|
||||||
PointerRNA tptr = RNA_property_pointer_get(ptr, prop);
|
PointerRNA tptr = RNA_property_pointer_get(ptr, prop);
|
||||||
cstring = RNA_pointer_as_string(C, ptr, prop, &tptr);
|
ss << RNA_pointer_as_string(C, ptr, prop, &tptr).value_or("");
|
||||||
BLI_dynstr_append(dynstr, cstring);
|
|
||||||
MEM_freeN(cstring);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROP_COLLECTION: {
|
case PROP_COLLECTION: {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
CollectionPropertyIterator collect_iter;
|
CollectionPropertyIterator collect_iter;
|
||||||
BLI_dynstr_append(dynstr, "[");
|
ss << "[";
|
||||||
|
|
||||||
for (RNA_property_collection_begin(ptr, prop, &collect_iter);
|
for (RNA_property_collection_begin(ptr, prop, &collect_iter);
|
||||||
(i < max_prop_length) && collect_iter.valid;
|
(i < max_prop_length) && collect_iter.valid;
|
||||||
|
@ -6121,27 +6111,22 @@ char *RNA_property_as_string(
|
||||||
PointerRNA itemptr = collect_iter.ptr;
|
PointerRNA itemptr = collect_iter.ptr;
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
BLI_dynstr_append(dynstr, ", ");
|
ss << ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now get every prop of the collection */
|
/* now get every prop of the collection */
|
||||||
cstring = RNA_pointer_as_string(C, ptr, prop, &itemptr);
|
ss << RNA_pointer_as_string(C, ptr, prop, &itemptr).value_or("");
|
||||||
BLI_dynstr_append(dynstr, cstring);
|
|
||||||
MEM_freeN(cstring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RNA_property_collection_end(&collect_iter);
|
RNA_property_collection_end(&collect_iter);
|
||||||
BLI_dynstr_append(dynstr, "]");
|
ss << "]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
|
return "'<UNKNOWN TYPE>'"; /* TODO */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cstring = BLI_dynstr_get_cstring(dynstr);
|
return ss.str();
|
||||||
BLI_dynstr_free(dynstr);
|
|
||||||
return cstring;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function */
|
/* Function */
|
||||||
|
|
|
@ -101,12 +101,10 @@ static ID *rna_property_override_property_real_id_owner(Main * /*bmain*/,
|
||||||
return owner_id;
|
return owner_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
|
if (const std::optional<std::string> rna_path = RNA_path_from_ID_to_property(ptr, prop)) {
|
||||||
if (rna_path) {
|
*r_rna_path = BLI_strdup(rna_path->c_str());
|
||||||
*r_rna_path = rna_path;
|
|
||||||
if (rna_path_prefix != nullptr) {
|
if (rna_path_prefix != nullptr) {
|
||||||
*r_rna_path = BLI_sprintfN("%s%s", rna_path_prefix, rna_path);
|
*r_rna_path = BLI_sprintfN("%s%s", rna_path_prefix, rna_path->c_str());
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return owner_id;
|
return owner_id;
|
||||||
|
@ -191,14 +189,15 @@ bool RNA_property_overridable_library_set(PointerRNA * /*ptr*/,
|
||||||
|
|
||||||
bool RNA_property_overridden(PointerRNA *ptr, PropertyRNA *prop)
|
bool RNA_property_overridden(PointerRNA *ptr, PropertyRNA *prop)
|
||||||
{
|
{
|
||||||
char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
|
const std::optional<std::string> rna_path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
ID *id = ptr->owner_id;
|
ID *id = ptr->owner_id;
|
||||||
|
|
||||||
if (rna_path == nullptr || id == nullptr || !ID_IS_OVERRIDE_LIBRARY(id)) {
|
if (!rna_path || id == nullptr || !ID_IS_OVERRIDE_LIBRARY(id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (BKE_lib_override_library_property_find(id->override_library, rna_path) != nullptr);
|
return (BKE_lib_override_library_property_find(id->override_library, rna_path->c_str()) !=
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RNA_property_comparable(PointerRNA * /*ptr*/, PropertyRNA *prop)
|
bool RNA_property_comparable(PointerRNA * /*ptr*/, PropertyRNA *prop)
|
||||||
|
@ -725,8 +724,7 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
|
|
||||||
#define RNA_PATH_BUFFSIZE 8192
|
#define RNA_PATH_BUFFSIZE 8192
|
||||||
|
|
||||||
char rna_path_buffer[RNA_PATH_BUFFSIZE];
|
std::optional<std::string> rna_path;
|
||||||
char *rna_path = rna_path_buffer;
|
|
||||||
size_t rna_path_len = 0;
|
size_t rna_path_len = 0;
|
||||||
|
|
||||||
/* XXX TODO: this will have to be refined to handle collections insertions, and array items. */
|
/* XXX TODO: this will have to be refined to handle collections insertions, and array items. */
|
||||||
|
@ -736,6 +734,9 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
const char *prop_name = prop_local.identifier;
|
const char *prop_name = prop_local.identifier;
|
||||||
const size_t prop_name_len = strlen(prop_name);
|
const size_t prop_name_len = strlen(prop_name);
|
||||||
|
|
||||||
|
char rna_path_buffer[RNA_PATH_BUFFSIZE];
|
||||||
|
char *rna_path_c = rna_path_buffer;
|
||||||
|
|
||||||
/* Inlined building (significantly more efficient). */
|
/* Inlined building (significantly more efficient). */
|
||||||
if (!prop_local.is_idprop) {
|
if (!prop_local.is_idprop) {
|
||||||
rna_path_len = root_path_len + 1 + prop_name_len;
|
rna_path_len = root_path_len + 1 + prop_name_len;
|
||||||
|
@ -743,46 +744,46 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
rna_path = static_cast<char *>(MEM_mallocN(rna_path_len + 1, __func__));
|
rna_path = static_cast<char *>(MEM_mallocN(rna_path_len + 1, __func__));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(rna_path, root_path, root_path_len);
|
memcpy(rna_path_c, root_path, root_path_len);
|
||||||
rna_path[root_path_len] = '.';
|
rna_path_c[root_path_len] = '.';
|
||||||
memcpy(rna_path + root_path_len + 1, prop_name, prop_name_len);
|
memcpy(rna_path_c + root_path_len + 1, prop_name, prop_name_len);
|
||||||
rna_path[rna_path_len] = '\0';
|
rna_path_c[rna_path_len] = '\0';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rna_path_len = root_path_len + 2 + prop_name_len + 2;
|
rna_path_len = root_path_len + 2 + prop_name_len + 2;
|
||||||
if (rna_path_len >= RNA_PATH_BUFFSIZE) {
|
if (rna_path_len >= RNA_PATH_BUFFSIZE) {
|
||||||
rna_path = static_cast<char *>(MEM_mallocN(rna_path_len + 1, __func__));
|
rna_path_c = static_cast<char *>(MEM_mallocN(rna_path_len + 1, __func__));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(rna_path, root_path, root_path_len);
|
memcpy(rna_path_c, root_path, root_path_len);
|
||||||
rna_path[root_path_len] = '[';
|
rna_path_c[root_path_len] = '[';
|
||||||
rna_path[root_path_len + 1] = '"';
|
rna_path_c[root_path_len + 1] = '"';
|
||||||
memcpy(rna_path + root_path_len + 2, prop_name, prop_name_len);
|
memcpy(rna_path_c + root_path_len + 2, prop_name, prop_name_len);
|
||||||
rna_path[root_path_len + 2 + prop_name_len] = '"';
|
rna_path_c[root_path_len + 2 + prop_name_len] = '"';
|
||||||
rna_path[root_path_len + 2 + prop_name_len + 1] = ']';
|
rna_path_c[root_path_len + 2 + prop_name_len + 1] = ']';
|
||||||
rna_path[rna_path_len] = '\0';
|
rna_path_c[rna_path_len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rna_path.emplace(rna_path_c);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* This is rather slow, but is not much called, so not really worth optimizing. */
|
/* This is rather slow, but is not much called, so not really worth optimizing. */
|
||||||
rna_path = RNA_path_from_ID_to_property(ptr_local, rawprop);
|
rna_path = RNA_path_from_ID_to_property(ptr_local, rawprop);
|
||||||
if (rna_path != nullptr) {
|
if (rna_path) {
|
||||||
rna_path_len = strlen(rna_path);
|
rna_path_len = rna_path->size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rna_path == nullptr) {
|
if (!rna_path) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOG_INFO(&LOG, 5, "Override Checking %s", rna_path);
|
CLOG_INFO(&LOG, 5, "Override Checking %s", rna_path->c_str());
|
||||||
|
|
||||||
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(liboverride, rna_path);
|
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(liboverride,
|
||||||
|
rna_path->c_str());
|
||||||
if (ignore_overridden && op != nullptr) {
|
if (ignore_overridden && op != nullptr) {
|
||||||
BKE_lib_override_library_operations_tag(op, LIBOVERRIDE_PROP_OP_TAG_UNUSED, false);
|
BKE_lib_override_library_operations_tag(op, LIBOVERRIDE_PROP_OP_TAG_UNUSED, false);
|
||||||
|
|
||||||
if (rna_path != rna_path_buffer) {
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +797,7 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
const int diff = rna_property_override_diff(bmain,
|
const int diff = rna_property_override_diff(bmain,
|
||||||
&prop_local,
|
&prop_local,
|
||||||
&prop_reference,
|
&prop_reference,
|
||||||
rna_path,
|
rna_path->c_str(),
|
||||||
rna_path_len,
|
rna_path_len,
|
||||||
RNA_EQ_STRICT,
|
RNA_EQ_STRICT,
|
||||||
liboverride,
|
liboverride,
|
||||||
|
@ -818,7 +819,7 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
|
|
||||||
if (diff != 0) {
|
if (diff != 0) {
|
||||||
/* XXX TODO: refine this for per-item overriding of arrays... */
|
/* XXX TODO: refine this for per-item overriding of arrays... */
|
||||||
op = BKE_lib_override_library_property_find(liboverride, rna_path);
|
op = BKE_lib_override_library_property_find(liboverride, rna_path->c_str());
|
||||||
IDOverrideLibraryPropertyOperation *opop = static_cast<IDOverrideLibraryPropertyOperation *>(
|
IDOverrideLibraryPropertyOperation *opop = static_cast<IDOverrideLibraryPropertyOperation *>(
|
||||||
op ? op->operations.first : nullptr);
|
op ? op->operations.first : nullptr);
|
||||||
|
|
||||||
|
@ -868,14 +869,15 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
CLOG_INFO(&LOG,
|
CLOG_INFO(&LOG,
|
||||||
2,
|
2,
|
||||||
"Failed to restore forbidden liboverride `%s` for override data '%s'",
|
"Failed to restore forbidden liboverride `%s` for override data '%s'",
|
||||||
rna_path,
|
rna_path->c_str(),
|
||||||
ptr_local->owner_id->name);
|
ptr_local->owner_id->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (op == nullptr) {
|
if (op == nullptr) {
|
||||||
/* An override property is needed, create a temp one if necessary. */
|
/* An override property is needed, create a temp one if necessary. */
|
||||||
op = BKE_lib_override_library_property_get(liboverride, rna_path, nullptr);
|
op = BKE_lib_override_library_property_get(
|
||||||
|
liboverride, rna_path->c_str(), nullptr);
|
||||||
BKE_lib_override_library_operations_tag(op, LIBOVERRIDE_PROP_OP_TAG_UNUSED, true);
|
BKE_lib_override_library_operations_tag(op, LIBOVERRIDE_PROP_OP_TAG_UNUSED, true);
|
||||||
}
|
}
|
||||||
IDOverrideLibraryPropertyOperation *opop_restore =
|
IDOverrideLibraryPropertyOperation *opop_restore =
|
||||||
|
@ -918,18 +920,11 @@ bool RNA_struct_override_matches(Main *bmain,
|
||||||
/* This property is not overridden, and differs from reference, so we have no match. */
|
/* This property is not overridden, and differs from reference, so we have no match. */
|
||||||
matching = false;
|
matching = false;
|
||||||
if (!(do_create || do_restore || do_tag_for_restore)) {
|
if (!(do_create || do_restore || do_tag_for_restore)) {
|
||||||
/* Since we have no 'changing' action allowed, we can break here. */
|
|
||||||
if (rna_path != rna_path_buffer) {
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rna_path != rna_path_buffer) {
|
|
||||||
MEM_freeN(rna_path);
|
|
||||||
}
|
|
||||||
#undef RNA_PATH_BUFFSIZE
|
#undef RNA_PATH_BUFFSIZE
|
||||||
}
|
}
|
||||||
RNA_property_collection_end(&iter);
|
RNA_property_collection_end(&iter);
|
||||||
|
|
|
@ -181,7 +181,6 @@ static char *rna_ColorRamp_path(const PointerRNA *ptr)
|
||||||
case ID_NT: {
|
case ID_NT: {
|
||||||
bNodeTree *ntree = (bNodeTree *)id;
|
bNodeTree *ntree = (bNodeTree *)id;
|
||||||
bNode *node;
|
bNode *node;
|
||||||
char *node_path;
|
|
||||||
|
|
||||||
for (node = static_cast<bNode *>(ntree->nodes.first); node; node = node->next) {
|
for (node = static_cast<bNode *>(ntree->nodes.first); node; node = node->next) {
|
||||||
if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
|
if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
|
||||||
|
@ -190,9 +189,8 @@ static char *rna_ColorRamp_path(const PointerRNA *ptr)
|
||||||
* prepend path from ID to the node
|
* prepend path from ID to the node
|
||||||
*/
|
*/
|
||||||
PointerRNA node_ptr = RNA_pointer_create(id, &RNA_Node, node);
|
PointerRNA node_ptr = RNA_pointer_create(id, &RNA_Node, node);
|
||||||
node_path = RNA_path_from_ID_to_struct(&node_ptr);
|
std::string node_path = RNA_path_from_ID_to_struct(&node_ptr).value_or("");
|
||||||
path = BLI_sprintfN("%s.color_ramp", node_path);
|
path = BLI_sprintfN("%s.color_ramp", node_path.c_str());
|
||||||
MEM_freeN(node_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,13 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "BLI_alloca.h"
|
#include "BLI_alloca.h"
|
||||||
#include "BLI_dynstr.h"
|
#include "BLI_dynstr.h"
|
||||||
#include "BLI_listbase.h"
|
#include "BLI_listbase.h"
|
||||||
#include "BLI_string.h"
|
#include "BLI_string.h"
|
||||||
|
#include "BLI_string_ref.hh"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "BKE_idprop.h"
|
#include "BKE_idprop.h"
|
||||||
|
@ -894,17 +897,18 @@ static char *rna_idp_path(PointerRNA *ptr,
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, const IDProperty *needle)
|
std::optional<std::string> RNA_path_from_struct_to_idproperty(PointerRNA *ptr,
|
||||||
|
const IDProperty *needle)
|
||||||
{
|
{
|
||||||
const IDProperty *haystack = RNA_struct_idprops(ptr, false);
|
const IDProperty *haystack = RNA_struct_idprops(ptr, false);
|
||||||
|
|
||||||
if (haystack) { /* can fail when called on bones */
|
if (haystack) { /* can fail when called on bones */
|
||||||
return rna_idp_path(ptr, haystack, needle, nullptr);
|
return rna_idp_path(ptr, haystack, needle, nullptr);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *rna_path_from_ID_to_idpgroup(const PointerRNA *ptr)
|
static std::optional<std::string> rna_path_from_ID_to_idpgroup(const PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
BLI_assert(ptr->owner_id != nullptr);
|
BLI_assert(ptr->owner_id != nullptr);
|
||||||
|
@ -947,7 +951,10 @@ ID *RNA_find_real_ID_and_path(ID *id, const char **r_path)
|
||||||
return (owner_id != nullptr) ? owner_id : id;
|
return (owner_id != nullptr) ? owner_id : id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *rna_prepend_real_ID_path(Main * /*bmain*/, ID *id, char *path, ID **r_real_id)
|
static std::optional<std::string> rna_prepend_real_ID_path(Main * /*bmain*/,
|
||||||
|
ID *id,
|
||||||
|
const blender::StringRef path,
|
||||||
|
ID **r_real_id)
|
||||||
{
|
{
|
||||||
if (r_real_id != nullptr) {
|
if (r_real_id != nullptr) {
|
||||||
*r_real_id = nullptr;
|
*r_real_id = nullptr;
|
||||||
|
@ -960,36 +967,36 @@ static char *rna_prepend_real_ID_path(Main * /*bmain*/, ID *id, char *path, ID *
|
||||||
*r_real_id = real_id;
|
*r_real_id = real_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path != nullptr) {
|
if (!path.is_empty()) {
|
||||||
char *new_path = nullptr;
|
|
||||||
|
|
||||||
if (real_id) {
|
if (real_id) {
|
||||||
if (prefix[0]) {
|
if (prefix[0]) {
|
||||||
new_path = BLI_sprintfN("%s%s%s", prefix, path[0] == '[' ? "" : ".", path);
|
return fmt::format("{}{}{}", prefix, path[0] == '[' ? "" : ".", std::string_view(path));
|
||||||
}
|
|
||||||
else {
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(path);
|
|
||||||
return new_path;
|
|
||||||
}
|
}
|
||||||
return prefix[0] != '\0' ? BLI_strdup(prefix) : nullptr;
|
|
||||||
|
if (prefix[0] == '\0') {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_ID_to_struct(const PointerRNA *ptr)
|
std::optional<std::string> RNA_path_from_ID_to_struct(const PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
char *ptrpath = nullptr;
|
std::optional<std::string> ptrpath;
|
||||||
|
|
||||||
if (!ptr->owner_id || !ptr->data) {
|
if (!ptr->owner_id || !ptr->data) {
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RNA_struct_is_ID(ptr->type)) {
|
if (!RNA_struct_is_ID(ptr->type)) {
|
||||||
if (ptr->type->path) {
|
if (ptr->type->path) {
|
||||||
/* if type has a path to some ID, use it */
|
/* if type has a path to some ID, use it */
|
||||||
ptrpath = ptr->type->path((PointerRNA *)ptr);
|
char *path_cstr = ptr->type->path((PointerRNA *)ptr);
|
||||||
|
ptrpath = path_cstr;
|
||||||
|
MEM_freeN(path_cstr);
|
||||||
}
|
}
|
||||||
else if (ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
|
else if (ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
|
||||||
PropertyRNA *userprop;
|
PropertyRNA *userprop;
|
||||||
|
@ -1001,10 +1008,11 @@ char *RNA_path_from_ID_to_struct(const PointerRNA *ptr)
|
||||||
userprop = rna_struct_find_nested(&parentptr, ptr->type);
|
userprop = rna_struct_find_nested(&parentptr, ptr->type);
|
||||||
|
|
||||||
if (userprop) {
|
if (userprop) {
|
||||||
ptrpath = BLI_strdup(RNA_property_identifier(userprop));
|
ptrpath = RNA_property_identifier(userprop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nullptr; /* can't do anything about this case yet... */
|
/* can't do anything about this case yet... */
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) {
|
else if (RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) {
|
||||||
|
@ -1012,19 +1020,21 @@ char *RNA_path_from_ID_to_struct(const PointerRNA *ptr)
|
||||||
return rna_path_from_ID_to_idpgroup(ptr);
|
return rna_path_from_ID_to_idpgroup(ptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptrpath;
|
return ptrpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_real_ID_to_struct(Main *bmain, const PointerRNA *ptr, ID **r_real)
|
std::optional<std::string> RNA_path_from_real_ID_to_struct(Main *bmain,
|
||||||
|
const PointerRNA *ptr,
|
||||||
|
ID **r_real)
|
||||||
{
|
{
|
||||||
char *path = RNA_path_from_ID_to_struct(ptr);
|
const std::optional<std::string> path = RNA_path_from_ID_to_struct(ptr);
|
||||||
|
|
||||||
/* Null path is valid in that case, when given struct is an ID one. */
|
/* Null path is valid in that case, when given struct is an ID one. */
|
||||||
return rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real);
|
return rna_prepend_real_ID_path(bmain, ptr->owner_id, path.value_or(""), r_real);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_path_array_multi_from_flat_index(const int dimsize[RNA_MAX_ARRAY_LENGTH],
|
static void rna_path_array_multi_from_flat_index(const int dimsize[RNA_MAX_ARRAY_LENGTH],
|
||||||
|
@ -1067,14 +1077,15 @@ static void rna_path_array_multi_string_from_flat_index(const PointerRNA *ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *rna_path_from_ptr_to_property_index_ex(
|
static std::string rna_path_from_ptr_to_property_index_ex(const PointerRNA *ptr,
|
||||||
const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index, const char *path_prefix)
|
PropertyRNA *prop,
|
||||||
|
int index_dim,
|
||||||
|
int index,
|
||||||
|
const blender::StringRef path_prefix)
|
||||||
{
|
{
|
||||||
const bool is_rna = (prop->magic == RNA_MAGIC);
|
const bool is_rna = (prop->magic == RNA_MAGIC);
|
||||||
const char *propname;
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
propname = RNA_property_identifier(prop);
|
const char *propname = RNA_property_identifier(prop);
|
||||||
|
|
||||||
/* support indexing w/ multi-dimensional arrays */
|
/* support indexing w/ multi-dimensional arrays */
|
||||||
char index_str[RNA_MAX_ARRAY_LENGTH * 12 + 1];
|
char index_str[RNA_MAX_ARRAY_LENGTH * 12 + 1];
|
||||||
|
@ -1086,107 +1097,98 @@ static char *rna_path_from_ptr_to_property_index_ex(
|
||||||
ptr, prop, index_dim, index, index_str, sizeof(index_str));
|
ptr, prop, index_dim, index, index_str, sizeof(index_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path_prefix) {
|
if (!path_prefix.is_empty()) {
|
||||||
if (is_rna) {
|
if (is_rna) {
|
||||||
path = BLI_sprintfN("%s.%s%s", path_prefix, propname, index_str);
|
return fmt::format("{}.{}{}", std::string_view(path_prefix), propname, index_str);
|
||||||
}
|
|
||||||
else {
|
|
||||||
char propname_esc[MAX_IDPROP_NAME * 2];
|
|
||||||
BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
|
|
||||||
path = BLI_sprintfN("%s[\"%s\"]%s", path_prefix, propname_esc, index_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (is_rna) {
|
|
||||||
if (index_dim == 0) {
|
|
||||||
/* Use direct duplication instead of #BLI_sprintfN because it's faster. */
|
|
||||||
path = BLI_strdup(propname);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
path = BLI_sprintfN("%s%s", propname, index_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
char propname_esc[MAX_IDPROP_NAME * 2];
|
|
||||||
BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
|
|
||||||
path = BLI_sprintfN("[\"%s\"]%s", propname_esc, index_str);
|
|
||||||
}
|
}
|
||||||
|
char propname_esc[MAX_IDPROP_NAME * 2];
|
||||||
|
BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
|
||||||
|
return fmt::format("{}[\"{}\"]{}", std::string_view(path_prefix), propname_esc, index_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
if (is_rna) {
|
||||||
|
if (index_dim == 0) {
|
||||||
|
/* Use direct duplication instead of #fmt::format because it's faster. */
|
||||||
|
return propname;
|
||||||
|
}
|
||||||
|
return fmt::format("{}{}", propname, index_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
char propname_esc[MAX_IDPROP_NAME * 2];
|
||||||
|
BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
|
||||||
|
return fmt::format("[\"{}\"]{}", propname_esc, index_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_ptr_to_property_index(const PointerRNA *ptr,
|
std::string RNA_path_from_ptr_to_property_index(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index_dim,
|
int index_dim,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
return rna_path_from_ptr_to_property_index_ex(ptr, prop, index_dim, index, nullptr);
|
return rna_path_from_ptr_to_property_index_ex(ptr, prop, index_dim, index, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_ID_to_property_index(const PointerRNA *ptr,
|
std::optional<std::string> RNA_path_from_ID_to_property_index(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index_dim,
|
int index_dim,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
if (!ptr->owner_id || !ptr->data) {
|
if (!ptr->owner_id || !ptr->data) {
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
/* Path from ID to the struct holding this property. */
|
/* Path from ID to the struct holding this property. */
|
||||||
char *ptrpath = RNA_path_from_ID_to_struct(ptr);
|
std::optional<std::string> ptrpath = RNA_path_from_ID_to_struct(ptr);
|
||||||
/* When there is no path and this is not an ID, there is no path to the ID. */
|
/* When there is no path and this is not an ID, there is no path to the ID. */
|
||||||
char *path = ((ptrpath == nullptr) && !RNA_struct_is_ID(ptr->type)) ?
|
if (!ptrpath && !RNA_struct_is_ID(ptr->type)) {
|
||||||
nullptr :
|
return std::nullopt;
|
||||||
rna_path_from_ptr_to_property_index_ex(ptr, prop, index_dim, index, ptrpath);
|
|
||||||
if (ptrpath != nullptr) {
|
|
||||||
MEM_freeN(ptrpath);
|
|
||||||
}
|
}
|
||||||
return path;
|
return rna_path_from_ptr_to_property_index_ex(ptr, prop, index_dim, index, ptrpath.value_or(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
|
std::optional<std::string> RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
|
||||||
{
|
{
|
||||||
return RNA_path_from_ID_to_property_index(ptr, prop, 0, -1);
|
return RNA_path_from_ID_to_property_index(ptr, prop, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_from_real_ID_to_property_index(Main *bmain,
|
std::optional<std::string> RNA_path_from_real_ID_to_property_index(Main *bmain,
|
||||||
const PointerRNA *ptr,
|
const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index_dim,
|
int index_dim,
|
||||||
int index,
|
int index,
|
||||||
ID **r_real_id)
|
ID **r_real_id)
|
||||||
{
|
{
|
||||||
char *path = RNA_path_from_ID_to_property_index(ptr, prop, index_dim, index);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property_index(
|
||||||
|
ptr, prop, index_dim, index);
|
||||||
|
if (!path) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
/* Null path is always an error here, in that case do not return the 'fake ID from real ID' part
|
/* Null path is always an error here, in that case do not return the 'fake ID from real ID' part
|
||||||
* of the path either. */
|
* of the path either. */
|
||||||
return path != nullptr ? rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real_id) :
|
return rna_prepend_real_ID_path(bmain, ptr->owner_id, path->c_str(), r_real_id);
|
||||||
nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_resolve_from_type_to_property(const PointerRNA *ptr,
|
std::optional<std::string> RNA_path_resolve_from_type_to_property(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
const StructRNA *type)
|
const StructRNA *type)
|
||||||
{
|
{
|
||||||
/* Try to recursively find an "type"'d ancestor,
|
/* Try to recursively find an "type"'d ancestor,
|
||||||
* to handle situations where path from ID is not enough. */
|
* to handle situations where path from ID is not enough. */
|
||||||
ListBase path_elems = {nullptr};
|
ListBase path_elems = {nullptr};
|
||||||
char *path = nullptr;
|
const std::optional<std::string> full_path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
char *full_path = RNA_path_from_ID_to_property(ptr, prop);
|
if (!full_path) {
|
||||||
|
return std::nullopt;
|
||||||
if (full_path == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerRNA idptr = RNA_id_pointer_create(ptr->owner_id);
|
PointerRNA idptr = RNA_id_pointer_create(ptr->owner_id);
|
||||||
|
|
||||||
if (RNA_path_resolve_elements(&idptr, full_path, &path_elems)) {
|
std::optional<std::string> path;
|
||||||
|
if (RNA_path_resolve_elements(&idptr, full_path->c_str(), &path_elems)) {
|
||||||
LISTBASE_FOREACH_BACKWARD (PropertyElemRNA *, prop_elem, &path_elems) {
|
LISTBASE_FOREACH_BACKWARD (PropertyElemRNA *, prop_elem, &path_elems) {
|
||||||
if (RNA_struct_is_a(prop_elem->ptr.type, type)) {
|
if (RNA_struct_is_a(prop_elem->ptr.type, type)) {
|
||||||
char *ref_path = RNA_path_from_ID_to_struct(&prop_elem->ptr);
|
if (const std::optional<std::string> ref_path = RNA_path_from_ID_to_struct(
|
||||||
if (ref_path) {
|
&prop_elem->ptr))
|
||||||
path = BLI_strdup(full_path + strlen(ref_path) + 1); /* +1 for the linking '.' */
|
{
|
||||||
MEM_freeN(ref_path);
|
path = blender::StringRef(*full_path).drop_prefix(ref_path->size() + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1195,11 +1197,10 @@ char *RNA_path_resolve_from_type_to_property(const PointerRNA *ptr,
|
||||||
BLI_freelistN(&path_elems);
|
BLI_freelistN(&path_elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(full_path);
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_full_ID_py(ID *id)
|
std::string RNA_path_full_ID_py(ID *id)
|
||||||
{
|
{
|
||||||
const char *path;
|
const char *path;
|
||||||
ID *id_real = RNA_find_real_ID_and_path(id, &path);
|
ID *id_real = RNA_find_real_ID_and_path(id, &path);
|
||||||
|
@ -1226,65 +1227,47 @@ char *RNA_path_full_ID_py(ID *id)
|
||||||
char id_esc[(sizeof(id->name) - 2) * 2];
|
char id_esc[(sizeof(id->name) - 2) * 2];
|
||||||
BLI_str_escape(id_esc, id->name + 2, sizeof(id_esc));
|
BLI_str_escape(id_esc, id->name + 2, sizeof(id_esc));
|
||||||
|
|
||||||
return BLI_sprintfN("bpy.data.%s[\"%s\"%s]%s%s",
|
return fmt::format("bpy.data.{}[\"{}\"{}]{}{}",
|
||||||
BKE_idtype_idcode_to_name_plural(GS(id->name)),
|
BKE_idtype_idcode_to_name_plural(GS(id->name)),
|
||||||
id_esc,
|
id_esc,
|
||||||
lib_filepath_esc,
|
lib_filepath_esc,
|
||||||
path[0] ? "." : "",
|
path[0] ? "." : "",
|
||||||
path);
|
path);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_full_struct_py(const PointerRNA *ptr)
|
std::optional<std::string> RNA_path_full_struct_py(const PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
char *id_path;
|
|
||||||
char *data_path;
|
|
||||||
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
if (!ptr->owner_id) {
|
if (!ptr->owner_id) {
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* never fails */
|
/* never fails */
|
||||||
id_path = RNA_path_full_ID_py(ptr->owner_id);
|
std::string id_path = RNA_path_full_ID_py(ptr->owner_id);
|
||||||
|
|
||||||
data_path = RNA_path_from_ID_to_struct(ptr);
|
std::optional<std::string> data_path = RNA_path_from_ID_to_struct(ptr);
|
||||||
|
|
||||||
/* XXX data_path may be null (see #36788),
|
/* XXX data_path may be null (see #36788),
|
||||||
* do we want to get the 'bpy.data.foo["bar"].(null)' stuff? */
|
* do we want to get the 'bpy.data.foo["bar"].(null)' stuff? */
|
||||||
ret = BLI_sprintfN("%s.%s", id_path, data_path);
|
return fmt::format("{}.{}", id_path, data_path.value_or(""));
|
||||||
|
|
||||||
if (data_path) {
|
|
||||||
MEM_freeN(data_path);
|
|
||||||
}
|
|
||||||
MEM_freeN(id_path);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_full_property_py_ex(const PointerRNA *ptr,
|
std::optional<std::string> RNA_path_full_property_py_ex(const PointerRNA *ptr,
|
||||||
PropertyRNA *prop,
|
PropertyRNA *prop,
|
||||||
int index,
|
int index,
|
||||||
bool use_fallback)
|
bool use_fallback)
|
||||||
{
|
{
|
||||||
char *id_path;
|
|
||||||
const char *data_delim;
|
const char *data_delim;
|
||||||
const char *data_path;
|
|
||||||
bool data_path_free;
|
|
||||||
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
if (!ptr->owner_id) {
|
if (!ptr->owner_id) {
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* never fails */
|
/* never fails */
|
||||||
id_path = RNA_path_full_ID_py(ptr->owner_id);
|
std::string id_path = RNA_path_full_ID_py(ptr->owner_id);
|
||||||
|
|
||||||
data_path = RNA_path_from_ID_to_property(ptr, prop);
|
std::optional<std::string> data_path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
if (data_path) {
|
if (data_path) {
|
||||||
data_delim = (data_path[0] == '[') ? "" : ".";
|
data_delim = ((*data_path)[0] == '[') ? "" : ".";
|
||||||
data_path_free = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (use_fallback) {
|
if (use_fallback) {
|
||||||
|
@ -1295,66 +1278,49 @@ char *RNA_path_full_property_py_ex(const PointerRNA *ptr,
|
||||||
else {
|
else {
|
||||||
data_delim = ".";
|
data_delim = ".";
|
||||||
}
|
}
|
||||||
data_path_free = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((index == -1) || (RNA_property_array_check(prop) == false)) {
|
if ((index == -1) || (RNA_property_array_check(prop) == false)) {
|
||||||
ret = BLI_sprintfN("%s%s%s", id_path, data_delim, data_path);
|
return fmt::format("{}{}{}", id_path, data_delim, data_path.value_or(""));
|
||||||
}
|
}
|
||||||
else {
|
return fmt::format("{}{}{}[{}]", id_path, data_delim, data_path.value_or(""), index);
|
||||||
ret = BLI_sprintfN("%s%s%s[%d]", id_path, data_delim, data_path, index);
|
|
||||||
}
|
|
||||||
MEM_freeN(id_path);
|
|
||||||
if (data_path_free) {
|
|
||||||
MEM_freeN((void *)data_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_full_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index)
|
std::optional<std::string> RNA_path_full_property_py(const PointerRNA *ptr,
|
||||||
|
PropertyRNA *prop,
|
||||||
|
int index)
|
||||||
{
|
{
|
||||||
return RNA_path_full_property_py_ex(ptr, prop, index, false);
|
return RNA_path_full_property_py_ex(ptr, prop, index, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
|
std::optional<std::string> RNA_path_struct_property_py(PointerRNA *ptr,
|
||||||
|
PropertyRNA *prop,
|
||||||
|
int index)
|
||||||
{
|
{
|
||||||
char *data_path;
|
|
||||||
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
if (!ptr->owner_id) {
|
if (!ptr->owner_id) {
|
||||||
return nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_path = RNA_path_from_ID_to_property(ptr, prop);
|
std::optional<std::string> data_path = RNA_path_from_ID_to_property(ptr, prop);
|
||||||
|
|
||||||
if (data_path == nullptr) {
|
if (!data_path) {
|
||||||
/* This may not be an ID at all, check for simple when pointer owns property.
|
/* This may not be an ID at all, check for simple when pointer owns property.
|
||||||
* TODO: more complex nested case. */
|
* TODO: more complex nested case. */
|
||||||
if (!RNA_struct_is_ID(ptr->type)) {
|
if (!RNA_struct_is_ID(ptr->type)) {
|
||||||
const char *prop_identifier = RNA_property_identifier(prop);
|
const char *prop_identifier = RNA_property_identifier(prop);
|
||||||
if (RNA_struct_find_property(ptr, prop_identifier) == prop) {
|
if (RNA_struct_find_property(ptr, prop_identifier) == prop) {
|
||||||
data_path = BLI_strdup(prop_identifier);
|
data_path = prop_identifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((index == -1) || (RNA_property_array_check(prop) == false)) {
|
if ((index == -1) || (RNA_property_array_check(prop) == false)) {
|
||||||
ret = BLI_strdup(data_path);
|
return *data_path;
|
||||||
}
|
}
|
||||||
else {
|
return fmt::format("{}[{}]", data_path.value_or(""), index);
|
||||||
ret = BLI_sprintfN("%s[%d]", data_path, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_path) {
|
|
||||||
MEM_freeN(data_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *RNA_path_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index)
|
std::string RNA_path_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||||
{
|
{
|
||||||
if (RNA_property_array_check(prop) == false) {
|
if (RNA_property_array_check(prop) == false) {
|
||||||
index = -1;
|
index = -1;
|
||||||
|
|
|
@ -924,10 +924,10 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
|
||||||
"bpy.data.%s[%R]", BKE_idtype_idcode_to_name_plural(GS(id->name)), tmp_str);
|
"bpy.data.%s[%R]", BKE_idtype_idcode_to_name_plural(GS(id->name)), tmp_str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const char *path;
|
|
||||||
ID *real_id = nullptr;
|
ID *real_id = nullptr;
|
||||||
path = RNA_path_from_real_ID_to_struct(G_MAIN, &self->ptr, &real_id);
|
const std::optional<std::string> path = RNA_path_from_real_ID_to_struct(
|
||||||
if (path != nullptr) {
|
G_MAIN, &self->ptr, &real_id);
|
||||||
|
if (path) {
|
||||||
/* 'real_id' may be nullptr in some cases, although the only valid one is evaluated data,
|
/* 'real_id' may be nullptr in some cases, although the only valid one is evaluated data,
|
||||||
* which should have already been caught above.
|
* which should have already been caught above.
|
||||||
* So assert, but handle it without crashing for release builds. */
|
* So assert, but handle it without crashing for release builds. */
|
||||||
|
@ -939,7 +939,7 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
|
||||||
ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
|
ret = PyUnicode_FromFormat("bpy.data.%s[%R].%s",
|
||||||
BKE_idtype_idcode_to_name_plural(GS(real_id->name)),
|
BKE_idtype_idcode_to_name_plural(GS(real_id->name)),
|
||||||
tmp_str,
|
tmp_str,
|
||||||
path);
|
path->c_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Can't find the path, print something useful as a fallback. */
|
/* Can't find the path, print something useful as a fallback. */
|
||||||
|
@ -948,7 +948,6 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
|
||||||
tmp_str,
|
tmp_str,
|
||||||
RNA_struct_identifier(self->ptr.type));
|
RNA_struct_identifier(self->ptr.type));
|
||||||
}
|
}
|
||||||
MEM_freeN((void *)path);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Can't find the path, print something useful as a fallback. */
|
/* Can't find the path, print something useful as a fallback. */
|
||||||
|
@ -1038,7 +1037,6 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim,
|
||||||
ID *id = self->ptr.owner_id;
|
ID *id = self->ptr.owner_id;
|
||||||
PyObject *tmp_str;
|
PyObject *tmp_str;
|
||||||
PyObject *ret;
|
PyObject *ret;
|
||||||
const char *path;
|
|
||||||
|
|
||||||
PYRNA_PROP_CHECK_OBJ(self);
|
PYRNA_PROP_CHECK_OBJ(self);
|
||||||
|
|
||||||
|
@ -1052,7 +1050,7 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim,
|
||||||
/* Note that using G_MAIN is absolutely not ideal, but we have no access to actual Main DB from
|
/* Note that using G_MAIN is absolutely not ideal, but we have no access to actual Main DB from
|
||||||
* here. */
|
* here. */
|
||||||
ID *real_id = nullptr;
|
ID *real_id = nullptr;
|
||||||
path = RNA_path_from_real_ID_to_property_index(
|
const std::optional<std::string> path = RNA_path_from_real_ID_to_property_index(
|
||||||
G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id);
|
G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id);
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
|
@ -1060,14 +1058,12 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim,
|
||||||
Py_DECREF(tmp_str);
|
Py_DECREF(tmp_str);
|
||||||
tmp_str = PyUnicode_FromString(real_id->name + 2);
|
tmp_str = PyUnicode_FromString(real_id->name + 2);
|
||||||
}
|
}
|
||||||
const char *data_delim = (path[0] == '[') ? "" : ".";
|
const char *data_delim = ((*path)[0] == '[') ? "" : ".";
|
||||||
ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s",
|
ret = PyUnicode_FromFormat("bpy.data.%s[%R]%s%s",
|
||||||
BKE_idtype_idcode_to_name_plural(GS(real_id->name)),
|
BKE_idtype_idcode_to_name_plural(GS(real_id->name)),
|
||||||
tmp_str,
|
tmp_str,
|
||||||
data_delim,
|
data_delim,
|
||||||
path);
|
path->c_str());
|
||||||
|
|
||||||
MEM_freeN((void *)path);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Can't find the path, print something useful as a fallback. */
|
/* Can't find the path, print something useful as a fallback. */
|
||||||
|
@ -3892,7 +3888,6 @@ PyDoc_STRVAR(
|
||||||
static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
||||||
{
|
{
|
||||||
const char *name = nullptr;
|
const char *name = nullptr;
|
||||||
const char *path;
|
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
PyObject *ret;
|
PyObject *ret;
|
||||||
|
|
||||||
|
@ -3902,6 +3897,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> path;
|
||||||
if (name) {
|
if (name) {
|
||||||
prop = RNA_struct_find_property(&self->ptr, name);
|
prop = RNA_struct_find_property(&self->ptr, name);
|
||||||
if (prop == nullptr) {
|
if (prop == nullptr) {
|
||||||
|
@ -3918,7 +3914,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
||||||
path = RNA_path_from_ID_to_struct(&self->ptr);
|
path = RNA_path_from_ID_to_struct(&self->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == nullptr) {
|
if (!path) {
|
||||||
if (name) {
|
if (name) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"%.200s.path_from_id(\"%s\") found, but does not support path creation",
|
"%.200s.path_from_id(\"%s\") found, but does not support path creation",
|
||||||
|
@ -3933,8 +3929,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = PyUnicode_FromString(path);
|
ret = PyUnicode_FromString(path->c_str());
|
||||||
MEM_freeN((void *)path);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3950,13 +3945,12 @@ PyDoc_STRVAR(
|
||||||
" :rtype: str\n");
|
" :rtype: str\n");
|
||||||
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
|
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
|
||||||
{
|
{
|
||||||
const char *path;
|
|
||||||
PropertyRNA *prop = self->prop;
|
PropertyRNA *prop = self->prop;
|
||||||
PyObject *ret;
|
PyObject *ret;
|
||||||
|
|
||||||
path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
|
const std::optional<std::string> path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
|
||||||
|
|
||||||
if (path == nullptr) {
|
if (!path) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"%.200s.%.200s.path_from_id() does not support path creation for this type",
|
"%.200s.%.200s.path_from_id() does not support path creation for this type",
|
||||||
RNA_struct_identifier(self->ptr.type),
|
RNA_struct_identifier(self->ptr.type),
|
||||||
|
@ -3964,8 +3958,7 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = PyUnicode_FromString(path);
|
ret = PyUnicode_FromString(path->c_str());
|
||||||
MEM_freeN((void *)path);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -4469,7 +4462,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
|
||||||
PointerRNA idptr;
|
PointerRNA idptr;
|
||||||
|
|
||||||
PointerRNA *base_ptr;
|
PointerRNA *base_ptr;
|
||||||
char *path_str;
|
std::optional<std::string> path_str;
|
||||||
|
|
||||||
if (newptr.owner_id) {
|
if (newptr.owner_id) {
|
||||||
idptr = RNA_id_pointer_create(newptr.owner_id);
|
idptr = RNA_id_pointer_create(newptr.owner_id);
|
||||||
|
@ -4485,10 +4478,8 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
|
||||||
ret = PyTuple_New(3);
|
ret = PyTuple_New(3);
|
||||||
PyTuple_SET_ITEMS(ret,
|
PyTuple_SET_ITEMS(ret,
|
||||||
pyrna_struct_CreatePyObject(base_ptr),
|
pyrna_struct_CreatePyObject(base_ptr),
|
||||||
PyUnicode_FromString(path_str),
|
PyUnicode_FromString(path_str->c_str()),
|
||||||
PyLong_FromLong(newindex));
|
PyLong_FromLong(newindex));
|
||||||
|
|
||||||
MEM_freeN(path_str);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = Py_None;
|
ret = Py_None;
|
||||||
|
@ -6783,18 +6774,15 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
|
||||||
static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void * /*closure*/)
|
static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void * /*closure*/)
|
||||||
{
|
{
|
||||||
PyObject *ret;
|
PyObject *ret;
|
||||||
char *args;
|
|
||||||
|
|
||||||
args = RNA_function_as_string_keywords(nullptr, self->func, true, true, INT_MAX);
|
std::string args = RNA_function_as_string_keywords(nullptr, self->func, true, true, INT_MAX);
|
||||||
|
|
||||||
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
|
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
|
||||||
RNA_struct_identifier(self->ptr.type),
|
RNA_struct_identifier(self->ptr.type),
|
||||||
RNA_function_identifier(self->func),
|
RNA_function_identifier(self->func),
|
||||||
args,
|
args.c_str(),
|
||||||
RNA_function_ui_description(self->func));
|
RNA_function_ui_description(self->func));
|
||||||
|
|
||||||
MEM_freeN(args);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,8 @@ static int pyrna_struct_anim_args_parse_ex(PointerRNA *ptr,
|
||||||
*r_path_full = BLI_strdup(path);
|
*r_path_full = BLI_strdup(path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*r_path_full = RNA_path_from_ID_to_property(&r_ptr, prop);
|
const std::optional<std::string> path_full = RNA_path_from_ID_to_property(&r_ptr, prop);
|
||||||
|
*r_path_full = path_full ? BLI_strdup(path_full->c_str()) : nullptr;
|
||||||
|
|
||||||
if (*r_path_full == nullptr) {
|
if (*r_path_full == nullptr) {
|
||||||
PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
|
PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
|
||||||
|
@ -176,8 +177,8 @@ static int pyrna_struct_anim_args_parse_no_resolve(PointerRNA *ptr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *path_prefix = RNA_path_from_ID_to_struct(ptr);
|
const std::optional<std::string> path_prefix = RNA_path_from_ID_to_struct(ptr);
|
||||||
if (path_prefix == nullptr) {
|
if (!path_prefix) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"%.200s could not make path for type %s",
|
"%.200s could not make path for type %s",
|
||||||
error_prefix,
|
error_prefix,
|
||||||
|
@ -186,12 +187,11 @@ static int pyrna_struct_anim_args_parse_no_resolve(PointerRNA *ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*path == '[') {
|
if (*path == '[') {
|
||||||
*r_path_full = BLI_string_joinN(path_prefix, path);
|
*r_path_full = BLI_string_joinN(path_prefix->c_str(), path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*r_path_full = BLI_string_join_by_sep_charN('.', path_prefix, path);
|
*r_path_full = BLI_string_join_by_sep_charN('.', path_prefix->c_str(), path);
|
||||||
}
|
}
|
||||||
MEM_freeN(path_prefix);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2930,7 +2930,7 @@ static const char *keymap_handler_log_kmi_op_str(bContext *C,
|
||||||
size_t buf_maxncpy)
|
size_t buf_maxncpy)
|
||||||
{
|
{
|
||||||
/* The key-map item properties can further help distinguish this item from others. */
|
/* The key-map item properties can further help distinguish this item from others. */
|
||||||
char *kmi_props = nullptr;
|
std::optional<std::string> kmi_props;
|
||||||
if (kmi->properties != nullptr) {
|
if (kmi->properties != nullptr) {
|
||||||
wmOperatorType *ot = WM_operatortype_find(kmi->idname, false);
|
wmOperatorType *ot = WM_operatortype_find(kmi->idname, false);
|
||||||
if (ot) {
|
if (ot) {
|
||||||
|
@ -2940,10 +2940,7 @@ static const char *keymap_handler_log_kmi_op_str(bContext *C,
|
||||||
kmi_props = IDP_reprN(kmi->properties, nullptr);
|
kmi_props = IDP_reprN(kmi->properties, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BLI_snprintf(buf, buf_maxncpy, "%s(%s)", kmi->idname, kmi_props ? kmi_props : "");
|
BLI_snprintf(buf, buf_maxncpy, "%s(%s)", kmi->idname, kmi_props.value_or("").c_str());
|
||||||
if (kmi_props != nullptr) {
|
|
||||||
MEM_freeN(kmi_props);
|
|
||||||
}
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,15 +246,14 @@ std::string WM_operator_pystring_ex(bContext *C,
|
||||||
opmptr = &opmptr_default;
|
opmptr = &opmptr_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cstring_args = RNA_pointer_as_string_id(C, opmptr);
|
std::string string_args = RNA_pointer_as_string_id(C, opmptr);
|
||||||
if (first_op) {
|
if (first_op) {
|
||||||
ss << opm->type->idname << '=' << cstring_args;
|
ss << opm->type->idname << '=' << string_args;
|
||||||
first_op = false;
|
first_op = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss << ", " << opm->type->idname << '=' << cstring_args;
|
ss << ", " << opm->type->idname << '=' << string_args;
|
||||||
}
|
}
|
||||||
MEM_freeN(cstring_args);
|
|
||||||
|
|
||||||
if (opmptr == &opmptr_default) {
|
if (opmptr == &opmptr_default) {
|
||||||
WM_operator_properties_free(&opmptr_default);
|
WM_operator_properties_free(&opmptr_default);
|
||||||
|
@ -271,10 +270,8 @@ std::string WM_operator_pystring_ex(bContext *C,
|
||||||
opptr = &opptr_default;
|
opptr = &opptr_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cstring_args = RNA_pointer_as_string_keywords(
|
ss << RNA_pointer_as_string_keywords(
|
||||||
C, opptr, false, all_args, macro_args_test, max_prop_length);
|
C, opptr, false, all_args, macro_args_test, max_prop_length);
|
||||||
ss << cstring_args;
|
|
||||||
MEM_freeN(cstring_args);
|
|
||||||
|
|
||||||
if (opptr == &opptr_default) {
|
if (opptr == &opptr_default) {
|
||||||
WM_operator_properties_free(&opptr_default);
|
WM_operator_properties_free(&opptr_default);
|
||||||
|
@ -608,34 +605,31 @@ std::optional<std::string> WM_context_path_resolve_property_full(const bContext
|
||||||
}
|
}
|
||||||
std::string member_id_data_path;
|
std::string member_id_data_path;
|
||||||
if (is_id && !RNA_struct_is_ID(ptr->type)) {
|
if (is_id && !RNA_struct_is_ID(ptr->type)) {
|
||||||
char *data_path = RNA_path_from_ID_to_struct(ptr);
|
std::optional<std::string> data_path = RNA_path_from_ID_to_struct(ptr);
|
||||||
if (data_path != nullptr) {
|
if (data_path) {
|
||||||
if (prop != nullptr) {
|
if (prop != nullptr) {
|
||||||
char *prop_str = RNA_path_property_py(ptr, prop, index);
|
std::string prop_str = RNA_path_property_py(ptr, prop, index);
|
||||||
if (prop_str[0] == '[') {
|
if (prop_str[0] == '[') {
|
||||||
member_id_data_path = fmt::format("{}.{}", data_path, prop_str);
|
member_id_data_path = fmt::format("{}.{}", *data_path, prop_str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
member_id_data_path = fmt::format("{}.{}.{}", member_id, data_path, prop_str);
|
member_id_data_path = fmt::format("{}.{}.{}", member_id, *data_path, prop_str);
|
||||||
}
|
}
|
||||||
MEM_freeN(prop_str);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
member_id_data_path = fmt::format("{}.{}", member_id, data_path);
|
member_id_data_path = fmt::format("{}.{}", member_id, *data_path);
|
||||||
}
|
}
|
||||||
MEM_freeN(data_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (prop != nullptr) {
|
if (prop != nullptr) {
|
||||||
char *prop_str = RNA_path_property_py(ptr, prop, index);
|
std::string prop_str = RNA_path_property_py(ptr, prop, index);
|
||||||
if (prop_str[0] == '[') {
|
if (prop_str[0] == '[') {
|
||||||
member_id_data_path = fmt::format("{}{}", member_id, prop_str);
|
member_id_data_path = fmt::format("{}{}", member_id, prop_str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
member_id_data_path = fmt::format("{}.{}", member_id, prop_str);
|
member_id_data_path = fmt::format("{}.{}", member_id, prop_str);
|
||||||
}
|
}
|
||||||
MEM_freeN(prop_str);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
member_id_data_path = member_id;
|
member_id_data_path = member_id;
|
||||||
|
@ -673,22 +667,17 @@ std::optional<std::string> WM_prop_pystring_assign(bContext *C,
|
||||||
|
|
||||||
if (!lhs.has_value()) {
|
if (!lhs.has_value()) {
|
||||||
/* Fallback to `bpy.data.foo[id]` if we don't find in the context. */
|
/* Fallback to `bpy.data.foo[id]` if we don't find in the context. */
|
||||||
if (char *lhs_cstr = RNA_path_full_property_py(ptr, prop, index)) {
|
if (std::optional<std::string> lhs_str = RNA_path_full_property_py(ptr, prop, index)) {
|
||||||
lhs = lhs_cstr;
|
lhs = lhs_str;
|
||||||
MEM_freeN(lhs_cstr);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rhs = RNA_property_as_string(C, ptr, prop, index, INT_MAX);
|
std::string rhs = RNA_property_as_string(C, ptr, prop, index, INT_MAX);
|
||||||
if (!rhs) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ret = fmt::format("{} = {}", lhs.value(), rhs);
|
std::string ret = fmt::format("{} = {}", lhs.value(), rhs);
|
||||||
MEM_freeN(rhs);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1523,12 +1512,12 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *region, void *user_
|
||||||
BLF_width(style->widget.uifont_id, data->title.c_str(), BLF_DRAW_STR_DUMMY_MAX));
|
BLF_width(style->widget.uifont_id, data->title.c_str(), BLF_DRAW_STR_DUMMY_MAX));
|
||||||
|
|
||||||
/* Break Message into multiple lines. */
|
/* Break Message into multiple lines. */
|
||||||
std::vector<std::string> message_lines;
|
blender::Vector<std::string> message_lines;
|
||||||
blender::StringRef messaged_trimmed = blender::StringRef(data->message).trim();
|
blender::StringRef messaged_trimmed = blender::StringRef(data->message).trim();
|
||||||
std::istringstream message_stream(messaged_trimmed);
|
std::istringstream message_stream(messaged_trimmed);
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(message_stream, line)) {
|
while (std::getline(message_stream, line)) {
|
||||||
message_lines.push_back(line);
|
message_lines.append(line);
|
||||||
text_width = std::max(
|
text_width = std::max(
|
||||||
text_width, int(BLF_width(style->widget.uifont_id, line.c_str(), BLF_DRAW_STR_DUMMY_MAX)));
|
text_width, int(BLF_width(style->widget.uifont_id, line.c_str(), BLF_DRAW_STR_DUMMY_MAX)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "BLI_ghash.h"
|
#include "BLI_ghash.h"
|
||||||
#include "BLI_listbase.h"
|
#include "BLI_listbase.h"
|
||||||
|
#include "BLI_string.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "WM_message.hh"
|
#include "WM_message.hh"
|
||||||
|
@ -316,7 +317,9 @@ void WM_msg_subscribe_rna_params(wmMsgBus *mbus,
|
||||||
if (msg_key->msg.params.data_path == nullptr) {
|
if (msg_key->msg.params.data_path == nullptr) {
|
||||||
if (msg_key->msg.params.ptr.data != msg_key->msg.params.ptr.owner_id) {
|
if (msg_key->msg.params.ptr.data != msg_key->msg.params.ptr.owner_id) {
|
||||||
/* We assume prop type can't change. */
|
/* We assume prop type can't change. */
|
||||||
msg_key->msg.params.data_path = RNA_path_from_ID_to_struct(&msg_key->msg.params.ptr);
|
const std::optional<std::string> str = RNA_path_from_ID_to_struct(
|
||||||
|
&msg_key->msg.params.ptr);
|
||||||
|
msg_key->msg.params.data_path = str ? BLI_strdupn(str->c_str(), str->size()) : nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue