New Object View

From ParaQ Wiki
Jump to navigationJump to search

When we create a new source or filter with ParaView, we obviously want to see the object once we hit accept. With ParaView 2, there was no question as to where to put the result since there was only one place to put it. With the introduction of multiple views in ParaView 3, the appropriate view to display the pipeline object's data becomes ambiguous. ParaView 3 also supports multiple types of views, further complicating the decision making processes. Currently, the process for creating a plot from a 3D object is to create the filter, then divide up the view, then assign the view type to the new view area, then finally add the new pipeline object to the view. Although explicit, that is far too many steps to establish a new plot.

Without a user mind reading device, which is not on the current feature list of ParaView 3.0, it is impossible to always accurately predict the desired behavior of the user. We must realize that, no matter what decision making processes we use, ParaView will make mistakes. With that in mind, we have two major criteria for the process of placing new objects. First, the processes should be simple. There should be few rules to the process and the rules should be intuitive (or at least make sense). Second, the result should be easy to "fix" if ParaView makes the wrong decision.

Immediately below is the proposed set of rules for placing new pipeline objects in views. The rules are to be traversed in order until an applicable one is reached. At that time the rule is applied and the process ends. Note that although the motivation for this discussion was for placing plot-type objects, these rules are designed to be generic enough for any object type.

  1. #Place the new object in the currently selected view, if possible
  2. #Place the new object in an empty view frame, if available
  3. #If the current view has nothing visible, replace it with a new view
  4. #Split the currently selected view and use the new view

The following sections are more detailed explanations of the rules as well as discussions of the ramifications and motivations for each. There is also a discussion of #corner cases for those situations in which add confusion to the interaction.

Place the new object in the currently selected view, if possible

This rule is a no-brainer. One of the views in the GUI is always selected as the "active" view. It is the view that most of the GUI components follow and where activity is supposed to take place. It would be very confusing indeed if new objects did not go into this view.

Despite the obvious nature of this rule, there are some caveats that need to be addressed.

Hiding filter inputs

It is the behavior of many filters to turn off the visibility of their input so that the new object may be seen. We should certainly follow this behavior, but we should be careful to ensure that the visibility of the input is not turned off in any other view. For example, consider the following ParaView 3 screenshot with two views both showing the same object. The view on the left is the active view.

InputVisibilityBefore.png

Now, if we were to add a clip filter, the clip filter geometry should be added to the left view and the visibility of the input should be removed from the left view. The right view should be left alone. (Note that this does not currently work like it should.)

InputVisibilityAfter.png

Input not visible in active window

We should get the same logical behavior even if the active view does not have the input visible (but another view might). Consider the previous example, except that the active (left) window does not show the data that we are filtering.

FilterNoVisInputBefore.png

When the filter completes, the active view shows the filtered data along with any other data it might have been viewing. Again, any other views remain untouched.

FilterNoVisInputAfter.png

Adding data to plots

Although all of the previous examples have to do with geometry, the rule should still be valid for plots. For example, if I have an XY-Plot view active with some probe data visible in it and then create another probe filter, the resulting data is placed in the active plot with the other data.

I can think of two open issues with this strategy. The first is that a filter like probe has a 3D widget associated with it. In the example where I want to add a second probe to an existing plot, how do I know where to put the 3D probe widget? If there is a logical place to put the 3D probe widget, what if I change the active view to use the probe filter? Will the result of the filter still go to the filter I previously made active?

The second issue is with bar charts. The current bar chart supports only one variable at a time (I think). Other bar charts (such as MS Excel) support multiple variables and we could implement something like that, but I don't know if we have a very good use case for that. Even if we did implement something like that, it's not really reasonable to assume that there will be enough consistency in the bars to group them?

If there is no way the bar chart can hold two data types, we would have to either replace the old data with the new data or declare it impossible to add to the current view and drop down to the next rule. My preference is to do the thing that is easier to correct.

