<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPainterPolyDataMapper.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkPainterPolyDataMapper.h"

#include "vtkChooserPainter.h"
#include "vtkClipPlanesPainter.h"
#include "vtkCoincidentTopologyResolutionPainter.h"
#include "vtkCommand.h"
#include "vtkDefaultPainter.h"
#include "vtkDisplayListPainter.h"
#include "vtkGarbageCollector.h"
#include "vtkGenericVertexAttributeMapping.h"
#include "vtkHardwareSelectionPolyDataPainter.h"
#include "vtkInformation.h"
#include "vtkInformationObjectBaseKey.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkPlaneCollection.h"
#include "vtkPolyData.h"
#include "vtkPrimitivePainter.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkScalarsToColorsPainter.h"
#include "vtkStandardPolyDataPainter.h"

vtkStandardNewMacro(vtkPainterPolyDataMapper);
//-----------------------------------------------------------------------------
class vtkPainterPolyDataMapperObserver : public vtkCommand
{
public:
  static vtkPainterPolyDataMapperObserver* New()
    { return new vtkPainterPolyDataMapperObserver; }

  virtual void Execute(vtkObject* caller, unsigned long event, void*)
    {
    vtkPainter* p = vtkPainter::SafeDownCast(caller);
    if (this->Target && p && event == vtkCommand::ProgressEvent)
      {
      this->Target->UpdateProgress(p->GetProgress());
      }
    }
  vtkPainterPolyDataMapperObserver()
    {
    this->Target = 0;
    }
  vtkPainterPolyDataMapper* Target;
};

//-----------------------------------------------------------------------------
vtkPainterPolyDataMapper::vtkPainterPolyDataMapper()
{
  this->Painter = 0;

  this->PainterInformation = vtkInformation::New();

  this->Observer = vtkPainterPolyDataMapperObserver::New();
  this->Observer->Target = this;

  vtkDefaultPainter* dp = vtkDefaultPainter::New();
  this->SetPainter(dp);
  dp->Delete();

  vtkChooserPainter* cp = vtkChooserPainter::New();
  this->Painter->SetDelegatePainter(cp);
  cp->Delete();

  this->SelectionPainter = 0;
  vtkPainter* selPainter = vtkHardwareSelectionPolyDataPainter::New();
  this->SetSelectionPainter(selPainter);
  selPainter->Delete();
}

//-----------------------------------------------------------------------------
vtkPainterPolyDataMapper::~vtkPainterPolyDataMapper()
{
  this->SetPainter(NULL);
  this->SetSelectionPainter(0);
  this->Observer->Target = NULL;
  this->Observer->Delete();
  this->PainterInformation->Delete();
}

//---------------------------------------------------------------------------
void vtkPainterPolyDataMapper::MapDataArrayToVertexAttribute(
  const char* vertexAttributeName,
  const char* dataArrayName,
  int field,
  int componentno)
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    }

  if (mappings==NULL)
    {
    mappings = vtkGenericVertexAttributeMapping::New();
    this->PainterInformation->Set(
      vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE(), mappings);
    mappings->Delete();
    }

  mappings->AddMapping(
    vertexAttributeName, dataArrayName, field, componentno);
}

