text: /*
   * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
   *
   * This file is part of Orfeo Toolbox
   *
   *     https://www.orfeo-toolbox.org/
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  #ifndef otbPointSetSource_h
  #define otbPointSetSource_h
  
  
  #include "itkProcessObject.h"
  
  namespace otb
  {
  /** \class PointSetSource
   *  \brief Base class for all process objects that output point set data.
   *
   * PointSetSource is the base class for all process objects that output
   * point set data. Specifically, this class defines the GetOutput() method
   * that returns a pointer to the output point set. The class also defines
   * some internal private data members that are used to manage streaming
   * of data.
   *
   * \ingroup DataSources
   *
   * \ingroup OTBPointSet
   */
  
  template <class TOutputPointSet>
  class ITK_EXPORT PointSetSource : public itk::ProcessObject
  {
  public:
    /** Standard class typedefs. */
    typedef PointSetSource                Self;
    typedef itk::ProcessObject            Superclass;
    typedef itk::SmartPointer<Self>       Pointer;
    typedef itk::SmartPointer<const Self> ConstPointer;
  
    /** Method for creation through the object factory. */
    itkNewMacro(Self);
  
    /** Run-time type information (and related methods). */
    itkTypeMacro(PointSetSource, itk::ProcessObject);
  
    /** Some convenient typedefs. */
    typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType;
    typedef itk::DataObject::Pointer                        DataObjectPointer;
    typedef TOutputPointSet                                 OutputPointSetType;
    typedef typename OutputPointSetType::Pointer            OutputPointSetPointer;
    typedef typename OutputPointSetType::PointsContainer    PointsContainerType;
    typedef typename OutputPointSetType::PointDataContainer PointDataContainerType;
  
    /** Get the point set output of this process object.  */
    OutputPointSetType * GetOutput(void);
    OutputPointSetType * GetOutput(DataObjectPointerArraySizeType idx);
  
    /** Set the point set output of this process object. This call is slated
     * to be removed from ITK. You should GraftOutput() and possible
     * DataObject::DisconnectPipeline() to properly change the output. */
    void SetOutput(OutputPointSetType *output);
    using Superclass::SetOutput;
  
    /** Graft the specified DataObject onto this ProcessObject's output.
     * This method grabs a handle to the specified DataObject's bulk
     * data to used as its output's own bulk data. It also copies the
     * region ivars (RequestedRegion, BufferedRegion,
     * LargestPossibleRegion) and meta-data (Spacing, Origin) from the
     * specified data object into this filter's output data object. Most
     * importantly, however, it leaves the Source ivar untouched so the
     * original pipeline routing is intact. This method is used when a
     * process object is implemented using a mini-pipeline which is
     * defined in its GenerateData() method.  The usage is:
     *
     * \code
     *    // setup the mini-pipeline to process the input to this filter
     *    firstFilterInMiniPipeline->SetInput( this->GetInput() );
     *
     *    // setup the mini-pipeline to calculate the correct regions
     *    // and write to the appropriate bulk data block
     *    lastFilterInMiniPipeline->GraftOutput( this->GetOutput() );
     *
     *    // execute the mini-pipeline
     *    lastFilterInMiniPipeline->Update();
     *
     *    // graft the mini-pipeline output back onto this filter's output.
     *    // this is needed to get the appropriate regions passed back.
     *    this->GraftOutput( lastFilterInMiniPipeline->GetOutput() );
     * \endcode
     *
     * For proper pipeline execution, a filter using a mini-pipeline
     * must implement the GenerateInputRequestedRegion(),
     * GenerateOutputRequestedRegion(), GenerateOutputInformation() and
     * EnlargeOutputRequestedRegion() methods as necessary to reflect
     * how the mini-pipeline will execute (in other words, the outer
     * filter's pipeline mechanism must be consistent with what the
     * mini-pipeline will do). */
    virtual void GraftOutput(itk::DataObject *output);
    virtual void GraftNthOutput(DataObjectPointerArraySizeType idx, itk::DataObject *output);
  
    /** Make a DataObject of the correct type to used as the specified
     * output.  Every ProcessObject subclass must be able to create a
     * DataObject that can be used as a specified output. This method
     * is automatically called when DataObject::DisconnectPipeline() is
     * called.  DataObject::DisconnectPipeline, disconnects a data object
     * from being an output of its current source.  When the data object
     * is disconnected, the ProcessObject needs to construct a replacement
     * output data object so that the ProcessObject is in a valid state.
     * So DataObject::DisconnectPipeline eventually calls
     * ProcessObject::MakeOutput. Note that MakeOutput always returns a
     * SmartPointer to a DataObject. If a subclass of MeshSource has
     * multiple outputs of different types, then that class must provide
     * an implementation of MakeOutput(). */
    DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override;
    using Superclass::MakeOutput;
  
  protected:
    PointSetSource();
    ~PointSetSource() override {}
    void PrintSelf(std::ostream& os, itk::Indent indent) const override;
  
    /** Requested region of Point Set is specified as i of N unstructured regions.
     * Since all DataObjects should be able to set the requested region in
     * unstructured form, just copy output->RequestedRegion all inputs. */
    void GenerateInputRequestedRegion() override;
  
  private:
    PointSetSource(const Self &) = delete;
    void operator =(const Self&) = delete;
  
    /** Used by streaming: The requested region of the output being processed
     * by the execute method. Set in the GenerateInputRequestedRegion method. */
    int m_GenerateDataRegion;
    int m_GenerateDataNumberOfRegions;
  };
  
  } // end namespace otb
  
  #ifndef OTB_MANUAL_INSTANTIATION
  #include "otbPointSetSource.hxx"
  #endif
  
  #endif
  