Nodes: Panel declarations for grouping sockets #108649
|
@ -590,9 +590,10 @@ void ntreeClearSocketPanels(bNodeTree *ntree);
|
|||
|
||||
/**
|
||||
* Move a socket panel up or down in the node tree.
|
||||
* \param index: Index to which to move the panel.
|
||||
* \param from_index: Current index of the poanel to move.
|
||||
* \param to_index: Index to which to move the panel.
|
||||
*/
|
||||
void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index);
|
||||
void ntreeMoveSocketPanel(bNodeTree *ntree, int from_index, int to_index);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -516,16 +516,6 @@ inline blender::Span<bNode *> bNodeTree::root_frames() const
|
|||
return this->runtime->root_frames;
|
||||
}
|
||||
|
||||
inline blender::Span<bNodeSocketPanel> bNodeTree::socket_panels() const
|
||||
{
|
||||
return blender::Span(socket_panels_array, socket_panels_num);
|
||||
}
|
||||
|
||||
inline blender::MutableSpan<bNodeSocketPanel> bNodeTree::socket_panels_for_write()
|
||||
{
|
||||
return blender::MutableSpan(socket_panels_array, socket_panels_num);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name #bNode Inline Methods
|
||||
* \{ */
|
||||
|
|
|
@ -643,10 +643,9 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
|
|||
write_node_socket_interface(writer, sock);
|
||||
}
|
||||
|
||||
BLO_write_struct_array(
|
||||
writer, bNodeSocketPanel, ntree->socket_panels_num, ntree->socket_panels_array);
|
||||
for (const bNodeSocketPanel &panel : ntree->socket_panels()) {
|
||||
BLO_write_string(writer, panel.name);
|
||||
LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) {
|
||||
BLO_write_struct(writer, bNodeSocketPanel, panel);
|
||||
BLO_write_string(writer, panel->name);
|
||||
}
|
||||
|
||||
BKE_previewimg_blend_write(writer, ntree->preview);
|
||||
|
@ -869,9 +868,9 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
|
|||
BLO_read_data_address(reader, &link->tosock);
|
||||
}
|
||||
|
||||
BLO_read_data_address(reader, &ntree->socket_panels_array);
|
||||
for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) {
|
||||
BLO_read_data_address(reader, &panel.name);
|
||||
BLO_read_list(reader, &ntree->socket_panels);
|
||||
LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) {
|
||||
BLO_read_data_address(reader, &panel->name);
|
||||
}
|
||||
|
||||
/* TODO: should be dealt by new generic cache handling of IDs... */
|
||||
|
@ -3682,25 +3681,27 @@ void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree)
|
|||
/* XXX Hack: store panel index in panel_id temporarily for sorting. */
|
||||
LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) {
|
||||
const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id);
|
||||
iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array);
|
||||
iosock->panel_id = (panel == nullptr ? -1 : BLI_findindex(&ntree->socket_panels, panel));
|
||||
}
|
||||
LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) {
|
||||
const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id);
|
||||
iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array);
|
||||
iosock->panel_id = panel == nullptr ? -1 : BLI_findindex(&ntree->socket_panels, panel);
|
||||
}
|
||||
BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_panel_cmp);
|
||||
BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_panel_cmp);
|
||||
/* Restore panel_id. */
|
||||
LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) {
|
||||
if (iosock->panel_id >= 0) {
|
||||
const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id];
|
||||
iosock->panel_id = panel.identifier;
|
||||
const bNodeSocketPanel *panel = static_cast<bNodeSocketPanel *>(
|
||||
BLI_findlink(&ntree->socket_panels, iosock->panel_id));
|
||||
iosock->panel_id = panel->identifier;
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) {
|
||||
if (iosock->panel_id >= 0) {
|
||||
const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id];
|
||||
iosock->panel_id = panel.identifier;
|
||||
const bNodeSocketPanel *panel = static_cast<bNodeSocketPanel *>(
|
||||
BLI_findlink(&ntree->socket_panels, iosock->panel_id));
|
||||
iosock->panel_id = panel->identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3818,9 +3819,9 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock)
|
|||
|
||||
bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id)
|
||||
{
|
||||
for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) {
|
||||
if (panel.identifier == id) {
|
||||
return &panel;
|
||||
LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) {
|
||||
if (panel->identifier == id) {
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -3828,111 +3829,53 @@ bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id)
|
|||
|
||||
bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag)
|
||||
{
|
||||
bNodeSocketPanel *old_panels_array = ntree->socket_panels_array;
|
||||
const Span<bNodeSocketPanel> old_panels = ntree->socket_panels();
|
||||
ntree->socket_panels_array = MEM_cnew_array<bNodeSocketPanel>(ntree->socket_panels_num + 1,
|
||||
__func__);
|
||||
++ntree->socket_panels_num;
|
||||
const MutableSpan<bNodeSocketPanel> new_panels = ntree->socket_panels_for_write();
|
||||
|
||||
std::copy(old_panels.begin(), old_panels.end(), new_panels.data());
|
||||
bNodeSocketPanel &new_panel = new_panels[new_panels.size() - 1];
|
||||
new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++};
|
||||
|
||||
MEM_SAFE_FREE(old_panels_array);
|
||||
bNodeSocketPanel *new_panel = MEM_cnew<bNodeSocketPanel>(__func__);
|
||||
LukasTonne marked this conversation as resolved
Outdated
|
||||
new_panel->name = BLI_strdup(name);
|
||||
new_panel->flag = flag;
|
||||
new_panel->identifier = ntree->next_socket_panel_identifier++;
|
||||
|
||||
LukasTonne marked this conversation as resolved
Outdated
Hans Goudey
commented
Don't have a strong preference, but this seems a bit more idiomatic and clear to me: Don't have a strong preference, but this seems a bit more idiomatic and clear to me:
` std::copy(old_categories.begin(), old_categories.end(), new_categories.data());`
|
||||
BLI_addtail(&ntree->socket_panels, new_panel);
|
||||
/* No need to sort sockets, nothing is using the new panel yet */
|
||||
|
||||
return &new_panel;
|
||||
return new_panel;
|
||||
}
|
||||
|
||||
bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index)
|
||||
{
|
||||
if (!blender::IndexRange(ntree->socket_panels().size() + 1).contains(index)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bNodeSocketPanel *old_panels_array = ntree->socket_panels_array;
|
||||
const Span<bNodeSocketPanel> old_panels = ntree->socket_panels();
|
||||
ntree->socket_panels_array = MEM_cnew_array<bNodeSocketPanel>(ntree->socket_panels_num + 1,
|
||||
__func__);
|
||||
++ntree->socket_panels_num;
|
||||
const MutableSpan<bNodeSocketPanel> new_panels = ntree->socket_panels_for_write();
|
||||
|
||||
Span old_panels_front = old_panels.take_front(index);
|
||||
Span old_panels_back = old_panels.drop_front(index);
|
||||
std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data());
|
||||
std::copy(
|
||||
old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data());
|
||||
bNodeSocketPanel &new_panel = new_panels[index];
|
||||
new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++};
|
||||
|
||||
MEM_SAFE_FREE(old_panels_array);
|
||||
bNodeSocketPanel *new_panel = MEM_cnew<bNodeSocketPanel>(__func__);
|
||||
new_panel->name = BLI_strdup(name);
|
||||
new_panel->flag = flag;
|
||||
new_panel->identifier = ntree->next_socket_panel_identifier++;
|
||||
|
||||
bNodeSocketPanel *panel_after = static_cast<bNodeSocketPanel *>(
|
||||
BLI_findlink(&ntree->socket_panels, index));
|
||||
BLI_insertlinkbefore(&ntree->socket_panels, panel_after, new_panel);
|
||||
/* No need to sort sockets, nothing is using the new panel yet */
|
||||
|
||||
return &new_panel;
|
||||
return new_panel;
|
||||
}
|
||||
|
||||
void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel)
|
||||
{
|
||||
const int index = panel - ntree->socket_panels_array;
|
||||
if (!ntree->socket_panels().contains_ptr(panel)) {
|
||||
return;
|
||||
if (BLI_remlink_safe(&ntree->socket_panels, panel)) {
|
||||
MEM_SAFE_FREE(panel->name);
|
||||
MEM_delete(panel);
|
||||
}
|
||||
|
||||
bNodeSocketPanel *old_panels_array = ntree->socket_panels_array;
|
||||
const Span<bNodeSocketPanel> old_panels = ntree->socket_panels();
|
||||
ntree->socket_panels_array = MEM_cnew_array<bNodeSocketPanel>(ntree->socket_panels_num - 1,
|
||||
__func__);
|
||||
--ntree->socket_panels_num;
|
||||
const MutableSpan<bNodeSocketPanel> new_panels = ntree->socket_panels_for_write();
|
||||
|
||||
Span old_panels_front = old_panels.take_front(index);
|
||||
Span old_panels_back = old_panels.drop_front(index + 1);
|
||||
std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data());
|
||||
std::copy(old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index).data());
|
||||
|
||||
MEM_SAFE_FREE(old_panels_array);
|
||||
|
||||
ntreeEnsureSocketInterfacePanelOrder(ntree);
|
||||
}
|
||||
|
||||
void ntreeClearSocketPanels(bNodeTree *ntree)
|
||||
{
|
||||
MEM_SAFE_FREE(ntree->socket_panels_array);
|
||||
ntree->socket_panels_array = nullptr;
|
||||
ntree->socket_panels_num = 0;
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) {
|
||||
MEM_SAFE_FREE(panel->name);
|
||||
}
|
||||
BLI_freelistN(&ntree->socket_panels);
|
||||
/* No need to sort sockets, only null panel exists, relative order remains unchanged. */
|
||||
}
|
||||
|
||||
void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index)
|
||||
void ntreeMoveSocketPanel(bNodeTree *ntree, int from_index, int to_index)
|
||||
{
|
||||
if (!ntree->socket_panels().contains_ptr(panel)) {
|
||||
return;
|
||||
if (BLI_listbase_move_index(&ntree->socket_panels, from_index, to_index)) {
|
||||
ntreeEnsureSocketInterfacePanelOrder(ntree);
|
||||
}
|
||||
|
||||
const MutableSpan<bNodeSocketPanel> panels = ntree->socket_panels_for_write();
|
||||
const int old_index = panel - ntree->socket_panels_array;
|
||||
if (old_index == new_index) {
|
||||
return;
|
||||
}
|
||||
else if (old_index < new_index) {
|
||||
const Span<bNodeSocketPanel> moved_panels = panels.slice(old_index + 1, new_index - old_index);
|
||||
const bNodeSocketPanel tmp = panels[old_index];
|
||||
std::copy(moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index).data());
|
||||
panels[new_index] = tmp;
|
||||
}
|
||||
else /* old_index > new_index */ {
|
||||
const Span<bNodeSocketPanel> moved_panels = panels.slice(new_index, old_index - new_index);
|
||||
const bNodeSocketPanel tmp = panels[old_index];
|
||||
std::copy_backward(
|
||||
moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index + 1).data());
|
||||
panels[new_index] = tmp;
|
||||
}
|
||||
|
||||
ntreeEnsureSocketInterfacePanelOrder(ntree);
|
||||
}
|
||||
|
||||
namespace blender::bke {
|
||||
|
|
|
@ -536,6 +536,8 @@ typedef struct bNodeLink {
|
|||
|
||||
/** Panel in node tree for grouping sockets. */
|
||||
typedef struct bNodeSocketPanel {
|
||||
struct bNodeSocketPanel *next, *prev;
|
||||
|
||||
char *name;
|
||||
int flag;
|
||||
int identifier;
|
||||
|
@ -605,11 +607,9 @@ typedef struct bNodeTree {
|
|||
struct PreviewImage *preview;
|
||||
|
||||
/* UI panels for sockets */
|
||||
struct bNodeSocketPanel *socket_panels_array;
|
||||
int socket_panels_num;
|
||||
ListBase socket_panels;
|
||||
int active_socket_panel;
|
||||
int next_socket_panel_identifier;
|
||||
char _pad2[4];
|
||||
|
||||
bNodeTreeRuntimeHandle *runtime;
|
||||
|
||||
|
@ -674,9 +674,6 @@ typedef struct bNodeTree {
|
|||
/** Inputs and outputs of the entire node group. */
|
||||
blender::Span<const bNodeSocket *> interface_inputs() const;
|
||||
blender::Span<const bNodeSocket *> interface_outputs() const;
|
||||
|
||||
blender::Span<bNodeSocketPanel> socket_panels() const;
|
||||
blender::MutableSpan<bNodeSocketPanel> socket_panels_for_write();
|
||||
#endif
|
||||
LukasTonne marked this conversation as resolved
Outdated
Hans Goudey
commented
`panels()` should return `Span<const bNodePanel *>`, so a `const bNodeSocket *` doesn't give you a mutable `bNodePanel`
|
||||
} bNodeTree;
|
||||
|
||||
|
|
|
@ -3188,12 +3188,9 @@ static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr,
|
|||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data;
|
||||
|
||||
if (panel != NULL) {
|
||||
const int64_t index = panel - ntree->socket_panels_array;
|
||||
if (index < 0 || index >= ntree->socket_panels_num) {
|
||||
BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface");
|
||||
return;
|
||||
}
|
||||
if (panel && BLI_findindex(&ntree->socket_panels, panel) < 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface");
|
||||
return;
|
||||
}
|
||||
|
||||
ntreeSetSocketInterfacePanel(ntree, socket, panel);
|
||||
|
@ -3207,8 +3204,7 @@ static bool rna_NodeSocketInterface_panel_poll(PointerRNA *ptr, PointerRNA value
|
|||
return true;
|
||||
LukasTonne marked this conversation as resolved
Outdated
Hans Goudey
commented
Super picky but this newline isn't helpful IMO, better to more closely connect the variable declaration and the null check. Super picky but this newline isn't helpful IMO, better to more closely connect the variable declaration and the null check.
|
||||
}
|
||||
|
||||
const int64_t index = panel - ntree->socket_panels_array;
|
||||
if (index < 0 || index >= ntree->socket_panels_num) {
|
||||
if (BLI_findindex(&ntree->socket_panels, panel) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3387,13 +3383,7 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree,
|
|||
int from_index,
|
||||
int to_index)
|
||||
{
|
||||
if (from_index < 0 || from_index >= ntree->socket_panels_num || to_index < 0 ||
|
||||
to_index >= ntree->socket_panels_num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ntreeMoveSocketPanel(ntree, &ntree->socket_panels_array[from_index], to_index);
|
||||
ntreeMoveSocketPanel(ntree, from_index, to_index);
|
||||
|
||||
BKE_ntree_update_tag_interface(ntree);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
|
@ -3403,12 +3393,7 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree,
|
|||
static PointerRNA rna_NodeTree_active_socket_panel_get(PointerRNA *ptr)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->data;
|
||||
bNodeSocketPanel *panel = NULL;
|
||||
if (ntree->active_socket_panel >= 0 &&
|
||||
ntree->active_socket_panel < ntree->socket_panels_num)
|
||||
{
|
||||
panel = &ntree->socket_panels_array[ntree->active_socket_panel];
|
||||
}
|
||||
bNodeSocketPanel *panel = BLI_findlink(&ntree->socket_panels, ntree->active_socket_panel);
|
||||
|
||||
PointerRNA r_ptr;
|
||||
RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketPanel, panel, &r_ptr);
|
||||
|
@ -3421,7 +3406,7 @@ static void rna_NodeTree_active_socket_panel_set(PointerRNA *ptr,
|
|||
{
|
||||
bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data;
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->data;
|
||||
ntree->active_socket_panel = panel - ntree->socket_panels_array;
|
||||
ntree->active_socket_panel = BLI_findindex(&ntree->socket_panels, panel);
|
||||
}
|
||||
|
||||
/* ******** Node Types ******** */
|
||||
|
@ -13350,7 +13335,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, NC_NODE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "socket_panels", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "socket_panels_array", "socket_panels_num");
|
||||
RNA_def_property_collection_sdna(prop, NULL, "socket_panels", NULL);
|
||||
RNA_def_property_struct_type(prop, "NodeSocketPanel");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
Loading…
Reference in New Issue
IMO
__func__
for the allocation string is nicer than specifying one manually. It just takes up less visual space. I've also seen other developers preferring that too.