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

  Program:   Visualization Library
  Module:    Camera.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#ifndef __vlCamera_hh
#define __vlCamera_hh

#include "Object.hh"
#include "Trans.hh"

class vlRenderer;

class vlCamera : public vlObject
{
 protected:
  float FocalPoint[3];
  float Position[3];
  float ViewUp[3];
  float ViewAngle;
  float ClippingRange[2];
  float EyeAngle;
  int   LeftEye;
  int   Switch;
  float Thickness;
  float Distance;
  float ViewPlaneNormal[3];
  vlTransform Transform;
  vlTransform PerspectiveTransform;
  float Orientation[3];

 public:
  vlCamera();

  void SetPosition(float , float, float);
  void SetPosition(float a[3]);
  vlGetVectorMacro(Position,float);

  void SetFocalPoint(float , float, float);
  void SetFocalPoint(float a[3]);
  vlGetVectorMacro(FocalPoint,float);

  void SetViewUp(float , float, float);
  void SetViewUp(float a[3]);
  vlGetVectorMacro(ViewUp,float);

  void SetClippingRange(float , float);
  void SetClippingRange(float a[2]);
  vlGetVectorMacro(ClippingRange,float);

  virtual void Render(vlRenderer *ren) = 0;

  vlSetClampMacro(ViewAngle,float,1.0,179.0);
  vlGetMacro(ViewAngle,float);

  vlSetMacro(EyeAngle,float);
  vlGetMacro(EyeAngle,float);

  void SetThickness(float);
  vlGetMacro(Thickness,float);

  void SetDistance(float);
  vlGetMacro(Distance,float);

  vlSetMacro(Switch,int);
  vlGetMacro(Switch,int);
  vlBooleanMacro(Switch,int);

  float GetTwist();
  void CalcViewPlaneNormal();
  void CalcDistance();
  void CalcPerspectiveTransform();
  vlMatrix4x4 &GetPerspectiveTransform();
  vlGetVectorMacro(ViewPlaneNormal,float);

  void SetRoll(float);
  void Roll(float);
  float GetRoll();

  void Zoom(float);
  void Azimuth(float);
  void Yaw(float);
  void Elevation(float);
  void Pitch(float);
  void OrthogonalizeViewUp();

  float *GetOrientation();

  void PrintSelf(ostream& os, vlIndent indent);
  char *GetClassName() {return "vlCamera";};
};

#endif
<commit_msg>Added set view plane normal<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    Camera.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#ifndef __vlCamera_hh
#define __vlCamera_hh

#include "Object.hh"
#include "Trans.hh"

class vlRenderer;

class vlCamera : public vlObject
{
 protected:
  float FocalPoint[3];
  float Position[3];
  float ViewUp[3];
  float ViewAngle;
  float ClippingRange[2];
  float EyeAngle;
  int   LeftEye;
  int   Switch;
  float Thickness;
  float Distance;
  float ViewPlaneNormal[3];
  vlTransform Transform;
  vlTransform PerspectiveTransform;
  float Orientation[3];

 public:
  vlCamera();

  void SetPosition(float , float, float);
  void SetPosition(float a[3]);
  vlGetVectorMacro(Position,float);

  void SetFocalPoint(float , float, float);
  void SetFocalPoint(float a[3]);
  vlGetVectorMacro(FocalPoint,float);

  void SetViewUp(float , float, float);
  void SetViewUp(float a[3]);
  vlGetVectorMacro(ViewUp,float);

  void SetClippingRange(float , float);
  void SetClippingRange(float a[2]);
  vlGetVectorMacro(ClippingRange,float);

  virtual void Render(vlRenderer *ren) = 0;

  vlSetClampMacro(ViewAngle,float,1.0,179.0);
  vlGetMacro(ViewAngle,float);

  vlSetMacro(EyeAngle,float);
  vlGetMacro(EyeAngle,float);

  void SetThickness(float);
  vlGetMacro(Thickness,float);

  void SetDistance(float);
  vlGetMacro(Distance,float);

  vlSetMacro(Switch,int);
  vlGetMacro(Switch,int);
  vlBooleanMacro(Switch,int);

  float GetTwist();
  void SetViewPlaneNormal(float a[3]);
  void SetViewPlaneNormal(float x,float y,float z);
  void CalcViewPlaneNormal();
  void CalcDistance();
  void CalcPerspectiveTransform();
  vlMatrix4x4 &GetPerspectiveTransform();
  vlGetVectorMacro(ViewPlaneNormal,float);

  void SetRoll(float);
  void Roll(float);
  float GetRoll();

  void Zoom(float);
  void Azimuth(float);
  void Yaw(float);
  void Elevation(float);
  void Pitch(float);
  void OrthogonalizeViewUp();

  float *GetOrientation();

  void PrintSelf(ostream& os, vlIndent indent);
  char *GetClassName() {return "vlCamera";};
};

#endif
<|endoftext|>


<commit_before>#ifndef PLUGIN_HH
#define PLUGIN_HH

// Helper macros used when looking for symbols in libraries
#define QUOTEME_(x) #x
#define QUOTEME(x) QUOTEME_(x)

// If present, this function will be called when the plugin is loaded.
#define PLUGIN_MAIN_FUNCTION plugin_main

// Exports main function that creates a single copy of Plugin descendant
#define MAKE_G4_PLUGIN(class_name) \
extern "C" g4::Plugin* PLUGIN_MAIN_FUNCTION()\
{\
    return new class_name;\
}
// end of MAKE_G4_PLUGIN

#include <string>
#include <vector>

#include "Component.hh"
// #include "RunObserver.hh"

namespace g4
{
    class PluginLoader;

    /**
      * @short Base class for any plugin. The plugin is a container
      *   of components stored in a DLL.
      */
    class Plugin
    {
        friend class PluginLoader;

    public:
        virtual const std::vector<std::string> GetAvailableComponents() const = 0;

        virtual Component* GetComponent(const std::string&) = 0;

        virtual ~Plugin() = default;

        /**
          * @short Procedure that is called after loading the plugin.
          */
        virtual void OnLoad() { }

        const std::string& GetName() { return _name; }

    private:
        std::string _name;

    };
}
#endif // PLUGIN_HH
<commit_msg>Update Plugin.hh<commit_after>#ifndef PLUGIN_HH
#define PLUGIN_HH

// Helper macros used when looking for symbols in libraries
#define QUOTEME_(x) #x
#define QUOTEME(x) QUOTEME_(x)

// If present, this function will be called when the plugin is loaded.
#define PLUGIN_MAIN_FUNCTION plugin_main

// Exports main function that creates a single copy of Plugin descendant
#define MAKE_G4_PLUGIN(class_name) \
extern "C" g4::Plugin* PLUGIN_MAIN_FUNCTION()\
{\
    return new class_name;\
}
// end of MAKE_G4_PLUGIN

#include <string>
#include <vector>

#include "Component.hh"
// #include "RunObserver.hh"

namespace g4
{
    class PluginLoader;

    /**
      * @short Base class for any plugin. The plugin is a container
      *   of components stored in a DLL.
      */
    class Plugin
    {
        friend class PluginLoader;

    public:
        /**
          * @short The list of component names the plugin provides.
          */
        virtual const std::vector<std::string> GetAvailableComponents() const = 0;

        /**
          * @short Create or return and existing component by name.
          *
          * Note: if there is no such component, the method should return nullptr,
          *   no G4Exceptions, no C++ exceptions.
          */
        virtual Component* GetComponent(const std::string&) = 0;

        virtual ~Plugin() = default;

        /**
          * @short Procedure that is called after loading the plugin.
          */
        virtual void OnLoad() { }

        const std::string& GetName() { return _name; }

    private:
        std::string _name;

    };
}
#endif // PLUGIN_HH
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkExtractSelectedIds.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 "vtkExtractSelectedIds.h"

#include "vtkDataSet.h"
#include "vtkExtractCells.h"
#include "vtkIdList.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSelection.h"
#include "vtkUnstructuredGrid.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkCellType.h"
#include "vtkCellArray.h"

vtkCxxRevisionMacro(vtkExtractSelectedIds, "1.8");
vtkStandardNewMacro(vtkExtractSelectedIds);

//----------------------------------------------------------------------------
vtkExtractSelectedIds::vtkExtractSelectedIds()
{
  this->SetNumberOfInputPorts(2);
}

