<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jun 28, 2016 at 12:04 PM, Elvis Stansvik <span dir="ltr"><<a href="mailto:elvis.stansvik@orexplore.com" target="_blank">elvis.stansvik@orexplore.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>So my question is: What is the proper way of "unhooking" (or "disabling" if you will) a pipeline? I want the render window to simply show empty space when in this state, but still have the entire pipeline intact and ready for when I next want to set the filename of the reader to a valid volume.</div></div></blockquote><div><br></div><div>I've found it convenient to build the pipeline in segments, with shallow copies as necessary to connect the segments.</div><div><br></div><div>For example, the reader is handled like this (drastically simplified code):</div><div><br></div><div>void ReadImage(vtkImageData *data, const char *filename)</div><div>{</div><div>  vtkSmartPointer<vtkImageReader2> reader = vtkSmartPointer<vtkImageReader2>::New();</div><div>  reader->SetFileName(filename); </div><div>  reader->Update();</div><div><br></div><div>  vtkImageData *image = reader->GetOutput();</div><div><br></div><div>  // shallow copy the data into the supplied data object</div><div>  data->CopyStructure(image);</div><div>  data->GetPointData()->PassData(image->GetPointData());</div><div>}</div><div><br></div><div>My app has a data management structure (i.e. an object) that contains a list of all the images that the app needs.  So to read a new file, I create a new vtkImageData object, call the above function to populate it via the reader, and then I connect it to the rest of my pipeline.  The reader object is temporary.  By doing my code like this, it's easy to support a broad range of readers.</div><div><br></div><div>Most processing pipelines are done the same way: they exist just long enough to generate an output.  Afterwards, the filter objects are deleted and only the output is kept (via a shallow copy done with the CopyStructure()/PassData() calls above).</div><div><br></div><div>Display pipelines (e.g. pipelines that terminate with a mapper) have a longer life: when I need to display a new data set, I generate the display pipeline as well as its actors, then I connect an input and add the actors to the renderer.  When I unload a data set, I also remove the actors. I have a class for each display pipeline that I need, and objects of these class are instantiated and destructed when data is loaded or unloaded.  Having as much of your program logic as possible tied to object construction/destruction helps to simplify things.</div><div><br></div><div>Interactive processing pipelines (as opposed to the run-once pipelines) are temporarily connected to a display pipeline via the usual AddInputConnection() mechanism, but when the interaction is complete the following is done: 1) the connection is broken with e.g. RemoveAllInputConnections(), 2) the output is shallow-copied into a new data object with the CopyStructure()/PassData() calls and the processing pipeline is deleted, and 3) the copy is connected directly to the display pipeline (and generally stored in my data management structure, as well).</div><div><br></div><div>The general idea is that pipeline segments only exist for as long as they are being used, i.e. they are either limited to the scope of a single function, or limited to the lifetime of a specific object. This helps to reduce the overall resource usage of the application.</div><div><br></div><div> - David</div><div><br></div></div></div></div>