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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROISpot5.tif}, {ROISpot5Warped.png}
//    OUTPUTS: {SIFTdeformationFieldOutput.png}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{KeyPointSetsMatchingFilter} for disparity map
// estimation. The idea here is to match SIFTs extracted from both the
// fixed and the moving images. The use of SIFTs is demonstrated in
// section \ref{sec:SIFTDetector}. The
// \doxygen{otb}{NearestPointDeformationFieldGenerator} will be used
// to generate a deformation field by using nearest neighbor
// interpolation on the deformation values from the point set. More
// advanced methods for deformation field interpolation are also
// available.
//
// The first step toward the use of these filters is to include the proper header files.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

#include "otbKeyPointSetsMatchingFilter.h"
#include "otbSiftFastImageFilter.h"
#include "itkDeformationFieldSource.h"
#include "itkWarpImageFilter.h"

// Software Guide : EndCodeSnippet

#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkPointSet.h"
#include "otbMultiToMonoChannelExtractROI.h"

int main (int argc, char* argv[])
{
  if(argc!= 4)
    {
      std::cerr <<"Usage: "<<argv[0];
      std::cerr<<"fixedFileName movingFileName fieldOutName" << std::endl;
      return EXIT_FAILURE;
    }

  const unsigned int Dimension = 2;

   // Software Guide : BeginLatex
   //
   // Then we must decide what pixel type to use for the image. We choose to do
   // all the computation in floating point precision and rescale the results
   // between 0 and 255 in order to export PNG images.
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef double        RealType;
  typedef unsigned char OutputPixelType;

  typedef otb::Image<RealType,Dimension> ImageType;
  typedef otb::Image<OutputPixelType,Dimension> OutputImageType;

  // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
   //
   // The SIFTs obtained for the matching will be stored in vector
   // form inside a point set. So we need the following types:
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::VariableLengthVector<RealType> RealVectorType;
  typedef itk::PointSet<RealVectorType,Dimension> PointSetType;

    // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
   //
   // The filter for computing the SIFTs has a type defined as follows:
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::SiftFastImageFilter<ImageType,PointSetType> ImageToSIFTKeyPointSetFilterType;

  // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
   //
   // Although many choices for evaluating the distances during the
   // matching procedure exist, we choose here to use a simple
   // Euclidean distance. We can then define the type for the matching filter.
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::Statistics::EuclideanDistance<RealVectorType> DistanceType;
  typedef otb::KeyPointSetsMatchingFilter<PointSetType, DistanceType>
                                      EuclideanDistanceMatchingFilterType;
    // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
   //
   // The following types are needed for dealing with the matched points.
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef PointSetType::PointType PointType;
  typedef std::pair<PointType,PointType> MatchType;
  typedef std::vector<MatchType> MatchVectorType;
  typedef EuclideanDistanceMatchingFilterType::LandmarkListType LandmarkListType;

  typedef PointSetType::PointsContainer PointsContainerType;
  typedef PointsContainerType::Iterator PointsIteratorType;
  typedef PointSetType::PointDataContainer PointDataContainerType;
  typedef PointDataContainerType::Iterator PointDataIteratorType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We define the type for the image reader.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::ImageFileReader<ImageType> ReaderType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Two readers are instantiated : one for the fixed image, and one for the moving image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ReaderType::Pointer fixedReader = ReaderType::New();
  ReaderType::Pointer movingReader = ReaderType::New();

  fixedReader->SetFileName(argv[1]);
  movingReader->SetFileName(argv[2]);
  fixedReader->UpdateOutputInformation();
  movingReader->UpdateOutputInformation();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We will now instantiate the 2 SIFT filters and the filter used
  // for the matching of the points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
                              ImageToSIFTKeyPointSetFilterType::New();
  ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
                              ImageToSIFTKeyPointSetFilterType::New();
  EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
                           EuclideanDistanceMatchingFilterType::New();
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We plug the pipeline and set the parameters.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  double secondOrderThreshold = 0.5;
  bool useBackMatching = 0;

  filter1->SetInput(0, fixedReader->GetOutput() );
  filter1->SetNumberOfScales(3);
  filter2->SetInput(0, movingReader->GetOutput() );
  filter2->SetNumberOfScales(3);

  euclideanMatcher->SetInput1(filter1->GetOutput());
  euclideanMatcher->SetInput2(filter2->GetOutput());
  euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
  euclideanMatcher->SetUseBackMatching(useBackMatching);
  euclideanMatcher->Update();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The matched points will be stored into a landmark list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  LandmarkListType::Pointer landmarkList;
  landmarkList = euclideanMatcher->GetOutput();

  // Software Guide : EndCodeSnippet
  MatchVectorType trueSecondOrder;

  for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it)
    {
      PointType point1 = it.Get()->GetPoint1();
      PointType point2 = it.Get()->GetPoint2();

      trueSecondOrder.push_back(MatchType(point1,point2));
    }

    // Displaying the matches
  typedef itk::RescaleIntensityImageFilter<ImageType, OutputImageType>
    PrintableFilterType;

  PrintableFilterType::Pointer printable1 = PrintableFilterType::New();
  PrintableFilterType::Pointer printable2 = PrintableFilterType::New();

  printable1->SetInput(fixedReader->GetOutput());
  printable1->SetOutputMinimum(0);
  printable1->SetOutputMaximum(255);
  printable1->Update();

  printable2->SetInput(movingReader->GetOutput());
  printable2->SetOutputMinimum(0);
  printable2->SetOutputMaximum(255);
  printable2->Update();

  typedef otb::Image<itk::RGBPixel<unsigned char>,2> RGBImageType;

  RGBImageType::Pointer rgbimage1 = RGBImageType::New();
  rgbimage1->SetRegions(printable1->GetOutput()->GetLargestPossibleRegion());
  rgbimage1->Allocate();
  itk::ImageRegionIterator<RGBImageType> outIt1(rgbimage1,rgbimage1->GetLargestPossibleRegion());
  itk::ImageRegionIterator<OutputImageType> inIt1(printable1->GetOutput(),printable1->GetOutput()->GetLargestPossibleRegion());
  outIt1.GoToBegin();
  inIt1.GoToBegin();
  while(!inIt1.IsAtEnd() && !outIt1.IsAtEnd())
    {
      itk::RGBPixel<unsigned char> pixel;
      pixel.SetRed(inIt1.Get());
      pixel.SetGreen(inIt1.Get());
      pixel.SetBlue(inIt1.Get());
      outIt1.Set(pixel);
      ++inIt1;
      ++outIt1;
    }

  RGBImageType::Pointer rgbimage2 = RGBImageType::New();
  rgbimage2->SetRegions(printable2->GetOutput()->GetLargestPossibleRegion());
  rgbimage2->Allocate();
  itk::ImageRegionIterator<RGBImageType> outIt2(rgbimage2,rgbimage2->GetLargestPossibleRegion());
  itk::ImageRegionIterator<OutputImageType> inIt2(printable2->GetOutput(),printable2->GetOutput()->GetLargestPossibleRegion());
  outIt2.GoToBegin();
  inIt2.GoToBegin();
  while(!inIt2.IsAtEnd() && !outIt2.IsAtEnd())
    {
      itk::RGBPixel<unsigned char> pixel;
      pixel.SetRed(inIt2.Get());
      pixel.SetGreen(inIt2.Get());
      pixel.SetBlue(inIt2.Get());
      outIt2.Set(pixel);
      ++inIt2;
      ++outIt2;
    }

  // Software Guide : BeginLatex
  //
  // The landmarks are used for building a deformation field. The
  // deformation field is an image of vectors created by the
  // \doxygen{itk}{DeformationFieldSource} class.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef   itk::Vector< RealType, Dimension >    VectorType;
  typedef   otb::Image< VectorType,  Dimension >   DeformationFieldType;

  typedef itk::DeformationFieldSource<
                                DeformationFieldType
                                             >  DeformationSourceType;

  DeformationSourceType::Pointer deformer = DeformationSourceType::New();

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The deformation field needs information about the extent and
  // spacing of the images on which it is defined.
  //
  // Software Guide : EndLatex

  ImageType::ConstPointer fixedImage = fixedReader->GetOutput();

  deformer->SetOutputSpacing( fixedImage->GetSpacing() );
  deformer->SetOutputOrigin(  fixedImage->GetOrigin() );
  deformer->SetOutputRegion(  fixedImage->GetLargestPossibleRegion() );

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // We will need some intermediate variables in order to pass the
  // matched SIFTs to the deformation field source.
  //
  // Software Guide : EndLatex

  typedef DeformationSourceType::LandmarkContainerPointer
                                              LandmarkContainerPointer;
  typedef DeformationSourceType::LandmarkContainer
                                                 LandmarkContainerType;
  typedef DeformationSourceType::LandmarkPointType          LandmarkPointType;

  LandmarkContainerType::Pointer sourceLandmarks = LandmarkContainerType::New();
  LandmarkContainerType::Pointer targetLandmarks = LandmarkContainerType::New();

  LandmarkPointType sourcePoint;
  LandmarkPointType targetPoint;

// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // We can now iterate through the list of matched points and store
  // them in the intermediate landmark sets.
  //
  // Software Guide : EndLatex

  unsigned int pointId = 0;

    for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it)
    {
      PointType point1 = it.Get()->GetPoint1();
      PointType point2 = it.Get()->GetPoint2();

      sourcePoint[0] = point1[0];
      sourcePoint[1] = point1[1];

      targetPoint[0] = point2[0];
      targetPoint[1] = point2[1];

      sourceLandmarks->InsertElement( pointId, sourcePoint );
      targetLandmarks->InsertElement( pointId, targetPoint );

      std::cout << sourcePoint << " " << targetPoint << std::endl;

      ++pointId;
    }

// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // We pass the landmarks to the deformer and we run it.
  //
  // Software Guide : EndLatex

  deformer->SetSourceLandmarks( sourceLandmarks.GetPointer() );
  deformer->SetTargetLandmarks( targetLandmarks.GetPointer() );

  deformer->UpdateLargestPossibleRegion();

  DeformationFieldType::ConstPointer deformationField = deformer->GetOutput();

  deformer->Update();

  // Software Guide : EndCodeSnippet

  ImageType::Pointer outdf = ImageType::New();
  outdf->SetRegions(fixedReader->GetOutput()->GetLargestPossibleRegion());
  outdf->Allocate();

  itk::ImageRegionIterator<ImageType> outIt(outdf,outdf->GetLargestPossibleRegion());

  itk::ImageRegionIterator<DeformationFieldType> inIt(deformer->GetOutput(),deformer->GetOutput()->GetLargestPossibleRegion());
  outIt.GoToBegin();
  inIt.GoToBegin();

  while(!inIt.IsAtEnd() && !outIt.IsAtEnd())
    {

    std::cout << inIt.Get() << std::endl;

      outIt.Set(inIt.Get()[1]);

      ++inIt;
      ++outIt;
    }

  typedef itk::RescaleIntensityImageFilter< ImageType,
                                         OutputImageType> RescaleType;

  RescaleType::Pointer rescaler = RescaleType::New();
  rescaler->SetInput( outdf );
  rescaler->SetOutputMinimum(0);
  rescaler->SetOutputMaximum(255);

  typedef otb::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( rescaler->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

    // Software Guide : BeginLatex
  //
  // Figure~\ref{fig:SIFTDME} shows the result of applying the SIFT
  // disparity map estimation. Only the horizontal component of the
  // deformation is shown.
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=0.40\textwidth]{ROISpot5.eps}
  // \includegraphics[width=0.40\textwidth]{ROISpot5Warped.eps}
  // \includegraphics[width=0.40\textwidth]{SIFTdeformationFieldOutput.eps}
  // \itkcaption[Deformation field from SIFT disparity map estimation]{From left
  // to right and top to bottom: fixed input image, moving image with a sinusoid deformation,
  // estimated deformation field in the horizontal direction.}
  // \label{fig:SIFTDME}
  // \end{figure}
  //
  // Software Guide : EndLatex

  return EXIT_SUCCESS;
}

<commit_msg>DOC: typo in latex<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROISpot5.tif}, {ROISpot5Warped.png}
//    OUTPUTS: {SIFTdeformationFieldOutput.png}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{KeyPointSetsMatchingFilter} for disparity map
// estimation. The idea here is to match SIFTs extracted from both the
// fixed and the moving images. The use of SIFTs is demonstrated in
// section \ref{sec:SIFTDetector}. The
// \doxygen{otb}{NearestPointDeformationFieldGenerator} will be used
// to generate a deformation field by using nearest neighbor
// interpolation on the deformation values from the point set. More
// advanced methods for deformation field interpolation are also
// available.
//
// The first step toward the use of these filters is to include the proper header files.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

#include "otbKeyPointSetsMatchingFilter.h"
#include "otbSiftFastImageFilter.h"
#include "itkDeformationFieldSource.h"
#include "itkWarpImageFilter.h"

// Software Guide : EndCodeSnippet

#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkPointSet.h"
#include "otbMultiToMonoChannelExtractROI.h"

int main (int argc, char* argv[])
{
  if(argc!= 4)
    {
      std::cerr <<"Usage: "<<argv[0];
      std::cerr<<"fixedFileName movingFileName fieldOutName" << std::endl;
      return EXIT_FAILURE;
    }

  const unsigned int Dimension = 2;

   // Software Guide : BeginLatex
   //
   // Then we must decide what pixel type to use for the image. We choose to do
   // all the computation in floating point precision and rescale the results
   // between 0 and 255 in order to export PNG images.
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef double        RealType;
  typedef unsigned char OutputPixelType;

  typedef otb::Image<RealType,Dimension> ImageType;
  typedef otb::Image<OutputPixelType,Dimension> OutputImageType;

  // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
   //
   // The SIFTs obtained for the matching will be stored in vector
   // form inside a point set. So we need the following types:
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::VariableLengthVector<RealType> RealVectorType;
  typedef itk::PointSet<RealVectorType,Dimension> PointSetType;

    // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
   //
   // The filter for computing the SIFTs has a type defined as follows:
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::SiftFastImageFilter<ImageType,PointSetType> ImageToSIFTKeyPointSetFilterType;

  // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
   //
   // Although many choices for evaluating the distances during the
   // matching procedure exist, we choose here to use a simple
   // Euclidean distance. We can then define the type for the matching filter.
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::Statistics::EuclideanDistance<RealVectorType> DistanceType;
  typedef otb::KeyPointSetsMatchingFilter<PointSetType, DistanceType>
                                      EuclideanDistanceMatchingFilterType;
    // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
   //
   // The following types are needed for dealing with the matched points.
   //
   // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef PointSetType::PointType PointType;
  typedef std::pair<PointType,PointType> MatchType;
  typedef std::vector<MatchType> MatchVectorType;
  typedef EuclideanDistanceMatchingFilterType::LandmarkListType LandmarkListType;

  typedef PointSetType::PointsContainer PointsContainerType;
  typedef PointsContainerType::Iterator PointsIteratorType;
  typedef PointSetType::PointDataContainer PointDataContainerType;
  typedef PointDataContainerType::Iterator PointDataIteratorType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We define the type for the image reader.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::ImageFileReader<ImageType> ReaderType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Two readers are instantiated : one for the fixed image, and one for the moving image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ReaderType::Pointer fixedReader = ReaderType::New();
  ReaderType::Pointer movingReader = ReaderType::New();

  fixedReader->SetFileName(argv[1]);
  movingReader->SetFileName(argv[2]);
  fixedReader->UpdateOutputInformation();
  movingReader->UpdateOutputInformation();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We will now instantiate the 2 SIFT filters and the filter used
  // for the matching of the points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
                              ImageToSIFTKeyPointSetFilterType::New();
  ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
                              ImageToSIFTKeyPointSetFilterType::New();
  EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
                           EuclideanDistanceMatchingFilterType::New();
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We plug the pipeline and set the parameters.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  double secondOrderThreshold = 0.5;
  bool useBackMatching = 0;

  filter1->SetInput(0, fixedReader->GetOutput() );
  filter1->SetNumberOfScales(3);
  filter2->SetInput(0, movingReader->GetOutput() );
  filter2->SetNumberOfScales(3);

  euclideanMatcher->SetInput1(filter1->GetOutput());
  euclideanMatcher->SetInput2(filter2->GetOutput());
  euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
  euclideanMatcher->SetUseBackMatching(useBackMatching);
  euclideanMatcher->Update();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The matched points will be stored into a landmark list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  LandmarkListType::Pointer landmarkList;
  landmarkList = euclideanMatcher->GetOutput();

  // Software Guide : EndCodeSnippet
  MatchVectorType trueSecondOrder;

  for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it)
    {
      PointType point1 = it.Get()->GetPoint1();
      PointType point2 = it.Get()->GetPoint2();

      trueSecondOrder.push_back(MatchType(point1,point2));
    }

    // Displaying the matches
  typedef itk::RescaleIntensityImageFilter<ImageType, OutputImageType>
    PrintableFilterType;

  PrintableFilterType::Pointer printable1 = PrintableFilterType::New();
  PrintableFilterType::Pointer printable2 = PrintableFilterType::New();

  printable1->SetInput(fixedReader->GetOutput());
  printable1->SetOutputMinimum(0);
  printable1->SetOutputMaximum(255);
  printable1->Update();

  printable2->SetInput(movingReader->GetOutput());
  printable2->SetOutputMinimum(0);
  printable2->SetOutputMaximum(255);
  printable2->Update();

  typedef otb::Image<itk::RGBPixel<unsigned char>,2> RGBImageType;

  RGBImageType::Pointer rgbimage1 = RGBImageType::New();
  rgbimage1->SetRegions(printable1->GetOutput()->GetLargestPossibleRegion());
  rgbimage1->Allocate();
  itk::ImageRegionIterator<RGBImageType> outIt1(rgbimage1,rgbimage1->GetLargestPossibleRegion());
  itk::ImageRegionIterator<OutputImageType> inIt1(printable1->GetOutput(),printable1->GetOutput()->GetLargestPossibleRegion());
  outIt1.GoToBegin();
  inIt1.GoToBegin();
  while(!inIt1.IsAtEnd() && !outIt1.IsAtEnd())
    {
      itk::RGBPixel<unsigned char> pixel;
      pixel.SetRed(inIt1.Get());
      pixel.SetGreen(inIt1.Get());
      pixel.SetBlue(inIt1.Get());
      outIt1.Set(pixel);
      ++inIt1;
      ++outIt1;
    }

  RGBImageType::Pointer rgbimage2 = RGBImageType::New();
  rgbimage2->SetRegions(printable2->GetOutput()->GetLargestPossibleRegion());
  rgbimage2->Allocate();
  itk::ImageRegionIterator<RGBImageType> outIt2(rgbimage2,rgbimage2->GetLargestPossibleRegion());
  itk::ImageRegionIterator<OutputImageType> inIt2(printable2->GetOutput(),printable2->GetOutput()->GetLargestPossibleRegion());
  outIt2.GoToBegin();
  inIt2.GoToBegin();
  while(!inIt2.IsAtEnd() && !outIt2.IsAtEnd())
    {
      itk::RGBPixel<unsigned char> pixel;
      pixel.SetRed(inIt2.Get());
      pixel.SetGreen(inIt2.Get());
      pixel.SetBlue(inIt2.Get());
      outIt2.Set(pixel);
      ++inIt2;
      ++outIt2;
    }

  // Software Guide : BeginLatex
  //
  // The landmarks are used for building a deformation field. The
  // deformation field is an image of vectors created by the
  // \doxygen{itk}{DeformationFieldSource} class.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef   itk::Vector< RealType, Dimension >    VectorType;
  typedef   otb::Image< VectorType,  Dimension >   DeformationFieldType;

  typedef itk::DeformationFieldSource<
                                DeformationFieldType
                                             >  DeformationSourceType;

  DeformationSourceType::Pointer deformer = DeformationSourceType::New();

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The deformation field needs information about the extent and
  // spacing of the images on which it is defined.
  //
  // Software Guide : EndLatex
    // Software Guide : BeginCodeSnippet
  ImageType::ConstPointer fixedImage = fixedReader->GetOutput();

  deformer->SetOutputSpacing( fixedImage->GetSpacing() );
  deformer->SetOutputOrigin(  fixedImage->GetOrigin() );
  deformer->SetOutputRegion(  fixedImage->GetLargestPossibleRegion() );

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // We will need some intermediate variables in order to pass the
  // matched SIFTs to the deformation field source.
  //
  // Software Guide : EndLatex

  typedef DeformationSourceType::LandmarkContainerPointer
                                              LandmarkContainerPointer;
  typedef DeformationSourceType::LandmarkContainer
                                                 LandmarkContainerType;
  typedef DeformationSourceType::LandmarkPointType          LandmarkPointType;

  LandmarkContainerType::Pointer sourceLandmarks = LandmarkContainerType::New();
  LandmarkContainerType::Pointer targetLandmarks = LandmarkContainerType::New();

  LandmarkPointType sourcePoint;
  LandmarkPointType targetPoint;

// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // We can now iterate through the list of matched points and store
  // them in the intermediate landmark sets.
  //
  // Software Guide : EndLatex

  unsigned int pointId = 0;

    for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it)
    {
      PointType point1 = it.Get()->GetPoint1();
      PointType point2 = it.Get()->GetPoint2();

      sourcePoint[0] = point1[0];
      sourcePoint[1] = point1[1];

      targetPoint[0] = point2[0];
      targetPoint[1] = point2[1];

      sourceLandmarks->InsertElement( pointId, sourcePoint );
      targetLandmarks->InsertElement( pointId, targetPoint );

      std::cout << sourcePoint << " " << targetPoint << std::endl;

      ++pointId;
    }

// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // We pass the landmarks to the deformer and we run it.
  //
  // Software Guide : EndLatex

  deformer->SetSourceLandmarks( sourceLandmarks.GetPointer() );
  deformer->SetTargetLandmarks( targetLandmarks.GetPointer() );

  deformer->UpdateLargestPossibleRegion();

  DeformationFieldType::ConstPointer deformationField = deformer->GetOutput();

  deformer->Update();

  // Software Guide : EndCodeSnippet

  ImageType::Pointer outdf = ImageType::New();
  outdf->SetRegions(fixedReader->GetOutput()->GetLargestPossibleRegion());
  outdf->Allocate();

  itk::ImageRegionIterator<ImageType> outIt(outdf,outdf->GetLargestPossibleRegion());

  itk::ImageRegionIterator<DeformationFieldType> inIt(deformer->GetOutput(),deformer->GetOutput()->GetLargestPossibleRegion());
  outIt.GoToBegin();
  inIt.GoToBegin();

  while(!inIt.IsAtEnd() && !outIt.IsAtEnd())
    {

    std::cout << inIt.Get() << std::endl;

      outIt.Set(inIt.Get()[1]);

      ++inIt;
      ++outIt;
    }

  typedef itk::RescaleIntensityImageFilter< ImageType,
                                         OutputImageType> RescaleType;

  RescaleType::Pointer rescaler = RescaleType::New();
  rescaler->SetInput( outdf );
  rescaler->SetOutputMinimum(0);
  rescaler->SetOutputMaximum(255);

  typedef otb::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( rescaler->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

    // Software Guide : BeginLatex
  //
  // Figure~\ref{fig:SIFTDME} shows the result of applying the SIFT
  // disparity map estimation. Only the horizontal component of the
  // deformation is shown.
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=0.40\textwidth]{ROISpot5.eps}
  // \includegraphics[width=0.40\textwidth]{ROISpot5Warped.eps}
  // \includegraphics[width=0.40\textwidth]{SIFTdeformationFieldOutput.eps}
  // \itkcaption[Deformation field from SIFT disparity map estimation]{From left
  // to right and top to bottom: fixed input image, moving image with a sinusoid deformation,
  // estimated deformation field in the horizontal direction.}
  // \label{fig:SIFTDME}
  // \end{figure}
  //
  // Software Guide : EndLatex

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include <benchmark/benchmark.h>

#include <blackhole/attributes.hpp>
#include <blackhole/cpp17/string_view.hpp>
#include <blackhole/extensions/writer.hpp>
#include <blackhole/formatter/string.hpp>
#include <blackhole/record.hpp>