//---------------------------------------------------------------------------
void vtkPainterPolyDataMapper::MapDataArrayToMultiTextureAttribute(
  int unit,
  const char* dataArrayName,
  int field,
  int componentno)
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    }

  if (mappings==NULL)
    {
    mappings = vtkGenericVertexAttributeMapping::New();
    this->PainterInformation->Set(
      vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE(), mappings);
    mappings->Delete();
    }

  mappings->AddMapping(
    unit, dataArrayName, field, componentno);
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RemoveAllVertexAttributeMappings()
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    mappings->RemoveAllMappings();
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RemoveVertexAttributeMapping(
  const char* vertexAttributeName)
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    mappings->RemoveMapping(vertexAttributeName);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::SetPainter(vtkPainter* p)
{
  if (this->Painter)
    {
    this->Painter->RemoveObservers(vtkCommand::ProgressEvent, this->Observer);
    this->Painter->SetInformation(0);
    }
  vtkSetObjectBodyMacro(Painter, vtkPainter, p);

   if (this->Painter)
    {
    this->Painter->AddObserver(vtkCommand::ProgressEvent, this->Observer);
    this->Painter->SetInformation(this->PainterInformation);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::SetSelectionPainter(vtkPainter* p)
{
  if (this->SelectionPainter)
    {
    this->SelectionPainter->SetInformation(0);
    this->SelectionPainter->RemoveObservers(vtkCommand::ProgressEvent, this->Observer);
    }
  vtkSetObjectBodyMacro(SelectionPainter, vtkPainter, p);
   if (this->SelectionPainter)
    {
    this->SelectionPainter->AddObserver(vtkCommand::ProgressEvent, this->Observer);
    this->SelectionPainter->SetInformation(this->PainterInformation);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::ReportReferences(vtkGarbageCollector *collector)
{
  this->Superclass::ReportReferences(collector);
  vtkGarbageCollectorReport(collector, this->Painter, "Painter");
  vtkGarbageCollectorReport(collector, this->SelectionPainter, "SelectionPainter");
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::ReleaseGraphicsResources(vtkWindow *w)
{
  if (this->Painter)
    {
    this->Painter->ReleaseGraphicsResources(w);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::UpdatePainterInformation()
{
  vtkInformation* info = this->PainterInformation;

  info->Set(vtkPainter::STATIC_DATA(), this->Static);

  info->Set(vtkScalarsToColorsPainter::USE_LOOKUP_TABLE_SCALAR_RANGE(),
    this->GetUseLookupTableScalarRange());
  info->Set(vtkScalarsToColorsPainter::SCALAR_RANGE(),
    this->GetScalarRange(), 2);
  info->Set(vtkScalarsToColorsPainter::SCALAR_MODE(), this->GetScalarMode());
  info->Set(vtkScalarsToColorsPainter::COLOR_MODE(), this->GetColorMode());
  info->Set(vtkScalarsToColorsPainter::INTERPOLATE_SCALARS_BEFORE_MAPPING(),
    this->GetInterpolateScalarsBeforeMapping());
  info->Set(vtkScalarsToColorsPainter::LOOKUP_TABLE(), this->LookupTable);
  info->Set(vtkScalarsToColorsPainter::SCALAR_VISIBILITY(),
    this->GetScalarVisibility());
  info->Set(vtkScalarsToColorsPainter::ARRAY_ACCESS_MODE(),
    this->ArrayAccessMode);
  info->Set(vtkScalarsToColorsPainter::ARRAY_ID(), this->ArrayId);
  info->Set(vtkScalarsToColorsPainter::ARRAY_NAME(), this->ArrayName);
  info->Set(vtkScalarsToColorsPainter::ARRAY_COMPONENT(), this->ArrayComponent);
  info->Set(vtkScalarsToColorsPainter::SCALAR_MATERIAL_MODE(),
    this->GetScalarMaterialMode());

  info->Set(vtkClipPlanesPainter::CLIPPING_PLANES(), this->ClippingPlanes);

  info->Set(vtkCoincidentTopologyResolutionPainter::RESOLVE_COINCIDENT_TOPOLOGY(),
    this->GetResolveCoincidentTopology());
  info->Set(vtkCoincidentTopologyResolutionPainter::Z_SHIFT(),
    this->GetResolveCoincidentTopologyZShift());
  double p[2];
  this->GetResolveCoincidentTopologyPolygonOffsetParameters(p[0], p[1]);
  info->Set(vtkCoincidentTopologyResolutionPainter::POLYGON_OFFSET_PARAMETERS(),
    p, 2);
  info->Set(vtkCoincidentTopologyResolutionPainter::POLYGON_OFFSET_FACES(),
    this->GetResolveCoincidentTopologyPolygonOffsetFaces());

  int immr = (this->ImmediateModeRendering ||
              vtkMapper::GetGlobalImmediateModeRendering());
  info->Set(vtkDisplayListPainter::IMMEDIATE_MODE_RENDERING(), immr);
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RenderPiece(vtkRenderer* ren, vtkActor* act)
{
  vtkDataObject *input= this->GetInputDataObject(0, 0);

   vtkStandardPolyDataPainter * painter =
    vtkStandardPolyDataPainter::SafeDownCast(this->Painter);
  if (painter != NULL && vtkPolyData::SafeDownCast(input))
    {
    // FIXME: This is not supported currently for composite datasets.
    vtkInformationVector *inArrayVec =
      this->Information->Get(INPUT_ARRAYS_TO_PROCESS());
    int numArrays = inArrayVec->GetNumberOfInformationObjects();

    for(int i = 0; i < numArrays; i++)
      {
      painter->AddMultiTextureCoordsArray(this->GetInputArrayToProcess(i,input));
      }
    }

  //
  // make sure that we've been properly initialized
  //
  if (ren->GetRenderWindow()->CheckAbortStatus())
    {
    return;
    }

  if ( input == NULL )
    {
    vtkErrorMacro(<< "No input!");
    return;
    }
  else
    {
    this->InvokeEvent(vtkCommand::StartEvent,NULL);
    if (!this->Static)
      {
      input->Update();
      }
    this->InvokeEvent(vtkCommand::EndEvent,NULL);

    // This check is unnecessary since the mapper will be cropped out by culling
    // if it returns invalid bounds which is what will happen when input has no
    // points.
    // vtkIdType numPts = input->GetNumberOfPoints();
    // if (numPts == 0)
    //   {
    //   vtkDebugMacro(<< "No points!");
    //   return;
    //   }
    }

  // Update Painter information if obsolete.
  if (this->PainterUpdateTime < this->GetMTime())
    {
    this->UpdatePainterInformation();
    this->PainterUpdateTime.Modified();
    }

  // make sure our window is current
  ren->GetRenderWindow()->MakeCurrent();
  this->TimeToDraw = 0.0;

  // If we are rendering in selection mode, then we use the selection painter
  // instead of the standard painter.
  if (this->SelectionPainter && ren->GetSelector())
    {
    this->SelectionPainter->SetInput(input);
    this->SelectionPainter->Render(ren, act, 0xff,
      (this->ForceCompileOnly==1));
    this->TimeToDraw = this->SelectionPainter->GetTimeToDraw();
    }
  else if (this->SelectionPainter && this->SelectionPainter != this->Painter)
    {
    this->SelectionPainter->ReleaseGraphicsResources(ren->GetRenderWindow());
    }

  if (this->Painter && ren->GetSelector() == 0)
    {
    // Pass polydata.
    this->Painter->SetInput(input);
    this->Painter->Render(ren, act, 0xff,this->ForceCompileOnly==1);
    this->TimeToDraw = this->Painter->GetTimeToDraw();
    }

  // If the timer is not accurate enough, set it to a small
  // time so that it is not zero
  if ( this->TimeToDraw == 0.0 )
    {
    this->TimeToDraw = 0.0001;
    }

  this->UpdateProgress(1.0);
}

//-------------------------------------------------------------------------
void vtkPainterPolyDataMapper::ComputeBounds()
{
  this->GetInput()->GetBounds(this->Bounds);

  // if the mapper has a painter, update the bounds in the painter
  vtkPainter *painter = this->GetPainter();
  if (painter)
    {
    // Update Painter information if obsolete.
    if (this->PainterUpdateTime < this->GetMTime())
      {
      this->UpdatePainterInformation();
      this->PainterUpdateTime.Modified();
      }
    painter->UpdateBounds(this->Bounds);
    }
}

//-----------------------------------------------------------------------------
bool vtkPainterPolyDataMapper::GetIsOpaque()
{
  if (this->ScalarVisibility &&
    this->ColorMode == VTK_COLOR_MODE_DEFAULT)
    {
    vtkPolyData* input =
      vtkPolyData::SafeDownCast(this->GetInputDataObject(0, 0));
    if (input)
      {
      int cellFlag;
      vtkDataArray* scalars = this->GetScalars(input,
        this->ScalarMode, this->ArrayAccessMode, this->ArrayId,
        this->ArrayName, cellFlag);
      if (scalars && scalars->IsA("vtkUnsignedCharArray") &&
        (scalars->GetNumberOfComponents() ==  4 /*(RGBA)*/ ||
         scalars->GetNumberOfComponents() == 2 /*(LuminanceAlpha)*/))
        {
        vtkUnsignedCharArray* colors =
          static_cast<vtkUnsignedCharArray*>(scalars);
        if ((colors->GetNumberOfComponents() == 4 && colors->GetValueRange(3)[0] < 255) ||
          (colors->GetNumberOfComponents() == 2 && colors->GetValueRange(1)[0] < 255))
          {
          // If the opacity is 255, despite the fact that the user specified
          // RGBA, we know that the Alpha is 100% opaque. So treat as opaque.
          return false;
          }
        }
      }
    }
  return this->Superclass::GetIsOpaque();
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Painter: " ;
  if (this->Painter)
    {
    os << endl;
    this->Painter->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << indent << "(none)" << endl;
    }
  os << indent << "SelectionPainter: " << this->SelectionPainter << endl;
}
<commit_msg>COMP: Removed another unused header.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPainterPolyDataMapper.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkPainterPolyDataMapper.h"

#include "vtkChooserPainter.h"
#include "vtkClipPlanesPainter.h"
#include "vtkCoincidentTopologyResolutionPainter.h"
#include "vtkCommand.h"
#include "vtkDefaultPainter.h"
#include "vtkDisplayListPainter.h"
#include "vtkGarbageCollector.h"
#include "vtkGenericVertexAttributeMapping.h"
#include "vtkHardwareSelectionPolyDataPainter.h"
#include "vtkInformation.h"
#include "vtkInformationObjectBaseKey.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPlaneCollection.h"
#include "vtkPolyData.h"
#include "vtkPrimitivePainter.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkScalarsToColorsPainter.h"
#include "vtkStandardPolyDataPainter.h"

vtkStandardNewMacro(vtkPainterPolyDataMapper);
//-----------------------------------------------------------------------------
class vtkPainterPolyDataMapperObserver : public vtkCommand
{
public:
  static vtkPainterPolyDataMapperObserver* New()
    { return new vtkPainterPolyDataMapperObserver; }

  virtual void Execute(vtkObject* caller, unsigned long event, void*)
    {
    vtkPainter* p = vtkPainter::SafeDownCast(caller);
    if (this->Target && p && event == vtkCommand::ProgressEvent)
      {
      this->Target->UpdateProgress(p->GetProgress());
      }
    }
  vtkPainterPolyDataMapperObserver()
    {
    this->Target = 0;
    }
  vtkPainterPolyDataMapper* Target;
};

//-----------------------------------------------------------------------------
vtkPainterPolyDataMapper::vtkPainterPolyDataMapper()
{
  this->Painter = 0;

  this->PainterInformation = vtkInformation::New();

  this->Observer = vtkPainterPolyDataMapperObserver::New();
  this->Observer->Target = this;

  vtkDefaultPainter* dp = vtkDefaultPainter::New();
  this->SetPainter(dp);
  dp->Delete();

  vtkChooserPainter* cp = vtkChooserPainter::New();
  this->Painter->SetDelegatePainter(cp);
  cp->Delete();

  this->SelectionPainter = 0;
  vtkPainter* selPainter = vtkHardwareSelectionPolyDataPainter::New();
  this->SetSelectionPainter(selPainter);
  selPainter->Delete();
}

//-----------------------------------------------------------------------------
vtkPainterPolyDataMapper::~vtkPainterPolyDataMapper()
{
  this->SetPainter(NULL);
  this->SetSelectionPainter(0);
  this->Observer->Target = NULL;
  this->Observer->Delete();
  this->PainterInformation->Delete();
}

//---------------------------------------------------------------------------
void vtkPainterPolyDataMapper::MapDataArrayToVertexAttribute(
  const char* vertexAttributeName,
  const char* dataArrayName,
  int field,
  int componentno)
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    }

  if (mappings==NULL)
    {
    mappings = vtkGenericVertexAttributeMapping::New();
    this->PainterInformation->Set(
      vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE(), mappings);
    mappings->Delete();
    }

  mappings->AddMapping(
    vertexAttributeName, dataArrayName, field, componentno);
}

//---------------------------------------------------------------------------
void vtkPainterPolyDataMapper::MapDataArrayToMultiTextureAttribute(
  int unit,
  const char* dataArrayName,
  int field,
  int componentno)
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    }

  if (mappings==NULL)
    {
    mappings = vtkGenericVertexAttributeMapping::New();
    this->PainterInformation->Set(
      vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE(), mappings);
    mappings->Delete();
    }

  mappings->AddMapping(
    unit, dataArrayName, field, componentno);
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RemoveAllVertexAttributeMappings()
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    mappings->RemoveAllMappings();
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RemoveVertexAttributeMapping(
  const char* vertexAttributeName)
{
  vtkGenericVertexAttributeMapping* mappings = 0;
  if( this->PainterInformation->Has(
      vtkPrimitivePainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()) )
    {
    mappings = vtkGenericVertexAttributeMapping::SafeDownCast(
      this->PainterInformation->Get(
        vtkPolyDataPainter::DATA_ARRAY_TO_VERTEX_ATTRIBUTE()));
    mappings->RemoveMapping(vertexAttributeName);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::SetPainter(vtkPainter* p)
{
  if (this->Painter)
    {
    this->Painter->RemoveObservers(vtkCommand::ProgressEvent, this->Observer);
    this->Painter->SetInformation(0);
    }
  vtkSetObjectBodyMacro(Painter, vtkPainter, p);

   if (this->Painter)
    {
    this->Painter->AddObserver(vtkCommand::ProgressEvent, this->Observer);
    this->Painter->SetInformation(this->PainterInformation);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::SetSelectionPainter(vtkPainter* p)
{
  if (this->SelectionPainter)
    {
    this->SelectionPainter->SetInformation(0);
    this->SelectionPainter->RemoveObservers(vtkCommand::ProgressEvent, this->Observer);
    }
  vtkSetObjectBodyMacro(SelectionPainter, vtkPainter, p);
   if (this->SelectionPainter)
    {
    this->SelectionPainter->AddObserver(vtkCommand::ProgressEvent, this->Observer);
    this->SelectionPainter->SetInformation(this->PainterInformation);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::ReportReferences(vtkGarbageCollector *collector)
{
  this->Superclass::ReportReferences(collector);
  vtkGarbageCollectorReport(collector, this->Painter, "Painter");
  vtkGarbageCollectorReport(collector, this->SelectionPainter, "SelectionPainter");
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::ReleaseGraphicsResources(vtkWindow *w)
{
  if (this->Painter)
    {
    this->Painter->ReleaseGraphicsResources(w);
    }
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::UpdatePainterInformation()
{
  vtkInformation* info = this->PainterInformation;

  info->Set(vtkPainter::STATIC_DATA(), this->Static);

  info->Set(vtkScalarsToColorsPainter::USE_LOOKUP_TABLE_SCALAR_RANGE(),
    this->GetUseLookupTableScalarRange());
  info->Set(vtkScalarsToColorsPainter::SCALAR_RANGE(),
    this->GetScalarRange(), 2);
  info->Set(vtkScalarsToColorsPainter::SCALAR_MODE(), this->GetScalarMode());
  info->Set(vtkScalarsToColorsPainter::COLOR_MODE(), this->GetColorMode());
  info->Set(vtkScalarsToColorsPainter::INTERPOLATE_SCALARS_BEFORE_MAPPING(),
    this->GetInterpolateScalarsBeforeMapping());
  info->Set(vtkScalarsToColorsPainter::LOOKUP_TABLE(), this->LookupTable);
  info->Set(vtkScalarsToColorsPainter::SCALAR_VISIBILITY(),
    this->GetScalarVisibility());
  info->Set(vtkScalarsToColorsPainter::ARRAY_ACCESS_MODE(),
    this->ArrayAccessMode);
  info->Set(vtkScalarsToColorsPainter::ARRAY_ID(), this->ArrayId);
  info->Set(vtkScalarsToColorsPainter::ARRAY_NAME(), this->ArrayName);
  info->Set(vtkScalarsToColorsPainter::ARRAY_COMPONENT(), this->ArrayComponent);
  info->Set(vtkScalarsToColorsPainter::SCALAR_MATERIAL_MODE(),
    this->GetScalarMaterialMode());

  info->Set(vtkClipPlanesPainter::CLIPPING_PLANES(), this->ClippingPlanes);

  info->Set(vtkCoincidentTopologyResolutionPainter::RESOLVE_COINCIDENT_TOPOLOGY(),
    this->GetResolveCoincidentTopology());
  info->Set(vtkCoincidentTopologyResolutionPainter::Z_SHIFT(),
    this->GetResolveCoincidentTopologyZShift());
  double p[2];
  this->GetResolveCoincidentTopologyPolygonOffsetParameters(p[0], p[1]);
  info->Set(vtkCoincidentTopologyResolutionPainter::POLYGON_OFFSET_PARAMETERS(),
    p, 2);
  info->Set(vtkCoincidentTopologyResolutionPainter::POLYGON_OFFSET_FACES(),
    this->GetResolveCoincidentTopologyPolygonOffsetFaces());

  int immr = (this->ImmediateModeRendering ||
              vtkMapper::GetGlobalImmediateModeRendering());
  info->Set(vtkDisplayListPainter::IMMEDIATE_MODE_RENDERING(), immr);
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::RenderPiece(vtkRenderer* ren, vtkActor* act)
{
  vtkDataObject *input= this->GetInputDataObject(0, 0);

   vtkStandardPolyDataPainter * painter =
    vtkStandardPolyDataPainter::SafeDownCast(this->Painter);
  if (painter != NULL && vtkPolyData::SafeDownCast(input))
    {
    // FIXME: This is not supported currently for composite datasets.
    vtkInformationVector *inArrayVec =
      this->Information->Get(INPUT_ARRAYS_TO_PROCESS());
    int numArrays = inArrayVec->GetNumberOfInformationObjects();

    for(int i = 0; i < numArrays; i++)
      {
      painter->AddMultiTextureCoordsArray(this->GetInputArrayToProcess(i,input));
      }
    }

  //
  // make sure that we've been properly initialized
  //
  if (ren->GetRenderWindow()->CheckAbortStatus())
    {
    return;
    }

  if ( input == NULL )
    {
    vtkErrorMacro(<< "No input!");
    return;
    }
  else
    {
    this->InvokeEvent(vtkCommand::StartEvent,NULL);
    if (!this->Static)
      {
      input->Update();
      }
    this->InvokeEvent(vtkCommand::EndEvent,NULL);

    // This check is unnecessary since the mapper will be cropped out by culling
    // if it returns invalid bounds which is what will happen when input has no
    // points.
    // vtkIdType numPts = input->GetNumberOfPoints();
    // if (numPts == 0)
    //   {
    //   vtkDebugMacro(<< "No points!");
    //   return;
    //   }
    }

  // Update Painter information if obsolete.
  if (this->PainterUpdateTime < this->GetMTime())
    {
    this->UpdatePainterInformation();
    this->PainterUpdateTime.Modified();
    }

  // make sure our window is current
  ren->GetRenderWindow()->MakeCurrent();
  this->TimeToDraw = 0.0;

  // If we are rendering in selection mode, then we use the selection painter
  // instead of the standard painter.
  if (this->SelectionPainter && ren->GetSelector())
    {
    this->SelectionPainter->SetInput(input);
    this->SelectionPainter->Render(ren, act, 0xff,
      (this->ForceCompileOnly==1));
    this->TimeToDraw = this->SelectionPainter->GetTimeToDraw();
    }
  else if (this->SelectionPainter && this->SelectionPainter != this->Painter)
    {
    this->SelectionPainter->ReleaseGraphicsResources(ren->GetRenderWindow());
    }

  if (this->Painter && ren->GetSelector() == 0)
    {
    // Pass polydata.
    this->Painter->SetInput(input);
    this->Painter->Render(ren, act, 0xff,this->ForceCompileOnly==1);
    this->TimeToDraw = this->Painter->GetTimeToDraw();
    }

  // If the timer is not accurate enough, set it to a small
  // time so that it is not zero
  if ( this->TimeToDraw == 0.0 )
    {
    this->TimeToDraw = 0.0001;
    }

  this->UpdateProgress(1.0);
}

//-------------------------------------------------------------------------
void vtkPainterPolyDataMapper::ComputeBounds()
{
  this->GetInput()->GetBounds(this->Bounds);

  // if the mapper has a painter, update the bounds in the painter
  vtkPainter *painter = this->GetPainter();
  if (painter)
    {
    // Update Painter information if obsolete.
    if (this->PainterUpdateTime < this->GetMTime())
      {
      this->UpdatePainterInformation();
      this->PainterUpdateTime.Modified();
      }
    painter->UpdateBounds(this->Bounds);
    }
}

//-----------------------------------------------------------------------------
bool vtkPainterPolyDataMapper::GetIsOpaque()
{
  if (this->ScalarVisibility &&
    this->ColorMode == VTK_COLOR_MODE_DEFAULT)
    {
    vtkPolyData* input =
      vtkPolyData::SafeDownCast(this->GetInputDataObject(0, 0));
    if (input)
      {
      int cellFlag;
      vtkDataArray* scalars = this->GetScalars(input,
        this->ScalarMode, this->ArrayAccessMode, this->ArrayId,
        this->ArrayName, cellFlag);
      if (scalars && scalars->IsA("vtkUnsignedCharArray") &&
        (scalars->GetNumberOfComponents() ==  4 /*(RGBA)*/ ||
         scalars->GetNumberOfComponents() == 2 /*(LuminanceAlpha)*/))
        {
        vtkUnsignedCharArray* colors =
          static_cast<vtkUnsignedCharArray*>(scalars);
        if ((colors->GetNumberOfComponents() == 4 && colors->GetValueRange(3)[0] < 255) ||
          (colors->GetNumberOfComponents() == 2 && colors->GetValueRange(1)[0] < 255))
          {
          // If the opacity is 255, despite the fact that the user specified
          // RGBA, we know that the Alpha is 100% opaque. So treat as opaque.
          return false;
          }
        }
      }
    }
  return this->Superclass::GetIsOpaque();
}

//-----------------------------------------------------------------------------
void vtkPainterPolyDataMapper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Painter: " ;
  if (this->Painter)
    {
    os << endl;
    this->Painter->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << indent << "(none)" << endl;
    }
  os << indent << "SelectionPainter: " << this->SelectionPainter << endl;
}
<|endoftext|>


<commit_before>#include <pthread.h>

#ifdef __ANDROID__
#include <unistd.h>
#endif // __ANDROID__

#include "../Include/CSoundManager.h"

namespace LM
{

	void* WaitSoundFinished(void* a_pSoundManager)
	{
		CCLOG("[SOUND] start waitSoundFinished");
		CSoundManager* pSoundManager = static_cast<CSoundManager*>(a_pSoundManager);
		CCLOG("[SOUND] after cast");
		std::string sSoundURL = pSoundManager->m_sPlayingSoundURL;
		CCLOG("[SOUND] after getting string");
		while (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
#if defined _WIN32 | defined _WIN64
			Sleep(100);
#else
			usleep(100000);
#endif
			CCLOG("[SOUND] in while");
		}
		if (sSoundURL != "")
		{
			CCLOG("[SOUND] before EndSound");
			pSoundManager->EndSound(sSoundURL);
			pSoundManager->m_sPlayingSoundURL = "";
		}
		return NULL;
	}

	CSoundManager::CSoundManager(CKernel* a_pKernel) : m_pKernel(a_pKernel), m_sPlayingSoundURL("")
	{

	}

	void CSoundManager::PlaySound(const std::string& a_rSoundURL)
	{
		m_sPlayingSoundURL = a_rSoundURL;
		CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic(a_rSoundURL.c_str(), false);
		//pthread_t thread;
		//CCLOG("[SOUND] before creating thread");
		//pthread_create(&thread, NULL, &WaitSoundFinished, this);
		//CCLOG("[SOUND] after creating thread");
	}

	void CSoundManager::PauseSound()
	{
		CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
	}

	void CSoundManager::PreloadSound(const std::string& a_rSoundURL)
	{
		CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic(a_rSoundURL.c_str());
	}

	void CSoundManager::EndSound(const std::string& a_rSoundURL)
	{
		CCLOG("[SOUND] sound ended : %s", a_rSoundURL.c_str());
	}

} // namespace LM<commit_msg>[FIX] fixed a cross platform include in CSoundManager.cpp<commit_after>#include <pthread.h>

#if !defined _WIN32 & !defined _WIN64
#include <unistd.h>
#endif

#include "../Include/CSoundManager.h"

namespace LM
{

	void* WaitSoundFinished(void* a_pSoundManager)
	{
		CCLOG("[SOUND] start waitSoundFinished");
		CSoundManager* pSoundManager = static_cast<CSoundManager*>(a_pSoundManager);
		CCLOG("[SOUND] after cast");
		std::string sSoundURL = pSoundManager->m_sPlayingSoundURL;
		CCLOG("[SOUND] after getting string");
		while (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
#if defined _WIN32 | defined _WIN64
			Sleep(100);
#else
			usleep(100000);
#endif
			CCLOG("[SOUND] in while");
		}
		if (sSoundURL != "")
		{
			CCLOG("[SOUND] before EndSound");
			pSoundManager->EndSound(sSoundURL);
			pSoundManager->m_sPlayingSoundURL = "";
		}
		return NULL;
	}

	CSoundManager::CSoundManager(CKernel* a_pKernel) : m_pKernel(a_pKernel), m_sPlayingSoundURL("")
	{

	}

	void CSoundManager::PlaySound(const std::string& a_rSoundURL)
	{
		m_sPlayingSoundURL = a_rSoundURL;
		CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic(a_rSoundURL.c_str(), false);
		//pthread_t thread;
		//CCLOG("[SOUND] before creating thread");
		//pthread_create(&thread, NULL, &WaitSoundFinished, this);
		//CCLOG("[SOUND] after creating thread");
	}

	void CSoundManager::PauseSound()
	{
		CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
	}

	void CSoundManager::PreloadSound(const std::string& a_rSoundURL)
	{
		CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic(a_rSoundURL.c_str());
	}

	void CSoundManager::EndSound(const std::string& a_rSoundURL)
	{
		CCLOG("[SOUND] sound ended : %s", a_rSoundURL.c_str());
	}

} // namespace LM
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#ifndef _Stroika_Foundation_Characters_String_inl_
#define _Stroika_Foundation_Characters_String_inl_

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include	"../Debug/Assertions.h"

namespace	Stroika {
	namespace	Foundation {
		namespace	Characters {

			class	StringRep_CharArray : public String::StringRep {
				public:
					StringRep_CharArray (const Character* arrayOfCharacters, size_t nBytes);
					~StringRep_CharArray ();

					virtual		StringRep*	Clone () const override;

					virtual		size_t	GetLength () const override;
					virtual		bool	Contains (Character item) const override;
					virtual		void	RemoveAll () override;

					virtual		Character	GetAt (size_t index) const override;
					virtual		void		SetAt (Character item, size_t index) override;
					virtual		void		InsertAt (Character item, size_t index) override;
					virtual		void		RemoveAt (size_t index, size_t amountToRemove) override;

					virtual		void	SetLength (size_t newLength) override;

					virtual		const Character*	Peek () const override;

				protected:
					StringRep_CharArray ();
					nonvirtual	void	SetStorage (Character* storage, size_t length);

				private:
					wchar_t*	fStorage;
					size_t	    fLength;
// STERLING:
// IF THIS IS PRIVATE - RENAME TO _ - AND THEN WHY VIRTUAL???? IS THAT REALLY RIGHT ?? SB PROTECTED?
//		-- LGP 2011-08-30
					virtual	size_t	CalcAllocSize (size_t requested);
			};

            inline	String::StringRep::StringRep ()
				{
				}

			inline	String::String (const String& from)
				: fRep (from.fRep)
				{
				}
            inline	String::String (const std::wstring& r)
                : fRep (&Clone_, 0)
				{
					fRep = new StringRep_CharArray ((const Character*)r.c_str (), r.length ());
				}
            inline	String&	String::operator= (const String& newString)
				{
					fRep = newString.fRep;
					return (*this);
				}
            inline	String::~String ()
				{
				}
			inline	String::StringRep*	String::Clone_ (const StringRep& rep)
				{
					return (rep.Clone ());
				}
            inline	void	String::RemoveAt (size_t i)
				{
					RemoveAt (i, 1);
				}
            inline	const Character*	String::Peek () const
				{
					return (fRep->Peek ());
				}
            inline	size_t	String::GetLength () const
				{
					return (fRep->GetLength ());
				}
            inline	Character	String::operator[] (size_t i) const
				{
					Require (i >= 0);
					Require (i < GetLength ());
					return (fRep->GetAt (i));
				}
            inline	void	String::SetRep (StringRep* rep)
				{
					fRep = rep;
				}
            inline	const String::StringRep*	String::GetRep () const
				{
					return (fRep.GetPointer ());
				}
            inline	String::StringRep*			String::GetRep ()
				{
					return (fRep.GetPointer ());
				}

			inline	bool	operator!= (const String& lhs, const String& rhs)
				{
					return (bool (not (lhs == rhs)));
				}
            inline	bool	operator!= (const wchar_t* lhs, const String& rhs)
				{
					return (bool (not (lhs == rhs)));
				}
            inline	bool	operator!= (const String& lhs, const wchar_t* rhs)
				{
					return (bool (not (lhs == rhs)));
				}
            inline	bool	operator> (const String& lhs, const String& rhs)
				{
					return (bool (not (lhs <= rhs)));
				}
            inline	bool	operator> (const wchar_t* lhs, const String& rhs)
				{
					return (bool (not (lhs <= rhs)));
				}
            inline	bool	operator> (const String& lhs, const wchar_t* rhs)
				{
					return (bool (not (lhs <= rhs)));
				}
            inline	bool	operator>= (const String& lhs, const String& rhs)
				{
					return (bool (not (lhs < rhs)));
				}
            inline	bool	operator>= (const wchar_t* lhs, const String& rhs)
				{
					return (bool (not (lhs < rhs)));
				}
            inline	bool	operator>= (const String& lhs, const wchar_t* rhs)
				{
					return (bool (not (lhs < rhs)));
				}

			inline	String_CharArray::String_CharArray (const String_CharArray& s)	: String (s)	{}
            inline	String_CharArray& String_CharArray::operator= (const String_CharArray& s)	{	String::operator= (s);	return (*this); }

			inline	String_BufferedCharArray::String_BufferedCharArray (const String_BufferedCharArray& s)	: String (s)	{}
            inline	String_BufferedCharArray& String_BufferedCharArray::operator= (const String_BufferedCharArray& s)	{	String::operator= (s);	return (*this); }

			inline	String_ReadOnlyChar::String_ReadOnlyChar (const String_ReadOnlyChar& s)	: String (s)	{}
            inline	String_ReadOnlyChar& String_ReadOnlyChar::operator= (const String_ReadOnlyChar& s)	{	String::operator= (s);	return (*this); }
		}
	}
}

#endif // _Stroika_Foundation_Characters_String_inl_
<commit_msg>massive changes, including becoming zero based and using Character more consistently, plus passes test suite<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#ifndef _Stroika_Foundation_Characters_String_inl_
#define _Stroika_Foundation_Characters_String_inl_

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include	"../Debug/Assertions.h"

namespace	Stroika {
	namespace	Foundation {
		namespace	Characters {

			class	StringRep_CharArray : public String::StringRep {
				public:
					StringRep_CharArray (const Character* arrayOfCharacters, size_t nBytes);
					~StringRep_CharArray ();

					virtual		StringRep*	Clone () const override;

					virtual		size_t	GetLength () const override;
					virtual		bool	Contains (Character item) const override;
					virtual		void	RemoveAll () override;

					virtual		Character	GetAt (size_t index) const override;
					virtual		void		SetAt (Character item, size_t index) override;
					virtual		void		InsertAt (Character item, size_t index) override;
					virtual		void		RemoveAt (size_t index, size_t amountToRemove) override;

					virtual		void	SetLength (size_t newLength) override;

					virtual		const Character*	Peek () const override;

				protected:
					StringRep_CharArray ();
					nonvirtual	void	SetStorage (Character* storage, size_t length);

				private:
					wchar_t*	fStorage;
					size_t	    fLength;
// STERLING:
// IF THIS IS PRIVATE - RENAME TO _ - AND THEN WHY VIRTUAL???? IS THAT REALLY RIGHT ?? SB PROTECTED?
//		-- LGP 2011-08-30
					virtual	size_t	CalcAllocChars (size_t requested);
			};

            inline	String::StringRep::StringRep ()
				{
				}

			inline	String::String (const String& from)
				: fRep (from.fRep)
				{
				}
            inline	String::String (const std::wstring& r)
                : fRep (&Clone_, 0)
				{
					fRep = new StringRep_CharArray ((const Character*)r.c_str (), r.length ());
				}
            inline	String&	String::operator= (const String& newString)
				{
					fRep = newString.fRep;
					return (*this);
				}
            inline	String::~String ()
				{
				}
			inline	String::StringRep*	String::Clone_ (const StringRep& rep)
				{
					return (rep.Clone ());
				}
            inline	void	String::RemoveAt (size_t i)
				{
					RemoveAt (i, 1);
				}
            inline	const Character*	String::Peek () const
				{
					return (fRep->Peek ());
				}
            inline	size_t	String::GetLength () const
				{
					return (fRep->GetLength ());
				}
            inline	Character	String::operator[] (size_t i) const
				{
					Require (i >= 0);
					Require (i < GetLength ());
					return (fRep->GetAt (i));
				}
            inline	void	String::SetRep (StringRep* rep)
				{
					fRep = rep;
				}
            inline	const String::StringRep*	String::GetRep () const
				{
					return (fRep.GetPointer ());
				}
            inline	String::StringRep*			String::GetRep ()
				{
					return (fRep.GetPointer ());
				}

			inline	bool	operator!= (const String& lhs, const String& rhs)
				{
					return (bool (not (lhs == rhs)));
				}
            inline	bool	operator!= (const wchar_t* lhs, const String& rhs)
				{
					return (bool (not (lhs == rhs)));
				}
            inline	bool	operator!= (const String& lhs, const wchar_t* rhs)
				{
					return (bool (not (lhs == rhs)));
				}
            inline	bool	operator> (const String& lhs, const String& rhs)
				{
					return (bool (not (lhs <= rhs)));
				}
            inline	bool	operator> (const wchar_t* lhs, const String& rhs)
				{
					return (bool (not (lhs <= rhs)));
				}
            inline	bool	operator> (const String& lhs, const wchar_t* rhs)
				{
					return (bool (not (lhs <= rhs)));
				}
            inline	bool	operator>= (const String& lhs, const String& rhs)
				{
					return (bool (not (lhs < rhs)));
				}
            inline	bool	operator>= (const wchar_t* lhs, const String& rhs)
				{
					return (bool (not (lhs < rhs)));
				}
            inline	bool	operator>= (const String& lhs, const wchar_t* rhs)
				{
					return (bool (not (lhs < rhs)));
				}

			inline	String_CharArray::String_CharArray (const String_CharArray& s)	: String (s)	{}
            inline	String_CharArray& String_CharArray::operator= (const String_CharArray& s)	{	String::operator= (s);	return (*this); }

			inline	String_BufferedCharArray::String_BufferedCharArray (const String_BufferedCharArray& s)	: String (s)	{}
            inline	String_BufferedCharArray& String_BufferedCharArray::operator= (const String_BufferedCharArray& s)	{	String::operator= (s);	return (*this); }

			inline	String_ReadOnlyChar::String_ReadOnlyChar (const String_ReadOnlyChar& s)	: String (s)	{}
            inline	String_ReadOnlyChar& String_ReadOnlyChar::operator= (const String_ReadOnlyChar& s)	{	String::operator= (s);	return (*this); }
		}
	}
}

#endif // _Stroika_Foundation_Characters_String_inl_
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkLevelWindow.h"
#include "mitkImageSliceSelector.h"

#include <ipFunc/ipFunc.h>
#include <ipPic/ipPic.h>
#include <algorithm>

mitk::LevelWindow::LevelWindow(mitk::ScalarType level, mitk::ScalarType window)
: m_Min( level - window / 2.0 ), m_Max( level + window / 2.0 ),
  m_RangeMin( -2048.0 ), m_RangeMax( 4096.0 ),
  m_DefaultRangeMin( -2048.0 ), m_DefaultRangeMax( 4096.0 ),
  m_DefaultLevel( level ), m_DefaultWindow( window ),
  m_Fixed( false )
{
}

mitk::LevelWindow::LevelWindow(const mitk::LevelWindow& levWin)
{
  *this=levWin;
}

mitk::LevelWindow::~LevelWindow()
{
}

mitk::ScalarType mitk::LevelWindow::GetLevel() const
{
  return (m_Max-m_Min) / 2.0 + m_Min;
}

mitk::ScalarType mitk::LevelWindow::GetWindow() const
{
  return (m_Max-m_Min);
}

mitk::ScalarType mitk::LevelWindow::GetDefaultLevel() const
{
  return m_DefaultLevel;
}

mitk::ScalarType mitk::LevelWindow::GetDefaultWindow() const
{
  return m_DefaultWindow;
}

void mitk::LevelWindow::ResetDefaultLevelWindow()
{
  if ( IsFixed() )
    return;
  SetLevelWindow(m_DefaultLevel, m_DefaultWindow);
}

mitk::ScalarType mitk::LevelWindow::GetMin() const
{
  return m_Min;
}

mitk::ScalarType mitk::LevelWindow::GetMax() const
{
  return m_Max;
}

void mitk::LevelWindow::SetDefaultLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
{
  if ( IsFixed() )
    return;

  m_DefaultLevel = level;
  m_DefaultWindow = window;
}

void mitk::LevelWindow::SetLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
{
  if ( IsFixed() )
    return;

  m_Min = level - window / 2.0;
  m_Max = level + window / 2.0;

  testValues();
}

void mitk::LevelWindow::SetMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
  if ( IsFixed() )
    return;

  if(min>max)
    std::swap(min,max);

  m_Min = min;
  m_Max = max;
  if (m_Min < m_RangeMin)
    m_Min = m_RangeMin;
  if (m_Min >= m_RangeMax)
    m_Min = m_RangeMax - 1;
  if (m_Max > m_RangeMax)
    m_Max = m_RangeMax;
  if (m_Max <= m_RangeMin)
    m_Max = m_RangeMin + 1;
  testValues();
}

void mitk::LevelWindow::SetToMaxWindowSize()
{
 m_Max = m_RangeMax;
 m_Min = m_RangeMin;
}

void mitk::LevelWindow::SetRangeMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
  if ( IsFixed() )
    return;

  if(min > max)
    std::swap(min, max);
  m_RangeMin = min;
  m_RangeMax = max;
  if ( m_RangeMin == m_RangeMax)
    m_RangeMin = m_RangeMax - 1;
  if (m_Min < m_RangeMin)
    m_Min = m_RangeMin;
  if (m_Min >= m_RangeMax)
    m_Min = m_RangeMax - 1;
  if (m_Max > m_RangeMax)
    m_Max = m_RangeMax;
  if (m_Max <= m_RangeMin)
    m_Max = m_RangeMin + 1;

  testValues();
}

void mitk::LevelWindow::SetDefaultRangeMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
  if ( IsFixed() )
    return;

  if(min > max)
    std::swap(min, max);
  m_DefaultRangeMin = min;
  m_DefaultRangeMax = max;
  if ( m_DefaultRangeMin == m_DefaultRangeMax)
    m_DefaultRangeMin = m_DefaultRangeMax - 1;
}

mitk::ScalarType mitk::LevelWindow::GetRangeMin() const
{
  return m_RangeMin;
}

mitk::ScalarType mitk::LevelWindow::GetRangeMax() const
{
  return m_RangeMax;
}

mitk::ScalarType mitk::LevelWindow::GetRange() const
{
  return  m_RangeMax - m_RangeMin;
}

mitk::ScalarType mitk::LevelWindow::GetDefaultRangeMax() const
{
  return m_DefaultRangeMax;
}

mitk::ScalarType mitk::LevelWindow::GetDefaultRangeMin() const
{
  return m_DefaultRangeMin;
}

void mitk::LevelWindow::ResetDefaultRangeMinMax()
{
  SetRangeMinMax(m_DefaultRangeMin, m_DefaultRangeMax);
}

/*!
This method initializes a mitk::LevelWindow from an mitk::Image. The algorithm is as follows:

Default to taking the central image slice for quick analysis.

Compute the smallest (minValue), second smallest (min2ndValue), second largest (max2ndValue), and
largest (maxValue) data value by traversing the pixel values only once. In the
same scan it also computes the count of minValue values and maxValue values.
After that a basic histogram with specific information about the
extrems is complete.

If minValue == maxValue, the center slice is uniform and the above scan is repeated for
the complete image, not just one slice

Next, special cases of images with only 1, 2 or 3 distinct data values
have hand assigned level window ranges.

Next the level window is set relative to the inner range IR = lengthOf([min2ndValue, max2ndValue])

For count(minValue) > 20% the smallest values are frequent and should be
distinct from the min2ndValue and larger values (minValue may be std:min, may signify
something special) hence the lower end of the level window is set to min2ndValue - 0.5 * IR

For count(minValue) <= 20% the smallest values are not so important and can
blend with the next ones => min(level window) = min2ndValue

And analog for max(level window):
count(max2ndValue) > 20%:  max(level window) = max2ndValue + 0.5 * IR
count(max2ndValue) < 20%:  max(level window) = max2ndValue

In both 20%+ cases the level window bounds are clamped to the [minValue, maxValue] range

In consequence the level window maximizes contrast with minimal amount of
computation and does do useful things if the data contains std::min or
std:max values or has only 1 or 2 or 3 data values.
*/
void mitk::LevelWindow::SetAuto(mitk::Image* image, bool tryPicTags, bool guessByCentralSlice)
{
  if ( IsFixed() )
    return;

  if ( image == NULL ) return;

  mitk::Image* wholeImage = image;
  mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New();
  if ( guessByCentralSlice )
  {
    sliceSelector->SetInput(image);
    sliceSelector->SetSliceNr(image->GetDimension(2)/2);
    sliceSelector->SetTimeNr(image->GetDimension(3)/2);
    sliceSelector->SetChannelNr(image->GetDimension(4)/2);
    sliceSelector->Update();

    image = sliceSelector->GetOutput();
  }
  else
  {
    image->Update();
  }

  if ( !image->IsInitialized() ) return;

  ScalarType minValue    = image->GetScalarValueMin();
  ScalarType maxValue    = image->GetScalarValueMaxNoRecompute();
  ScalarType min2ndValue = image->GetScalarValue2ndMinNoRecompute();
  ScalarType max2ndValue = image->GetScalarValue2ndMaxNoRecompute();
  unsigned int numPixelsInSlice = image->GetDimensions()[0];
  for ( unsigned int k=0;  k<image->GetDimension();  ++k ) numPixelsInSlice *= image->GetDimensions()[k];
  unsigned int minCount = image->GetCountOfMinValuedVoxelsNoRecompute();
  unsigned int maxCount = image->GetCountOfMaxValuedVoxelsNoRecompute();
  float minCountFraction = minCount/float(numPixelsInSlice);
  float maxCountFraction = maxCount/float(numPixelsInSlice);
  if ( minValue == maxValue )
  {
    // guessByCentralSlice seems to have failed, lets look at all data
    minValue    = wholeImage->GetScalarValueMin();
    maxValue    = wholeImage->GetScalarValueMaxNoRecompute();
    min2ndValue = wholeImage->GetScalarValue2ndMinNoRecompute();
    max2ndValue = wholeImage->GetScalarValue2ndMaxNoRecompute();
    unsigned int numPixelsInDataset = image->GetDimensions()[0];
    for ( unsigned int k=0;  k<image->GetDimension();  ++k )
    {
      numPixelsInDataset *= image->GetDimensions()[k];
    }
    minCount = image->GetCountOfMinValuedVoxelsNoRecompute();
    maxCount = image->GetCountOfMaxValuedVoxelsNoRecompute();
    minCountFraction = minCount/float(numPixelsInDataset);
    maxCountFraction = maxCount/float(numPixelsInDataset);
  }

  // Fix for bug# 344 Level Window wird bei Eris Cut bildern nicht richtig gesetzt
  if (image->GetPixelType().GetType() == ipPicInt && image->GetPixelType().GetBpe() >= 8)
  {
    if (minValue == -(pow((double)2.0,image->GetPixelType().GetBpe())/2))
    {
      minValue = min2ndValue;
    }
  }
  // End fix

  //// uniform image
  if ( minValue == maxValue )
  {
    minValue = maxValue-1;
    SetRangeMinMax(minValue, maxValue);
    SetDefaultRangeMinMax(minValue, maxValue);
  }

  SetRangeMinMax(minValue, maxValue);
  SetDefaultRangeMinMax(minValue, maxValue);
  SetMinMax(minValue, maxValue);
  SetDefaultLevelWindow((maxValue - minValue) / 2 + minValue, maxValue - minValue);
  if ( tryPicTags )
  {
    if ( SetAutoByPicTags(image->GetPic()) )
      return;
  }
}

bool mitk::LevelWindow::SetAutoByPicTags(const ipPicDescriptor* aPic)
{
  if ( IsFixed() )
    return false;

  ipPicDescriptor* pic = const_cast<ipPicDescriptor*>(aPic);
  if ( pic == NULL )
  {
    return false;
  }
  ipPicTSV_t *tsv = ipPicQueryTag( pic, "LEVEL/WINDOW" );
  if( tsv != NULL )
  {
    double level = 0;
    double window = 0;
    #define GET_C_W( type, tsv, C, W )    \
      level = ((type *)tsv->value)[0];    \
      window = ((type *)tsv->value)[1];

    ipPicFORALL_2( GET_C_W, tsv, level, window );

    ScalarType min = GetRangeMin();
    ScalarType max = GetRangeMax();
    if ((double)(GetRangeMin()) > (level - window/2))
    {
      min = level - window/2;
    }
    if ((double)(GetRangeMax()) < (level + window/2))
    {
      max = level + window/2;
    }
    SetRangeMinMax(min, max);
    SetDefaultRangeMinMax(min, max);
    SetLevelWindow( level, window );
    SetDefaultLevelWindow(level, window);
    return true;
  }
  return false;
}

void mitk::LevelWindow::SetFixed( bool fixed )
{
  this->m_Fixed = fixed;
}

bool mitk::LevelWindow::GetFixed() const
{
  return m_Fixed;
}

bool mitk::LevelWindow::IsFixed() const
{
  return m_Fixed;
}

bool mitk::LevelWindow::operator==(const mitk::LevelWindow& levWin) const
{
  if ( m_RangeMin == levWin.GetRangeMin() &&
    m_RangeMax == levWin.GetRangeMax() &&
    m_Min == levWin.GetMin() && m_Max == levWin.GetMax() &&
    m_DefaultLevel == levWin.GetDefaultLevel() && m_DefaultWindow == levWin.GetDefaultWindow() &&
    m_DefaultRangeMin == levWin.GetDefaultRangeMin() && m_DefaultRangeMax == levWin.GetDefaultRangeMax() && m_Fixed == levWin.IsFixed() ) {

      return true;
    }
  else {
    return false;
  }
}

bool mitk::LevelWindow::operator!=(const mitk::LevelWindow& levWin) const
{
  return ! ( (*this) == levWin);
}

mitk::LevelWindow& mitk::LevelWindow::operator=(const mitk::LevelWindow& levWin)
{
  if (this == &levWin) {
    return *this;
  }
  else {
    m_RangeMin = levWin.GetRangeMin();
    m_RangeMax = levWin.GetRangeMax();
    m_Min= levWin.GetMin();
    m_Max= levWin.GetMax();
    m_DefaultLevel = levWin.GetDefaultLevel();
    m_DefaultWindow = levWin.GetDefaultWindow();
    m_DefaultRangeMin = levWin.GetDefaultRangeMin();
    m_DefaultRangeMax = levWin.GetDefaultRangeMax();
    m_Fixed = levWin.GetFixed();
    return *this;
  }
}
<commit_msg>FIX bug #427. Missing test on image->IsInitialized()<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkLevelWindow.h"
#include "mitkImageSliceSelector.h"

#include <ipFunc/ipFunc.h>
#include <ipPic/ipPic.h>
#include <algorithm>

mitk::LevelWindow::LevelWindow(mitk::ScalarType level, mitk::ScalarType window)
: m_Min( level - window / 2.0 ), m_Max( level + window / 2.0 ),
  m_RangeMin( -2048.0 ), m_RangeMax( 4096.0 ),
  m_DefaultRangeMin( -2048.0 ), m_DefaultRangeMax( 4096.0 ),
  m_DefaultLevel( level ), m_DefaultWindow( window ),
  m_Fixed( false )
{
}

mitk::LevelWindow::LevelWindow(const mitk::LevelWindow& levWin)
{
  *this=levWin;
}

mitk::LevelWindow::~LevelWindow()
{
}

mitk::ScalarType mitk::LevelWindow::GetLevel() const
{
  return (m_Max-m_Min) / 2.0 + m_Min;
}

mitk::ScalarType mitk::LevelWindow::GetWindow() const
{
  return (m_Max-m_Min);
}

mitk::ScalarType mitk::LevelWindow::GetDefaultLevel() const
{
  return m_DefaultLevel;
}

mitk::ScalarType mitk::LevelWindow::GetDefaultWindow() const
{
  return m_DefaultWindow;
}

void mitk::LevelWindow::ResetDefaultLevelWindow()
{
  if ( IsFixed() )
    return;
  SetLevelWindow(m_DefaultLevel, m_DefaultWindow);
}

mitk::ScalarType mitk::LevelWindow::GetMin() const
{
  return m_Min;
}

mitk::ScalarType mitk::LevelWindow::GetMax() const
{
  return m_Max;
}

void mitk::LevelWindow::SetDefaultLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
{
  if ( IsFixed() )
    return;

  m_DefaultLevel = level;
  m_DefaultWindow = window;
}

void mitk::LevelWindow::SetLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
{
  if ( IsFixed() )
    return;

  m_Min = level - window / 2.0;
  m_Max = level + window / 2.0;

  testValues();
}

void mitk::LevelWindow::SetMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
  if ( IsFixed() )
    return;

  if(min>max)
    std::swap(min,max);

  m_Min = min;
  m_Max = max;
  if (m_Min < m_RangeMin)
    m_Min = m_RangeMin;
  if (m_Min >= m_RangeMax)
    m_Min = m_RangeMax - 1;
  if (m_Max > m_RangeMax)
    m_Max = m_RangeMax;
  if (m_Max <= m_RangeMin)
    m_Max = m_RangeMin + 1;
  testValues();
}

void mitk::LevelWindow::SetToMaxWindowSize()
{
 m_Max = m_RangeMax;
 m_Min = m_RangeMin;
}

void mitk::LevelWindow::SetRangeMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
  if ( IsFixed() )
    return;

  if(min > max)
    std::swap(min, max);
  m_RangeMin = min;
  m_RangeMax = max;
  if ( m_RangeMin == m_RangeMax)
    m_RangeMin = m_RangeMax - 1;
  if (m_Min < m_RangeMin)
    m_Min = m_RangeMin;
  if (m_Min >= m_RangeMax)
    m_Min = m_RangeMax - 1;
  if (m_Max > m_RangeMax)
    m_Max = m_RangeMax;
  if (m_Max <= m_RangeMin)
    m_Max = m_RangeMin + 1;

  testValues();
}

void mitk::LevelWindow::SetDefaultRangeMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
  if ( IsFixed() )
    return;

  if(min > max)
    std::swap(min, max);
  m_DefaultRangeMin = min;
  m_DefaultRangeMax = max;
  if ( m_DefaultRangeMin == m_DefaultRangeMax)
    m_DefaultRangeMin = m_DefaultRangeMax - 1;
}

mitk::ScalarType mitk::LevelWindow::GetRangeMin() const
{
  return m_RangeMin;
}

mitk::ScalarType mitk::LevelWindow::GetRangeMax() const
{
  return m_RangeMax;
}

mitk::ScalarType mitk::LevelWindow::GetRange() const
{
  return  m_RangeMax - m_RangeMin;
}

mitk::ScalarType mitk::LevelWindow::GetDefaultRangeMax() const
{
  return m_DefaultRangeMax;
}

mitk::ScalarType mitk::LevelWindow::GetDefaultRangeMin() const
{
  return m_DefaultRangeMin;
}

void mitk::LevelWindow::ResetDefaultRangeMinMax()
{
  SetRangeMinMax(m_DefaultRangeMin, m_DefaultRangeMax);
}

/*!
This method initializes a mitk::LevelWindow from an mitk::Image. The algorithm is as follows:

Default to taking the central image slice for quick analysis.

Compute the smallest (minValue), second smallest (min2ndValue), second largest (max2ndValue), and
largest (maxValue) data value by traversing the pixel values only once. In the
same scan it also computes the count of minValue values and maxValue values.
After that a basic histogram with specific information about the
extrems is complete.

If minValue == maxValue, the center slice is uniform and the above scan is repeated for
the complete image, not just one slice

Next, special cases of images with only 1, 2 or 3 distinct data values
have hand assigned level window ranges.

Next the level window is set relative to the inner range IR = lengthOf([min2ndValue, max2ndValue])

For count(minValue) > 20% the smallest values are frequent and should be
distinct from the min2ndValue and larger values (minValue may be std:min, may signify
something special) hence the lower end of the level window is set to min2ndValue - 0.5 * IR

For count(minValue) <= 20% the smallest values are not so important and can
blend with the next ones => min(level window) = min2ndValue

And analog for max(level window):
count(max2ndValue) > 20%:  max(level window) = max2ndValue + 0.5 * IR
count(max2ndValue) < 20%:  max(level window) = max2ndValue

In both 20%+ cases the level window bounds are clamped to the [minValue, maxValue] range

In consequence the level window maximizes contrast with minimal amount of
computation and does do useful things if the data contains std::min or
std:max values or has only 1 or 2 or 3 data values.
*/
void mitk::LevelWindow::SetAuto(mitk::Image* image, bool tryPicTags, bool guessByCentralSlice)
{
  if ( IsFixed() )
    return;

  if ( image == NULL || !image->IsInitialized() ) return;

  mitk::Image* wholeImage = image;
  mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New();
  if ( guessByCentralSlice )
  {
    sliceSelector->SetInput(image);
    sliceSelector->SetSliceNr(image->GetDimension(2)/2);
    sliceSelector->SetTimeNr(image->GetDimension(3)/2);
    sliceSelector->SetChannelNr(image->GetDimension(4)/2);
    sliceSelector->Update();

    image = sliceSelector->GetOutput();
  }
  else
  {
    image->Update();
  }

  if ( !image->IsInitialized() ) return;

  ScalarType minValue    = image->GetScalarValueMin();
  ScalarType maxValue    = image->GetScalarValueMaxNoRecompute();
  ScalarType min2ndValue = image->GetScalarValue2ndMinNoRecompute();
  ScalarType max2ndValue = image->GetScalarValue2ndMaxNoRecompute();
  unsigned int numPixelsInSlice = image->GetDimensions()[0];
  for ( unsigned int k=0;  k<image->GetDimension();  ++k ) numPixelsInSlice *= image->GetDimensions()[k];
  unsigned int minCount = image->GetCountOfMinValuedVoxelsNoRecompute();
  unsigned int maxCount = image->GetCountOfMaxValuedVoxelsNoRecompute();
  float minCountFraction = minCount/float(numPixelsInSlice);
  float maxCountFraction = maxCount/float(numPixelsInSlice);
  if ( minValue == maxValue )
  {
    // guessByCentralSlice seems to have failed, lets look at all data
    minValue    = wholeImage->GetScalarValueMin();
    maxValue    = wholeImage->GetScalarValueMaxNoRecompute();
    min2ndValue = wholeImage->GetScalarValue2ndMinNoRecompute();
    max2ndValue = wholeImage->GetScalarValue2ndMaxNoRecompute();
    unsigned int numPixelsInDataset = image->GetDimensions()[0];
    for ( unsigned int k=0;  k<image->GetDimension();  ++k )
    {
      numPixelsInDataset *= image->GetDimensions()[k];
    }
    minCount = image->GetCountOfMinValuedVoxelsNoRecompute();
    maxCount = image->GetCountOfMaxValuedVoxelsNoRecompute();
    minCountFraction = minCount/float(numPixelsInDataset);
    maxCountFraction = maxCount/float(numPixelsInDataset);
  }

  // Fix for bug# 344 Level Window wird bei Eris Cut bildern nicht richtig gesetzt
  if (image->GetPixelType().GetType() == ipPicInt && image->GetPixelType().GetBpe() >= 8)
  {
    if (minValue == -(pow((double)2.0,image->GetPixelType().GetBpe())/2))
    {
      minValue = min2ndValue;
    }
  }
  // End fix

  //// uniform image
  if ( minValue == maxValue )
  {
    minValue = maxValue-1;
    SetRangeMinMax(minValue, maxValue);
    SetDefaultRangeMinMax(minValue, maxValue);
  }

  SetRangeMinMax(minValue, maxValue);
  SetDefaultRangeMinMax(minValue, maxValue);
  SetMinMax(minValue, maxValue);
  SetDefaultLevelWindow((maxValue - minValue) / 2 + minValue, maxValue - minValue);
  if ( tryPicTags )
  {
    if ( SetAutoByPicTags(image->GetPic()) )
      return;
  }
}

bool mitk::LevelWindow::SetAutoByPicTags(const ipPicDescriptor* aPic)
{
  if ( IsFixed() )
    return false;

  ipPicDescriptor* pic = const_cast<ipPicDescriptor*>(aPic);
  if ( pic == NULL )
  {
    return false;
  }
  ipPicTSV_t *tsv = ipPicQueryTag( pic, "LEVEL/WINDOW" );
  if( tsv != NULL )
  {
    double level = 0;
    double window = 0;
    #define GET_C_W( type, tsv, C, W )    \
      level = ((type *)tsv->value)[0];    \
      window = ((type *)tsv->value)[1];

    ipPicFORALL_2( GET_C_W, tsv, level, window );

    ScalarType min = GetRangeMin();
    ScalarType max = GetRangeMax();
    if ((double)(GetRangeMin()) > (level - window/2))
    {
      min = level - window/2;
    }
    if ((double)(GetRangeMax()) < (level + window/2))
    {
      max = level + window/2;
    }
    SetRangeMinMax(min, max);
    SetDefaultRangeMinMax(min, max);
    SetLevelWindow( level, window );
    SetDefaultLevelWindow(level, window);
    return true;
  }
  return false;
}

void mitk::LevelWindow::SetFixed( bool fixed )
{
  this->m_Fixed = fixed;
}

bool mitk::LevelWindow::GetFixed() const
{
  return m_Fixed;
}

bool mitk::LevelWindow::IsFixed() const
{
  return m_Fixed;
}

bool mitk::LevelWindow::operator==(const mitk::LevelWindow& levWin) const
{
  if ( m_RangeMin == levWin.GetRangeMin() &&
    m_RangeMax == levWin.GetRangeMax() &&
    m_Min == levWin.GetMin() && m_Max == levWin.GetMax() &&
    m_DefaultLevel == levWin.GetDefaultLevel() && m_DefaultWindow == levWin.GetDefaultWindow() &&
    m_DefaultRangeMin == levWin.GetDefaultRangeMin() && m_DefaultRangeMax == levWin.GetDefaultRangeMax() && m_Fixed == levWin.IsFixed() ) {

      return true;
    }
  else {
    return false;
  }
}

bool mitk::LevelWindow::operator!=(const mitk::LevelWindow& levWin) const
{
  return ! ( (*this) == levWin);
}

mitk::LevelWindow& mitk::LevelWindow::operator=(const mitk::LevelWindow& levWin)
{
  if (this == &levWin) {
    return *this;
  }
  else {
    m_RangeMin = levWin.GetRangeMin();
    m_RangeMax = levWin.GetRangeMax();
    m_Min= levWin.GetMin();
    m_Max= levWin.GetMax();
    m_DefaultLevel = levWin.GetDefaultLevel();
    m_DefaultWindow = levWin.GetDefaultWindow();
    m_DefaultRangeMin = levWin.GetDefaultRangeMin();
    m_DefaultRangeMax = levWin.GetDefaultRangeMax();
    m_Fixed = levWin.GetFixed();
    return *this;
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 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.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbMultiChannelExtractROI.h"
#include "otbGenericRSTransform.h"

namespace otb
{
namespace Wrapper
{

class PixelValue : public Application
{
public:
  /** Standard class typedefs. */
  typedef PixelValue                    Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType,
              FloatVectorImageType::InternalPixelType> ExtractROIFilterType;

  typedef otb::GenericRSTransform<>  RSTransformType;
  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(PixelValue, otb::Application);

private:
  void DoInit() ITK_OVERRIDE
  {
    SetName("PixelValue");
    SetDescription("Get the value of a pixel.");

    // Documentation
    SetDocName("Pixel Value");
    SetDocLongDescription("This application gives the value of a selected "
      "pixel. There are three way of designate a pixel, with its index, "
      "its physical coordinate (in the physical space attached to the image), "
      "and with geographical coordinate system. Coordinates will be "
      "interpreted differently depending on which mode is chosen.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

	AddDocTag("Miscellaneous");
    AddDocTag("Utilities");
    AddDocTag("Coordinates");
    AddDocTag("Raster");

    AddParameter(ParameterType_InputImage , "in", "Input Image");
    SetParameterDescription("in" , "Input image");
    // SetParameterString("in" , "/home/antoine/dev/otb-data/Examples/QB_1_ortho.tif");

    AddParameter(ParameterType_Float , "coordx" , "X coordinate" );
    SetParameterDescription("coordx" ,
          "This will be the X coordinate interpreted depending on the "
          "chosen mode");
    AddParameter(ParameterType_Float , "coordy" , "Y coordinate" );
    SetParameterDescription("coordy" ,
          "This will be the Y coordinate interpreted depending on the "
          "chosen mode");

    AddParameter(ParameterType_Choice , "mode" ,
          "Coordinate system used to designate the pixel");
    SetParameterDescription( "mode" ,
          "Different mode can be selected, default mode is Index.");
    AddChoice( "mode.ind" , "Index");
    SetParameterDescription( "mode.ind" ,
          "This mode use the given coordinates as index to locate the pixel.");
    AddChoice( "mode.phy" , "Image physical space");
    SetParameterDescription( "mode.phy" ,
          "This mode interpret the given coordinates in the image "
          "physical space.");
    AddChoice( "mode.epsg" , "EPSG coordinates");
    SetParameterDescription( "mode.epsg" ,
          "This mode interpret the given coordinates in the specified "
          "geographical coordinate system by the EPSG code.");

    AddParameter(ParameterType_Int , "epsg" , "EPSG code");
    SetParameterDescription("epsg" ,
          "This code is used to define a geographical coordinate system. "
          "If no system is specified, WGS84 (EPSG : 4326) is used by default.");
    MandatoryOff("epsg");

    AddParameter(ParameterType_ListView,"cl","Channels");
    SetParameterDescription("cl","Displayed channels");
    MandatoryOff("cl");

    AddParameter(ParameterType_String,"value","Pixel Value");
    SetParameterDescription("value", "Pixel radiometric value");
    SetParameterRole("value", Role_Output);

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("coordx", "50");
    SetDocExampleParameterValue("coordy", "100");
    SetDocExampleParameterValue("cl", "Channel1");

    SetOfficialDocLink();
  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    if ( HasValue("in") )
      {
      ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");

      // Update the values of the channels to be selected
      unsigned int nbComponents = inImage->GetNumberOfComponentsPerPixel();
      ClearChoices("cl");
      for (unsigned int idx = 0; idx < nbComponents; ++idx)
        {
        std::ostringstream key, item;
        key<<"cl.channel"<<idx+1;
        item<<"Channel"<<idx+1;
        AddChoice(key.str(), item.str());
        }
      }
  }

  std::string CreateBoundaryBox( std::string mode )
  {
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    FloatVectorImageType::IndexType min , max;
    min.Fill(30);
    max[0] = inImage->GetLargestPossibleRegion().GetSize()[0] - 1;
    max[1] = inImage->GetLargestPossibleRegion().GetSize()[1] - 1;
    std::string boundaries[4];
    if (mode == "ind")
      {
      boundaries[0] = std::to_string(max[0]);
      boundaries[1] = std::to_string(max[1]);
      boundaries[2] = std::to_string(min[0]);
      boundaries[3] = std::to_string(min[1]);
      }
    if (mode == "phy")
      {
      itk::Point<float, 2> minP , maxP;
      inImage->TransformIndexToPhysicalPoint(min,minP);
      inImage->TransformIndexToPhysicalPoint(max,maxP);
      boundaries[0] = std::to_string(std::max(minP[0],maxP[0]));
      boundaries[1] = std::to_string(std::max(minP[1],maxP[1]));
      boundaries[2] = std::to_string(std::min(minP[0],maxP[0]));
      boundaries[3] = std::to_string(std::min(minP[1],maxP[1]));
      }
    if (mode == "epsg")
      {
      RSTransformType::Pointer inverse = RSTransformType::New();
      if ( HasUserValue("epsg") )
        {
        std::string wktFromEpsg =
          otb::GeoInformationConversion::ToWKT(GetParameterInt( "epsg" ));
        inverse->SetOutputProjectionRef(wktFromEpsg);
        }
      inverse->SetInputKeywordList( inImage->GetImageKeywordlist() );
      inverse->SetInputProjectionRef( inImage->GetProjectionRef() );
      inverse->InstantiateTransform();
      itk::Point<float, 2> minPOut , maxPOut , minP , maxP;
      inImage->TransformIndexToPhysicalPoint(min,minP);
      inImage->TransformIndexToPhysicalPoint(max,maxP);
      minPOut = inverse->TransformPoint( minP );
      maxPOut = inverse->TransformPoint( maxP );
      boundaries[0] = std::to_string(std::max(minPOut[0],maxPOut[0]));
      boundaries[1] = std::to_string(std::max(minPOut[1],maxPOut[1]));
      boundaries[2] = std::to_string(std::min(minPOut[0],maxPOut[0]));
      boundaries[3] = std::to_string(std::min(minPOut[1],maxPOut[1]));
      }
    if ( mode != "ind" )
      {
      for (int i = 0 ; i<4 ; i++)
        {
        while (boundaries[i].back() == '0' && boundaries[i].size() > 1)
          {
          boundaries[i].pop_back();
          }
        }
      }

    std::string box = "";
    box += "["+boundaries[2]+" , "+boundaries[0]+"] x ";
    box += "["+boundaries[3]+" , "+boundaries[1]+"]";
    return box;
  }

  void DoExecute() ITK_OVERRIDE
  {
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    FloatVectorImageType::IndexType id ;
    id.Fill(0);
    bool isPixelIn = false;
    if (GetParameterString( "mode" ) == "ind" )
      {
      id[0] = static_cast< int >( GetParameterFloat( "coordx" ) );
      id[1] = static_cast< int >( GetParameterFloat( "coordy" ) );
      if (static_cast< uint >( id[0] ) >=
                    inImage->GetLargestPossibleRegion().GetSize()[0]
       || static_cast< uint >( id[1] ) >=
                    inImage->GetLargestPossibleRegion().GetSize()[1]
       || id[0] < 0 || id[1] < 0 )
        {
        id.Fill(0);
        isPixelIn = false;
        }
      else
        {
        isPixelIn = true;
        }
      }

    if (GetParameterString( "mode" ) == "phy" )
      {
      itk::Point<float, 2> pixel;
      pixel[ 0 ] = GetParameterFloat( "coordx" );
      pixel[ 1 ] = GetParameterFloat( "coordy" );
      isPixelIn = inImage->TransformPhysicalPointToIndex(pixel,id);
      }

    if (GetParameterString( "mode" ) == "epsg" )
      {
      RSTransformType::Pointer rsTransform = RSTransformType::New();
      if ( HasUserValue("epsg") )
        {
        std::string wktFromEpsg =
          otb::GeoInformationConversion::ToWKT( GetParameterInt( "epsg" ) );
        rsTransform->SetInputProjectionRef(wktFromEpsg);
        }
      rsTransform->SetOutputKeywordList( inImage->GetImageKeywordlist() );
      rsTransform->SetOutputProjectionRef( inImage->GetProjectionRef() );
      rsTransform->InstantiateTransform();
      itk::Point<float, 2> pixelIn , pixelOut;
      pixelIn[ 0 ] = GetParameterFloat( "coordx" );
      pixelIn[ 1 ] = GetParameterFloat( "coordy" );
      rsTransform->InstantiateTransform();
      pixelOut = rsTransform->TransformPoint(pixelIn);
      isPixelIn = inImage->TransformPhysicalPointToIndex(pixelOut,id);
      }
    if ( !isPixelIn )
      {
      std::string why = "Accessible pixels are in ";
      why += CreateBoundaryBox( GetParameterString( "mode" ) );
      why += " for the selected mode.";
      otbAppLogFATAL(<<"Specified position out of bound.\n" + why);
      }

    ExtractROIFilterType::Pointer extractor = ExtractROIFilterType::New();
    extractor->SetInput(inImage);

    // Extract the channels if needed
    if ( GetParameterByKey("cl")->GetActive() )
      {
      for (unsigned int idx = 0; idx < GetSelectedItems("cl").size(); ++idx)
        {
        extractor->SetChannel(GetSelectedItems("cl")[idx] + 1 );
        }
      }
    FloatVectorImageType::SizeType size;
    size.Fill(0);
    FloatVectorImageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(id);

    extractor->SetExtractionRegion(region);
    extractor->Update();

    // Display the pixel value
    id.Fill(0);
    std::ostringstream oss;
    oss << extractor->GetOutput()->GetPixel(id)<<std::endl;
    SetParameterString("value", oss.str(), false);
    //Display image information in the dedicated logger
    otbAppLogINFO( << oss.str() );
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::PixelValue)
<commit_msg>DOC : fixing typos<commit_after>/*
 * Copyright (C) 2005-2017 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.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbMultiChannelExtractROI.h"
#include "otbGenericRSTransform.h"

namespace otb
{
namespace Wrapper
{

class PixelValue : public Application
{
public:
  /** Standard class typedefs. */
  typedef PixelValue                    Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType,
              FloatVectorImageType::InternalPixelType> ExtractROIFilterType;

  typedef otb::GenericRSTransform<>  RSTransformType;
  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(PixelValue, otb::Application);

private:
  void DoInit() ITK_OVERRIDE
  {
    SetName("PixelValue");
    SetDescription("Get the value of a pixel.");

    // Documentation
    SetDocName("Pixel Value");
    SetDocLongDescription("This application gives the value of a selected "
      "pixel. There are three ways of designate a pixel, with its index, "
      "its physical coordinate (in the physical space attached to the image), "
      "and with geographical coordinate system. Coordinates will be "
      "interpreted differently depending on which mode is chosen.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

	AddDocTag("Miscellaneous");
    AddDocTag("Utilities");
    AddDocTag("Coordinates");
    AddDocTag("Raster");

    AddParameter(ParameterType_InputImage , "in", "Input Image");
    SetParameterDescription("in" , "Input image");
    // SetParameterString("in" , "/home/antoine/dev/otb-data/Examples/QB_1_ortho.tif");

    AddParameter(ParameterType_Float , "coordx" , "X coordinate" );
    SetParameterDescription("coordx" ,
          "This will be the X coordinate interpreted depending on the "
          "chosen mode");
    AddParameter(ParameterType_Float , "coordy" , "Y coordinate" );
    SetParameterDescription("coordy" ,
          "This will be the Y coordinate interpreted depending on the "
          "chosen mode");

    AddParameter(ParameterType_Choice , "mode" ,
          "Coordinate system used to designate the pixel");
    SetParameterDescription( "mode" ,
          "Different mode can be selected, default mode is Index.");
    AddChoice( "mode.ind" , "Index");
    SetParameterDescription( "mode.ind" ,
          "This mode use the given coordinates as index to locate the pixel.");
    AddChoice( "mode.phy" , "Image physical space");
    SetParameterDescription( "mode.phy" ,
          "This mode interpret the given coordinates in the image "
          "physical space.");
    AddChoice( "mode.epsg" , "EPSG coordinates");
    SetParameterDescription( "mode.epsg" ,
          "This mode interpret the given coordinates in the specified "
          "geographical coordinate system by the EPSG code.");

    AddParameter(ParameterType_Int , "epsg" , "EPSG code");
    SetParameterDescription("epsg" ,
          "This code is used to define a geographical coordinate system. "
          "If no system is specified, WGS84 (EPSG : 4326) is used by default.");
    MandatoryOff("epsg");

    AddParameter(ParameterType_ListView,"cl","Channels");
    SetParameterDescription("cl","Displayed channels");
    MandatoryOff("cl");

    AddParameter(ParameterType_String,"value","Pixel Value");
    SetParameterDescription("value", "Pixel radiometric value");
    SetParameterRole("value", Role_Output);

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("coordx", "50");
    SetDocExampleParameterValue("coordy", "100");
    SetDocExampleParameterValue("cl", "Channel1");

    SetOfficialDocLink();
  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    if ( HasValue("in") )
      {
      ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");

      // Update the values of the channels to be selected
      unsigned int nbComponents = inImage->GetNumberOfComponentsPerPixel();
      ClearChoices("cl");
      for (unsigned int idx = 0; idx < nbComponents; ++idx)
        {
        std::ostringstream key, item;
        key<<"cl.channel"<<idx+1;
        item<<"Channel"<<idx+1;
        AddChoice(key.str(), item.str());
        }
      }
  }

  std::string CreateBoundaryBox( std::string mode )
  {
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    FloatVectorImageType::IndexType min , max;
    min.Fill(30);
    max[0] = inImage->GetLargestPossibleRegion().GetSize()[0] - 1;
    max[1] = inImage->GetLargestPossibleRegion().GetSize()[1] - 1;
    std::string boundaries[4];
    if (mode == "ind")
      {
      boundaries[0] = std::to_string(max[0]);
      boundaries[1] = std::to_string(max[1]);
      boundaries[2] = std::to_string(min[0]);
      boundaries[3] = std::to_string(min[1]);
      }
    if (mode == "phy")
      {
      itk::Point<float, 2> minP , maxP;
      inImage->TransformIndexToPhysicalPoint(min,minP);
      inImage->TransformIndexToPhysicalPoint(max,maxP);
      boundaries[0] = std::to_string(std::max(minP[0],maxP[0]));
      boundaries[1] = std::to_string(std::max(minP[1],maxP[1]));
      boundaries[2] = std::to_string(std::min(minP[0],maxP[0]));
      boundaries[3] = std::to_string(std::min(minP[1],maxP[1]));
      }
    if (mode == "epsg")
      {
      RSTransformType::Pointer inverse = RSTransformType::New();
      if ( HasUserValue("epsg") )
        {
        std::string wktFromEpsg =
          otb::GeoInformationConversion::ToWKT(GetParameterInt( "epsg" ));
        inverse->SetOutputProjectionRef(wktFromEpsg);
        }
      inverse->SetInputKeywordList( inImage->GetImageKeywordlist() );
      inverse->SetInputProjectionRef( inImage->GetProjectionRef() );
      inverse->InstantiateTransform();
      itk::Point<float, 2> minPOut , maxPOut , minP , maxP;
      inImage->TransformIndexToPhysicalPoint(min,minP);
      inImage->TransformIndexToPhysicalPoint(max,maxP);
      minPOut = inverse->TransformPoint( minP );
      maxPOut = inverse->TransformPoint( maxP );
      boundaries[0] = std::to_string(std::max(minPOut[0],maxPOut[0]));
      boundaries[1] = std::to_string(std::max(minPOut[1],maxPOut[1]));
      boundaries[2] = std::to_string(std::min(minPOut[0],maxPOut[0]));
      boundaries[3] = std::to_string(std::min(minPOut[1],maxPOut[1]));
      }
    if ( mode != "ind" )
      {
      for (int i = 0 ; i<4 ; i++)
        {
        while (boundaries[i].back() == '0' && boundaries[i].size() > 1)
          {
          boundaries[i].pop_back();
          }
        }
      }

    std::string box = "";
    box += "["+boundaries[2]+" , "+boundaries[0]+"] x ";
    box += "["+boundaries[3]+" , "+boundaries[1]+"]";
    return box;
  }

  void DoExecute() ITK_OVERRIDE
  {
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    FloatVectorImageType::IndexType id ;
    id.Fill(0);
    bool isPixelIn = false;
    if (GetParameterString( "mode" ) == "ind" )
      {
      id[0] = static_cast< int >( GetParameterFloat( "coordx" ) );
      id[1] = static_cast< int >( GetParameterFloat( "coordy" ) );
      if (static_cast< uint >( id[0] ) >=
                    inImage->GetLargestPossibleRegion().GetSize()[0]
       || static_cast< uint >( id[1] ) >=
                    inImage->GetLargestPossibleRegion().GetSize()[1]
       || id[0] < 0 || id[1] < 0 )
        {
        id.Fill(0);
        isPixelIn = false;
        }
      else
        {
        isPixelIn = true;
        }
      }

    if (GetParameterString( "mode" ) == "phy" )
      {
      itk::Point<float, 2> pixel;
      pixel[ 0 ] = GetParameterFloat( "coordx" );
      pixel[ 1 ] = GetParameterFloat( "coordy" );
      isPixelIn = inImage->TransformPhysicalPointToIndex(pixel,id);
      }

    if (GetParameterString( "mode" ) == "epsg" )
      {
      RSTransformType::Pointer rsTransform = RSTransformType::New();
      if ( HasUserValue("epsg") )
        {
        std::string wktFromEpsg =
          otb::GeoInformationConversion::ToWKT( GetParameterInt( "epsg" ) );
        rsTransform->SetInputProjectionRef(wktFromEpsg);
        }
      rsTransform->SetOutputKeywordList( inImage->GetImageKeywordlist() );
      rsTransform->SetOutputProjectionRef( inImage->GetProjectionRef() );
      rsTransform->InstantiateTransform();
      itk::Point<float, 2> pixelIn , pixelOut;
      pixelIn[ 0 ] = GetParameterFloat( "coordx" );
      pixelIn[ 1 ] = GetParameterFloat( "coordy" );
      rsTransform->InstantiateTransform();
      pixelOut = rsTransform->TransformPoint(pixelIn);
      isPixelIn = inImage->TransformPhysicalPointToIndex(pixelOut,id);
      }
    if ( !isPixelIn )
      {
      std::string why = "Accessible pixels are in ";
      why += CreateBoundaryBox( GetParameterString( "mode" ) );
      why += " for the selected mode.";
      otbAppLogFATAL(<<"Specified position out of bound.\n" + why);
      }

    ExtractROIFilterType::Pointer extractor = ExtractROIFilterType::New();
    extractor->SetInput(inImage);

    // Extract the channels if needed
    if ( GetParameterByKey("cl")->GetActive() )
      {
      for (unsigned int idx = 0; idx < GetSelectedItems("cl").size(); ++idx)
        {
        extractor->SetChannel(GetSelectedItems("cl")[idx] + 1 );
        }
      }
    FloatVectorImageType::SizeType size;
    size.Fill(0);
    FloatVectorImageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(id);

    extractor->SetExtractionRegion(region);
    extractor->Update();

    // Display the pixel value
    id.Fill(0);
    std::ostringstream oss;
    oss << extractor->GetOutput()->GetPixel(id)<<std::endl;
    SetParameterString("value", oss.str(), false);
    //Display image information in the dedicated logger
    otbAppLogINFO( << oss.str() );
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::PixelValue)
<|endoftext|>