//----------------------------------------------------------------------------
vtkExtractSelectedIds::~vtkExtractSelectedIds()
{
}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *selInfo = inputVector[1]->GetInformationObject(0);
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the selection, input and ouptut
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkSelection *sel = vtkSelection::SafeDownCast(
    selInfo->Get(vtkDataObject::DATA_OBJECT()));
  if ( ! sel )
    {
    vtkErrorMacro(<<"No selection specified");
    return 1;
    }

  vtkDebugMacro(<< "Extracting from dataset");

  if (!sel->GetProperties()->Has(vtkSelection::CONTENT_TYPE())
      ||
      (
        sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE()) != vtkSelection::GLOBALIDS &&
        sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE()) != vtkSelection::VALUES &&
        sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE()) != vtkSelection::OFFSETS
        )
    )
    {
    return 1;
    }

  int fieldType = vtkSelection::CELL;
  if (sel->GetProperties()->Has(vtkSelection::FIELD_TYPE()))
    {
    fieldType = sel->GetProperties()->Get(vtkSelection::FIELD_TYPE());
    }
  switch (fieldType)
    {
    case vtkSelection::CELL:
      return this->ExtractCells(sel, input, output);
      break;
    case vtkSelection::POINT:
      return this->ExtractPoints(sel, input, output);
    }
  return 1;
}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::ExtractCells(
  vtkSelection *sel,  vtkDataSet *input,
  vtkUnstructuredGrid *output)
{
  vtkIdTypeArray* idArray =
    vtkIdTypeArray::SafeDownCast(sel->GetSelectionList());
  if (!idArray)
    {
    return 1;
    }

  vtkIdType numIds = idArray->GetNumberOfTuples();
  if (numIds == 0)
    {
    return 1;
    }

  //decide what the IDS mean
  vtkIdTypeArray *labelArray = NULL;
  int selType = sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE());
  if (selType == vtkSelection::GLOBALIDS)
    {
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetCellData()->GetGlobalIds());
    }
  else if (selType == vtkSelection::VALUES &&
           sel->GetProperties()->Has(vtkSelection::ARRAY_NAME()))
    {
    //user chose a specific label array
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetCellData()->GetArray(
        sel->GetProperties()->Get(vtkSelection::ARRAY_NAME())
        )
      }
    }

  if (labelArray == NULL && selType != vtkSelection::OFFSETS)
    {
    return 1;
    }

  vtkCell *cell;
  vtkIdList *cellPts;
  vtkIdType newCellId;
  vtkIdType numCellPts;

  vtkPointData *pd = input->GetPointData();
  vtkCellData *cd = input->GetCellData();
  vtkPointData *outputPD = output->GetPointData();
  vtkCellData *outputCD = output->GetCellData();
  outputPD->CopyAllocate(pd);
  outputCD->CopyAllocate(cd);
  vtkIdTypeArray *originalCellIds = NULL;
  originalCellIds = vtkIdTypeArray::New();
  originalCellIds->SetNumberOfComponents(1);
  originalCellIds->SetName("vtkOriginalCellIds");
  outputCD->AddArray(originalCellIds);

  vtkIdType numPts = input->GetNumberOfPoints();
  vtkIdType numCells = input->GetNumberOfCells();

  vtkPoints *newPts = vtkPoints::New();
  newPts->Allocate(numPts/4,numPts);

  output->Allocate(numCells/4); //allocate storage for geometry/topology

  vtkIdType *pointMap = new vtkIdType[numPts]; // maps old point ids into new
  vtkIdList *newCellPts = vtkIdList::New();
  newCellPts->Allocate(VTK_CELL_SIZE);

  vtkIdType updateInterval = numCells/1000 + 1;

  vtkIdType ptId, newPointId;

  //initialize all points to say not looked at
  for (ptId=0; ptId < numPts; ptId++)
    {
    pointMap[ptId] = -1;
    }

  // Loop over all cells to see whether they are inside.
  vtkIdType cellId;
  for (cellId=0; cellId < numCells; cellId++)
    {
    if ( ! (cellId % updateInterval) ) //manage progress reports
      {
      this->UpdateProgress ((float)cellId / numCells);
      }

    cell = input->GetCell(cellId);
    cellPts = cell->GetPointIds();
    numCellPts = cell->GetNumberOfPoints();
    newCellPts->Reset();

    vtkIdType id;
    int isect = 0;
    if (labelArray == NULL)
      {
      //check if this cell's offset is one of the selected ids
      for (id = 0; id < numIds; id++)
        {
        if (idArray->GetValue(id) == cellId)
          {
          isect = 1;
          break;
          }
        }
      }
    else
      {
      //check if this cell's label is one of the selected ids
      vtkIdType id2find = labelArray->GetValue(cellId);
      for (id = 0; id < numIds; id++)
        {
        if (idArray->GetValue(id) == id2find)
          {
          isect = 1;
          break;
          }
        }
      }

    if (isect == 1)
      {
      //intersects, put all of the points inside
      for (vtkIdType i=0; i < numCellPts; i++)
        {
        ptId = cellPts->GetId(i);
        newPointId = pointMap[ptId];
        if (newPointId < 0)
          {
          double X[3];
          input->GetPoint(ptId, X);
          newPointId = newPts->InsertNextPoint(X);
          outputPD->CopyData(pd,ptId,newPointId);
          pointMap[ptId] = newPointId;
          }
        newCellPts->InsertId(i,newPointId);
        }

      newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
      outputCD->CopyData(cd,cellId,newCellId);
      originalCellIds->InsertNextValue(cellId);
      }
    }//for all cells

  output->SetPoints(newPts);
  newPts->Delete();
  originalCellIds->Delete();
  delete [] pointMap;
  newCellPts->Delete();
  output->Squeeze();

  return 1;
}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::ExtractPoints(
  vtkSelection *sel,  vtkDataSet *input,
  vtkUnstructuredGrid *output)
{
  vtkIdTypeArray* idArray =
    vtkIdTypeArray::SafeDownCast(sel->GetSelectionList());
  if (!idArray)
    {
    return 1;
    }

  vtkIdType numIds = idArray->GetNumberOfTuples();
  if (numIds == 0)
    {
    return 1;
    }

  //decide what the IDS mean
  vtkIdTypeArray *labelArray = NULL;
  int selType = sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE());
  if (selType == vtkSelection::GLOBALIDS)
    {
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetPointData()->GetGlobalIds());
    }
  else if (selType == vtkSelection::VALUES &&
           sel->GetProperties()->Has(vtkSelection::ARRAY_NAME()))
    {
      //user chose a specific label array
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetPointData()->GetArray(
        sel->GetProperties()->Get(vtkSelection::ARRAY_NAME())
        )
      );
    }
  if (labelArray == NULL && selType != vtkSelection::OFFSETS)
    {
    return 1;
    }

  //copy the point data attribute array names, data types and widths
  vtkPoints *opoints = vtkPoints::New();
  output->SetPoints(opoints);
  opoints->Delete();
  output->Allocate(numIds);
  vtkPointData *opd = output->GetPointData();
  vtkPointData *ipd = input->GetPointData();
  opd->CopyStructure(ipd);
  opd->CopyAllOn();
  opd->CopyAllocate(ipd);
  vtkIdType outloc = 0;
  if (labelArray == NULL)
    {
    //using offset within point data as the ID
    //this is fast but doesn't work in parallel
    for (vtkIdType i = 0; i < numIds; i++)
      {
      double X[3];
      vtkIdType id2find = idArray->GetValue(i);
      if (id2find > 0 && id2find < input->GetNumberOfPoints())
        {
        input->GetPoint(id2find, X);
        output->GetPoints()->InsertNextPoint(X);
        output->InsertNextCell(VTK_VERTEX, 1, &outloc);
        opd->CopyData(ipd, id2find, outloc);
        outloc++;
        }
      }
    }
  else
    {
    //each point has a label (such as the globalidarray) use that
    //TODO: sort both idarray and labelarray and step through them so that
    //we don't have n^2 run time
    for (vtkIdType i = 0; i < numIds; i++)
      {
      double X[3];
      vtkIdType id2find = idArray->GetValue(i);
      bool found = false;
      vtkIdType idfound = 0;
      vtkIdType actualLocation = 0;
      for (vtkIdType j = 0; j < input->GetNumberOfPoints(); j++)
        {
        idfound = labelArray->GetValue(j);
        if (idfound == id2find)
          {
          actualLocation = j;
          found = true;
          break;
          }
        }
      if (found)
        {
        input->GetPoint(actualLocation, X);
        output->GetPoints()->InsertNextPoint(X);
        output->InsertNextCell(VTK_VERTEX, 1, &outloc);
        opd->CopyData(ipd, actualLocation, outloc);
        outloc++;
        }
      }
    }
  output->Squeeze();
  return 1;
}

//----------------------------------------------------------------------------
void vtkExtractSelectedIds::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::FillInputPortInformation(
  int port, vtkInformation* info)
{
  if (port==0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
    }
  else
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkSelection");
    }
  return 1;
}
<commit_msg>COMP: Fix bug I introduced fixing the last bug.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExtractSelectedIds.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 "vtkExtractSelectedIds.h"

#include "vtkDataSet.h"
#include "vtkExtractCells.h"
#include "vtkIdList.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSelection.h"
#include "vtkUnstructuredGrid.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkCellType.h"
#include "vtkCellArray.h"

vtkCxxRevisionMacro(vtkExtractSelectedIds, "1.9");
vtkStandardNewMacro(vtkExtractSelectedIds);

//----------------------------------------------------------------------------
vtkExtractSelectedIds::vtkExtractSelectedIds()
{
  this->SetNumberOfInputPorts(2);
}

