Node Grouping Design

From K-3D

Jump to: navigation, search

Overview

As improvements in functionality and stability lead to increasingly complex K-3D documents, managing that complexity will grow in importance. Currently, K-3D makes no attempt to organize or group the nodes in a document - as a consequence, the user interface is limited to displaying a flattened view of every node in the document.

Although there is no mechanism to explicitly group nodes today, there are already many implicit groups:

  • The set of all nodes within a document, displayed by the Node List Panel.
  • Sets of nodes that are instances of a particular plugin type, e.g: RenderManLight.
  • Sets of nodes whose plugin types are members of the same plugin category, e.g: Category:RenderMan.
  • Sets of nodes that have the same name, or some variation on a particular name.
  • Hierarchies formed by nodes that are (recursively) connected to a particular node, and displayed by the Node History Panel.
  • Hierarchies formed by the "Parent" property of transformable nodes, which is used to point to the "logical" parent of a node in the forward/inverse kinematics sense.

Some explicit grouping / subsetting operations that will likely be useful in the near future:

  • User-defined hierarchical groups that are not related to kinematics. For example, user-defined group "spaceships" could contain individual "spaceship" groups, which could contain "hull", "turret", and "antennae" groups, etc.
  • User-defined categories. In this case a node could be a member of zero-to-many categories, without limitation.

Use-Cases

  • The user can navigate the contents of a document using the grouping mechanism of their choice.
  • Per-node lighting - RenderMan allows, and K-3D should support, enabling / disabling of lights on a per-node basis.
  • Per-node rendering - It should be possible to control which nodes are rendered by a given render engine.
  • Multi-pass rendering - Combine the above to handle N x M mapping of nodes to render engines for multipass rendering. Although we currently do some primitive multi-pass rendering for shadow maps, it won't scale up to reflection maps, global illumination, texture baking, etc.

Requirements

  • The system must support multiple, alternative, simultaneous grouping mechanisms.
  • Grouping mechanisms must be "non-intrusive" - i.e membership in a group should not be stored within nodes.
  • It should be possible to introduce new grouping mechanisms that can automatically be used within the user interface layer.

Proposal

Define an abstract interface that encapsulates a "group", k3d::inode_group, so that new mechanisms for grouping can be integrated into the system easily:

class inode_group :
  public iunknown
{
public:
  typedef std::vector<inode*> nodes_t;

  /// Returns the set of nodes that are members of the group
  virtual const nodes_t nodes() = 0;
};

k3d::inode_group can be treated as a "query" that returns some subset of nodes in the document, and "groups" would be plugins that implement k3d::inode_group. The UI would be coded to k3d::inode_group, and new searches (group plugins) could be added as-needed.

Note: there's a lot of similarity between k3d::inode_group and k3d::inode_collection, they might merge / need to be refactored.