3.13. Naming Nodes

You can assign a name to a node, path, or engine and then search for the object by name. Because the names are preserved when the objects are written to or read from files, they are also a useful way of identifying objects. The base class SoBase SoBase SoBase provides the setName() method, which allows you to specify a name for a node, path, or engine. It also provides the getName() method, which returns the name for the given object.

Any node, path, or engine has one name, which does not have to be unique. Names can be any SbName . An SbName can start with any uppercase or lowercase letter (A-Z) or an underscore (_). All characters in an SbName must be digits 0-9, upper/lowercase A-Z, or underscores. The default name for an object is the empty string ("").

Use the SoNode SoNode SoNode method getByName() to find a node or nodes with a given name. (SoPath SoPath SoPath and SoEngine SoEngine SoEngine provide similar getByName() methods.) The search action also allows you to search for an object or objects with a given name (see Chapter 8, Applying Actions).

An example of how names might be used is a slot-car racer program that allows users to create their own slot cars, following simple conventions for how big the cars are, which direction is up, and how the standard nodes or engines in the slot cars are named. For example, the guidelines might specify that the SoTransform SoTransform SoTransform node that is the steering wheel's rotation is always named SteeringWheelRotation. The slot-car program could then read in the scene graph for a given car, search for the SteeringWheelRotation node, and then animate the steering wheel using that node.

Example 3.3, “ Naming Nodes shows naming several nodes with setName(), then using getByName() to return specific nodes. The child node named MyCube is removed from the parent named Root.

Example 3.3.  Naming Nodes

#include <Inventor/SoDB.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/sensors/SoNodeSensor.h>

void RemoveCube();  // Defined later...

main( int , char ** )
{
  SoDB::init();
  
  // Create some objects and give them names:
  SoSeparator *root = new SoSeparator;
  root->ref();
  root->setName("Root");
  
  SoCube *myCube = new SoCube;
  root->addChild(myCube);
  myCube->setName("MyCube");
  SoSphere *mySphere = new SoSphere;
  root->addChild(mySphere);
  mySphere->setName("MySphere");
  
  RemoveCube();
}

void
RemoveCube()
{
  // Remove the cube named 'MyCube' from the separator named
  // 'Root'.  In a real application, isOfType() would probably
  // be used to make sure the nodes are of the correct type
  // before doing the cast.
  
  SoSeparator *myRoot;
  myRoot = (SoSeparator *)SoNode::getByName("Root");
  
  SoCube *myCube;
  myCube = (SoCube *)SoNode::getByName("MyCube");
  
  myRoot->removeChild(myCube);
}
using OIV.Inventor.Nodes;

namespace _03_3_Naming
{
  public partial class MainForm : Form
  {
    public MainForm()
    {
      InitializeComponent();
      CreateSample();
    }

    public void CreateSample()
    {
      // Create some objects and give them names:
      SoSeparator root = new SoSeparator();

      root.SetName("Root");

      SoCube myCube = new SoCube();
      root.AddChild(myCube);
      myCube.SetName("MyCube");

      SoSphere mySphere = new SoSphere();
      root.AddChild(mySphere);
      mySphere.SetName("MySphere");

      RemoveCube();
    }

    void RemoveCube()
    {
      // Remove the cube named 'MyCube' from the separator named
      // 'Root'.  In a real application, is would probably
      // be used to make sure the nodes are of the correct type
      // before doing the cast.

      SoSeparator myRoot = (SoSeparator)SoNode.GetByName("Root");
      SoCube myCube = (SoCube)SoNode.GetByName("MyCube");

      myRoot.RemoveChild(myCube);
    }
  }
}
public void start()
{
  super.start();
  // Create some objects and give them names:
  SoSeparator root = new SoSeparator();
  root.setName("Root");
  
  SoCube myCube = new SoCube();
  root.addChild(myCube);
  myCube.setName("MyCube");
  
  SoSphere mySphere = new SoSphere();
  root.addChild(mySphere);
  mySphere.setName("MySphere");
  
  removeCube();
}

void removeCube()
{
  // Remove the cube named 'MyCube' from the separator named
  // 'Root'.  In a real application, isOfType() would probably
  // be used to make sure the nodes are of the correct type
  // before doing the cast.
  
  SoSeparator myRoot = (SoSeparator )SoNode.getByName("Root");
  SoCube myCube = (SoCube )SoNode.getByName("MyCube");
  
  myRoot.removeChild(myCube);
}