namespace blackhole {
namespace benchmark {

static
void
format_literal(::benchmark::State& state) {
    formatter::string_t formatter("message: value");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_pid(::benchmark::State& state) {
    formatter::string_t formatter("{process}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_procname(::benchmark::State& state) {
    formatter::string_t formatter("{process:s}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_message(::benchmark::State& state) {
    formatter::string_t formatter("message: {message}");

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_timestamp(::benchmark::State& state) {
    formatter::string_t formatter("{timestamp}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    record.activate();
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_severity_message(::benchmark::State& state) {
    formatter::string_t formatter("{severity:d}: {message}");

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

BENCHMARK(format_literal);
BENCHMARK(format_pid);
BENCHMARK(format_procname);
BENCHMARK(format_message);
BENCHMARK(format_timestamp);
BENCHMARK(format_severity_message);

}  // namespace benchmark
}  // namespace blackhole
<commit_msg>feat(bench): add thread format benchmark<commit_after>#include <benchmark/benchmark.h>

#include <blackhole/attributes.hpp>
#include <blackhole/cpp17/string_view.hpp>
#include <blackhole/extensions/writer.hpp>
#include <blackhole/formatter/string.hpp>
#include <blackhole/record.hpp>

namespace blackhole {
namespace benchmark {

static
void
format_literal(::benchmark::State& state) {
    formatter::string_t formatter("message: value");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_pid(::benchmark::State& state) {
    formatter::string_t formatter("{process}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_procname(::benchmark::State& state) {
    formatter::string_t formatter("{process:s}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_tid(::benchmark::State& state) {
    formatter::string_t formatter("{thread}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_message(::benchmark::State& state) {
    formatter::string_t formatter("message: {message}");

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_timestamp(::benchmark::State& state) {
    formatter::string_t formatter("{timestamp}");

    const string_view message("-");
    const attribute_pack pack;
    record_t record(0, message, pack);
    record.activate();
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

static
void
format_severity_message(::benchmark::State& state) {
    formatter::string_t formatter("{severity:d}: {message}");

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
    }

    state.SetItemsProcessed(state.iterations());
}

BENCHMARK(format_literal);
BENCHMARK(format_pid);
BENCHMARK(format_procname);
BENCHMARK(format_tid);
BENCHMARK(format_message);
BENCHMARK(format_timestamp);
BENCHMARK(format_severity_message);

}  // namespace benchmark
}  // namespace blackhole
<|endoftext|>


<commit_before>#include "uuidxx.h"
#include <random>
#include <stdio.h>
#include <inttypes.h>

using namespace std;
using namespace uuidxx;

#ifdef _WIN32
#define sscanf sscanf_s
#endif

bool uuid::operator == (const uuid & guid2) const
{
	return memcmp(&guid2, this, sizeof(uuid)) == 0;
}

bool uuid::operator != (const uuid & guid2) const
{
	return !(*this == guid2);
}

bool uuid::operator < (const uuid &guid2) const
{
	return memcmp(this, &guid2, sizeof(uuid)) < 0;
}

bool uuid::operator > (const uuid &guid2) const
{
	return memcmp(this, &guid2, sizeof(uuid)) > 0;
}

uuid::uuid (const std::string &uuidString)
	: uuid(uuidString.c_str())
{
}

uuid::uuid (const char *uuidString)
{
	if (uuidString == nullptr)
	{
		return;
	}

	if (uuidString[0] == '{')
	{
		sscanf(uuidString, "{%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%02" SCNx8 "%02" SCNx8 "-%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "}", &Uuid.Data1, &Uuid.Data2, &Uuid.Data3, &Uuid.Data4[0], &Uuid.Data4[1], &Uuid.Data4[2], &Uuid.Data4[3], &Uuid.Data4[4], &Uuid.Data4[5], &Uuid.Data4[6], &Uuid.Data4[7]);
	}
	else
	{
		sscanf(uuidString, "%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%02" SCNx8 "%02" SCNx8 "-%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "", &Uuid.Data1, &Uuid.Data2, &Uuid.Data3, &Uuid.Data4[0], &Uuid.Data4[1], &Uuid.Data4[2], &Uuid.Data4[3], &Uuid.Data4[4], &Uuid.Data4[5], &Uuid.Data4[6], &Uuid.Data4[7]);
	}
}

string uuid::ToString(bool withBraces) const
{
	char buffer[39];
#ifndef _WIN32
	sprintf(buffer, "%s%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%s", withBraces ? "{" : "", Uuid.Data1, Uuid.Data2, Uuid.Data3, Uuid.Data4[0], Uuid.Data4[1], Uuid.Data4[2], Uuid.Data4[3], Uuid.Data4[4], Uuid.Data4[5], Uuid.Data4[6], Uuid.Data4[7], withBraces ? "}" : "");
#else
	sprintf_s(buffer, 38+1, "%s%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%s", withBraces ? "{" : "", Uuid.Data1, Uuid.Data2, Uuid.Data3, Uuid.Data4[0], Uuid.Data4[1], Uuid.Data4[2], Uuid.Data4[3], Uuid.Data4[4], Uuid.Data4[5], Uuid.Data4[6], Uuid.Data4[7], withBraces ? "}" : "");
#endif
	return buffer;
}

uuid uuid::FromString(const char *uuidString)
{
	uuid temp(uuidString);
	return temp;
}

uuid uuid::FromString(const std::string &uuidString)
{
	uuid temp(uuidString.c_str());
	return temp;
}

uuid uuid::Generate()
{
//mach-o does not support TLS and clang still has issues with thread_local
#if !defined(__APPLE__) && !defined(__clang__)
	thread_local std::random_device rd;
	thread_local auto gen = std::mt19937_64(rd());
#else
	std::random_device rd;
	std::mt19937_64 gen(rd());
#endif
	std::uniform_int_distribution<uint64_t> dis64;

	uuid newGuid;
	newGuid.WideIntegers[0] = dis64(gen);
	newGuid.WideIntegers[1] = dis64(gen);

	return newGuid;
}
<commit_msg>Explicitly include string.h for memcmp/memset<commit_after>#include "uuidxx.h"
#include <random>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>

using namespace std;
using namespace uuidxx;

#ifdef _WIN32
#define sscanf sscanf_s
#endif

bool uuid::operator == (const uuid & guid2) const
{
	return memcmp(&guid2, this, sizeof(uuid)) == 0;
}

bool uuid::operator != (const uuid & guid2) const
{
	return !(*this == guid2);
}

bool uuid::operator < (const uuid &guid2) const
{
	return memcmp(this, &guid2, sizeof(uuid)) < 0;
}

bool uuid::operator > (const uuid &guid2) const
{
	return memcmp(this, &guid2, sizeof(uuid)) > 0;
}

uuid::uuid (const std::string &uuidString)
	: uuid(uuidString.c_str())
{
}

uuid::uuid (const char *uuidString)
{
	if (uuidString == nullptr)
	{
		return;
	}

	if (uuidString[0] == '{')
	{
		sscanf(uuidString, "{%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%02" SCNx8 "%02" SCNx8 "-%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "}", &Uuid.Data1, &Uuid.Data2, &Uuid.Data3, &Uuid.Data4[0], &Uuid.Data4[1], &Uuid.Data4[2], &Uuid.Data4[3], &Uuid.Data4[4], &Uuid.Data4[5], &Uuid.Data4[6], &Uuid.Data4[7]);
	}
	else
	{
		sscanf(uuidString, "%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%02" SCNx8 "%02" SCNx8 "-%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "", &Uuid.Data1, &Uuid.Data2, &Uuid.Data3, &Uuid.Data4[0], &Uuid.Data4[1], &Uuid.Data4[2], &Uuid.Data4[3], &Uuid.Data4[4], &Uuid.Data4[5], &Uuid.Data4[6], &Uuid.Data4[7]);
	}
}

string uuid::ToString(bool withBraces) const
{
	char buffer[39];
#ifndef _WIN32
	sprintf(buffer, "%s%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%s", withBraces ? "{" : "", Uuid.Data1, Uuid.Data2, Uuid.Data3, Uuid.Data4[0], Uuid.Data4[1], Uuid.Data4[2], Uuid.Data4[3], Uuid.Data4[4], Uuid.Data4[5], Uuid.Data4[6], Uuid.Data4[7], withBraces ? "}" : "");
#else
	sprintf_s(buffer, 38+1, "%s%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%s", withBraces ? "{" : "", Uuid.Data1, Uuid.Data2, Uuid.Data3, Uuid.Data4[0], Uuid.Data4[1], Uuid.Data4[2], Uuid.Data4[3], Uuid.Data4[4], Uuid.Data4[5], Uuid.Data4[6], Uuid.Data4[7], withBraces ? "}" : "");
#endif
	return buffer;
}

uuid uuid::FromString(const char *uuidString)
{
	uuid temp(uuidString);
	return temp;
}

uuid uuid::FromString(const std::string &uuidString)
{
	uuid temp(uuidString.c_str());
	return temp;
}

uuid uuid::Generate()
{
//mach-o does not support TLS and clang still has issues with thread_local
#if !defined(__APPLE__) && !defined(__clang__)
	thread_local std::random_device rd;
	thread_local auto gen = std::mt19937_64(rd());
#else
	std::random_device rd;
	std::mt19937_64 gen(rd());
#endif
	std::uniform_int_distribution<uint64_t> dis64;

	uuid newGuid;
	newGuid.WideIntegers[0] = dis64(gen);
	newGuid.WideIntegers[1] = dis64(gen);

	return newGuid;
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#define BOOST_TEST_MODULE solid_solid_collision

#include <boost/test/included/unit_test.hpp>

#include <limits>
#include <hpp/fcl/math/transform.h>
#include <hpp/fcl/shape/geometric_shapes.h>

#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/simple-device.hh>
#include <pinocchio/multibody/model.hpp>
#include <pinocchio/multibody/geometry.hpp>

#include <hpp/core/continuous-validation/solid-solid-collision.hh>

using std::numeric_limits;
using hpp::pinocchio::BodyPtr_t;
using hpp::pinocchio::CollisionObject;
using hpp::pinocchio::CollisionObjectPtr_t;
using hpp::pinocchio::Device;
using hpp::pinocchio::DevicePtr_t;
using hpp::pinocchio::JointPtr_t;
using hpp::pinocchio::JointConstPtr_t;
using hpp::pinocchio::ObjectVector_t;
using hpp::core::continuousValidation::SolidSolidCollision;
using hpp::core::continuousValidation::SolidSolidCollisionPtr_t;

using namespace hpp::core;
using namespace hpp::pinocchio;

using ::se3::JointModelRX;
using ::se3::JointModelPX;
using ::se3::JointModelPY;
using ::se3::JointModelPZ;
using ::se3::JointModelRUBX;
using ::se3::JointModelFreeFlyer;
using ::se3::JointModelSpherical;
using ::se3::JointIndex;

void display(const se3::Model& model,
    const std::vector<se3::JointIndex>& joints) {
  std::vector <se3::JointIndex>::const_iterator it;
  for (it = joints.begin (); it != joints.end (); ++it) {
    if (*it > 0) std::cout << model.names[*it];
    else         std::cout << "None";
    std::cout << ", ";
  }
  std::cout << std::endl;
}

BOOST_AUTO_TEST_SUITE( test_hpp_core )

DevicePtr_t createRobot (){
  DevicePtr_t robot = hpp::pinocchio::humanoidSimple("test");
  return robot;
}

BOOST_AUTO_TEST_CASE (solid_solid_collision_1)
{
  DevicePtr_t robot = createRobot();
  const se3::Model& model = robot->model();
  JointPtr_t joint_a = robot->getJointByBodyName ("lleg5_body");
  JointPtr_t joint_b = robot->getJointByBodyName ("rleg5_body");

  SolidSolidCollisionPtr_t bpc = SolidSolidCollision::create
    (joint_a, joint_b, 0.001);
  display(model, bpc->joints());

  ConstObjectStdVector_t obstacles;
  fcl::CollisionGeometryPtr_t box (new fcl::Box (.2, .4, .6));
  // FIXME this is a bit ugly.
  int frame_id = robot->model().addFrame(se3::Frame("base_link",0,0,Transform3f (),se3::BODY));
  BOOST_CHECK(frame_id>=0);
  ::se3::GeomIndex idObj = robot->geomModel().addGeometryObject
    (se3::GeometryObject("obstacle", frame_id, 0, box, Transform3f (), "", hpp::pinocchio::vector3_t::Ones()),
     robot->model());
  CollisionObjectPtr_t collObj (new hpp::pinocchio::CollisionObject(
        robot->geomModelPtr(), robot->geomDataPtr(), idObj));
  obstacles.push_back (collObj);
  bpc = SolidSolidCollision::create (joint_a, obstacles, 0.001);
  display(model, bpc->joints());

  joint_a = robot->getJointByBodyName ("lleg5_body");
  joint_b = robot->getJointByBodyName ("lleg1_body");
  bpc = SolidSolidCollision::create (joint_a, joint_b, 0.001);
  display(model, bpc->joints());

  joint_a = robot->getJointByBodyName ("lleg1_body");
  joint_b = robot->getJointByBodyName ("lleg5_body");
  bpc = SolidSolidCollision::create (joint_a, joint_b, 0.001);
  display(model, bpc->joints());
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>[Minor] Fix unit-test compilation<commit_after>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#define BOOST_TEST_MODULE solid_solid_collision

#include <boost/test/included/unit_test.hpp>

#include <limits>
#include <hpp/fcl/math/transform.h>
#include <hpp/fcl/shape/geometric_shapes.h>

#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/simple-device.hh>
#include <pinocchio/multibody/model.hpp>
#include <pinocchio/multibody/geometry.hpp>

#include <hpp/core/continuous-validation/solid-solid-collision.hh>

using std::numeric_limits;
using hpp::pinocchio::BodyPtr_t;
using hpp::pinocchio::CollisionObject;
using hpp::pinocchio::CollisionObjectPtr_t;
using hpp::pinocchio::Device;
using hpp::pinocchio::DevicePtr_t;
using hpp::pinocchio::JointPtr_t;
using hpp::pinocchio::JointConstPtr_t;
using hpp::pinocchio::ObjectVector_t;
using hpp::core::continuousValidation::SolidSolidCollision;
using hpp::core::continuousValidation::SolidSolidCollisionPtr_t;
using hpp::core::continuousValidation::CoefficientVelocities_t;

using namespace hpp::core;
using namespace hpp::pinocchio;

using ::se3::JointModelRX;
using ::se3::JointModelPX;
using ::se3::JointModelPY;
using ::se3::JointModelPZ;
using ::se3::JointModelRUBX;
using ::se3::JointModelFreeFlyer;
using ::se3::JointModelSpherical;
using ::se3::JointIndex;

void display(const se3::Model& model, const CoefficientVelocities_t& cvs) {
  CoefficientVelocities_t::const_iterator it;
  for (it = cvs.begin (); it != cvs.end (); ++it) {
    size_type jidx = it->joint_->index();
    if (jidx > 0) std::cout << model.names[jidx];
    else         std::cout << "None";
    std::cout << ", ";
  }
  std::cout << std::endl;
}

BOOST_AUTO_TEST_SUITE( test_hpp_core )

DevicePtr_t createRobot (){
  DevicePtr_t robot = hpp::pinocchio::humanoidSimple("test");
  return robot;
}

BOOST_AUTO_TEST_CASE (solid_solid_collision_1)
{
  DevicePtr_t robot = createRobot();
  const se3::Model& model = robot->model();
  JointPtr_t joint_a = robot->getJointByBodyName ("lleg5_body");
  JointPtr_t joint_b = robot->getJointByBodyName ("rleg5_body");

  SolidSolidCollisionPtr_t bpc = SolidSolidCollision::create
    (joint_a, joint_b, 0.001);
  display(model, bpc->coefficients());

  ConstObjectStdVector_t obstacles;
  fcl::CollisionGeometryPtr_t box (new fcl::Box (.2, .4, .6));
  // FIXME this is a bit ugly.
  int frame_id = robot->model().addFrame(se3::Frame("base_link",0,0,Transform3f (),se3::BODY));
  BOOST_CHECK(frame_id>=0);
  ::se3::GeomIndex idObj = robot->geomModel().addGeometryObject
    (se3::GeometryObject("obstacle", frame_id, 0, box, Transform3f (), "", hpp::pinocchio::vector3_t::Ones()),
     robot->model());
  CollisionObjectPtr_t collObj (new hpp::pinocchio::CollisionObject(
        robot->geomModelPtr(), robot->geomDataPtr(), idObj));
  obstacles.push_back (collObj);
  bpc = SolidSolidCollision::create (joint_a, obstacles, 0.001);
  display(model, bpc->coefficients());

  joint_a = robot->getJointByBodyName ("lleg5_body");
  joint_b = robot->getJointByBodyName ("lleg1_body");
  bpc = SolidSolidCollision::create (joint_a, joint_b, 0.001);
  display(model, bpc->coefficients());

  joint_a = robot->getJointByBodyName ("lleg1_body");
  joint_b = robot->getJointByBodyName ("lleg5_body");
  bpc = SolidSolidCollision::create (joint_a, joint_b, 0.001);
  display(model, bpc->coefficients());
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before><commit_msg>fix newlines<commit_after><|endoftext|>


<commit_before>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/* custom_redirect.cc: Allows read header set by origin for internal redirects
 */

#include <stdio.h>
#include <string>
#include <iostream>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ts/ts.h>
#include <string.h>
#include <stdlib.h>

static char *redirect_url_header = NULL;
static int redirect_url_header_len = 0;
static int return_code = TS_HTTP_STATUS_NONE;

static void
handle_response(TSHttpTxn txnp, TSCont /* contp ATS_UNUSED */)
{
  TSMBuffer resp_bufp;
  TSMLoc resp_loc;
  TSMBuffer req_bufp;
  TSMLoc req_loc;
  TSMLoc redirect_url_loc;
  TSHttpStatus status;
  const char *redirect_url_str;
  int redirect_url_length;

  if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
    TSError("couldn't retrieve server response header\n");
  } else {
    if ((status = TSHttpHdrStatusGet(resp_bufp, resp_loc)) == TS_HTTP_STATUS_NONE) {
      TSError("couldn't retrieve status from client response header\n");
    } else {
      if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) != TS_SUCCESS) {
        TSError("couldn't retrieve server response header\n");
      } else {
        int method_len;
        const char *method = TSHttpHdrMethodGet(req_bufp, req_loc, &method_len);
        if ((return_code == TS_HTTP_STATUS_NONE || return_code == status) &&
            ((strncasecmp(method, TS_HTTP_METHOD_GET, TS_HTTP_LEN_GET) == 0))) {
          redirect_url_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, redirect_url_header, redirect_url_header_len);

          if (redirect_url_loc) {
            redirect_url_str = TSMimeHdrFieldValueStringGet(resp_bufp, resp_loc, redirect_url_loc, -1, &redirect_url_length);
            if (redirect_url_str) {
              if (redirect_url_length > 0) {
                char *url = (char *)TSmalloc(redirect_url_length + 1);

                TSstrlcpy(url, redirect_url_str, redirect_url_length + 1);
                TSHttpTxnRedirectUrlSet(txnp, url, redirect_url_length);
              }
            }
            TSHandleMLocRelease(resp_bufp, resp_loc, redirect_url_loc);
          }
        }
        // TSHandleStringRelease(req_bufp, req_loc, method);
        TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc);
      }
    }
    TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
  }
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}

static int
plugin_main_handler(TSCont contp, TSEvent event, void *edata)
{
  switch (event) {
  case TS_EVENT_HTTP_READ_RESPONSE_HDR: {
    TSHttpTxn txnp = (TSHttpTxn)edata;
    TSDebug("[custom_redirect1]", "MAIN_HANDLER::TS_HTTP_READ_RESPONSE_HDR_HOOK");
    handle_response(txnp, contp);
    break;
  }

  default: {
    TSDebug("[custom_redirect]", "default event");
    break;
  }
  }

  return 0;
}

bool
isNumber(const char *str)
{
  for (int i = 0; str[i] != '\0'; i++) {
    if (!isdigit(str[i])) {
      return false;
    }
  }
  return true;
}

void
TSPluginInit(int argc, const char *argv[])
{
  // TSPluginRegistrationInfo info;

  /*
      info.plugin_name = (char*)"";
      info.vendor_name = (char*)"Apache Software Foundation";
      info.support_email = (char*)"dev@trafficserver.apache.org";
  */
  /* This plugin supports following types of url redirect here:
   *
   * 1. User can specify a particular redirect-url header name in the plugin command line,
   *    in which case plugin will just look for that header in response and redirect to it.
   *
   *OR:
   * 2. User can also specify a return error code, in which case if the code matches with
   *    the response, plugin will look for the standard "Location" header and redirect to it
   *
   *OR:
   * 3. If nothing specified, plugin will assume the first case and use the default redirect-url
   *    header name "x-redirect-url"
  */
  if (argc > 1) {
    if (isNumber(argv[1])) {
      return_code = atoi(argv[1]);
      redirect_url_header = TSstrdup(TS_MIME_FIELD_LOCATION);
    } else {
      redirect_url_header = TSstrdup(argv[1]);
    }
  } else {
    // default header name is x-redirect-url
    redirect_url_header = TSstrdup("x-redirect-url");
    redirect_url_header_len = strlen(redirect_url_header);
  }
  if (TSPluginRegister(&info) != TS_SUCCESS) {
      TSError ("[custom_redirect] Plugin registration failed.");
  }
  TSError("[custom_redirect] Plugin registered successfully.");
  TSCont mainCont = TSContCreate(plugin_main_handler, NULL);
  TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, mainCont);
}
<commit_msg>TS-3546: For global plugin registration with TSPluginRegister API and remove version information Fixed problem with info not being defined in custom_redirect<commit_after>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/* custom_redirect.cc: Allows read header set by origin for internal redirects
 */

#include <stdio.h>
#include <string>
#include <iostream>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ts/ts.h>
#include <string.h>
#include <stdlib.h>

static char *redirect_url_header = NULL;
static int redirect_url_header_len = 0;
static int return_code = TS_HTTP_STATUS_NONE;

static void
handle_response(TSHttpTxn txnp, TSCont /* contp ATS_UNUSED */)
{
  TSMBuffer resp_bufp;
  TSMLoc resp_loc;
  TSMBuffer req_bufp;
  TSMLoc req_loc;
  TSMLoc redirect_url_loc;
  TSHttpStatus status;
  const char *redirect_url_str;
  int redirect_url_length;

  if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
    TSError("couldn't retrieve server response header\n");
  } else {
    if ((status = TSHttpHdrStatusGet(resp_bufp, resp_loc)) == TS_HTTP_STATUS_NONE) {
      TSError("couldn't retrieve status from client response header\n");
    } else {
      if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) != TS_SUCCESS) {
        TSError("couldn't retrieve server response header\n");
      } else {
        int method_len;
        const char *method = TSHttpHdrMethodGet(req_bufp, req_loc, &method_len);
        if ((return_code == TS_HTTP_STATUS_NONE || return_code == status) &&
            ((strncasecmp(method, TS_HTTP_METHOD_GET, TS_HTTP_LEN_GET) == 0))) {
          redirect_url_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, redirect_url_header, redirect_url_header_len);

          if (redirect_url_loc) {
            redirect_url_str = TSMimeHdrFieldValueStringGet(resp_bufp, resp_loc, redirect_url_loc, -1, &redirect_url_length);
            if (redirect_url_str) {
              if (redirect_url_length > 0) {
                char *url = (char *)TSmalloc(redirect_url_length + 1);

                TSstrlcpy(url, redirect_url_str, redirect_url_length + 1);
                TSHttpTxnRedirectUrlSet(txnp, url, redirect_url_length);
              }
            }
            TSHandleMLocRelease(resp_bufp, resp_loc, redirect_url_loc);
          }
        }
        // TSHandleStringRelease(req_bufp, req_loc, method);
        TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc);
      }
    }
    TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
  }
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}

static int
plugin_main_handler(TSCont contp, TSEvent event, void *edata)
{
  switch (event) {
  case TS_EVENT_HTTP_READ_RESPONSE_HDR: {
    TSHttpTxn txnp = (TSHttpTxn)edata;
    TSDebug("[custom_redirect1]", "MAIN_HANDLER::TS_HTTP_READ_RESPONSE_HDR_HOOK");
    handle_response(txnp, contp);
    break;
  }

  default: {
    TSDebug("[custom_redirect]", "default event");
    break;
  }
  }

  return 0;
}

bool
isNumber(const char *str)
{
  for (int i = 0; str[i] != '\0'; i++) {
    if (!isdigit(str[i])) {
      return false;
    }
  }
  return true;
}

void
TSPluginInit(int argc, const char *argv[])
{
  TSPluginRegistrationInfo info;

  info.plugin_name = (char*)"";
  info.vendor_name = (char*)"Apache Software Foundation";
  info.support_email = (char*)"dev@trafficserver.apache.org";
  /* This plugin supports following types of url redirect here:
   *
   * 1. User can specify a particular redirect-url header name in the plugin command line,
   *    in which case plugin will just look for that header in response and redirect to it.
   *
   *OR:
   * 2. User can also specify a return error code, in which case if the code matches with
   *    the response, plugin will look for the standard "Location" header and redirect to it
   *
   *OR:
   * 3. If nothing specified, plugin will assume the first case and use the default redirect-url
   *    header name "x-redirect-url"
  */
  if (argc > 1) {
    if (isNumber(argv[1])) {
      return_code = atoi(argv[1]);
      redirect_url_header = TSstrdup(TS_MIME_FIELD_LOCATION);
    } else {
      redirect_url_header = TSstrdup(argv[1]);
    }
  } else {
    // default header name is x-redirect-url
    redirect_url_header = TSstrdup("x-redirect-url");
    redirect_url_header_len = strlen(redirect_url_header);
  }
  if (TSPluginRegister(&info) != TS_SUCCESS) {
      TSError ("[custom_redirect] Plugin registration failed.");
  }
  TSError("[custom_redirect] Plugin registered successfully.");
  TSCont mainCont = TSContCreate(plugin_main_handler, NULL);
  TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, mainCont);
}
<|endoftext|>


<commit_before>/*
 For more information, please see: http://software.sci.utah.edu

 The MIT License

 Copyright (c) 2013 Scientific Computing and Imaging Institute,
 University of Utah.

 License for the specific language governing rights and limitations under
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
*/

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <boost/assign.hpp>
#include <boost/foreach.hpp>

//#include <Core/Datatypes/Legacy/Field/MeshFactory.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Core/Datatypes/Legacy/Field/TriSurfMesh.h>
#include <Core/Datatypes/Mesh/VirtualMeshFacade.h>
#include <Core/Datatypes/Legacy/Field/VMesh.h>

#include <Core/GeometryPrimitives/Point.h>

#include <iostream>

using namespace SCIRun;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Geometry;

using ::testing::_;
using ::testing::DefaultValue;
using ::testing::Return;
using namespace boost::assign;

class TriSurfMeshFacadeTests : public ::testing::Test
{
protected:
  virtual void SetUp()
  {
    {
      FieldInformation fi("TriSurfMesh", LINEARDATA_E, "double");
      basicTriangleMesh_ = CreateMesh(fi);
      auto triangleVMesh = basicTriangleMesh_->vmesh();
      triangleVMesh->add_point(Point(0.0, 0.0, 0.0));
      triangleVMesh->add_point(Point(1.0, 0.0, 0.0));
      triangleVMesh->add_point(Point(0.5, 1.0, 0.0));

      VMesh::Node::array_type vdata;
      vdata += 0, 1, 2;
      triangleVMesh->add_elem(vdata);
    }

    {
      FieldInformation fi("TriSurfMesh", LINEARDATA_E, "double");
      cubeMesh_ = CreateMesh(fi);
      auto cubeVMesh = cubeMesh_->vmesh();
      cubeVMesh->add_point(Point(0.0, 1.0, 0.0));
      cubeVMesh->add_point(Point(0.0, 0.0, 0.0));
      cubeVMesh->add_point(Point(1.0, 1.0, 0.0));
      cubeVMesh->add_point(Point(1.0, 0.0, 0.0));
      cubeVMesh->add_point(Point(1.0, 0.0, -1.0));
      cubeVMesh->add_point(Point(1.0, 1.0, -1.0));
      cubeVMesh->add_point(Point(0.0, 1.0, -1.0));
      cubeVMesh->add_point(Point(0.0, 0.0, -1.0));

      VMesh::Node::array_type vdata1;
      vdata1 += 0, 1, 7;
      cubeVMesh->add_elem(vdata1);
      VMesh::Node::array_type vdata2;
      vdata2 += 0, 7, 6;
      cubeVMesh->add_elem(vdata2);
      VMesh::Node::array_type vdata3;
      vdata3 += 1, 0, 2;
      cubeVMesh->add_elem(vdata2);
      VMesh::Node::array_type vdata4;
      vdata4 += 1, 3, 2;
      cubeVMesh->add_elem(vdata4);
      VMesh::Node::array_type vdata5;
      vdata5 += 2, 3, 4;
      cubeVMesh->add_elem(vdata5);
      VMesh::Node::array_type vdata6;
      vdata6 += 2, 4, 5;
      cubeVMesh->add_elem(vdata6);
      VMesh::Node::array_type vdata7;
      vdata7 += 4, 7, 1;
      cubeVMesh->add_elem(vdata7);
      VMesh::Node::array_type vdata8;
      vdata8 += 4, 3, 1;
      cubeVMesh->add_elem(vdata8);
      VMesh::Node::array_type vdata9;
      vdata9 += 5, 6, 0;
      cubeVMesh->add_elem(vdata9);
      VMesh::Node::array_type vdata10;
      vdata10 += 5, 2, 0;
      cubeVMesh->add_elem(vdata10);
      VMesh::Node::array_type vdata11;
      vdata11 += 7, 6, 5;
      cubeVMesh->add_elem(vdata11);
      VMesh::Node::array_type vdata12;
      vdata12 += 7, 4, 5;
      cubeVMesh->add_elem(vdata12);
    }
  }

  MeshHandle basicTriangleMesh_;
  MeshHandle cubeMesh_;
};

// TODO: move to utils file (duplicated in LatticeVolumeMeshFacadeTests.cc)
namespace
{
  template <typename T>
  std::string join(const T& list)
  {
    std::ostringstream oss;
    const int SIZE = list.size();
    for (int i = 0; i < SIZE; ++i)
    {
      oss << list[i];
      if (i < SIZE - 1)
        oss << ", ";
    }
    return oss.str();
  }
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleTest)
{
  ASSERT_TRUE(basicTriangleMesh_);

  auto facade(basicTriangleMesh_->getFacade());

  EXPECT_EQ(3, facade->numNodes());
  EXPECT_EQ(1, facade->numFaces());
  EXPECT_EQ(1, facade->numElements());
  EXPECT_EQ(3, facade->numEdges());
}

TEST_F(TriSurfMeshFacadeTests, CubeTest)
{
  ASSERT_TRUE(cubeMesh_);

  auto facade(cubeMesh_->getFacade());

  EXPECT_EQ(8, facade->numNodes());
  EXPECT_EQ(12, facade->numFaces());
  EXPECT_EQ(12, facade->numElements());
  EXPECT_EQ(18, facade->numEdges());
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleEdgeIterationTest)
{
  auto facade(basicTriangleMesh_->getFacade());

  std::ostringstream ostr;
  BOOST_FOREACH(const EdgeInfo<VMesh>& edge, facade->edges())
  {
    auto nodesFromEdge = edge.nodeIndices();
    auto nodePoints = edge.nodePoints();
    ostr << "Edge " << edge.index() << " nodes=[" << nodesFromEdge[0] << " point=" << nodePoints[0].get_string()
    << ", " << nodesFromEdge[1] << " point=" << nodePoints[1].get_string() << "]" << std::endl;
  }

  EXPECT_EQ(
            "Edge 0 nodes=[0 point=[0, 0, 0], 1 point=[1, 0, 0]]\n"
            "Edge 1 nodes=[2 point=[0.5, 1, 0], 0 point=[0, 0, 0]]\n"
            "Edge 2 nodes=[1 point=[1, 0, 0], 2 point=[0.5, 1, 0]]\n"
            , ostr.str());
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleFaceIterationTest)
{
  auto facade(basicTriangleMesh_->getFacade());
  ASSERT_TRUE(facade);
  std::ostringstream ostr;
  BOOST_FOREACH(const FaceInfo<VMesh>& face, facade->faces())
  {
    auto faceID = face.index();
    auto edges = face.edgeIndices();
    auto nodes = face.nodeIndices();
    ostr << "Face " << faceID << " edges=[" << join(edges) << "]" << std::endl;
    ostr << "Face " << faceID << " nodes=[" << join(nodes) << "]" << std::endl;
  }

  EXPECT_EQ("Face 0 edges=[0, 2, 1]\n"
            "Face 0 nodes=[0, 1, 2]\n"
            ,ostr.str());
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleNodeIterationTest)
{
  auto facade(basicTriangleMesh_->getFacade());
  ASSERT_TRUE(facade);
  std::ostringstream ostr;
  BOOST_FOREACH(const NodeInfo<VMesh>& node, facade->nodes())
  {
    // special case, since this is essentially a 2D mesh with a single element,
    // the last edge value is not filled
    auto edges = node.edgeIndices();
    edges[3] = 666666;
    ostr << "Node " << node.index() << " point=" << node.point().get_string() << " edges=[" << join(edges) << "]" << std::endl;
  }

  EXPECT_EQ("Node 0 point=[0, 0, 0] edges=[0, 2, 1, 666666]\n"
            "Node 1 point=[1, 0, 0] edges=[0, 2, 1, 666666]\n"
            "Node 2 point=[0.5, 1, 0] edges=[0, 2, 1, 666666]\n"
            ,ostr.str());
}

<commit_msg>Added a new trisurf mesh to unit test.<commit_after>/*
 For more information, please see: http://software.sci.utah.edu

 The MIT License

 Copyright (c) 2013 Scientific Computing and Imaging Institute,
 University of Utah.

 License for the specific language governing rights and limitations under
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
*/

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <boost/assign.hpp>
#include <boost/foreach.hpp>

//#include <Core/Datatypes/Legacy/Field/MeshFactory.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Core/Datatypes/Legacy/Field/TriSurfMesh.h>
#include <Core/Datatypes/Mesh/VirtualMeshFacade.h>
#include <Core/Datatypes/Legacy/Field/VMesh.h>

#include <Core/GeometryPrimitives/Point.h>

#include <iostream>

using namespace SCIRun;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Geometry;

using ::testing::_;
using ::testing::DefaultValue;
using ::testing::Return;
using namespace boost::assign;

class TriSurfMeshFacadeTests : public ::testing::Test
{
protected:
  virtual void SetUp()
  {
    {
      FieldInformation fi("TriSurfMesh", LINEARDATA_E, "double");
      basicTriangleMesh_ = CreateMesh(fi);
      auto triangleVMesh = basicTriangleMesh_->vmesh();
      triangleVMesh->add_point(Point(0.0, 0.0, 0.0));
      triangleVMesh->add_point(Point(1.0, 0.0, 0.0));
      triangleVMesh->add_point(Point(0.5, 1.0, 0.0));

      VMesh::Node::array_type vdata;
      vdata += 0, 1, 2;
      triangleVMesh->add_elem(vdata);
    }

    {
      FieldInformation fi("TriSurfMesh", LINEARDATA_E, "double");
      cubeMesh_ = CreateMesh(fi);
      auto cubeVMesh = cubeMesh_->vmesh();
      cubeVMesh->add_point(Point(0.0, 1.0, 0.0));
      cubeVMesh->add_point(Point(0.0, 0.0, 0.0));
      cubeVMesh->add_point(Point(1.0, 1.0, 0.0));
      cubeVMesh->add_point(Point(1.0, 0.0, 0.0));
      cubeVMesh->add_point(Point(1.0, 0.0, -1.0));
      cubeVMesh->add_point(Point(1.0, 1.0, -1.0));
      cubeVMesh->add_point(Point(0.0, 1.0, -1.0));
      cubeVMesh->add_point(Point(0.0, 0.0, -1.0));

      VMesh::Node::array_type vdata1;
      vdata1 += 0, 1, 7;
      cubeVMesh->add_elem(vdata1);
      VMesh::Node::array_type vdata2;
      vdata2 += 0, 7, 6;
      cubeVMesh->add_elem(vdata2);
      VMesh::Node::array_type vdata3;
      vdata3 += 1, 0, 2;
      cubeVMesh->add_elem(vdata2);
      VMesh::Node::array_type vdata4;
      vdata4 += 1, 3, 2;
      cubeVMesh->add_elem(vdata4);
      VMesh::Node::array_type vdata5;
      vdata5 += 2, 3, 4;
      cubeVMesh->add_elem(vdata5);
      VMesh::Node::array_type vdata6;
      vdata6 += 2, 4, 5;
      cubeVMesh->add_elem(vdata6);
      VMesh::Node::array_type vdata7;
      vdata7 += 4, 7, 1;
      cubeVMesh->add_elem(vdata7);
      VMesh::Node::array_type vdata8;
      vdata8 += 4, 3, 1;
      cubeVMesh->add_elem(vdata8);
      VMesh::Node::array_type vdata9;
      vdata9 += 5, 6, 0;
      cubeVMesh->add_elem(vdata9);
      VMesh::Node::array_type vdata10;
      vdata10 += 5, 2, 0;
      cubeVMesh->add_elem(vdata10);
      VMesh::Node::array_type vdata11;
      vdata11 += 7, 6, 5;
      cubeVMesh->add_elem(vdata11);
      VMesh::Node::array_type vdata12;
      vdata12 += 7, 4, 5;
      cubeVMesh->add_elem(vdata12);
    }

    {
      FieldInformation fi("TriSurfMesh", LINEARDATA_E, "double");
      tetrahedronMesh_ = CreateMesh(fi);
      auto tetrahedronVMesh = tetrahedronMesh_->vmesh();
      tetrahedronVMesh->add_point(Point(1.0, 0.0, -0.707));
      tetrahedronVMesh->add_point(Point(-1.0, 0.0, -0.707));
      tetrahedronVMesh->add_point(Point(0.0, 1.0, 0.707));
      tetrahedronVMesh->add_point(Point(0.0, -1.0, 0.707));

      VMesh::Node::array_type vdata1;
      vdata1 += 0, 1, 2;
      tetrahedronVMesh->add_elem(vdata1);
      VMesh::Node::array_type vdata2;
      vdata2 += 0, 1, 3;
      tetrahedronVMesh->add_elem(vdata2);
      VMesh::Node::array_type vdata3;
      vdata3 += 1, 2, 3;
      tetrahedronVMesh->add_elem(vdata2);
      VMesh::Node::array_type vdata4;
      vdata4 += 0, 2, 3;
      tetrahedronVMesh->add_elem(vdata4);
    }
  }

  MeshHandle basicTriangleMesh_;
  MeshHandle cubeMesh_;
  MeshHandle tetrahedronMesh_;
};

// TODO: move to utils file (duplicated in LatticeVolumeMeshFacadeTests.cc)
namespace
{
  template <typename T>
  std::string join(const T& list)
  {
    std::ostringstream oss;
    const int SIZE = list.size();
    for (int i = 0; i < SIZE; ++i)
    {
      oss << list[i];
      if (i < SIZE - 1)
        oss << ", ";
    }
    return oss.str();
  }
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleTest)
{
  ASSERT_TRUE(basicTriangleMesh_);

  auto facade(basicTriangleMesh_->getFacade());

  EXPECT_EQ(3, facade->numNodes());
  EXPECT_EQ(1, facade->numFaces());
  EXPECT_EQ(1, facade->numElements());
  EXPECT_EQ(3, facade->numEdges());
}

TEST_F(TriSurfMeshFacadeTests, CubeTest)
{
  ASSERT_TRUE(cubeMesh_);

  auto facade(cubeMesh_->getFacade());

  EXPECT_EQ(8, facade->numNodes());
  EXPECT_EQ(12, facade->numFaces());
  EXPECT_EQ(12, facade->numElements());
  EXPECT_EQ(18, facade->numEdges());
}

TEST_F(TriSurfMeshFacadeTests, TetrahedronTest)
{
  ASSERT_TRUE(tetrahedronMesh_);

  auto facade(tetrahedronMesh_->getFacade());

  EXPECT_EQ(4, facade->numNodes());
  EXPECT_EQ(4, facade->numFaces());
  EXPECT_EQ(4, facade->numElements());
  EXPECT_EQ(6, facade->numEdges());
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleEdgeIterationTest)
{
  auto facade(basicTriangleMesh_->getFacade());

  std::ostringstream ostr;
  BOOST_FOREACH(const EdgeInfo<VMesh>& edge, facade->edges())
  {
    auto nodesFromEdge = edge.nodeIndices();
    auto nodePoints = edge.nodePoints();
    ostr << "Edge " << edge.index() << " nodes=[" << nodesFromEdge[0] << " point=" << nodePoints[0].get_string()
    << ", " << nodesFromEdge[1] << " point=" << nodePoints[1].get_string() << "]" << std::endl;
  }

  EXPECT_EQ(
            "Edge 0 nodes=[0 point=[0, 0, 0], 1 point=[1, 0, 0]]\n"
            "Edge 1 nodes=[2 point=[0.5, 1, 0], 0 point=[0, 0, 0]]\n"
            "Edge 2 nodes=[1 point=[1, 0, 0], 2 point=[0.5, 1, 0]]\n"
            , ostr.str());
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleFaceIterationTest)
{
  auto facade(basicTriangleMesh_->getFacade());
  ASSERT_TRUE(facade);
  std::ostringstream ostr;
  BOOST_FOREACH(const FaceInfo<VMesh>& face, facade->faces())
  {
    auto faceID = face.index();
    auto edges = face.edgeIndices();
    auto nodes = face.nodeIndices();
    ostr << "Face " << faceID << " edges=[" << join(edges) << "]" << std::endl;
    ostr << "Face " << faceID << " nodes=[" << join(nodes) << "]" << std::endl;
  }

  EXPECT_EQ("Face 0 edges=[0, 2, 1]\n"
            "Face 0 nodes=[0, 1, 2]\n"
            ,ostr.str());
}

TEST_F(TriSurfMeshFacadeTests, BasicTriangleNodeIterationTest)
{
  auto facade(basicTriangleMesh_->getFacade());
  ASSERT_TRUE(facade);
  std::ostringstream ostr;
  BOOST_FOREACH(const NodeInfo<VMesh>& node, facade->nodes())
  {
    // special case, since this is essentially a 2D mesh with a single element,
    // the last edge value is not filled
    auto edges = node.edgeIndices();
    edges[3] = 666666;
    ostr << "Node " << node.index() << " point=" << node.point().get_string() << " edges=[" << join(edges) << "]" << std::endl;
  }

  EXPECT_EQ("Node 0 point=[0, 0, 0] edges=[0, 2, 1, 666666]\n"
            "Node 1 point=[1, 0, 0] edges=[0, 2, 1, 666666]\n"
            "Node 2 point=[0.5, 1, 0] edges=[0, 2, 1, 666666]\n"
            ,ostr.str());
}

<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

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

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <bhxx/Runtime.hpp>
#include <bhxx/array_operations.hpp>
#include <bhxx/util.hpp>
#include <complex>

namespace bhxx {

template <typename T>
T as_scalar(BhArray<T> ary) {
    if (ary.base == nullptr) {
        throw std::runtime_error(
              "Cannot call bhxx::as_scalar on BhArray objects without base");
    }

    if (ary.n_elem() != 1) {
        throw std::runtime_error(
              "Cannot call bhxx::as_scalar on BhArray objects with more than one "
              "element");
    }

    sync(ary);
    Runtime::instance().flush();

    const T* data = ary.data();
    if (data == nullptr) {
        throw std::runtime_error("Cannot get the scalar from an uninitialised BhArray.");
    }

    return *data;
}

template <typename T>
BhArray<T> broadcast(BhArray<T> ary, int64_t axis, size_t size) {
    if (axis < 0 || static_cast<size_t>(axis) > ary.rank()) {
        throw std::runtime_error(
              "Axis to replicate needs to be larger than -1 and less than or equal to "
              "the rank of the array.");
    }
    if (size == 0) throw std::runtime_error("The new size needs to be larger than 0");
    auto& shape  = ary.shape;
    auto& stride = ary.stride;

    shape.insert(shape.begin() + axis, size);
    stride.insert(stride.begin() + axis, 0);
    return ary;
}

template <typename T>
BhArray<T> transpose(BhArray<T> ary) {
    std::reverse(ary.shape.begin(), ary.shape.end());
    std::reverse(ary.stride.begin(), ary.stride.end());
    return ary;
}

template <typename T>
BhArray<T> reshape(BhArray<T> ary, Shape shape) {
    if (ary.n_elem() != shape.prod()) {
        throw std::runtime_error(
              "Changing the shape cannot change the number of elements");
    }

    if (ary.shape == shape) return ary;

    if (!ary.is_contiguous()) {
        throw std::runtime_error(
              "Reshape not yet implemented for non-contiguous arrays.");
    }

    ary.shape  = shape;
    ary.stride = contiguous_stride(shape);
    return ary;
}

template <typename T>
BhArray<T> matmul(BhArray<T> lhs, BhArray<T> rhs) {
    if (lhs.rank() == 0 || rhs.rank() == 0) {
        throw std::runtime_error("Lhs and Rhs need to be of at least rank 1.");
    }

    // Check that the axis we contract over is common.
    if (lhs.shape.back() != rhs.shape.front()) {
        throw std::runtime_error("Common axis of arrays has incompatible sizes. LHS == " +
                                 std::to_string(lhs.shape.back()) + ", RHS == " +
                                 std::to_string(rhs.shape.front()) + ".");
    }

    if (lhs.rank() > 2 || rhs.rank() > 2) {
        throw std::runtime_error("matmul not implemented for arrays with rank > 2.");
    }

    // Make lhs and rhs matrices in case they are not
    // (i.e. prepend/append 1 to the dimension if they are vectors)
    // and build the resulting shapes
    //
    // Notice that the case where both and lhs and rhs have rank 1
    // is also covered, since then both branches will be executed
    // leading to a result_shape of {1}.
    Shape result_shape{lhs.shape.front(), rhs.shape.back()};
    if (lhs.rank() == 1) {
        result_shape = {rhs.shape.back()};
        lhs          = reshape(std::move(lhs), {1, lhs.n_elem()});
    }
    if (rhs.rank() == 1) {
        result_shape = {lhs.shape.front()};
        rhs          = reshape(std::move(rhs), {rhs.n_elem(), 1});
    }

    // Broadcast lhs and a transposed rhs
    Shape      broad_shape{lhs.shape.front(), rhs.shape.back(), rhs.shape.front()};
    BhArray<T> rhs_trans = transpose(std::move(rhs));
    BhArray<T> lhs_broad = broadcast(std::move(lhs), 1, broad_shape[1]);
    BhArray<T> rhs_broad = broadcast(std::move(rhs_trans), 0, broad_shape[0]);
    assert(lhs_broad.shape == rhs_broad.shape);
    assert(lhs_broad.shape == broad_shape);

    // Multiply and reduce
    BhArray<T> tmp(broad_shape);
    multiply(tmp, lhs_broad, rhs_broad);
    BhArray<T> result({broad_shape[0], broad_shape[1]});
    add_reduce(result, tmp, 2);

    return reshape(std::move(result), result_shape);
}

// Instantiate all possible types of `BhArray`
#define INSTANTIATE(T)                         \
    template T          as_scalar(BhArray<T>); \
    template BhArray<T> transpose(BhArray<T>); \
    template BhArray<T> broadcast(BhArray<T>, int64_t, size_t)

#define INSTANTIATE_NOBOOL(T) \
    INSTANTIATE(T);           \
    template BhArray<T> matmul(BhArray<T>, BhArray<T>)

INSTANTIATE(bool);
INSTANTIATE_NOBOOL(int8_t);
INSTANTIATE_NOBOOL(int16_t);
INSTANTIATE_NOBOOL(int32_t);
INSTANTIATE_NOBOOL(int64_t);
INSTANTIATE_NOBOOL(uint8_t);
INSTANTIATE_NOBOOL(uint16_t);
INSTANTIATE_NOBOOL(uint32_t);
INSTANTIATE_NOBOOL(uint64_t);
INSTANTIATE_NOBOOL(float);
INSTANTIATE_NOBOOL(double);
INSTANTIATE_NOBOOL(std::complex<float>);
INSTANTIATE_NOBOOL(std::complex<double>);

#undef INSTANTIATE
#undef INSTANTIATE_NOBOOL

}  // namespace bhxx
<commit_msg>Use blas call in matmul where available<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

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

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <bhxx/Runtime.hpp>
#include <bhxx/array_operations.hpp>
#include <bhxx/util.hpp>
#include <complex>

namespace bhxx {

template <typename T>
T as_scalar(BhArray<T> ary) {
    if (ary.base == nullptr) {
        throw std::runtime_error(
              "Cannot call bhxx::as_scalar on BhArray objects without base");
    }

    if (ary.n_elem() != 1) {
        throw std::runtime_error(
              "Cannot call bhxx::as_scalar on BhArray objects with more than one "
              "element");
    }

    sync(ary);
    Runtime::instance().flush();

    const T* data = ary.data();
    if (data == nullptr) {
        throw std::runtime_error("Cannot get the scalar from an uninitialised BhArray.");
    }

    return *data;
}

template <typename T>
BhArray<T> broadcast(BhArray<T> ary, int64_t axis, size_t size) {
    if (axis < 0 || static_cast<size_t>(axis) > ary.rank()) {
        throw std::runtime_error(
              "Axis to replicate needs to be larger than -1 and less than or equal to "
              "the rank of the array.");
    }
    if (size == 0) throw std::runtime_error("The new size needs to be larger than 0");
    auto& shape  = ary.shape;
    auto& stride = ary.stride;

    shape.insert(shape.begin() + axis, size);
    stride.insert(stride.begin() + axis, 0);
    return ary;
}

template <typename T>
BhArray<T> transpose(BhArray<T> ary) {
    std::reverse(ary.shape.begin(), ary.shape.end());
    std::reverse(ary.stride.begin(), ary.stride.end());
    return ary;
}

template <typename T>
BhArray<T> reshape(BhArray<T> ary, Shape shape) {
    if (ary.n_elem() != shape.prod()) {
        throw std::runtime_error(
              "Changing the shape cannot change the number of elements");
    }

    if (ary.shape == shape) return ary;

    if (!ary.is_contiguous()) {
        throw std::runtime_error(
              "Reshape not yet implemented for non-contiguous arrays.");
    }

    ary.shape  = shape;
    ary.stride = contiguous_stride(shape);
    return ary;
}

template <typename T>
BhArray<T> matmul(BhArray<T> lhs, BhArray<T> rhs) {
    if (lhs.rank() == 0 || rhs.rank() == 0) {
        throw std::runtime_error("Lhs and Rhs need to be of at least rank 1.");
    }

    // Check that the axis we contract over is common.
    if (lhs.shape.back() != rhs.shape.front()) {
        throw std::runtime_error("Common axis of arrays has incompatible sizes. LHS == " +
                                 std::to_string(lhs.shape.back()) + ", RHS == " +
                                 std::to_string(rhs.shape.front()) + ".");
    }

    if (lhs.rank() > 2 || rhs.rank() > 2) {
        throw std::runtime_error("matmul not implemented for arrays with rank > 2.");
    }

    // Make lhs and rhs matrices in case they are not
    // (i.e. prepend/append 1 to the dimension if they are vectors)
    // and build the resulting shapes
    //
    // Notice that the case where both and lhs and rhs have rank 1
    // is also covered, since then both branches will be executed
    // leading to a result_shape of {1}.
    Shape result_shape{lhs.shape.front(), rhs.shape.back()};
    if (lhs.rank() == 1) {
        result_shape = {rhs.shape.back()};
        lhs          = reshape(std::move(lhs), {1, lhs.n_elem()});
    }
    if (rhs.rank() == 1) {
        result_shape = {lhs.shape.front()};
        rhs          = reshape(std::move(rhs), {rhs.n_elem(), 1});
    }

    BhArray<T> result({lhs.shape.front(), rhs.shape.back()});
    try {
        lhs = as_contiguous(std::move(lhs));
        rhs = as_contiguous(std::move(rhs));
        Runtime::instance().enqueue_extmethod("blas_gemm", result, lhs, rhs);
    } catch (...) {
        // No blas could be found.
        // TODO Use check function once it is available

        // Broadcast lhs and a transposed rhs
        Shape      broad_shape{lhs.shape.front(), rhs.shape.back(), rhs.shape.front()};
        BhArray<T> rhs_trans = transpose(std::move(rhs));
        BhArray<T> lhs_broad = broadcast(std::move(lhs), 1, broad_shape[1]);
        BhArray<T> rhs_broad = broadcast(std::move(rhs_trans), 0, broad_shape[0]);
        assert(lhs_broad.shape == rhs_broad.shape);
        assert(lhs_broad.shape == broad_shape);

        // Multiply and reduce
        BhArray<T> tmp(broad_shape);
        multiply(tmp, lhs_broad, rhs_broad);
        add_reduce(result, tmp, 2);
    }

    return reshape(std::move(result), result_shape);
}

// Instantiate all possible types of `BhArray`
#define INSTANTIATE(T)                         \
    template T          as_scalar(BhArray<T>); \
    template BhArray<T> transpose(BhArray<T>); \
    template BhArray<T> broadcast(BhArray<T>, int64_t, size_t)

#define INSTANTIATE_NOBOOL(T) \
    INSTANTIATE(T);           \
    template BhArray<T> matmul(BhArray<T>, BhArray<T>)

INSTANTIATE(bool);
INSTANTIATE_NOBOOL(int8_t);
INSTANTIATE_NOBOOL(int16_t);
INSTANTIATE_NOBOOL(int32_t);
INSTANTIATE_NOBOOL(int64_t);
INSTANTIATE_NOBOOL(uint8_t);
INSTANTIATE_NOBOOL(uint16_t);
INSTANTIATE_NOBOOL(uint32_t);
INSTANTIATE_NOBOOL(uint64_t);
INSTANTIATE_NOBOOL(float);
INSTANTIATE_NOBOOL(double);
INSTANTIATE_NOBOOL(std::complex<float>);
INSTANTIATE_NOBOOL(std::complex<double>);

#undef INSTANTIATE
#undef INSTANTIATE_NOBOOL

}  // namespace bhxx
<|endoftext|>