[Bf-blender-cvs] [600fb28b629] master: Geometry Nodes: active modifier + geometry nodes editor

Hans Goudey noreply at git.blender.org
Wed Dec 2 15:54:36 CET 2020


Commit: 600fb28b629598af2537c542e7f3f76ba0e94389
Author: Hans Goudey
Date:   Wed Dec 2 13:35:07 2020 +0100
Branches: master
https://developer.blender.org/rB600fb28b629598af2537c542e7f3f76ba0e94389

Geometry Nodes: active modifier + geometry nodes editor

This commit adds functions to set and get the object's active
modifier, which is stored as a flag in the ModifierData struct,
similar to constraints. This will be used to set the context in
the node editor. There are no visible changes in this commit.

Similar to how the node editor context works for materials, this commit
makes the node group displayed in the node editor depend on the active
object and its active modifier. To keep the node group from changing,
just pin the node group in the header.

* Shortcuts performed while there is an active modifier will affect
  only that modifier (the exception is the A to expand the modifiers).
* Clicking anywhere on the empty space in a modifier's panel will make it active.

These changes require some refactoring of object modifier code. First
is splitting up the modifier property invoke callback, which now needs
to be able to get the active modifier separately from the hovered
modifier for the different operators.

Second is a change to removing modifiers, where there is now a separate
function to remove a modifier from an object's list, in order to handle
changing the active.

Finally, the panel handler needs a small tweak so that this "click in panel"
event can be handled afterwards.

===================================================================

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/blenkernel/BKE_modifier.h
M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/BKE_screen.h
M	source/blender/blenkernel/intern/fluid.c
M	source/blender/blenkernel/intern/modifier.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/particle.c
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/editors/object/object_data_transfer.c
M	source/blender/editors/object/object_hook.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_ops.c
M	source/blender/editors/object/object_relations.c
M	source/blender/editors/space_buttons/buttons_context.c
M	source/blender/editors/space_node/space_node.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesdna/DNA_object_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/modifiers/intern/MOD_ui_common.c
M	source/blender/nodes/geometry/node_geometry_tree.cc

