This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/geometry/geometry_attributes.c
Philipp Oeser 543becac36 Fix T86921: Executing "Operator Cheat Sheet" Crashes Blender
This was only happening without an active object.

The "Operator Cheat Sheet" operator collects info about all operators,
and as part of that executes the callbacks to create dynamic enums. The
callback to enumerate the geometry operators (introduced in
rB370d6e50252b) attribute domains depends on a context object. If this
isn't available, we just have to return `DummyRNA_NULL_items`.

Maniphest Tasks: T86921

Differential Revision: https://developer.blender.org/D10814
2021-03-25 14:03:20 +01:00

159 lines
4.6 KiB
C

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2020 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup edgeometry
*/
#include "BKE_attribute.h"
#include "BKE_context.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_object.h"
#include "geometry_intern.h"
/*********************** Attribute Operators ************************/
static bool geometry_attributes_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data)) &&
BKE_id_attributes_supported(data);
}
static const EnumPropertyItem *geometry_attribute_domain_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
Object *ob = ED_object_context(C);
if (ob != NULL) {
return rna_enum_attribute_domain_itemf(ob->data, r_free);
}
return DummyRNA_NULL_items;
}
static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
ID *id = ob->data;
char name[MAX_NAME];
RNA_string_get(op->ptr, "name", name);
CustomDataType type = (CustomDataType)RNA_enum_get(op->ptr, "data_type");
AttributeDomain domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain");
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports);
if (layer == NULL) {
return OPERATOR_CANCELLED;
}
BKE_id_attributes_active_set(id, layer);
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
return OPERATOR_FINISHED;
}
void GEOMETRY_OT_attribute_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Geometry Attribute";
ot->description = "Add attribute to geometry";
ot->idname = "GEOMETRY_OT_attribute_add";
/* api callbacks */
ot->poll = geometry_attributes_poll;
ot->exec = geometry_attribute_add_exec;
ot->invoke = WM_operator_props_popup_confirm;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
PropertyRNA *prop;
prop = RNA_def_string(ot->srna, "name", "Attribute", MAX_NAME, "Name", "Name of new attribute");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_enum(ot->srna,
"data_type",
rna_enum_attribute_type_items,
CD_PROP_FLOAT,
"Data Type",
"Type of data stored in attribute");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_enum(ot->srna,
"domain",
rna_enum_attribute_domain_items,
ATTR_DOMAIN_POINT,
"Domain",
"Type of element that attribute is stored on");
RNA_def_enum_funcs(prop, geometry_attribute_domain_itemf);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int geometry_attribute_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
ID *id = ob->data;
CustomDataLayer *layer = BKE_id_attributes_active_get(id);
if (layer == NULL) {
return OPERATOR_CANCELLED;
}
if (!BKE_id_attribute_remove(id, layer, op->reports)) {
return OPERATOR_CANCELLED;
}
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
return OPERATOR_FINISHED;
}
void GEOMETRY_OT_attribute_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Geometry Attribute";
ot->description = "Remove attribute from geometry";
ot->idname = "GEOMETRY_OT_attribute_remove";
/* api callbacks */
ot->exec = geometry_attribute_remove_exec;
ot->poll = geometry_attributes_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}