[Bf-blender-cvs] [336b263b568] sculpt-dev: Sculpt: brush engine stuff
Joseph Eagar
noreply at git.blender.org
Mon Sep 20 12:14:53 CEST 2021
Commit: 336b263b568fad2547014fe50d5810f03daa1677
Author: Joseph Eagar
Date: Sun Sep 19 15:35:10 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB336b263b568fad2547014fe50d5810f03daa1677
Sculpt: brush engine stuff
BrushChannels are now stored in linked lists
instead of simple arrays. This helps to
avoid memory corruption.
I had originally wanted to be able to pass
BrushChannels by value, but that doesn't really
work since they heap allocd data (the input
mapping curves).
===================================================================
M release/scripts/startup/bl_ui/properties_paint_common.py
M source/blender/blenkernel/BKE_brush_engine.h
M source/blender/blenkernel/intern/brush.c
M source/blender/blenkernel/intern/brush_engine.c
M source/blender/blenkernel/intern/brush_engine_presets.c
M source/blender/blenkernel/intern/colortools.c
M source/blender/blenloader/intern/versioning_300.c
M source/blender/makesdna/DNA_sculpt_brush_types.h
M source/blender/makesrna/intern/rna_brush_engine.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index b3d9230974e..ee748af74b3 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -137,7 +137,7 @@ class UnifiedPaintPanel:
if ch.inherit:
sd = context.tool_settings.sculpt
#ensure channel exists in tool settings channel set
- sd.channels.ensure(ch, queue=True)
+ sd.channels.ensure(ch)
finalch = sd.channels.channels[prop_name]
diff --git a/source/blender/blenkernel/BKE_brush_engine.h b/source/blender/blenkernel/BKE_brush_engine.h
index 25c6227cf32..8fd2ded7075 100644
--- a/source/blender/blenkernel/BKE_brush_engine.h
+++ b/source/blender/blenkernel/BKE_brush_engine.h
@@ -73,18 +73,26 @@ typedef struct BrushMappingData {
#define MAX_BRUSH_ENUM_DEF 32
typedef struct BrushEnumDef {
- EnumPropertyItem items[MAX_BRUSH_ENUM_DEF];
+ int value;
+ const char identifier[64];
+ int icon;
+ const char name[64];
+ const char description[512];
} BrushEnumDef;
typedef struct BrushChannelType {
- char name[32], idname[32], tooltip[512];
+ char name[64], idname[64], tooltip[512];
float min, max, soft_min, soft_max;
BrushMappingPreset mappings;
int type, flag;
int ivalue;
float fvalue;
- BrushEnumDef enumdef; // if an enum type
+
+ BrushEnumDef enumdef[MAX_BRUSH_ENUM_DEF]; // for enum/bitmask types
+ EnumPropertyItem *rna_enumdef;
+
+ bool user_defined;
} BrushChannelType;
typedef struct BrushCommand {
@@ -98,6 +106,7 @@ typedef struct BrushCommandList {
int totcommand;
} BrushCommandList;
+void BKE_brush_channel_free_data(BrushChannel *ch);
void BKE_brush_channel_free(BrushChannel *ch);
void BKE_brush_channel_copy_data(BrushChannel *dst, BrushChannel *src);
void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def);
@@ -106,14 +115,22 @@ BrushChannelSet *BKE_brush_channelset_create();
BrushChannelSet *BKE_brush_channelset_copy(BrushChannelSet *src);
void BKE_brush_channelset_free(BrushChannelSet *chset);
-// makes a copy of ch
void BKE_brush_channelset_add(BrushChannelSet *chset, BrushChannel *ch);
-void BKE_brush_channelset_queue(BrushChannelSet *chset, BrushChannel *ch);
+
+// makes a copy of ch
+void BKE_brush_channelset_add_duplicate(BrushChannelSet *chset, BrushChannel *ch);
+
+// does not add to namemap ghash
+void BKE_brush_channel_ensure_unque_name(BrushChannelSet *chset, BrushChannel *ch);
+
+// does not free ch or its data
+void BKE_brush_channelset_remove(BrushChannelSet *chset, BrushChannel *ch);
+
+// does not free ch or its data
+bool BKE_brush_channelset_remove_named(BrushChannelSet *chset, const char *idname);
// checks is a channel with existing->idname exists; if not a copy of existing is made and inserted
-void BKE_brush_channelset_ensure_existing(BrushChannelSet *chset,
- BrushChannel *existing,
- bool queue);
+void BKE_brush_channelset_ensure_existing(BrushChannelSet *chset, BrushChannel *existing);
BrushChannel *BKE_brush_channelset_lookup(BrushChannelSet *chset, const char *idname);
@@ -193,6 +210,7 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset,
// merge in channels the ui requested
void BKE_brush_apply_queued_channels(BrushChannelSet *chset, bool do_override);
+void BKE_brush_channeltype_rna_check(BrushChannelType *def);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e2e33db0fd8..0151cc4e16d 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -315,6 +315,7 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
if (brush->channels) {
BLO_read_data_address(reader, &brush->channels);
+
BKE_brush_channelset_read(reader, brush->channels);
BKE_brush_builtin_patch(brush, brush->sculpt_tool);
}
@@ -1798,12 +1799,12 @@ void BKE_brush_sculpt_reset(Brush *br)
// BKE_brush_debug_print_state(br);
BKE_brush_builtin_create(br, br->sculpt_tool);
+ BrushChannel *ch;
- for (int i = 0; i < br->channels->totchannel; i++) {
- BrushChannel *ch = br->channels->channels + i;
+ for (ch = (BrushChannel *)br->channels->channels.first; ch; ch = ch->next) {
BrushChannelType *def = ch->def;
- BKE_brush_channel_free(ch);
+ BKE_brush_channel_free_data(ch);
BKE_brush_channel_init(ch, def);
}
diff --git a/source/blender/blenkernel/intern/brush_engine.c b/source/blender/blenkernel/intern/brush_engine.c
index ee345bccd3a..4a67ffd2e37 100644
--- a/source/blender/blenkernel/intern/brush_engine.c
+++ b/source/blender/blenkernel/intern/brush_engine.c
@@ -10,8 +10,12 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_mempool.h"
+#include "BLI_rand.h"
#include "BLI_rect.h"
#include "BLI_smallhash.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+#include "BLI_utildefines.h"
#include "DNA_brush_enums.h"
#include "DNA_brush_types.h"
@@ -38,7 +42,7 @@ static struct {
} namestack[256] = {0};
int namestack_i = 1;
-ATTR_NO_OPT void namestack_push(const char *name)
+void namestack_push(const char *name)
{
namestack_i++;
@@ -50,6 +54,7 @@ void namestack_pop()
{
namestack_i--;
}
+
#define namestack_head_name strdup(namestack[namestack_i].tag)
void BKE_curvemapping_copy_data_tag_ex(CurveMapping *target,
@@ -59,7 +64,7 @@ void BKE_curvemapping_copy_data_tag_ex(CurveMapping *target,
#define BKE_curvemapping_copy_data(dst, src) \
BKE_curvemapping_copy_data_tag_ex(dst, src, namestack_head_name)
-static bool check_corrupted_curve(BrushMapping *dst)
+ATTR_NO_OPT static bool check_corrupted_curve(BrushMapping *dst)
{
const float clip_size_x = BLI_rctf_size_x(&dst->curve.curr);
@@ -100,13 +105,44 @@ generated from the node group inputs.
extern BrushChannelType brush_builtin_channels[];
extern const int brush_builtin_channel_len;
-void BKE_brush_channel_free(BrushChannel *ch)
+ATTR_NO_OPT void BKE_brush_channeltype_rna_check(BrushChannelType *def)
+{
+ if (def->rna_enumdef) {
+ return;
+ }
+
+ if (!def->user_defined) {
+ // builtin channel types are never freed, don't use guardedalloc
+ def->rna_enumdef = malloc(sizeof(EnumPropertyItem) * ARRAY_SIZE(def->enumdef));
+ }
+
+ else {
+ def->rna_enumdef = MEM_calloc_arrayN(
+ ARRAY_SIZE(def->enumdef), sizeof(EnumPropertyItem), "def->rna_enumdef");
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(def->enumdef); i++) {
+ def->rna_enumdef[i].value = def->enumdef[i].value;
+ def->rna_enumdef[i].identifier = def->enumdef[i].identifier;
+ def->rna_enumdef[i].icon = def->enumdef[i].icon;
+ def->rna_enumdef[i].name = def->enumdef[i].name;
+ def->rna_enumdef[i].description = def->enumdef[i].description;
+ }
+}
+
+ATTR_NO_OPT void BKE_brush_channel_free_data(BrushChannel *ch)
{
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
BKE_curvemapping_free_data(&ch->mappings[i].curve);
}
}
+ATTR_NO_OPT void BKE_brush_channel_free(BrushChannel *ch)
+{
+ BKE_brush_channel_free_data(ch);
+ MEM_freeN(ch);
+}
+
ATTR_NO_OPT void BKE_brush_channel_copy_data(BrushChannel *dst, BrushChannel *src)
{
// we have to free old curvemappings here,
@@ -116,8 +152,14 @@ ATTR_NO_OPT void BKE_brush_channel_copy_data(BrushChannel *dst, BrushChannel *sr
BKE_curvemapping_free_data(&dst->mappings[i].curve);
}
+ // preserve linked list pointers
+ void *next = dst->next, *prev = dst->prev;
+
*dst = *src;
+ dst->next = next;
+ dst->prev = prev;
+
// clear curves in dst, see comment above
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
memset(&dst->mappings[i].curve, 0, sizeof(CurveMapping));
@@ -135,7 +177,12 @@ ATTR_NO_OPT void BKE_brush_channel_copy_data(BrushChannel *dst, BrushChannel *sr
ATTR_NO_OPT void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
{
+ // preserve linked list pointers
+ BrushChannel *next = ch->next, *prev = ch->prev;
+
memset(ch, 0, sizeof(*ch));
+ ch->next = next;
+ ch->prev = prev;
strcpy(ch->name, def->name);
strcpy(ch->idname, def->idname);
@@ -197,108 +244,137 @@ ATTR_NO_OPT void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
BrushChannelSet *BKE_brush_channelset_create()
{
- return (BrushChannelSet *)MEM_callocN(sizeof(BrushChannelSet), "BrushChannelSet");
-}
+ BrushChannelSet *chset = (BrushChannelSet *)MEM_callocN(sizeof(BrushChannelSet),
+ "BrushChannelSet");
-void BKE_brush_apply_queued_channels(BrushChannelSet *chset, bool do_override)
-{
- if (!chset->tot_queued_channel) {
- return;
- }
+ chset->namemap = BLI_ghash_str_new("BrushChannelSet");
- for (int i = 0; i < chset->tot_queued_channel; i++) {
- BrushChannel *ch = chset->queued_channels;
+ return chset;
+}
- BrushChannel *exist = BKE_brush_channelset_lookup(chset, ch->idname);
+ATTR_NO_OPT void BKE_brush_channelset_free(BrushChannelSet *chset)
+{
+ BrushChannel *ch, *next;
- if (exist) {
- if (!do_override) {
- continue;
- }
+ BLI_ghash_free(chset->namemap, NULL, NULL);
- BKE_brush_channel_free(exist);
- *exist = *ch;
+ for (ch = chset->channels.first; ch; ch = next) {
+ next = ch->next;
- continue;
- }
- else {
- BKE_brush_channelset_add(chset, ch);
- BKE_brush_channel_free(ch);
- }
+ BKE_brush_channel_free(ch);
}
- MEM_SAFE_FREE(chset->queued_channels);
- chset->queued_channels = NULL;
- chset->tot_queued_channel = NULL;
+ MEM_freeN(chset);
}
-void BKE_brush_channelset_free(BrushChannelSet *chset)
+static int _rng_seed = 0;
+
+ATTR_NO_OPT void BKE_brush_channel_ensure_unque_name(BrushChannelSet *chset, BrushChannel *ch)
{
- for (int step = 0; step < 2; step++) {
- BrushChannel *channels = step ? chset->queued_channels : chset->channels;
- int totchannel = step ? chset->tot_queued_channel : chset->totchannel;
+ BrushChannel *ch2;
+ int i = 1;
+ char idname[512];
- if (ch
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list