===================================================================

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 20755fcf856..8171b9ce1a4 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -742,6 +742,7 @@ def km_property_editor(_params):
         ("buttons.start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
         ("buttons.clear_filter", {"type": 'F', "value": 'PRESS', "alt": True}, None),
         # Modifier panels
+        ("object.modifier_set_active", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
         ("object.modifier_remove", {"type": 'X', "value": 'PRESS'}, {"properties": [("report", True)]}),
         ("object.modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}),
         ("object.modifier_copy", {"type": 'D', "value": 'PRESS', "shift": True}, None),
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 2491f0953c0..b0a7d89e3d8 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -407,6 +407,7 @@ struct ModifierData *BKE_modifier_new(int type);
 
 void BKE_modifier_free_ex(struct ModifierData *md, const int flag);
 void BKE_modifier_free(struct ModifierData *md);
+void BKE_modifier_remove_from_list(struct Object *ob, struct ModifierData *md);
 
 /* Generate new UUID for the given modifier. */
 void BKE_modifier_session_uuid_generate(struct ModifierData *md);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 28c912a4c9a..a620d9af946 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -77,6 +77,10 @@ bool BKE_object_shaderfx_use_time(struct Object *ob, struct ShaderFxData *md);
 
 bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifier_type);
 
+/* Active modifier. */
+void BKE_object_modifier_set_active(struct Object *ob, struct ModifierData *md);
+struct ModifierData *BKE_object_active_modifier(const struct Object *ob);
+
 bool BKE_object_copy_modifier(struct Object *ob_dst,
                               const struct Object *ob_src,
                               struct ModifierData *md);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 68c341692c2..dea9884f508 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -251,6 +251,11 @@ typedef struct PanelType {
   /* draw entirely, view changes should be handled here */
   void (*draw)(const struct bContext *C, struct Panel *panel);
 
+  /**
+   * Identifier of a boolean property of the panel custom data. Used to draw a highlighted border.
+   */
+  const char *active_property;
+
   /* For instanced panels corresponding to a list: */
 
   /** Reorder function, called when drag and drop finishes. */
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 73ca490c395..1bdc2a5dfd2 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -4559,7 +4559,7 @@ void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_typ
     if (psys->part->type == particle_type) {
       /* clear modifier */
       pfmd = psys_get_modifier(ob, psys);
-      BLI_remlink(&ob->modifiers, (ModifierData *)pfmd);
+      BKE_modifier_remove_from_list(ob, (ModifierData *)pfmd);
       BKE_modifier_free((ModifierData *)pfmd);
 
       /* clear particle system */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 3c8b685a0e0..c9bdaecfa2a 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -212,6 +212,26 @@ void BKE_modifier_free(ModifierData *md)
   BKE_modifier_free_ex(md, 0);
 }
 
+/**
+ * Use instead of `BLI_remlink` when the object's active modifier should change.
+ */
+void BKE_modifier_remove_from_list(Object *ob, ModifierData *md)
+{
+  BLI_assert(BLI_findindex(&ob->modifiers, md) != -1);
+
+  if (md->flag & eModifierFlag_Active) {
+    /* Prefer the previous modifier but use the next if this modifier is the first in the list. */
+    if (md->next != NULL) {
+      BKE_object_modifier_set_active(ob, md->next);
+    }
+    else if (md->prev != NULL) {
+      BKE_object_modifier_set_active(ob, md->prev);
+    }
+  }
+
+  BLI_remlink(&ob->modifiers, md);
+}
+
 void BKE_modifier_session_uuid_generate(ModifierData *md)
 {
   md->session_uuid = BLI_session_uuid_generate();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 31d2e3738f4..d747da2213e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1274,6 +1274,46 @@ void BKE_object_modifier_gpencil_hook_reset(Object *ob, HookGpencilModifierData
   }
 }
 
+/**
+ * Set the object's active modifier.
+ *
+ * \param md: If NULL, only clear the active modifier, otherwise
+ * it must be in the #Object.modifiers list.
+ */
+void BKE_object_modifier_set_active(Object *ob, ModifierData *md)
+{
+  LISTBASE_FOREACH (ModifierData *, md_iter, &ob->modifiers) {
+    md_iter->flag &= ~eModifierFlag_Active;
+  }
+
+  if (md != NULL) {
+    BLI_assert(BLI_findindex(&ob->modifiers, md) != -1);
+    md->flag |= eModifierFlag_Active;
+  }
+}
+
+ModifierData *BKE_object_active_modifier(const Object *ob)
+{
+  /* In debug mode, check for only one active modifier. */
+#ifndef NDEBUG
+  int active_count = 0;
+  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+    if (md->flag & eModifierFlag_Active) {
+      active_count++;
+    }
+  }
+  BLI_assert(ELEM(active_count, 0, 1));
+#endif
+
+  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+    if (md->flag & eModifierFlag_Active) {
+      return md;
+    }
+  }
+
+  return NULL;
+}
+
 bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
 {
   const ModifierTypeInfo *mti;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 0b331fb88d2..d516de535f9 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -4046,7 +4046,7 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob
   /* Clear modifier, skip empty ones. */
   psmd = psys_get_modifier(ob, psys);
   if (psmd) {
-    BLI_remlink(&ob->modifiers, psmd);
+    BKE_modifier_remove_from_list(ob, (ModifierData *)psmd);
     BKE_modifier_free((ModifierData *)psmd);
   }
 
@@ -5401,7 +5401,7 @@ void BKE_particle_system_blend_read_lib(BlendLibReader *reader,
     else {
       /* particle modifier must be removed before particle system */
       ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
-      BLI_remlink(&ob->modifiers, psmd);
+      BKE_modifier_remove_from_list(ob, (ModifierData *)psmd);
       BKE_modifier_free((ModifierData *)psmd);
 
       BLI_remlink(particles, psys);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 5cfaafeec2c..d1e5bbcb536 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -45,6 +45,8 @@
 #include "BKE_context.h"
 #include "BKE_screen.h"
 
+#include "RNA_access.h"
+
 #include "BLF_api.h"
 
 #include "WM_api.h"
@@ -90,6 +92,8 @@ typedef enum uiPanelRuntimeFlag {
    * position. Unlike #PANEL_STATE_ANIMATION, this is applied to sub-panels as well.
    */
   PANEL_IS_DRAG_DROP = (1 << 10),
+  /** Draw a border with the active color around the panel. */
+  PANEL_ACTIVE_BORDER = (1 << 11),
 } uiPanelRuntimeFlag;
 
 /* The state of the mouse position relative to the panel. */
@@ -579,6 +583,22 @@ static void set_panels_list_data_expand_flag(const bContext *C, const ARegion *r
 /** \name Panels
  * \{ */
 
+static bool panel_use_active_highlight(const Panel *panel)
+{
+  /* The caller should make sure the panel is active and has a type. */
+  BLI_assert(UI_panel_is_active(panel));
+  BLI_assert(panel->type != NULL);
+
+  if (panel->type->active_property) {
+    PointerRNA *ptr = UI_panel_custom_data_get(panel);
+    if (ptr != NULL && !RNA_pointer_is_null(ptr)) {
+      return RNA_boolean_get(ptr, panel->type->active_property);
+    }
+  }
+
+  return false;
+}
+
 /**
  * Set flag state for a panel and its sub-panels.
  */
@@ -1062,6 +1082,40 @@ static void panel_title_color_get(const Panel *panel,
   }
 }
 
+static void panel_draw_highlight_border(const Panel *panel,
+                                        const rcti *rect,
+                                        const rcti *header_rect)
+{
+  const bool draw_box_style = panel->type->flag & PANEL_TYPE_DRAW_BOX;
+  const bool is_subpanel = panel->type->parent != NULL;
+  if (is_subpanel) {
+    return;
+  }
+
+  float radius;
+  if (draw_box_style) {
+    /* Use the theme for box widgets. */
+    const uiWidgetColors *box_wcol = &UI_GetTheme()->tui.wcol_box;
+    UI_draw_roundbox_corner_set(UI_CNR_ALL);
+    radius = box_wcol->roundness * U.widget_unit;
+  }
+  else {
+    UI_draw_roundbox_corner_set(UI_CNR_NONE);
+    radius = 0.0f;
+  }
+
+  /* Abuse the property search theme color for now. */
+  float color[4];
+  UI_GetThemeColor4fv(TH_MATCH, color);
+  UI_draw_roundbox_aa(false,
+                      rect->xmin,
+                      UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin,
+                      rect->xmax,
+                      header_rect->ymax,
+                      radius,
+                      color);
+}
+
 static void panel_draw_aligned_widgets(const uiStyle *style,
                                        const Panel *panel,
                                        const rcti *header_rect,
@@ -1287,6 +1341,10 @@ void ui_draw_aligned_panel(const uiStyle *style,
                                show_background,
                                region_search_filter_active);
   }
+
+  if (panel_use_active_highlight(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list