LineInterpolator called 3 times when loop is closed
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
LineInterpolator is called 3 times when the loop is closed or when a node is deleted. I.e. if you have a rectangle and you delete a node, not only the line interpolator for the line between the neighboring nodes of deleted node are called, but the interpolator is also called for the neighboring lines of the new line. The results is, that the interpolation of the last (the closing) line is 3 times slower than the interpolation of non-closing lines.
See my email below and karthiks answer for additional information about the issue.
Hi itkvtk123:
Nice catch.
Try to re-implement the GetSpan method in vtkContourLineInterpolator. This method dictates the list of nodes that will be updated when any node is moved. This decision is to be made by each interpolator allowing it to specify the region of influence of each control point.
For instance on the vtkBezierContourLineInterpolator, this returns a pair of 4 control points, indicating that one must update the lines that lie between nodes
([n-2, n-1], [n-1, n], [n, n+1], [n+1, n+2]).
I really cannot recall why I made the span = 3 in the baseclass, vtkContourLineInterpolator, instead of 1. I don't have the time to dig into it at the moment.
However my recommendation is to just override this in your interpolator. Be sure to wrap around the indices for closed loop situations, just as is done here.
Dean made some changes here too....
1.5 (karthik 08-Feb-07): void vtkContourLineInterpolator::GetSpan( int nodeIndex, 1.5 (karthik 08-Feb-07): vtkIntArray *nodeIndices, 1.5 (karthik 08-Feb-07): vtkContourRepresentation *rep) 1.5 (karthik 08-Feb-07): { 1.6 (dean 21-Aug-08): int start = nodeIndex - 1; 1.6 (dean 21-Aug-08): int end = nodeIndex; 1.6 (dean 21-Aug-08): int index[2]; 1.5 (karthik 08-Feb-07): 1.5 (karthik 08-Feb-07): // Clear the array 1.5 (karthik 08-Feb-07): nodeIndices->Reset(); 1.5 (karthik 08-Feb-07): nodeIndices->Squeeze(); 1.5 (karthik 08-Feb-07): nodeIndices->SetNumberOfComponents(2); 1.5 (karthik 08-Feb-07): 1.6 (dean 21-Aug-08): for ( int i = 0; i < 3; i++ ) 1.5 (karthik 08-Feb-07): { 1.6 (dean 21-Aug-08): index[0] = start++; 1.6 (dean 21-Aug-08): index[1] = end++; 1.6 (dean 21-Aug-08): 1.6 (dean 21-Aug-08): if ( rep->GetClosedLoop() ) 1.5 (karthik 08-Feb-07): { 1.6 (dean 21-Aug-08): if ( index[0] < 0 ) 1.6 (dean 21-Aug-08): { 1.6 (dean 21-Aug-08): index[0] += rep->GetNumberOfNodes(); 1.6 (dean 21-Aug-08): } 1.6 (dean 21-Aug-08): if ( index[1] < 0 ) 1.6 (dean 21-Aug-08): { 1.6 (dean 21-Aug-08): index[1] += rep->GetNumberOfNodes(); 1.6 (dean 21-Aug-08): } 1.6 (dean 21-Aug-08): if ( index[0] >= rep->GetNumberOfNodes() ) 1.6 (dean 21-Aug-08): { 1.6 (dean 21-Aug-08): index[0] -= rep->GetNumberOfNodes(); 1.6 (dean 21-Aug-08): } 1.6 (dean 21-Aug-08): if ( index[1] >= rep->GetNumberOfNodes() ) 1.6 (dean 21-Aug-08): { 1.6 (dean 21-Aug-08): index[1] -= rep->GetNumberOfNodes(); 1.6 (dean 21-Aug-08): } 1.5 (karthik 08-Feb-07): } 1.6 (dean 21-Aug-08): 1.6 (dean 21-Aug-08): if ( index[0] >= 0 && index[0] < rep->GetNumberOfNodes() && 1.6 (dean 21-Aug-08): index[1] >= 0 && index[1] < rep->GetNumberOfNodes() ) 1.5 (karthik 08-Feb-07): { 1.6 (dean 21-Aug-08): nodeIndices->InsertNextTupleValue( index ); 1.5 (karthik 08-Feb-07): } 1.5 (karthik 08-Feb-07): }
Please also file a bug report copy pasting this email thread, so we don't lose track of it.
Thanks
k
On Thu, Oct 29, 2009 at 1:55 PM, wrote:
Hi vtkusers,
why is the LineInterpolator called 3 times, when the loop gets closed using vtkContourWidget? In my opinion, it should be called only once, for the line between the current point and the last point (= first point in closed loop). But in reality, the LineInterpolator is not only called for this line, but also for the neighboring lines. Thus, the interpolator is called 3 times.
The same happens, when you draw a rectangle and you delete one node (so you have a triangle now). Instead of just calling the line interpolator once (for the line between the neighboring points of the deleted node), the interpolator is again called 3 times (for the new line and the neighboring lines of the new line).
I do not understand this behaviour. Is it a bug or is it a feature? In case it is a feature, what is the sense of it and in which scenario is the current implementation beneficial?
Minimal code example to see how often the interpolator is called:
#include "vtkImageViewer2.h" #include "vtkRenderWindowInteractor.h" #include "vtkContourWidget.h" #include "vtkContourLineInterpolator.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkPNGReader.h"
class MyInterpolator : public vtkContourLineInterpolator { public: static MyInterpolator* New() { return new MyInterpolator; }
int InterpolateLine(vtkRenderer* ren, vtkContourRepresentation* rep,
int idx1, int idx2) { if(rep->GetClosedLoop()) { cout << "closed loop - interpolating line..." << endl; } else { cout << "open loop - interpolating line..." << endl; } return 0; } };
int main() { //Setting up Viewer vtkImageViewer2* viewer = vtkImageViewer2::New(); vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New(); viewer->SetupInteractor(iren);
//Load Image into Viewer vtkPNGReader* reader = vtkPNGReader::New(); reader->SetFileName("BrainProtonDensitySlice.png"); reader->Update(); viewer->SetInput(reader->GetOutput()); //Setting up Contour Widget vtkContourWidget* widget = vtkContourWidget::New(); vtkOrientedGlyphContourRepresentation* rep =
vtkOrientedGlyphContourRepresentation::New(); widget->SetRepresentation(rep); widget->SetCurrentRenderer(viewer->GetRenderer()); widget->SetInteractor(iren);
//Setting up Line Interpolator rep->SetLineInterpolator(MyInterpolator::New()); //Start Interaction widget->On(); viewer->Render(); iren->Start();
}
Thank you so much