//----------------------------------------------------------------------------
vtkExtractSelectedIds::~vtkExtractSelectedIds()
{
}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *selInfo = inputVector[1]->GetInformationObject(0);
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the selection, input and ouptut
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkSelection *sel = vtkSelection::SafeDownCast(
    selInfo->Get(vtkDataObject::DATA_OBJECT()));
  if ( ! sel )
    {
    vtkErrorMacro(<<"No selection specified");
    return 1;
    }

  vtkDebugMacro(<< "Extracting from dataset");

  if (!sel->GetProperties()->Has(vtkSelection::CONTENT_TYPE())
      ||
      (
        sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE()) != vtkSelection::GLOBALIDS &&
        sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE()) != vtkSelection::VALUES &&
        sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE()) != vtkSelection::OFFSETS
        )
    )
    {
    return 1;
    }

  int fieldType = vtkSelection::CELL;
  if (sel->GetProperties()->Has(vtkSelection::FIELD_TYPE()))
    {
    fieldType = sel->GetProperties()->Get(vtkSelection::FIELD_TYPE());
    }
  switch (fieldType)
    {
    case vtkSelection::CELL:
      return this->ExtractCells(sel, input, output);
      break;
    case vtkSelection::POINT:
      return this->ExtractPoints(sel, input, output);
    }
  return 1;
}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::ExtractCells(
  vtkSelection *sel,  vtkDataSet *input,
  vtkUnstructuredGrid *output)
{
  vtkIdTypeArray* idArray =
    vtkIdTypeArray::SafeDownCast(sel->GetSelectionList());
  if (!idArray)
    {
    return 1;
    }

  vtkIdType numIds = idArray->GetNumberOfTuples();
  if (numIds == 0)
    {
    return 1;
    }

  //decide what the IDS mean
  vtkIdTypeArray *labelArray = NULL;
  int selType = sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE());
  if (selType == vtkSelection::GLOBALIDS)
    {
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetCellData()->GetGlobalIds());
    }
  else if (selType == vtkSelection::VALUES &&
           sel->GetProperties()->Has(vtkSelection::ARRAY_NAME()))
    {
    //user chose a specific label array
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetCellData()->GetArray(
        sel->GetProperties()->Get(vtkSelection::ARRAY_NAME())
        ));
    }

  if (labelArray == NULL && selType != vtkSelection::OFFSETS)
    {
    return 1;
    }

  vtkCell *cell;
  vtkIdList *cellPts;
  vtkIdType newCellId;
  vtkIdType numCellPts;

  vtkPointData *pd = input->GetPointData();
  vtkCellData *cd = input->GetCellData();
  vtkPointData *outputPD = output->GetPointData();
  vtkCellData *outputCD = output->GetCellData();
  outputPD->CopyAllocate(pd);
  outputCD->CopyAllocate(cd);
  vtkIdTypeArray *originalCellIds = NULL;
  originalCellIds = vtkIdTypeArray::New();
  originalCellIds->SetNumberOfComponents(1);
  originalCellIds->SetName("vtkOriginalCellIds");
  outputCD->AddArray(originalCellIds);

  vtkIdType numPts = input->GetNumberOfPoints();
  vtkIdType numCells = input->GetNumberOfCells();

  vtkPoints *newPts = vtkPoints::New();
  newPts->Allocate(numPts/4,numPts);

  output->Allocate(numCells/4); //allocate storage for geometry/topology

  vtkIdType *pointMap = new vtkIdType[numPts]; // maps old point ids into new
  vtkIdList *newCellPts = vtkIdList::New();
  newCellPts->Allocate(VTK_CELL_SIZE);

  vtkIdType updateInterval = numCells/1000 + 1;

  vtkIdType ptId, newPointId;

  //initialize all points to say not looked at
  for (ptId=0; ptId < numPts; ptId++)
    {
    pointMap[ptId] = -1;
    }

  // Loop over all cells to see whether they are inside.
  vtkIdType cellId;
  for (cellId=0; cellId < numCells; cellId++)
    {
    if ( ! (cellId % updateInterval) ) //manage progress reports
      {
      this->UpdateProgress ((float)cellId / numCells);
      }

    cell = input->GetCell(cellId);
    cellPts = cell->GetPointIds();
    numCellPts = cell->GetNumberOfPoints();
    newCellPts->Reset();

    vtkIdType id;
    int isect = 0;
    if (labelArray == NULL)
      {
      //check if this cell's offset is one of the selected ids
      for (id = 0; id < numIds; id++)
        {
        if (idArray->GetValue(id) == cellId)
          {
          isect = 1;
          break;
          }
        }
      }
    else
      {
      //check if this cell's label is one of the selected ids
      vtkIdType id2find = labelArray->GetValue(cellId);
      for (id = 0; id < numIds; id++)
        {
        if (idArray->GetValue(id) == id2find)
          {
          isect = 1;
          break;
          }
        }
      }

    if (isect == 1)
      {
      //intersects, put all of the points inside
      for (vtkIdType i=0; i < numCellPts; i++)
        {
        ptId = cellPts->GetId(i);
        newPointId = pointMap[ptId];
        if (newPointId < 0)
          {
          double X[3];
          input->GetPoint(ptId, X);
          newPointId = newPts->InsertNextPoint(X);
          outputPD->CopyData(pd,ptId,newPointId);
          pointMap[ptId] = newPointId;
          }
        newCellPts->InsertId(i,newPointId);
        }

      newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
      outputCD->CopyData(cd,cellId,newCellId);
      originalCellIds->InsertNextValue(cellId);
      }
    }//for all cells

  output->SetPoints(newPts);
  newPts->Delete();
  originalCellIds->Delete();
  delete [] pointMap;
  newCellPts->Delete();
  output->Squeeze();

  return 1;
}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::ExtractPoints(
  vtkSelection *sel,  vtkDataSet *input,
  vtkUnstructuredGrid *output)
{
  vtkIdTypeArray* idArray =
    vtkIdTypeArray::SafeDownCast(sel->GetSelectionList());
  if (!idArray)
    {
    return 1;
    }

  vtkIdType numIds = idArray->GetNumberOfTuples();
  if (numIds == 0)
    {
    return 1;
    }

  //decide what the IDS mean
  vtkIdTypeArray *labelArray = NULL;
  int selType = sel->GetProperties()->Get(vtkSelection::CONTENT_TYPE());
  if (selType == vtkSelection::GLOBALIDS)
    {
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetPointData()->GetGlobalIds());
    }
  else if (selType == vtkSelection::VALUES &&
           sel->GetProperties()->Has(vtkSelection::ARRAY_NAME()))
    {
    //user chose a specific label array
    labelArray = vtkIdTypeArray::SafeDownCast(
      input->GetPointData()->GetArray(
        sel->GetProperties()->Get(vtkSelection::ARRAY_NAME())
        ));
    }
  if (labelArray == NULL && selType != vtkSelection::OFFSETS)
    {
    return 1;
    }

  //copy the point data attribute array names, data types and widths
  vtkPoints *opoints = vtkPoints::New();
  output->SetPoints(opoints);
  opoints->Delete();
  output->Allocate(numIds);
  vtkPointData *opd = output->GetPointData();
  vtkPointData *ipd = input->GetPointData();
  opd->CopyStructure(ipd);
  opd->CopyAllOn();
  opd->CopyAllocate(ipd);
  vtkIdType outloc = 0;
  if (labelArray == NULL)
    {
    //using offset within point data as the ID
    //this is fast but doesn't work in parallel
    for (vtkIdType i = 0; i < numIds; i++)
      {
      double X[3];
      vtkIdType id2find = idArray->GetValue(i);
      if (id2find > 0 && id2find < input->GetNumberOfPoints())
        {
        input->GetPoint(id2find, X);
        output->GetPoints()->InsertNextPoint(X);
        output->InsertNextCell(VTK_VERTEX, 1, &outloc);
        opd->CopyData(ipd, id2find, outloc);
        outloc++;
        }
      }
    }
  else
    {
    //each point has a label (such as the globalidarray) use that
    //TODO: sort both idarray and labelarray and step through them so that
    //we don't have n^2 run time
    for (vtkIdType i = 0; i < numIds; i++)
      {
      double X[3];
      vtkIdType id2find = idArray->GetValue(i);
      bool found = false;
      vtkIdType idfound = 0;
      vtkIdType actualLocation = 0;
      for (vtkIdType j = 0; j < input->GetNumberOfPoints(); j++)
        {
        idfound = labelArray->GetValue(j);
        if (idfound == id2find)
          {
          actualLocation = j;
          found = true;
          break;
          }
        }
      if (found)
        {
        input->GetPoint(actualLocation, X);
        output->GetPoints()->InsertNextPoint(X);
        output->InsertNextCell(VTK_VERTEX, 1, &outloc);
        opd->CopyData(ipd, actualLocation, outloc);
        outloc++;
        }
      }
    }
  output->Squeeze();
  return 1;
}

//----------------------------------------------------------------------------
void vtkExtractSelectedIds::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

}

//----------------------------------------------------------------------------
int vtkExtractSelectedIds::FillInputPortInformation(
  int port, vtkInformation* info)
{
  if (port==0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
    }
  else
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkSelection");
    }
  return 1;
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2001 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "cssys/sysfunc.h"
#include "iutil/vfs.h"
#include "csutil/cscolor.h"
#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "simple1.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iengine/sector.h"
#include "iengine/engine.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/statlght.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"
#include "imesh/thing/polygon.h"
#include "imesh/thing/thing.h"
#include "imesh/object.h"
#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/txtmgr.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"
#include "igraphic/imageio.h"
#include "imap/parser.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "csutil/cmdhelp.h"

CS_IMPLEMENT_APPLICATION

//-----------------------------------------------------------------------------

// The global pointer to simple
Simple *simple;

Simple::Simple (iObjectRegistry* object_reg)
{
  Simple::object_reg = object_reg;
}

Simple::~Simple ()
{
}

void Simple::SetupFrame ()
{
  // First get elapsed time from the virtual clock.
  csTicks elapsed_time = vc->GetElapsedTicks ();

  // Now rotate the camera according to keyboard state
  float speed = (elapsed_time / 1000.0) * (0.03 * 20);

  iCamera* c = view->GetCamera();
  if (kbd->GetKeyState (CSKEY_RIGHT))
    c->GetTransform ().RotateThis (CS_VEC_ROT_RIGHT, speed);
  if (kbd->GetKeyState (CSKEY_LEFT))
    c->GetTransform ().RotateThis (CS_VEC_ROT_LEFT, speed);
  if (kbd->GetKeyState (CSKEY_PGUP))
    c->GetTransform ().RotateThis (CS_VEC_TILT_UP, speed);
  if (kbd->GetKeyState (CSKEY_PGDN))
    c->GetTransform ().RotateThis (CS_VEC_TILT_DOWN, speed);
  if (kbd->GetKeyState (CSKEY_UP))
    c->Move (CS_VEC_FORWARD * 4 * speed);
  if (kbd->GetKeyState (CSKEY_DOWN))
    c->Move (CS_VEC_BACKWARD * 4 * speed);

  // Tell 3D driver we're going to display 3D things.
  if (!g3d->BeginDraw (engine->GetBeginDrawFlags () | CSDRAW_3DGRAPHICS))
    return;

  // Tell the camera to render into the frame buffer.
  view->Draw ();
}

void Simple::FinishFrame ()
{
  g3d->FinishDraw ();
  g3d->Print (NULL);
}

bool Simple::HandleEvent (iEvent& ev)
{
  if (ev.Type == csevBroadcast && ev.Command.Code == cscmdProcess)
  {
    simple->SetupFrame ();
    return true;
  }
  else if (ev.Type == csevBroadcast && ev.Command.Code == cscmdFinalProcess)
  {
    simple->FinishFrame ();
    return true;
  }
  else if (ev.Type == csevKeyDown && ev.Key.Code == CSKEY_ESC)
  {
    iEventQueue* q = CS_QUERY_REGISTRY (object_reg, iEventQueue);
    if (q)
    {
      q->GetEventOutlet()->Broadcast (cscmdQuit);
      q->DecRef ();
    }
    return true;
  }

  return false;
}

bool Simple::SimpleEventHandler (iEvent& ev)
{
  return simple->HandleEvent (ev);
}