Place the new object in an empty view frame, if available

This rule states that if the new object cannot be placed in the currently selected view, then ParaView should try to find a view frame that is empty. A view of the appropriate type is created in that view frame and the new object is placed inside of it.

This rule operates under the assumption that when a view is split into two view frames, the new view frame starts up as empty, with no view (render window or plot widget) assigned to it as shown in the image below. This is not the current behavior of ParaView, but probably will be once different view types are supported in the main window display. If for some reason this behavior is never implemented, then this rule is obsolete.

EmptyViewFrame.png

The choice of empty pane to use is not vital because if ParaView picks the wrong one, it is easy to correct. A simple drag to the appropriate view frame. However, their needs to be some logic for doing so, and it is always better to pick the most reasonable frame. Thus, there are two subrules for choosing the empty frame.

  1. If the current view is empty, use that. Again, this is a no-brainer.
  2. Do a depth first search, starting with the upper left. The splitting mechanism naturally creates a hierarchy of views. Doing the depth first search helps ensure new frames will be added in a general left-to-right, top-to-bottom manner, which will be natural to most people (at least in the western hemisphere).

If the current view has nothing visible, replace it with a new view

Views with nothing visible are not providing any information. Furthermore, they do not hold a lot of state worth saving. Chances are that if a view with nothing visible is active and the user creates a source or filter, the user would like the result to just go in the area of the screen selected.

This situation is most likely to happen when creating a new source or reader right after ParaView is started. When ParaView starts, it (typically) has a single 3D view.

ReplaceViewBefore.png

Now let's say we create a Mandelbrot source with the default values. This results in a 2D image that is supposed to go into a 2D view. Per this rule, the 3D view will be replaced with a 2D view, and the Mandelbrot will come up filling the view as expected.

ReplaceViewAfter.png

This rule is a new addition. Previously, the only instances of non 3D views were filters that applied to existing data. Thus, it was unlikely to encounter the need for a new view when the current is empty. However, with the new 2D view type, this will probably occur a lot when reading image data. This change address bug 7133
--Ken 17:33, 30 May 2008 (EDT)

Split the currently selected view and use the new view

If the currently selected view cannot hold the new data and there are no empty view panes to put a new view in, our final fallback is to split the current view and add the new object to the newly created view. The view should be split vertically. The top pane keeps the original view intact and takes up 2/3 of the space. The remaining 1/3 of the space on the bottom will be the new view.

For example, consider the running application with a single geometric view below.

AutoViewSplitBefore.png

Now, if the user creates a histogram filter, a new view pane is created below the currently selected (and only) view. A bar chart view is placed in the new pane and the histogram is put there. The result is shown below.

AutoViewSplitAfter.png

Although this example is the common use case, the same mechanism should work if a plot view is selected and a new filter providing geometric information is created.

Note that even if this rule does the wrong thing, that is the user did not want the current view split, it is easy and natural to correct. Just click the "x" button on the newly created view.

Note that we have since abandoned the vertical 2/3,1/3 rule for sizing the new view. It worked OK for creating one plot/histogram, but produced strange results for just about everything else. We now use a simpler scheme in which the view is split evenly in the longest dimension.
--Ken 17:13, 30 May 2008 (EDT)

Corner Cases

New 3D widgets on an invisible input

The example concerning an #input not visible in active window raises an interesting question about 3D widgets. What happens if a filter with an associated 3D widget is created when the active view does not have its input visible? I tried this in ParaView 2 and found that this situation is not supported. The 3D widget is not even drawn correctly.

We can probably get away with that in ParaView 2 since it is very rare to create a filter on an invisible object. With the multiview support ParaView 3, we are probably much more likely to run into this situation. At the very least we should sure the 3D widget is drawn correctly when possible. It may also be helpful if the filter input is temporarily displayed with the 3D widget. If we do the latter, we need to be careful to make sure that the input visibility is turned off no matter what when either accept is hit or the filter is deleted.

