Tools

“Tools” are described in detail in the VisIt Users Manual. They are defined as “an object that can be added to a visualization window to set attributes for certain plots and operators”. Tools also provide the capability for “linked views” as the tools between multiple windows can be locked, although this is not described in the Users Manual.

This page describes how to make a plot or operator be affected by a tool.

Attributes

Attributes tell plots and operators how to do their job. For example, attributes for a slice operator would include the plane definition, such as an origin for the plane and its normal. As an example for plots, the vector plot's attributes would contain directions for how to thin the vector field, as well as directions for how to color it.

Attributes are implemented as C++ classes. Each plot or operator has its own class for its attributes, for example SliceAttributes or VectorAttributes, which are located in the directory for its respective plugin. Each of these attributes inherits from the base class AttributeSubject, which provides the machinery for publish/subscribe communication.

There are three ways to modify the value of a plugin's attributes:

  • When the user modifies the Plot Attribute or Operator Attribute windows in the gui, they are causing the values of the plugins attributes object (e.g. SliceAttributes, VectorAttributes) to change.
  • Users can also change the attributes using the SetPlotOptions or SetOperatorOptions methods in the cli.
  • Tools can directly modify the attributes.

The attributes for a tool versus the attributes for a plugin

Tools are typically not specific to plugins. That is, there is a plane tool, but that tool is divorced from, and different from, the slice operator. The plane tool's attributes have a origin, normal, and up axis. The slice operator's attributes have that information, as well as additional attributes, such as a Boolean for whether the slice should be projected to two dimensions and many alternate ways of specifying an origin. (Note that this explanation is a bit oversimplified in terms of the details of the attributes, keeping in mind that its purpose is to motivate that tools and plugins have similar yet different attributes.)

How to create a new type of tool or modify an existing tool's behavior

Brad: help!

What happens when you modify a tool

When you modify a tool, a callback gets sent to the ViewerWindowManager. This callback gets sent to the correct window with an argument of type “avtToolInterface”. For each plot in the window, the method ViewerPlot::HandleTool is called. This method takes the tool attributes and calls SetPlotAtts for the plot and SetOperatorAtts for each of the plot's operators. Of course, the attributes being sent in are the attributes for the tool, not the attributes for the plugin. Note that this section describes existing VisIt infrastructure. If you simply want to hook up a plugin with a tool, then this section is simply informative and contains no actionable items.

Making tool attributes modify plugin attributes

The SetPlotAtts and SetOperatorAtts ultimately get to your plugin by trying to set the plugin's attributes. This will come in the form of calling either CopyAttributes or CreateCompatible for your plugin attribute. VisIt automatically code-generated these methods when it made the plugin. You will have to override these definitions. Do this using xmledits option to override methods. Go to the Functions tab and click on New. Make the Name be CopyAttributes, select "Replaces builtin", check "Class member" to on, make the Declaration be:

virtual bool CopyAttributes(const AttributeGroup *);

and then set the definition to something like:

bool
SliceAttributes::CopyAttributes(const AttributeGroup *atts)
{
   bool retval = false;
   if(TypeName() == atts->TypeName())
   {
       // Call assignment operator.
       const SliceAttributes *tmp = (const SliceAttributes *)atts;
       *this = *tmp;
       retval = true;
   }
   else if(atts->TypeName() == "PlaneAttributes")
   {
       const PlaneAttributes *tmp = (const PlaneAttributes *)atts;
       SetOriginPoint(tmp->GetOrigin());
       SetOriginType(Point);
       SetNormal(tmp->GetNormal());
       SetUpAxis(tmp->GetUpAxis());
       SetAxisType(Arbitrary);
       retval = true;
       }
   }
   return retval;
}

Similarly, you'll need to override CreateCompatible. The Name is "CreateCompatible" and the Declaration is:

virtual AttributeSubject *CreateCompatible(const std::string &) const;

The rest of the options are the same as those for CopyAttributes.

CreateCompatible's definition should be something like:

AttributeSubject *
SliceAttributes::CreateCompatible(const std::string &tname) const
{
   AttributeSubject *retval = 0;
   if(TypeName() == tname)
   {
       retval = new SliceAttributes(*this);
   }
   else if(tname == "PlaneAttributes")
   {
       PlaneAttributes *p = new PlaneAttributes;
       p->SetOrigin(GetOriginPoint());
       p->SetNormal(GetNormal());
       p->SetUpAxis(GetUpAxis());
       p->SetThreeSpace(!GetProject2d());
       retval = p;
   }
   return retval;
}

If you redefine the CopyAttributes and CreateCompatible methods, then tool modifications should affect your plugin.

Finally, note that it is possible to allow the user to control whether or not the tool affects your plugin. The slice operator, for example, has an interactive button. It only accepts the plane attributes if the variable "interactive" is set to true:

bool
SliceAttributes::CopyAttributes(const AttributeGroup *atts)
{
   ...
   else if(atts->TypeName() == "PlaneAttributes")
   {
       if(interactive) // <<-- Here's the magic
       {
           const PlaneAttributes *tmp = (const PlaneAttributes *)atts;
           SetOriginPoint(tmp->GetOrigin());
           SetOriginType(Point);
           ...
       }
   }
   ...
}


Future documentation

This page contains more ideas about what should go in this page.