bool Simple::Initialize ()
{
  if (!csInitializer::RequestPlugins (object_reg,
  	CS_REQUEST_VFS,
	CS_REQUEST_SOFTWARE3D,
	CS_REQUEST_ENGINE,
	CS_REQUEST_FONTSERVER,
	CS_REQUEST_IMAGELOADER,
	CS_REQUEST_LEVELLOADER,
	CS_REQUEST_REPORTER,
	CS_REQUEST_REPORTERLISTENER,
	CS_REQUEST_END))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"Can't initialize plugins!");
    return false;
  }

  if (!csInitializer::SetupEventHandler (object_reg, SimpleEventHandler))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"Can't initialize event handler!");
    return false;
  }

  // Check for commandline help.
  if (csCommandLineHelper::CheckHelp (object_reg))
  {
    csCommandLineHelper::Help (object_reg);
    return false;
  }

  // The virtual clock.
  vc.Assign (CS_QUERY_REGISTRY (object_reg, iVirtualClock));
  if (!vc)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"Can't find the virtual clock!");
    return false;
  }

  // Find the pointer to engine plugin
  engine.Assign (CS_QUERY_REGISTRY (object_reg, iEngine));
  if (!engine)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"No iEngine plugin!");
    return false;
  }

  loader.Assign (CS_QUERY_REGISTRY (object_reg, iLoader));
  if (!loader)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"No iLoader plugin!");
    return false;
  }

  g3d.Assign (CS_QUERY_REGISTRY (object_reg, iGraphics3D));
  if (!g3d)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"No iGraphics3D plugin!");
    return false;
  }

  kbd.Assign (CS_QUERY_REGISTRY (object_reg, iKeyboardDriver));
  if (!kbd)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"No iKeyboardDriver plugin!");
    return false;
  }

  // Open the main system. This will open all the previously loaded plug-ins.
  if (!csInitializer::OpenApplication (object_reg))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"Error opening system!");
    return false;
  }

  // First disable the lighting cache. Our app is simple enough
  // not to need this.
  engine->SetLightingCacheMode (0);

  if (!loader->LoadTexture ("stone", "/lib/std/stone4.gif"))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"Error loading 'stone4' texture!");
    return false;
  }
  iMaterialWrapper* tm = engine->GetMaterialList ()->FindByName ("stone");

  room = engine->CreateSector ("room");
  csRef<iMeshWrapper> walls (
  	engine->CreateSectorWallsMesh (room, "walls"));
  csRef<iThingState> walls_state (
  	SCF_QUERY_INTERFACE (walls->GetMeshObject (), iThingState));
  iPolygon3D* p;
  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 0, 5));
  p->CreateVertex (csVector3 (5, 0, 5));
  p->CreateVertex (csVector3 (5, 0, -5));
  p->CreateVertex (csVector3 (-5, 0, -5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 20, -5));
  p->CreateVertex (csVector3 (5, 20, -5));
  p->CreateVertex (csVector3 (5, 20, 5));
  p->CreateVertex (csVector3 (-5, 20, 5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 20, 5));
  p->CreateVertex (csVector3 (5, 20, 5));
  p->CreateVertex (csVector3 (5, 0, 5));
  p->CreateVertex (csVector3 (-5, 0, 5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (5, 20, 5));
  p->CreateVertex (csVector3 (5, 20, -5));
  p->CreateVertex (csVector3 (5, 0, -5));
  p->CreateVertex (csVector3 (5, 0, 5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 20, -5));
  p->CreateVertex (csVector3 (-5, 20, 5));
  p->CreateVertex (csVector3 (-5, 0, 5));
  p->CreateVertex (csVector3 (-5, 0, -5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (5, 20, -5));
  p->CreateVertex (csVector3 (-5, 20, -5));
  p->CreateVertex (csVector3 (-5, 0, -5));
  p->CreateVertex (csVector3 (5, 0, -5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  csRef<iStatLight> light;
  iLightList* ll = room->GetLights ();

  light.Assign (engine->CreateLight (NULL, csVector3 (-3, 5, 0), 10,
  	csColor (1, 0, 0), false));
  ll->Add (light->QueryLight ());

  light.Assign (engine->CreateLight (NULL, csVector3 (3, 5,  0), 10,
  	csColor (0, 0, 1), false));
  ll->Add (light->QueryLight ());

  light.Assign (engine->CreateLight (NULL, csVector3 (0, 5, -3), 10,
  	csColor (0, 1, 0), false));
  ll->Add (light->QueryLight ());

  engine->Prepare ();

  view.Assign (new csView (engine, g3d));
  view->GetCamera ()->SetSector (room);
  view->GetCamera ()->GetTransform ().SetOrigin (csVector3 (0, 5, -3));
  iGraphics2D* g2d = g3d->GetDriver2D ();
  view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ());

  iTextureManager* txtmgr = g3d->GetTextureManager ();
  txtmgr->SetPalette ();
  return true;
}

void Simple::Start ()
{
  csDefaultRunLoop (object_reg);
}

/*---------------------------------------------------------------------*
 * Main function
 *---------------------------------------------------------------------*/
int main (int argc, char* argv[])
{
  iObjectRegistry* object_reg = csInitializer::CreateEnvironment (argc, argv);

  simple = new Simple (object_reg);
  if (simple->Initialize ())
    simple->Start ();
  delete simple;

  csInitializer::DestroyApplication (object_reg);
  return 0;
}

<commit_msg>Fixed operator ! ambiguity error under MSVC 7.<commit_after>/*
    Copyright (C) 2001 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "cssys/sysfunc.h"
#include "iutil/vfs.h"
#include "csutil/cscolor.h"
#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "simple1.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iengine/sector.h"
#include "iengine/engine.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/statlght.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"
#include "imesh/thing/polygon.h"
#include "imesh/thing/thing.h"
#include "imesh/object.h"
#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/txtmgr.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"
#include "igraphic/imageio.h"
#include "imap/parser.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "csutil/cmdhelp.h"

CS_IMPLEMENT_APPLICATION

//-----------------------------------------------------------------------------

// The global pointer to simple
Simple *simple;

Simple::Simple (iObjectRegistry* object_reg)
{
  Simple::object_reg = object_reg;
}

Simple::~Simple ()
{
}

void Simple::SetupFrame ()
{
  // First get elapsed time from the virtual clock.
  csTicks elapsed_time = vc->GetElapsedTicks ();

  // Now rotate the camera according to keyboard state
  float speed = (elapsed_time / 1000.0) * (0.03 * 20);

  iCamera* c = view->GetCamera();
  if (kbd->GetKeyState (CSKEY_RIGHT))
    c->GetTransform ().RotateThis (CS_VEC_ROT_RIGHT, speed);
  if (kbd->GetKeyState (CSKEY_LEFT))
    c->GetTransform ().RotateThis (CS_VEC_ROT_LEFT, speed);
  if (kbd->GetKeyState (CSKEY_PGUP))
    c->GetTransform ().RotateThis (CS_VEC_TILT_UP, speed);
  if (kbd->GetKeyState (CSKEY_PGDN))
    c->GetTransform ().RotateThis (CS_VEC_TILT_DOWN, speed);
  if (kbd->GetKeyState (CSKEY_UP))
    c->Move (CS_VEC_FORWARD * 4 * speed);
  if (kbd->GetKeyState (CSKEY_DOWN))
    c->Move (CS_VEC_BACKWARD * 4 * speed);

  // Tell 3D driver we're going to display 3D things.
  if (!g3d->BeginDraw (engine->GetBeginDrawFlags () | CSDRAW_3DGRAPHICS))
    return;

  // Tell the camera to render into the frame buffer.
  view->Draw ();
}

void Simple::FinishFrame ()
{
  g3d->FinishDraw ();
  g3d->Print (NULL);
}

bool Simple::HandleEvent (iEvent& ev)
{
  if (ev.Type == csevBroadcast && ev.Command.Code == cscmdProcess)
  {
    simple->SetupFrame ();
    return true;
  }
  else if (ev.Type == csevBroadcast && ev.Command.Code == cscmdFinalProcess)
  {
    simple->FinishFrame ();
    return true;
  }
  else if (ev.Type == csevKeyDown && ev.Key.Code == CSKEY_ESC)
  {
    iEventQueue* q = CS_QUERY_REGISTRY (object_reg, iEventQueue);
    if (q)
    {
      q->GetEventOutlet()->Broadcast (cscmdQuit);
      q->DecRef ();
    }
    return true;
  }

  return false;
}

bool Simple::SimpleEventHandler (iEvent& ev)
{
  return simple->HandleEvent (ev);
}

bool Simple::Initialize ()
{
  if (!csInitializer::RequestPlugins (object_reg,
  	CS_REQUEST_VFS,
	CS_REQUEST_SOFTWARE3D,
	CS_REQUEST_ENGINE,
	CS_REQUEST_FONTSERVER,
	CS_REQUEST_IMAGELOADER,
	CS_REQUEST_LEVELLOADER,
	CS_REQUEST_REPORTER,
	CS_REQUEST_REPORTERLISTENER,
	CS_REQUEST_END))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"Can't initialize plugins!");
    return false;
  }

  if (!csInitializer::SetupEventHandler (object_reg, SimpleEventHandler))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"Can't initialize event handler!");
    return false;
  }

  // Check for commandline help.
  if (csCommandLineHelper::CheckHelp (object_reg))
  {
    csCommandLineHelper::Help (object_reg);
    return false;
  }

  // The virtual clock.
  vc.Assign (CS_QUERY_REGISTRY (object_reg, iVirtualClock));
  if (vc == NULL)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"Can't find the virtual clock!");
    return false;
  }

  // Find the pointer to engine plugin
  engine.Assign (CS_QUERY_REGISTRY (object_reg, iEngine));
  if (engine == NULL)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
	"No iEngine plugin!");
    return false;
  }

  loader.Assign (CS_QUERY_REGISTRY (object_reg, iLoader));
  if (loader == NULL)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"No iLoader plugin!");
    return false;
  }

  g3d.Assign (CS_QUERY_REGISTRY (object_reg, iGraphics3D));
  if (g3d == NULL)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"No iGraphics3D plugin!");
    return false;
  }

  kbd.Assign (CS_QUERY_REGISTRY (object_reg, iKeyboardDriver));
  if (kbd == NULL)
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"No iKeyboardDriver plugin!");
    return false;
  }

  // Open the main system. This will open all the previously loaded plug-ins.
  if (!csInitializer::OpenApplication (object_reg))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"Error opening system!");
    return false;
  }

  // First disable the lighting cache. Our app is simple enough
  // not to need this.
  engine->SetLightingCacheMode (0);

  if (!loader->LoadTexture ("stone", "/lib/std/stone4.gif"))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple1",
    	"Error loading 'stone4' texture!");
    return false;
  }
  iMaterialWrapper* tm = engine->GetMaterialList ()->FindByName ("stone");

  room = engine->CreateSector ("room");
  csRef<iMeshWrapper> walls (
  	engine->CreateSectorWallsMesh (room, "walls"));
  csRef<iThingState> walls_state (
  	SCF_QUERY_INTERFACE (walls->GetMeshObject (), iThingState));
  iPolygon3D* p;
  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 0, 5));
  p->CreateVertex (csVector3 (5, 0, 5));
  p->CreateVertex (csVector3 (5, 0, -5));
  p->CreateVertex (csVector3 (-5, 0, -5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 20, -5));
  p->CreateVertex (csVector3 (5, 20, -5));
  p->CreateVertex (csVector3 (5, 20, 5));
  p->CreateVertex (csVector3 (-5, 20, 5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 20, 5));
  p->CreateVertex (csVector3 (5, 20, 5));
  p->CreateVertex (csVector3 (5, 0, 5));
  p->CreateVertex (csVector3 (-5, 0, 5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (5, 20, 5));
  p->CreateVertex (csVector3 (5, 20, -5));
  p->CreateVertex (csVector3 (5, 0, -5));
  p->CreateVertex (csVector3 (5, 0, 5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (-5, 20, -5));
  p->CreateVertex (csVector3 (-5, 20, 5));
  p->CreateVertex (csVector3 (-5, 0, 5));
  p->CreateVertex (csVector3 (-5, 0, -5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  p = walls_state->CreatePolygon ();
  p->SetMaterial (tm);
  p->CreateVertex (csVector3 (5, 20, -5));
  p->CreateVertex (csVector3 (-5, 20, -5));
  p->CreateVertex (csVector3 (-5, 0, -5));
  p->CreateVertex (csVector3 (5, 0, -5));
  p->SetTextureSpace (p->GetVertex (0), p->GetVertex (1), 3);

  csRef<iStatLight> light;
  iLightList* ll = room->GetLights ();

  light.Assign (engine->CreateLight (NULL, csVector3 (-3, 5, 0), 10,
  	csColor (1, 0, 0), false));
  ll->Add (light->QueryLight ());

  light.Assign (engine->CreateLight (NULL, csVector3 (3, 5,  0), 10,
  	csColor (0, 0, 1), false));
  ll->Add (light->QueryLight ());

  light.Assign (engine->CreateLight (NULL, csVector3 (0, 5, -3), 10,
  	csColor (0, 1, 0), false));
  ll->Add (light->QueryLight ());

  engine->Prepare ();

  view.Assign (new csView (engine, g3d));
  view->GetCamera ()->SetSector (room);
  view->GetCamera ()->GetTransform ().SetOrigin (csVector3 (0, 5, -3));
  iGraphics2D* g2d = g3d->GetDriver2D ();
  view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ());

  iTextureManager* txtmgr = g3d->GetTextureManager ();
  txtmgr->SetPalette ();
  return true;
}

void Simple::Start ()
{
  csDefaultRunLoop (object_reg);
}

/*---------------------------------------------------------------------*
 * Main function
 *---------------------------------------------------------------------*/
int main (int argc, char* argv[])
{
  iObjectRegistry* object_reg = csInitializer::CreateEnvironment (argc, argv);

  simple = new Simple (object_reg);
  if (simple->Initialize ())
    simple->Start ();
  delete simple;

  csInitializer::DestroyApplication (object_reg);
  return 0;
}

<|endoftext|>


<commit_before>#include <ns3/core-module.h>

#include "llegadas.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("Llegadas");

Llegadas::Llegadas (double tasa)
{
  double mean = 1/tasa;
  // Creamos la variable aleatoria ...
  tEntreLlegadas = CreateObject<ExponentialRandomVariable> ();
  // ... y ajustamos su valor medio
  tEntreLlegadas->SetAttribute ("Mean", DoubleValue (mean));
  // Programamos la primera llegada. //HAY QUE PASAR UN TIME COMO PRIMER PARAMETRO
  Simulator::Schedule (Time::(tEntreLlegadas->GetValue()), &Llegadas::NuevaLlegada, this, Simulator::Now.GetDouble());
}

void
Llegadas::NuevaLlegada (double tiempo)
{
  // Calculamos el tiempo transcurrido desde la última llegada
  double t = Simulator::Now.GetDouble() - tiempo;
  // Presentamos el tiempo transcurrido entre llegadas.
  NS_LOG_INFO ("Tiempo transcurrido entre llegadas: " << t);
  // Programamos la siguiente llegada
  Simulator::Schedule (tEntreLlegadas->GetValue(), &Llegadas::NuevaLlegada, this, Simulator::Now.GetDouble());
  // Acumulamos el valor del intervalo
  acumulador.Update(t);
}

double
Llegadas::Media ()
{
  // Devolvemos el valor medio de las muestras recogidas.
  acumulador.Mean()
}
<commit_msg>fixed various errors. Now it works<commit_after>#include <ns3/core-module.h>

#include "llegadas.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("Llegadas");

Llegadas::Llegadas (double tasa)
{
  double mean = 1/tasa;
  // Creamos la variable aleatoria ...
  tEntreLlegadas = CreateObject<ExponentialRandomVariable> ();
  // ... y ajustamos su valor medio
  tEntreLlegadas->SetAttribute ("Mean", DoubleValue (mean));
  // Programamos la primera llegada. //HAY QUE PASAR UN TIME COMO PRIMER PARAMETRO
  Simulator::Schedule (Seconds(tEntreLlegadas->GetValue()), &Llegadas::NuevaLlegada, this, Simulator::Now ().GetSeconds());
}

void
Llegadas::NuevaLlegada (double tiempo)
{
  // Calculamos el tiempo transcurrido desde la última llegada
  double t = Simulator::Now ().GetSeconds() - tiempo;
  // Presentamos el tiempo transcurrido entre llegadas.
  NS_LOG_INFO ("Tiempo transcurrido entre llegadas: " << t);
  // Programamos la siguiente llegada
  Simulator::Schedule (Seconds(tEntreLlegadas->GetValue()), &Llegadas::NuevaLlegada, this, Simulator::Now ().GetSeconds());
  // Acumulamos el valor del intervalo
  acumulador.Update(t);
}

double
Llegadas::Media ()
{
  // Devolvemos el valor medio de las muestras recogidas.
  return acumulador.Mean();
}
<|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include "CxxNativeModule.h"
#include "Instance.h"

#include <iterator>

#include <folly/json.h>

#include "JsArgumentHelpers.h"
#include "SystraceSection.h"
#include "MessageQueueThread.h"

using facebook::xplat::module::CxxModule;

namespace facebook {
namespace react {

std::function<void(folly::dynamic)> makeCallback(
    std::weak_ptr<Instance> instance, const folly::dynamic& callbackId) {
  if (!callbackId.isNumber()) {
    throw std::invalid_argument("Expected callback(s) as final argument");
  }

  auto id = callbackId.asInt();
  return [winstance = std::move(instance), id](folly::dynamic args) {
    if (auto instance = winstance.lock()) {
      instance->callJSCallback(id, std::move(args));
    }
  };
}

namespace {

/**
 * CxxModule::Callback accepts a vector<dynamic>, makeCallback returns
 * a callback that accepts a dynamic, adapt the second into the first.
 * TODO: Callback types should be made equal (preferably
 * function<void(dynamic)>) to avoid the extra copy and indirect call.
 */
CxxModule::Callback convertCallback(
    std::function<void(folly::dynamic)> callback) {
  return [callback = std::move(callback)](std::vector<folly::dynamic> args) {
    callback(folly::dynamic(std::make_move_iterator(args.begin()),
                            std::make_move_iterator(args.end())));
  };
}

}

std::string CxxNativeModule::getName() {
  return name_;
}

std::vector<MethodDescriptor> CxxNativeModule::getMethods() {
  lazyInit();

  std::vector<MethodDescriptor> descs;
  for (auto& method : methods_) {
    descs.emplace_back(method.name, method.getType());
  }
  return descs;
}

folly::dynamic CxxNativeModule::getConstants() {
  lazyInit();

  if (!module_) {
    return nullptr;
  }

  folly::dynamic constants = folly::dynamic::object();
  for (auto& pair : module_->getConstants()) {
    constants.insert(std::move(pair.first), std::move(pair.second));
  }
  return constants;
}

void CxxNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
  if (reactMethodId >= methods_.size()) {
    throw std::invalid_argument(folly::to<std::string>("methodId ", reactMethodId,
        " out of range [0..", methods_.size(), "]"));
  }
  if (!params.isArray()) {
    throw std::invalid_argument(
      folly::to<std::string>("method parameters should be array, but are ", params.typeName()));
  }

  CxxModule::Callback first;
  CxxModule::Callback second;

  const auto& method = methods_[reactMethodId];

  if (!method.func) {
    throw std::runtime_error(folly::to<std::string>("Method ", method.name,
        " is synchronous but invoked asynchronously"));
  }

  if (params.size() < method.callbacks) {
    throw std::invalid_argument(folly::to<std::string>("Expected ", method.callbacks,
        " callbacks, but only ", params.size(), " parameters provided"));
  }

  if (method.callbacks == 1) {
    first = convertCallback(makeCallback(instance_, params[params.size() - 1]));
  } else if (method.callbacks == 2) {
    first = convertCallback(makeCallback(instance_, params[params.size() - 2]));
    second = convertCallback(makeCallback(instance_, params[params.size() - 1]));
  }

  params.resize(params.size() - method.callbacks);

  // I've got a few flawed options here.  I can let the C++ exception
  // propogate, and the registry will log/convert them to java exceptions.
  // This lets all the java and red box handling work ok, but the only info I
  // can capture about the C++ exception is the what() string, not the stack.
  // I can std::terminate() the app.  This causes the full, accurate C++
  // stack trace to be added to logcat by debuggerd.  The java state is lost,
  // but in practice, the java stack is always the same in this case since
  // the javascript stack is not visible, and the crash is unfriendly to js
  // developers, but crucial to C++ developers.  The what() value is also
  // lost.  Finally, I can catch, log the java stack, then rethrow the C++
  // exception.  In this case I get java and C++ stack data, but the C++
  // stack is as of the rethrow, not the original throw, both the C++ and
  // java stacks always look the same.
  //
  // I am going with option 2, since that seems like the most useful
  // choice.  It would be nice to be able to get what() and the C++
  // stack.  I'm told that will be possible in the future.  TODO
  // mhorowitz #7128529: convert C++ exceptions to Java

  messageQueueThread_->runOnQueue([method, params=std::move(params), first, second, callId] () {
  #ifdef WITH_FBSYSTRACE
    if (callId != -1) {
      fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
    }
  #endif
    SystraceSection s(method.name.c_str());
    try {
      method.func(std::move(params), first, second);
    } catch (const facebook::xplat::JsArgumentException& ex) {
      throw;
    } catch (...) {
      // This means some C++ code is buggy.  As above, we fail hard so the C++
      // developer can debug and fix it.
      std::terminate();
    }
  });
}

MethodCallResult CxxNativeModule::callSerializableNativeHook(unsigned int hookId, folly::dynamic&& args) {
  if (hookId >= methods_.size()) {
    throw std::invalid_argument(
      folly::to<std::string>("methodId ", hookId, " out of range [0..", methods_.size(), "]"));
  }

  const auto& method = methods_[hookId];

  if (!method.syncFunc) {
    throw std::runtime_error(
      folly::to<std::string>("Method ", method.name,
                             " is asynchronous but invoked synchronously"));
  }

  return method.syncFunc(std::move(args));
}

void CxxNativeModule::lazyInit() {
  if (module_ || !provider_) {
    return;
  }

  // TODO 17216751: providers should never return null modules
  module_ = provider_();
  provider_ = nullptr;
  if (module_) {
    methods_ = module_->getMethods();
    module_->setInstance(instance_);
  }
}

}
}
<commit_msg>more detailed CxxModule logging<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include "CxxNativeModule.h"
#include "Instance.h"

#include <iterator>
#include <glog/logging.h>
#include <folly/json.h>

#include "JsArgumentHelpers.h"
#include "SystraceSection.h"
#include "MessageQueueThread.h"

using facebook::xplat::module::CxxModule;
namespace facebook {
namespace react {

std::function<void(folly::dynamic)> makeCallback(
    std::weak_ptr<Instance> instance, const folly::dynamic& callbackId) {
  if (!callbackId.isNumber()) {
    throw std::invalid_argument("Expected callback(s) as final argument");
  }

  auto id = callbackId.asInt();
  return [winstance = std::move(instance), id](folly::dynamic args) {
    if (auto instance = winstance.lock()) {
      instance->callJSCallback(id, std::move(args));
    }
  };
}

namespace {

/**
 * CxxModule::Callback accepts a vector<dynamic>, makeCallback returns
 * a callback that accepts a dynamic, adapt the second into the first.
 * TODO: Callback types should be made equal (preferably
 * function<void(dynamic)>) to avoid the extra copy and indirect call.
 */
CxxModule::Callback convertCallback(
    std::function<void(folly::dynamic)> callback) {
  return [callback = std::move(callback)](std::vector<folly::dynamic> args) {
    callback(folly::dynamic(std::make_move_iterator(args.begin()),
                            std::make_move_iterator(args.end())));
  };
}

}

std::string CxxNativeModule::getName() {
  return name_;
}

std::vector<MethodDescriptor> CxxNativeModule::getMethods() {
  lazyInit();

  std::vector<MethodDescriptor> descs;
  for (auto& method : methods_) {
    descs.emplace_back(method.name, method.getType());
  }
  return descs;
}

folly::dynamic CxxNativeModule::getConstants() {
  lazyInit();

  if (!module_) {
    return nullptr;
  }

  folly::dynamic constants = folly::dynamic::object();
  for (auto& pair : module_->getConstants()) {
    constants.insert(std::move(pair.first), std::move(pair.second));
  }
  return constants;
}

void CxxNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
  if (reactMethodId >= methods_.size()) {
    throw std::invalid_argument(folly::to<std::string>("methodId ", reactMethodId,
        " out of range [0..", methods_.size(), "]"));
  }
  if (!params.isArray()) {
    throw std::invalid_argument(
      folly::to<std::string>("method parameters should be array, but are ", params.typeName()));
  }

  CxxModule::Callback first;
  CxxModule::Callback second;

  const auto& method = methods_[reactMethodId];

  if (!method.func) {
    throw std::runtime_error(folly::to<std::string>("Method ", method.name,
        " is synchronous but invoked asynchronously"));
  }

  if (params.size() < method.callbacks) {
    throw std::invalid_argument(folly::to<std::string>("Expected ", method.callbacks,
        " callbacks, but only ", params.size(), " parameters provided"));
  }

  if (method.callbacks == 1) {
    first = convertCallback(makeCallback(instance_, params[params.size() - 1]));
  } else if (method.callbacks == 2) {
    first = convertCallback(makeCallback(instance_, params[params.size() - 2]));
    second = convertCallback(makeCallback(instance_, params[params.size() - 1]));
  }

  params.resize(params.size() - method.callbacks);

  // I've got a few flawed options here.  I can let the C++ exception
  // propogate, and the registry will log/convert them to java exceptions.
  // This lets all the java and red box handling work ok, but the only info I
  // can capture about the C++ exception is the what() string, not the stack.
  // I can std::terminate() the app.  This causes the full, accurate C++
  // stack trace to be added to logcat by debuggerd.  The java state is lost,
  // but in practice, the java stack is always the same in this case since
  // the javascript stack is not visible, and the crash is unfriendly to js
  // developers, but crucial to C++ developers.  The what() value is also
  // lost.  Finally, I can catch, log the java stack, then rethrow the C++
  // exception.  In this case I get java and C++ stack data, but the C++
  // stack is as of the rethrow, not the original throw, both the C++ and
  // java stacks always look the same.
  //
  // I am going with option 2, since that seems like the most useful
  // choice.  It would be nice to be able to get what() and the C++
  // stack.  I'm told that will be possible in the future.  TODO
  // mhorowitz #7128529: convert C++ exceptions to Java

  messageQueueThread_->runOnQueue([method, params=std::move(params), first, second, callId] () {
  #ifdef WITH_FBSYSTRACE
    if (callId != -1) {
      fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
    }
  #endif
    SystraceSection s(method.name.c_str());
    try {
      method.func(std::move(params), first, second);
    } catch (const facebook::xplat::JsArgumentException& ex) {
      throw;
    } catch (std::exception& e) {
      LOG(ERROR) << "std::exception. Method call " << method.name.c_str() << " failed: " << e.what();
      std::terminate();
    } catch (std::string& error) {
      LOG(ERROR) << "std::string. Method call " << method.name.c_str() << " failed: " << error.c_str();
      std::terminate();
    } catch (...) {
      LOG(ERROR) << "Method call " << method.name.c_str() << " failed. unknown error";
      std::terminate();
    }
  });
}

MethodCallResult CxxNativeModule::callSerializableNativeHook(unsigned int hookId, folly::dynamic&& args) {
  if (hookId >= methods_.size()) {
    throw std::invalid_argument(
      folly::to<std::string>("methodId ", hookId, " out of range [0..", methods_.size(), "]"));
  }

  const auto& method = methods_[hookId];

  if (!method.syncFunc) {
    throw std::runtime_error(
      folly::to<std::string>("Method ", method.name,
                             " is asynchronous but invoked synchronously"));
  }

  return method.syncFunc(std::move(args));
}

void CxxNativeModule::lazyInit() {
  if (module_ || !provider_) {
    return;
  }

  // TODO 17216751: providers should never return null modules
  module_ = provider_();
  provider_ = nullptr;
  if (module_) {
    methods_ = module_->getMethods();
    module_->setInstance(instance_);
  }
}

}
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkNewickTreeReader.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 "vtkNewickTreeReader.h"

#include "vtkByteSwap.h"
#include "vtkCellArray.h"
#include "vtkDataSetAttributes.h"
#include "vtkDoubleArray.h"
#include "vtkFieldData.h"
#include "vtkNew.h"
#include "vtkTree.h"
#include "vtkTreeDFSIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMutableDirectedGraph.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStringArray.h"

#include <iostream>
#include <fstream>

vtkStandardNewMacro(vtkNewickTreeReader);

#ifdef read
#undef read
#endif

//----------------------------------------------------------------------------
vtkNewickTreeReader::vtkNewickTreeReader()
{
  vtkTree *output = vtkTree::New();
  this->SetOutput(output);
  // Releasing data for pipeline parallism.
  // Filters will know it is empty.
  output->ReleaseData();
  output->Delete();
}

//----------------------------------------------------------------------------
vtkNewickTreeReader::~vtkNewickTreeReader()
{
}

//----------------------------------------------------------------------------
vtkTree* vtkNewickTreeReader::GetOutput()
{
  return this->GetOutput(0);
}

//----------------------------------------------------------------------------
vtkTree* vtkNewickTreeReader::GetOutput(int idx)
{
  return vtkTree::SafeDownCast(this->GetOutputDataObject(idx));
}

//----------------------------------------------------------------------------
void vtkNewickTreeReader::SetOutput(vtkTree *output)
{
  this->GetExecutive()->SetOutputData(0, output);
}

//----------------------------------------------------------------------------
// I do not think this should be here, but I do not want to remove it now.
int vtkNewickTreeReader::RequestUpdateExtent(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  int piece, numPieces;

  piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  numPieces = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());

  // make sure piece is valid
  if (piece < 0 || piece >= numPieces)
    {
    return 1;
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkNewickTreeReader:: ReadNewickTree(  const char *  buffer, vtkTree & tree)
{
  // Read through the input file to count the number of nodes in the tree.
  // We start at one to account for the root node
  vtkIdType numNodes = 1;
  this->CountNodes(buffer, &numNodes);

  // Create the edge weight array
  vtkNew<vtkDoubleArray> weights;
  weights->SetNumberOfComponents(1);
  weights->SetName("weight");
  weights->SetNumberOfValues(numNodes-1);//the number of edges = number of nodes -1 for a tree
  weights->FillComponent(0, 0.0);

  // Create the names array
  vtkNew<vtkStringArray> names;
  names->SetNumberOfComponents(1);
  names->SetName("node name");
  names->SetNumberOfValues(numNodes);

  //parse the input file to create the graph
  vtkNew<vtkMutableDirectedGraph> builder;
  this->BuildTree(const_cast<char*> (buffer), builder.GetPointer(), weights.GetPointer(),
    names.GetPointer(), -1);

  builder->GetEdgeData()->AddArray(weights.GetPointer());
  builder->GetVertexData()->AddArray(names.GetPointer());

  if (!tree.CheckedShallowCopy(builder.GetPointer()))
    {
    vtkErrorMacro(<<"Edges do not create a valid tree.");
    return 1;
    }

  vtkNew<vtkDoubleArray> nodeWeights;
  nodeWeights->SetNumberOfTuples(tree.GetNumberOfVertices());

  //set node weights
  vtkNew<vtkTreeDFSIterator> treeIterator;
  treeIterator->SetStartVertex(tree.GetRoot());
  treeIterator->SetTree(&tree);
  while (treeIterator->HasNext())
    {
    vtkIdType vertex = treeIterator->Next();
    vtkIdType parent = tree.GetParent(vertex);
    double weight = 0.0;
    if (parent >= 0)
      {
      weight = weights->GetValue(tree.GetEdgeId(parent, vertex));
      weight += nodeWeights->GetValue(parent);
      }
    nodeWeights->SetValue(vertex, weight);
    }

  nodeWeights->SetName("node weight");
  tree.GetVertexData()->AddArray(nodeWeights.GetPointer());

  return 1;

}
//----------------------------------------------------------------------------
int vtkNewickTreeReader::RequestData(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // Return all data in the first piece ...
  if(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
    {
    return 1;
    }

  vtkDebugMacro(<<"Reading Newick tree ...");

  if( !this->ReadFromInputString)
    {
    if(!this->GetFileName())
      {
      vtkErrorMacro("FileName not set.");
      return 1;
      }

    std::ifstream ifs( this->GetFileName(), std::ifstream::in );
    if(!ifs.good())
      {
      vtkErrorMacro(<<"Unable to open " << this->GetFileName() << " for reading");
      return 1;
      }

    // Read the input file into a char *
    ifs.seekg(0, std::ios::end);
    this->InputStringLength = ifs.tellg();
    ifs.seekg(0, std::ios::beg);
    this->InputString = new char[this->InputStringLength];
    ifs.read(this->InputString, this->InputStringLength);
    ifs.close();
    }
  else
    {
    if ( (!this->InputString) || (this->InputStringLength == 0))
      {
      vtkErrorMacro(<<"Input string is empty!");
      return 1;
      }
    }

  vtkTree* const output = vtkTree::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  if(!ReadNewickTree(this->InputString, *output))
    {
    vtkErrorMacro(<<"Error reading a vtkTree from the input.");
    return 1;
    }

  vtkDebugMacro(<< "Read " << output->GetNumberOfVertices() <<" vertices and "
    << output->GetNumberOfEdges() <<" edges.\n");

  return 1;
}

void vtkNewickTreeReader::CountNodes(const char *buffer, vtkIdType *numNodes)
{
  char *current;
  char *start;
  char temp;
  int childCount;

  start = const_cast<char*>(buffer);

  if (*start != '(')
  {
    // Leaf node. Separate name from weight.
    // If weight doesn't exist then take care of name only
    current = const_cast<char*>(buffer);
    while (*current != '\0')
    {
      current++;
    }
    ++(*numNodes);
  }
  else
  {
    ++(*numNodes);
    // Search for all child nodes
    // Find all ',' until corresponding ')' is encountered
    childCount = 0;
    start++;
    current = start;
    while (childCount >= 0)
    {
      switch (*current)
      {
        case '(':
          // Find corresponding ')' by counting
          start = current;
          current++;
          childCount++;
          while (childCount > 0)
          {
            if (*current == '(')
            {
              childCount++;
            }
            else if (*current == ')')
            {
              childCount--;
            }
            current++;
          }
          while (*current != ',' && *current != ')')
          {
            current++;
          }

          temp = *current;
          *current = '\0';
          // Count child nodes using recursion
          this->CountNodes(start, numNodes);
          *current = temp;

          if (*current != ')')
          {
            current++;
          }
        break;

        case ')':
          // End of this tree. Go to next part to retrieve distance
          childCount--;
        break;

        case ',':
          // Impossible separation since according to the algorithm, this symbol will never encountered.
          // Currently don't handle this and don't create any node
        break;

        default:
          // leaf node encountered
          start = current;
          while (*current != ',' && *current != ')')
          {
            current++;
          }

          temp = *current;
          *current = '\0';
          // Count child nodes using recursion
          this->CountNodes(start, numNodes);
          *current = temp;

          if (*current != ')')
          {
            current++;
          }
        break;
      }
    }

    // If start at ':', then the internal node has no name.
    current++;
    if (*current == ':')
    {
      start = current + 1;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
    }
    else if (*current != ';' && *current != '\0')
    {
      while (*current != ':' && *(current+1) != ';' && *(current+1) != '\0')
      {
        current++;
      }
      current++;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
    }
  }
}

vtkIdType vtkNewickTreeReader::BuildTree(char *buffer,
  vtkMutableDirectedGraph *g, vtkDoubleArray *weights, vtkStringArray *names,
  vtkIdType parent)
{
  char *current;
  char *start;
  char *colon = NULL;
  char temp;
  int childCount;
  vtkIdType node;

  start = buffer;

  if(parent == -1)
    {
    parent = g->AddVertex();
    names->SetValue(parent, "");
    }

  if (*start != '(')
  {
    // Leaf node. Separate name from weight (if it exists).
    current = buffer;
    while (*current != '\0')
    {
      if (*current == ':')
      {
        colon = current;
      }
      current++;
    }
    node = g->AddChild(parent);
    if (colon == NULL)
    {
      // Name only
      std::string name(start, strlen(start));
      names->SetValue(node, name);
    }
    else
    {
      // Name
      *colon = '\0';
      std::string name(start, strlen(start));
      names->SetValue(node, name);
      *colon = ':';
      // Weight
      colon++;
      weights->SetValue(g->GetEdgeId(parent, node), atof(colon));
    }
  }
  else
  {
    // Create node
    node = g->AddChild(parent);

    // Search for all child nodes
    // Find all ',' until corresponding ')' is encountered
    childCount = 0;
    start++;
    current = start;
    while (childCount >= 0)
    {
      switch (*current)
      {
        case '(':
          // Find corresponding ')' by counting
          start = current;
          current++;
          childCount++;
          while (childCount > 0)
          {
            if (*current == '(')
            {
              childCount++;
            }
            else if (*current == ')')
            {
              childCount--;
            }
            current++;
          }
          while (*current != ',' && *current != ')')
          {
            current++;
          }
          temp = *current;
          *current = '\0';
          // Create a child node using recursion
          this->BuildTree(start, g, weights, names, node);
          *current = temp;
          if (*current != ')')
          {
            current++;
          }
        break;

        case ')':
          // End of this tree. Go to next part to retrieve distance
          childCount--;
        break;

        case ',':
          // Impossible separation since according to the algorithm, this symbol will never encountered.
          // Currently don't handle this and don't create any node
        break;

        default:
          // leaf node encountered
          start = current;
          while (*current != ',' && *current != ')')
          {
            current++;
          }
          temp = *current;
          *current = '\0';
          // Create a child node using recursion
          this->BuildTree(start, g, weights, names, node);
          *current = temp;
          if (*current != ')')
          {
            current++;
          }
        break;
      }
    }

    // If start at ':', then the internal node has no name.
    current++;
    if (*current == ':')
    {
      start = current + 1;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
      temp = *current;
      *current = '\0';
      weights->SetValue(g->GetEdgeId(parent, node), atof(start));
      names->SetValue(node, "");
      *current = temp;
    }
    else if (*current != ';' && *current != '\0')
    {
      // Find ':' to retrieve distance, if any.
      // At this time *current should equal to ')'
      start = current;
      while (*current != ':')
      {
        current++;
      }
      temp = *current;
      *current = '\0';
      std::string name(start, strlen(start));
      names->SetValue(node, name);
      *current = temp;
      current++;
      start = current;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
      temp = *current;
      *current = '\0';
      weights->SetValue(g->GetEdgeId(parent, node), atof(start));
      *current = temp;
    }
  }

  return node;
}

//----------------------------------------------------------------------------
int vtkNewickTreeReader::FillOutputPortInformation(int, vtkInformation* info)
{
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTree");
  return 1;
}

//----------------------------------------------------------------------------
void vtkNewickTreeReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "FileName: "
     << (this->FileName ? this->FileName : "(none)") << endl;
  os << indent << "InputString: "
     << (this->InputString ? this->InputString : "(none)") << endl;
  os << indent << "ReadFromInputString: "
     << (this->ReadFromInputString ? "on" : "off") << endl;
}
<commit_msg>support Newick files with no edge weights<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkNewickTreeReader.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 "vtkNewickTreeReader.h"

#include "vtkByteSwap.h"
#include "vtkCellArray.h"
#include "vtkDataSetAttributes.h"
#include "vtkDoubleArray.h"
#include "vtkFieldData.h"
#include "vtkNew.h"
#include "vtkTree.h"
#include "vtkTreeDFSIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMutableDirectedGraph.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStringArray.h"

#include <iostream>
#include <fstream>

vtkStandardNewMacro(vtkNewickTreeReader);

#ifdef read
#undef read
#endif

//----------------------------------------------------------------------------
vtkNewickTreeReader::vtkNewickTreeReader()
{
  vtkTree *output = vtkTree::New();
  this->SetOutput(output);
  // Releasing data for pipeline parallelism.
  // Filters will know it is empty.
  output->ReleaseData();
  output->Delete();
}

//----------------------------------------------------------------------------
vtkNewickTreeReader::~vtkNewickTreeReader()
{
}

//----------------------------------------------------------------------------
vtkTree* vtkNewickTreeReader::GetOutput()
{
  return this->GetOutput(0);
}

//----------------------------------------------------------------------------
vtkTree* vtkNewickTreeReader::GetOutput(int idx)
{
  return vtkTree::SafeDownCast(this->GetOutputDataObject(idx));
}

//----------------------------------------------------------------------------
void vtkNewickTreeReader::SetOutput(vtkTree *output)
{
  this->GetExecutive()->SetOutputData(0, output);
}

//----------------------------------------------------------------------------
// I do not think this should be here, but I do not want to remove it now.
int vtkNewickTreeReader::RequestUpdateExtent(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  int piece, numPieces;

  piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  numPieces = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());

  // make sure piece is valid
  if (piece < 0 || piece >= numPieces)
    {
    return 1;
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkNewickTreeReader:: ReadNewickTree(  const char *  buffer, vtkTree & tree)
{
  // Read through the input file to count the number of nodes in the tree.
  // We start at one to account for the root node
  vtkIdType numNodes = 1;
  this->CountNodes(buffer, &numNodes);

  // Create the edge weight array
  vtkNew<vtkDoubleArray> weights;
  weights->SetNumberOfComponents(1);
  weights->SetName("weight");
  weights->SetNumberOfValues(numNodes-1);//the number of edges = number of nodes -1 for a tree
  weights->FillComponent(0, 0.0);

  // Create the names array
  vtkNew<vtkStringArray> names;
  names->SetNumberOfComponents(1);
  names->SetName("node name");
  names->SetNumberOfValues(numNodes);

  // parse the input file to create the graph
  vtkNew<vtkMutableDirectedGraph> builder;
  this->BuildTree(const_cast<char*> (buffer), builder.GetPointer(), weights.GetPointer(),
    names.GetPointer(), -1);

  // check if our input file contained edge weight information
  bool haveWeights = false;
  for (vtkIdType i = 0; i < weights->GetNumberOfTuples(); ++i)
    {
    if (weights->GetValue(i) != 0.0)
      {
      haveWeights = true;
      break;
      }
    }
  // if not, make it so each edge has a weight of 1.0.
  if (!haveWeights)
    {
    weights->FillComponent(0, 1.0);
    }

  builder->GetEdgeData()->AddArray(weights.GetPointer());
  builder->GetVertexData()->AddArray(names.GetPointer());

  if (!tree.CheckedShallowCopy(builder.GetPointer()))
    {
    vtkErrorMacro(<<"Edges do not create a valid tree.");
    return 1;
    }

  vtkNew<vtkDoubleArray> nodeWeights;
  nodeWeights->SetNumberOfTuples(tree.GetNumberOfVertices());

  //set node weights
  vtkNew<vtkTreeDFSIterator> treeIterator;
  treeIterator->SetStartVertex(tree.GetRoot());
  treeIterator->SetTree(&tree);
  while (treeIterator->HasNext())
    {
    vtkIdType vertex = treeIterator->Next();
    vtkIdType parent = tree.GetParent(vertex);
    double weight = 0.0;
    if (parent >= 0)
      {
      weight = weights->GetValue(tree.GetEdgeId(parent, vertex));
      weight += nodeWeights->GetValue(parent);
      }
    nodeWeights->SetValue(vertex, weight);
    }

  nodeWeights->SetName("node weight");
  tree.GetVertexData()->AddArray(nodeWeights.GetPointer());

  return 1;
}

//----------------------------------------------------------------------------
int vtkNewickTreeReader::RequestData(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // Return all data in the first piece ...
  if(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
    {
    return 1;
    }

  vtkDebugMacro(<<"Reading Newick tree ...");

  if( !this->ReadFromInputString)
    {
    if(!this->GetFileName())
      {
      vtkErrorMacro("FileName not set.");
      return 1;
      }

    std::ifstream ifs( this->GetFileName(), std::ifstream::in );
    if(!ifs.good())
      {
      vtkErrorMacro(<<"Unable to open " << this->GetFileName() << " for reading");
      return 1;
      }

    // Read the input file into a char *
    ifs.seekg(0, std::ios::end);
    this->InputStringLength = ifs.tellg();
    ifs.seekg(0, std::ios::beg);
    this->InputString = new char[this->InputStringLength];
    ifs.read(this->InputString, this->InputStringLength);
    ifs.close();
    }
  else
    {
    if ( (!this->InputString) || (this->InputStringLength == 0))
      {
      vtkErrorMacro(<<"Input string is empty!");
      return 1;
      }
    }

  vtkTree* const output = vtkTree::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  if(!ReadNewickTree(this->InputString, *output))
    {
    vtkErrorMacro(<<"Error reading a vtkTree from the input.");
    return 1;
    }

  vtkDebugMacro(<< "Read " << output->GetNumberOfVertices() <<" vertices and "
    << output->GetNumberOfEdges() <<" edges.\n");

  return 1;
}

//----------------------------------------------------------------------------
void vtkNewickTreeReader::CountNodes(const char *buffer, vtkIdType *numNodes)
{
  char *current;
  char *start;
  char temp;
  int childCount;

  start = const_cast<char*>(buffer);

  if (*start != '(')
  {
    // Leaf node. Separate name from weight.
    // If weight doesn't exist then take care of name only
    current = const_cast<char*>(buffer);
    while (*current != '\0')
    {
      current++;
    }
    ++(*numNodes);
  }
  else
  {
    ++(*numNodes);
    // Search for all child nodes
    // Find all ',' until corresponding ')' is encountered
    childCount = 0;
    start++;
    current = start;
    while (childCount >= 0)
    {
      switch (*current)
      {
        case '(':
          // Find corresponding ')' by counting
          start = current;
          current++;
          childCount++;
          while (childCount > 0)
          {
            if (*current == '(')
            {
              childCount++;
            }
            else if (*current == ')')
            {
              childCount--;
            }
            current++;
          }
          while (*current != ',' && *current != ')')
          {
            current++;
          }

          temp = *current;
          *current = '\0';
          // Count child nodes using recursion
          this->CountNodes(start, numNodes);
          *current = temp;

          if (*current != ')')
          {
            current++;
          }
        break;

        case ')':
          // End of this tree. Go to next part to retrieve distance
          childCount--;
        break;

        case ',':
          // Impossible separation since according to the algorithm, this symbol will never encountered.
          // Currently don't handle this and don't create any node
        break;

        default:
          // leaf node encountered
          start = current;
          while (*current != ',' && *current != ')')
          {
            current++;
          }

          temp = *current;
          *current = '\0';
          // Count child nodes using recursion
          this->CountNodes(start, numNodes);
          *current = temp;

          if (*current != ')')
          {
            current++;
          }
        break;
      }
    }

    // If start at ':', then the internal node has no name.
    current++;
    if (*current == ':')
    {
      start = current + 1;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
    }
    else if (*current != ';' && *current != '\0')
    {
      while (*current != ':' && *(current+1) != ';' && *(current+1) != '\0')
      {
        current++;
      }
      current++;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
    }
  }
}

//----------------------------------------------------------------------------
vtkIdType vtkNewickTreeReader::BuildTree(char *buffer,
  vtkMutableDirectedGraph *g, vtkDoubleArray *weights, vtkStringArray *names,
  vtkIdType parent)
{
  char *current;
  char *start;
  char *colon = NULL;
  char temp;
  int childCount;
  vtkIdType node;

  start = buffer;

  if(parent == -1)
    {
    parent = g->AddVertex();
    names->SetValue(parent, "");
    }

  if (*start != '(')
  {
    // Leaf node. Separate name from weight (if it exists).
    current = buffer;
    while (*current != '\0')
    {
      if (*current == ':')
      {
        colon = current;
      }
      current++;
    }
    node = g->AddChild(parent);
    if (colon == NULL)
    {
      // Name only
      std::string name(start, strlen(start));
      names->SetValue(node, name);
    }
    else
    {
      // Name
      *colon = '\0';
      std::string name(start, strlen(start));
      names->SetValue(node, name);
      *colon = ':';
      // Weight
      colon++;
      weights->SetValue(g->GetEdgeId(parent, node), atof(colon));
    }
  }
  else
  {
    // Create node
    node = g->AddChild(parent);

    // Search for all child nodes
    // Find all ',' until corresponding ')' is encountered
    childCount = 0;
    start++;
    current = start;
    while (childCount >= 0)
    {
      switch (*current)
      {
        case '(':
          // Find corresponding ')' by counting
          start = current;
          current++;
          childCount++;
          while (childCount > 0)
          {
            if (*current == '(')
            {
              childCount++;
            }
            else if (*current == ')')
            {
              childCount--;
            }
            current++;
          }
          while (*current != ',' && *current != ')')
          {
            current++;
          }
          temp = *current;
          *current = '\0';
          // Create a child node using recursion
          this->BuildTree(start, g, weights, names, node);
          *current = temp;
          if (*current != ')')
          {
            current++;
          }
        break;

        case ')':
          // End of this tree. Go to next part to retrieve distance
          childCount--;
        break;

        case ',':
          // Impossible separation since according to the algorithm, this symbol will never encountered.
          // Currently don't handle this and don't create any node
        break;

        default:
          // leaf node encountered
          start = current;
          while (*current != ',' && *current != ')')
          {
            current++;
          }
          temp = *current;
          *current = '\0';
          // Create a child node using recursion
          this->BuildTree(start, g, weights, names, node);
          *current = temp;
          if (*current != ')')
          {
            current++;
          }
        break;
      }
    }

    // If start at ':', then the internal node has no name.
    current++;
    if (*current == ':')
    {
      start = current + 1;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
      temp = *current;
      *current = '\0';
      weights->SetValue(g->GetEdgeId(parent, node), atof(start));
      names->SetValue(node, "");
      *current = temp;
    }
    else if (*current != ';' && *current != '\0')
    {
      // Find ':' to retrieve distance, if any.
      // At this time *current should equal to ')'
      start = current;
      while (*current != ':')
      {
        current++;
      }
      temp = *current;
      *current = '\0';
      std::string name(start, strlen(start));
      names->SetValue(node, name);
      *current = temp;
      current++;
      start = current;
      while (*current != '\0' && *current != ';')
      {
        current++;
      }
      temp = *current;
      *current = '\0';
      weights->SetValue(g->GetEdgeId(parent, node), atof(start));
      *current = temp;
    }
  }

  return node;
}

//----------------------------------------------------------------------------
int vtkNewickTreeReader::FillOutputPortInformation(int, vtkInformation* info)
{
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTree");
  return 1;
}

//----------------------------------------------------------------------------
void vtkNewickTreeReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "FileName: "
     << (this->FileName ? this->FileName : "(none)") << endl;
  os << indent << "InputString: "
     << (this->InputString ? this->InputString : "(none)") << endl;
  os << indent << "ReadFromInputString: "
     << (this->ReadFromInputString ? "on" : "off") << endl;
}
<|endoftext|>