The problem gets more confusing when the current view is not of the correct type. In this case, there is no way to draw the 3D widget at all. One solution is to immediately create a view that can hold the 3D widget as per the rules given, but I do not recommend doing that, at least in the short term. That raises another bag of issues we would have to address for ParaView 3.0.

I think a simpler solution is to simply have the 3D widget appear in any render window view that gets selected. That gives the user the ability to switch to a different view where he/she can manipulate the 3D widget. This solution is pretty much already implemented. However, it raises another corner case about switching views in the middle of creating a new pipeline object. Of course, that issue needs to be addressed anyway.

Changing views between pipeline object creation and acceptance

Creating a new pipeline object is (usually) a two step object. First, the reader/source/filter is selected. An entry is added to the pipeline browser; the underlying VTK object is created; but the filter is not yet run and no data is displayed in a view. The user then has a chance to setup the parameters in the object inspector before hitting accept. At this time, the data is actually displayed and created.

The issue here is that in the time between object creation and the first hit of accept, the user may change the active view. This can be a feature in that it gives the user a chance to switch views to make 3D widget interaction easier. However, it opens the question of which view to put the resulting data in. Do you base your decision on the active view when the pipeline object was created or the active view when accept is first hit.

It is most appropriate to base the decision on the active view when the accept button is first hit. This decision is most consistent with other behaviors of ParaView during object creation (such as when the visibility of an input is turned off). It also is more natural for a user. In short order any user will know at what time data is added to a view. It is at that point when the decision should be made. Choosing the view at the time of accept also relieves some ambiguities. For example, what happens if the user destroys the current view between object creation and accept? That is not an issue if we choose the view after hitting accept.


Active view is not the preferred view of the source and preferred type of view already exists

Consider a case when the application already has 2 views: 1 3D render view, 1 bar-chart view. The active view is the 3D view. The user then creates a "histogram" filter and hits accept without changing the active view. What happens? Does the histogram show up in the bar-chart view even though it's not active or doesn't show up at all, or we split the active 3D view and create a new bar-chart view? Possible solution is as follows:

  1. When a source/filter is newly accepted, we first determine the peferred type of view.
  2. Once we know the view type and we've determined that the active view is not the preferred type of view, we check if a view of that type already exists.
  3. If no view of the required type exists, we create a new view as described earlier in this document.
  4. If 1 view of the required type exists, we make it the active view and make the source/filter visible in that view.
  5. If more than 1 view of the required type is present, we try to choose the first view in which the input (if any) of this filter is visible. If the input is not visible in any of the views, we simply choose the first view of the preferred type and make it the active view and make the source/filter visible in it.
When I originally wrote this document, I was using the assumption that a source would either apply to only one type of view or apply equally to multiple views. So in the example above, I assumed that the output of the histogram filter simply could not be viewed in a 3D view. Is there a use case for showing a histogram in a 3D view?
If it is necessary to allow, for example, a histogram in a 3D view, or there is some similar situation with a more clear use case (load a saved histogram from a file, but is it really a histogram?) then still not thrilled with the solution above. First, it is too complicated. The choosing mechanism should be simple so that the behavior of ParaView is predictable. Second, it's not a good idea to add an object to some other view that we have selected. No set of criteria is going to accurately predict if that is what we really want to do, and it's much more difficult to find and remove the new input from an existing view than it is to just delete an erroneously created view.
I don't think the concept of having a "preferred" view should fundamentally change the rules. They should all apply the same, except change the wording from possible to preferred. So the original three rules become:
  1. Place the new object in the currently selected view, if it is preferred.
  2. Place the new object in an empty view frame, if available.
  3. Split the currently selected view and use the new view.
If it is important to have the notion of "preferred" view (and you are probably right about this), I recommend changing removing this corner case and instead change the document to talk about preferred views.
--Ken 19:33, 1 Feb 2007 (EST)