<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2013 - 2018)
//   René Fritze     (2014, 2016, 2018)
//   René Milk       (2017)
//   Tobias Leibner  (2014, 2016)

#ifndef DUNE_GDT_PROLONGATIONS_HH
#define DUNE_GDT_PROLONGATIONS_HH

#include <vector>

#include <dune/common/dynvector.hh>

#include <dune/xt/la/container/vector-interface.hh>

#include <dune/gdt/discretefunction/bochner.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/discretefunction/reinterpret.hh>
#include <dune/gdt/interpolations.hh>
#include <dune/gdt/spaces/bochner.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

// ## Variants for a DiscreteFunction ##

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [most general
 *        variant].
 *
 * \note This does not clear target.dofs().vector(). Thus, if prolongation_grid_view only covers a part of the domain of
 *       target.space().grid_view(), other contributions in target remain (which is on purpose).
 *
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 void>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        DiscreteFunction<TV, TGV, r, rC, TR>& target,
        const GridView<PGV>& prolongation_grid_view)
{
  interpolate(reinterpret(source, prolongation_grid_view), target, prolongation_grid_view);
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [uses
 *        target.space().grid_view() as prolongation_grid_view].
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR>
void prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source, DiscreteFunction<TV, TGV, r, rC, TR>& target)
{
  prolong(source, target, target.space().grid_view());
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space, prolongation_grid_view);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<
    XT::LA::is_vector<TargetVectorType>::value
        && std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
    DiscreteFunction<TargetVectorType, TGV, r, rC, TR>>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided, uses target.space().grid_view() as
 *        prolongation_grid_view].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
std::enable_if_t<XT::LA::is_vector<TargetVectorType>::value, DiscreteFunction<TargetVectorType, TGV, r, rC, TR>>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source, const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 DiscreteFunction<V, TGV, r, rC, TR>>
prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source, uses target.space().grid_view() as
 *        prolongation_grid_view].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
DiscreteFunction<V, TGV, r, rC, TR> prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
                                            const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function);
  return target_function;
}

// ## Variants for a DiscreteBochnerFunction ##

/**
 * \brief Prolongs a DiscreteBochnerFunction from one (usually coarser) time grid onto another (usually finer) one [most
 *        general variant].
 *
 * \note Uses prolong() in space.
 *
 * \sa prolong
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class R, class TV, class TGV, class PGV>
void prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source,
             DiscreteBochnerFunction<TV, TGV, r, rC, R>& target,
             const GridView<PGV>& spatial_prolongation_grid_view)
{
  // prepare
  const auto& temporal_space = target.space().temporal_space();
  DynamicVector<size_t> local_dof_indices(temporal_space.mapper().max_local_size());
  std::vector<bool> dof_has_been_handled(temporal_space.mapper().size(), false);
  // walk the time intervals
  for (auto&& time_interval : elements(temporal_space.grid_view())) {
    temporal_space.mapper().global_indices(time_interval, local_dof_indices);
    const auto& lagrange_points_in_time =
        temporal_space.finite_element(time_interval.geometry().type()).lagrange_points();
    for (size_t ii = 0; ii < lagrange_points_in_time.size(); ++ii) {
      const size_t global_dof_index = local_dof_indices[ii];
      if (!dof_has_been_handled[global_dof_index]) {
        const auto& point_in_time = time_interval.geometry().global(lagrange_points_in_time[ii]);
        // evaluate in time
        const auto coarse_spatial_function = source.evaluate(point_in_time);
        // prolong in space
        auto fine_spatial_function =
            make_discrete_function(target.space().spatial_space(), target.dof_vectors()[global_dof_index].vector());
        prolong(coarse_spatial_function, fine_spatial_function, spatial_prolongation_grid_view);
        dof_has_been_handled[global_dof_index] = true;
      }
    }
  }
} // ... prolong(...)

/**
 * \brief Prolongs a DiscreteBochnerFunction from one (usually coarser) time grid onto another (usually finer) one [uses
 *        target.space().spatial_space().grid_view() as spatial_prolongation_grid_view].
 *
 * \note Uses prolong() in space.
 *
 * \sa prolong
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class R, class TV, class TGV>
void prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source,
             DiscreteBochnerFunction<TV, TGV, r, rC, R>& target)
{
  prolong(source, target, target.space().spatial_space().grid_view());
}

/**
 * \brief Prolongs a DiscreteBochnerFunction from one (usually coarser) time grid onto another (usually finer) one
 *        [creates suitable target_function, TargetVectorType has to be provided].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space, spatial_prolongation_grid_view);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class R, class TGV, class PGV>
std::enable_if_t<
    XT::LA::is_vector<TargetVectorType>::value
        && std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
    DiscreteBochnerFunction<TargetVectorType, TGV, r, rC, R>>
prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source,
        const BochnerSpace<TGV, r, rC, R>& target_space,
        const GridView<PGV>& spatial_prolongation_grid_view)
{
  auto target_function = make_discrete_bochner_function<TargetVectorType>(target_space);
  prolong(source, target_function, spatial_prolongation_grid_view);
  return target_function;
}

template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class R, class TGV>
std::enable_if_t<XT::LA::is_vector<TargetVectorType>::value, DiscreteBochnerFunction<TargetVectorType, TGV, r, rC, R>>
prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source, const BochnerSpace<TGV, r, rC, R>& target_space)
{
  return prolong<TargetVectorType>(source, target_space, target_space.spatial_space().grid_view());
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PROLONGATIONS_HH
<commit_msg>[prolongations] fix ambiguouity<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2013 - 2018)
//   René Fritze     (2014, 2016, 2018)
//   René Milk       (2017)
//   Tobias Leibner  (2014, 2016)

#ifndef DUNE_GDT_PROLONGATIONS_HH
#define DUNE_GDT_PROLONGATIONS_HH

#include <vector>

#include <dune/common/dynvector.hh>

#include <dune/xt/la/container/vector-interface.hh>

#include <dune/gdt/discretefunction/bochner.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/discretefunction/reinterpret.hh>
#include <dune/gdt/interpolations.hh>
#include <dune/gdt/spaces/bochner.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

// ## Variants for a DiscreteFunction ##

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [most general
 *        variant].
 *
 * \note This does not clear target.dofs().vector(). Thus, if prolongation_grid_view only covers a part of the domain of
 *       target.space().grid_view(), other contributions in target remain (which is on purpose).
 *
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 void>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        DiscreteFunction<TV, TGV, r, rC, TR>& target,
        const GridView<PGV>& prolongation_grid_view)
{
  interpolate(reinterpret(source, prolongation_grid_view), target, prolongation_grid_view);
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [uses
 *        target.space().grid_view() as prolongation_grid_view].
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR>
void prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source, DiscreteFunction<TV, TGV, r, rC, TR>& target)
{
  prolong(source, target, target.space().grid_view());
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space, prolongation_grid_view);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<
    XT::LA::is_vector<TargetVectorType>::value
        && std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
    DiscreteFunction<TargetVectorType, TGV, r, rC, TR>>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided, uses target.space().grid_view() as
 *        prolongation_grid_view].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
std::enable_if_t<XT::LA::is_vector<TargetVectorType>::value, DiscreteFunction<TargetVectorType, TGV, r, rC, TR>>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source, const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 DiscreteFunction<V, TGV, r, rC, TR>>
prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source, uses target.space().grid_view() as
 *        prolongation_grid_view].
 */
// we require the enable_if for disambigouation with a variant above
template <class SGV, class V, size_t r, size_t rC, class SR, class TGV, class TR>
std::enable_if_t<!XT::LA::is_vector<SGV>::value, DiscreteFunction<V, TGV, r, rC, TR>>
prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source, const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function);
  return target_function;
}

// ## Variants for a DiscreteBochnerFunction ##

/**
 * \brief Prolongs a DiscreteBochnerFunction from one (usually coarser) time grid onto another (usually finer) one [most
 *        general variant].
 *
 * \note Uses prolong() in space.
 *
 * \sa prolong
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class R, class TV, class TGV, class PGV>
void prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source,
             DiscreteBochnerFunction<TV, TGV, r, rC, R>& target,
             const GridView<PGV>& spatial_prolongation_grid_view)
{
  // prepare
  const auto& temporal_space = target.space().temporal_space();
  DynamicVector<size_t> local_dof_indices(temporal_space.mapper().max_local_size());
  std::vector<bool> dof_has_been_handled(temporal_space.mapper().size(), false);
  // walk the time intervals
  for (auto&& time_interval : elements(temporal_space.grid_view())) {
    temporal_space.mapper().global_indices(time_interval, local_dof_indices);
    const auto& lagrange_points_in_time =
        temporal_space.finite_element(time_interval.geometry().type()).lagrange_points();
    for (size_t ii = 0; ii < lagrange_points_in_time.size(); ++ii) {
      const size_t global_dof_index = local_dof_indices[ii];
      if (!dof_has_been_handled[global_dof_index]) {
        const auto& point_in_time = time_interval.geometry().global(lagrange_points_in_time[ii]);
        // evaluate in time
        const auto coarse_spatial_function = source.evaluate(point_in_time);
        // prolong in space
        auto fine_spatial_function =
            make_discrete_function(target.space().spatial_space(), target.dof_vectors()[global_dof_index].vector());
        prolong(coarse_spatial_function, fine_spatial_function, spatial_prolongation_grid_view);
        dof_has_been_handled[global_dof_index] = true;
      }
    }
  }
} // ... prolong(...)

/**
 * \brief Prolongs a DiscreteBochnerFunction from one (usually coarser) time grid onto another (usually finer) one [uses
 *        target.space().spatial_space().grid_view() as spatial_prolongation_grid_view].
 *
 * \note Uses prolong() in space.
 *
 * \sa prolong
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class R, class TV, class TGV>
void prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source,
             DiscreteBochnerFunction<TV, TGV, r, rC, R>& target)
{
  prolong(source, target, target.space().spatial_space().grid_view());
}

/**
 * \brief Prolongs a DiscreteBochnerFunction from one (usually coarser) time grid onto another (usually finer) one
 *        [creates suitable target_function, TargetVectorType has to be provided].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space, spatial_prolongation_grid_view);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class R, class TGV, class PGV>
std::enable_if_t<
    XT::LA::is_vector<TargetVectorType>::value
        && std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
    DiscreteBochnerFunction<TargetVectorType, TGV, r, rC, R>>
prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source,
        const BochnerSpace<TGV, r, rC, R>& target_space,
        const GridView<PGV>& spatial_prolongation_grid_view)
{
  auto target_function = make_discrete_bochner_function<TargetVectorType>(target_space);
  prolong(source, target_function, spatial_prolongation_grid_view);
  return target_function;
}

template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class R, class TGV>
std::enable_if_t<XT::LA::is_vector<TargetVectorType>::value, DiscreteBochnerFunction<TargetVectorType, TGV, r, rC, R>>
prolong(const DiscreteBochnerFunction<SV, SGV, r, rC, R>& source, const BochnerSpace<TGV, r, rC, R>& target_space)
{
  return prolong<TargetVectorType>(source, target_space, target_space.spatial_space().grid_view());
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PROLONGATIONS_HH
<|endoftext|>


<commit_before>#include "vtkVuzixARScene.h"
#include "vtkObjectFactory.h"

vtkStandardNewMacro(vtkVuzixARScene);

vtkVuzixARScene::vtkVuzixARScene(){

	//allocates the piece of the compilation
	leftEyeRenderer = vtkRenderer::New();
	rightEyeRenderer = vtkRenderer::New();
	leftEyeCamera = vtkVuzixARCamera::New();
	leftEyeRenderer->SetActiveCamera(leftEyeCamera);
	rightEyeCamera = vtkVuzixARCamera::New();
	rightEyeRenderer->SetActiveCamera(rightEyeCamera);

	//allocate the texture bases for the renderers and link them together
	leftEyePhysicalWorld = 0;
	leftEyeTexture = vtkTexture::New();
	leftEyeRenderer->SetBackgroundTexture( leftEyeTexture );
	leftEyeRenderer->SetTexturedBackground( true );
	rightEyePhysicalWorld = 0;
	rightEyeTexture = vtkTexture::New();
	rightEyeRenderer->SetBackgroundTexture( rightEyeTexture );
	rightEyeRenderer->SetTexturedBackground( true );

	//set some defaults for the poses
	trackedDevice = vtkTransform::New();
	trackedDevice->Identity();
	deviceToLeftEye = vtkTransform::New();
	deviceToLeftEye->Identity();
	deviceToRightEye = vtkTransform::New();
	deviceToRightEye->Identity();

	//allocate space for the temporary variables
	leftFocalPoint = vtkTransform::New();
	leftFocalPoint->PostMultiply();
	rightFocalPoint = vtkTransform::New();
	rightFocalPoint->PostMultiply();

	IdealLeftFocus = 1.0;
	IdealRightFocus = 1.0;

}

vtkVuzixARScene::~vtkVuzixARScene(){
	leftEyeTexture->Delete();
	rightEyeTexture->Delete();
	leftEyeRenderer->Delete();
	rightEyeRenderer->Delete();
	leftEyeCamera->Delete();
	rightEyeCamera->Delete();
	leftFocalPoint->Delete();
	rightFocalPoint->Delete();
	deviceToLeftEye->Delete();
	deviceToRightEye->Delete();
}

void vtkVuzixARScene::Update(){

	//update the frame sizes
	UpdateFrameSizes();

	//tell the cameras that they have been modified
	leftEyeCamera->Modified();
	rightEyeCamera->Modified();
}

//update the frame sizes on the cameras (used for determining the projection matrix)
void vtkVuzixARScene::UpdateFrameSizes(){
	if( leftEyePhysicalWorld ){
		int extent[6];
		this->leftEyePhysicalWorld->GetExtent( extent );
		this->leftEyeCamera->SetFrameSize(	(double) (extent[1] - extent[0]+1),
											(double) (extent[3] - extent[2]+1) );
	}
	if( rightEyePhysicalWorld ){
		int extent[6];
		this->rightEyePhysicalWorld->GetExtent( extent );
		this->rightEyeCamera->SetFrameSize(	(double) (extent[1] - extent[0]+1),
											(double) (extent[3] - extent[2]+1) );
	}
}

vtkRenderer* vtkVuzixARScene::GetLeftEyeView(){
	return leftEyeRenderer;
}

vtkRenderer* vtkVuzixARScene::GetRightEyeView(){
	return rightEyeRenderer;
}

void vtkVuzixARScene::SetLeftEyeSource( vtkImageData* eye ){
	this->leftEyeTexture->SetInput( (vtkDataObject*) eye );
	leftEyePhysicalWorld = eye;
}

void vtkVuzixARScene::SetRightEyeSource( vtkImageData* eye ){
	this->rightEyeTexture->SetInput( (vtkDataObject*) eye );
	rightEyePhysicalWorld = eye;

}

void vtkVuzixARScene::SetTrackedTransform( vtkTransform* t){
	trackedDevice = t;
	leftEyeCamera->SetUserTransform(t);
	rightEyeCamera->SetUserTransform(t);
}

void vtkVuzixARScene::SetLeftEyeTransform( vtkTransform* t){
	deviceToLeftEye = t;
	deviceToLeftEye->Inverse();

	//find the focal point of the left camera
	leftFocalPoint->Identity();
	leftFocalPoint->Translate( 0, 0, IdealLeftFocus );
	leftFocalPoint->Concatenate( deviceToLeftEye );

	//apply the poses to the camera
	leftEyeCamera->SetPosition( deviceToLeftEye->GetPosition() );
	leftEyeCamera->SetFocalPoint( leftFocalPoint->GetPosition() );
	leftEyeCamera->OrthogonalizeViewUp();

}

void vtkVuzixARScene::SetRightEyeTransform( vtkTransform* t){
	deviceToRightEye = t;
	deviceToRightEye->Inverse();

	//find the focal point of the right camera
	rightFocalPoint->Identity();
	rightFocalPoint->Translate( 0, 0, IdealRightFocus );
	rightFocalPoint->Concatenate( deviceToRightEye );

	//apply the poses to the camera
	rightEyeCamera->SetPosition( deviceToRightEye->GetPosition() );
	rightEyeCamera->SetFocalPoint( rightFocalPoint->GetPosition() );
	rightEyeCamera->OrthogonalizeViewUp();
}

void vtkVuzixARScene::SetLeftEyePixelwiseIntrinsicParameters(	double fx,
																double fy,
																double cx,
																double cy ){
	this->leftEyeCamera->SetPixelwiseIntrinsicParameters(fx,fy,cx,cy);
	IdealLeftFocus = 0.5 * (fx + fy);

	//find the focal point of the left camera
	leftFocalPoint->Identity();
	leftFocalPoint->Translate( 0, 0, IdealLeftFocus );
	leftFocalPoint->Concatenate( deviceToLeftEye );

	//apply the poses to the camera
	leftEyeCamera->SetPosition( deviceToLeftEye->GetPosition() );
	leftEyeCamera->SetFocalPoint( leftFocalPoint->GetPosition() );
	leftEyeCamera->OrthogonalizeViewUp();
}

void vtkVuzixARScene::SetRightEyePixelwiseIntrinsicParameters(	double fx,
																double fy,
																double cx,
																double cy ){
	this->rightEyeCamera->SetPixelwiseIntrinsicParameters(fx,fy,cx,cy);
	IdealRightFocus = 0.5 * (fx + fy);

	//find the focal point of the right camera
	rightFocalPoint->Identity();
	rightFocalPoint->Translate( 0, 0, IdealRightFocus );
	rightFocalPoint->Concatenate( deviceToRightEye );

	//apply the poses to the camera
	rightEyeCamera->SetPosition( deviceToRightEye->GetPosition() );
	rightEyeCamera->SetFocalPoint( rightFocalPoint->GetPosition() );
	rightEyeCamera->OrthogonalizeViewUp();
}<commit_msg>Fixed bad view-up vector. Can't use OrthogonalizeViewUp because it gives faulty vector.<commit_after>#include "vtkVuzixARScene.h"
#include "vtkObjectFactory.h"

vtkStandardNewMacro(vtkVuzixARScene);

vtkVuzixARScene::vtkVuzixARScene(){

	//allocates the piece of the compilation
	leftEyeRenderer = vtkRenderer::New();
	rightEyeRenderer = vtkRenderer::New();
	leftEyeCamera = vtkVuzixARCamera::New();
	leftEyeRenderer->SetActiveCamera(leftEyeCamera);
	rightEyeCamera = vtkVuzixARCamera::New();
	rightEyeRenderer->SetActiveCamera(rightEyeCamera);

	//allocate the texture bases for the renderers and link them together
	leftEyePhysicalWorld = 0;
	leftEyeTexture = vtkTexture::New();
	leftEyeRenderer->SetBackgroundTexture( leftEyeTexture );
	leftEyeRenderer->SetTexturedBackground( true );
	rightEyePhysicalWorld = 0;
	rightEyeTexture = vtkTexture::New();
	rightEyeRenderer->SetBackgroundTexture( rightEyeTexture );
	rightEyeRenderer->SetTexturedBackground( true );

	//set some defaults for the poses
	trackedDevice = vtkTransform::New();
	trackedDevice->Identity();
	deviceToLeftEye = vtkTransform::New();
	deviceToLeftEye->Identity();
	deviceToRightEye = vtkTransform::New();
	deviceToRightEye->Identity();

	//allocate space for the temporary variables
	leftFocalPoint = vtkTransform::New();
	leftFocalPoint->PostMultiply();
	rightFocalPoint = vtkTransform::New();
	rightFocalPoint->PostMultiply();

	//give default values to the focal parameters
	IdealLeftFocus = 1.0;
	IdealRightFocus = 1.0;

}

vtkVuzixARScene::~vtkVuzixARScene(){
	leftEyeTexture->Delete();
	rightEyeTexture->Delete();
	leftEyeRenderer->Delete();
	rightEyeRenderer->Delete();
	leftEyeCamera->Delete();
	rightEyeCamera->Delete();
	leftFocalPoint->Delete();
	rightFocalPoint->Delete();
	deviceToLeftEye->Delete();
	deviceToRightEye->Delete();
}

void vtkVuzixARScene::Update(){

	//update the frame sizes
	UpdateFrameSizes();

	//tell the cameras that they have been modified
	leftEyeCamera->Modified();
	rightEyeCamera->Modified();
}

//update the frame sizes on the cameras (used for determining the projection matrix)
void vtkVuzixARScene::UpdateFrameSizes(){
	if( leftEyePhysicalWorld ){
		int extent[6];
		this->leftEyePhysicalWorld->GetExtent( extent );
		this->leftEyeCamera->SetFrameSize(	(double) (extent[1] - extent[0]+1),
											(double) (extent[3] - extent[2]+1) );
	}
	if( rightEyePhysicalWorld ){
		int extent[6];
		this->rightEyePhysicalWorld->GetExtent( extent );
		this->rightEyeCamera->SetFrameSize(	(double) (extent[1] - extent[0]+1),
											(double) (extent[3] - extent[2]+1) );
	}
}

vtkRenderer* vtkVuzixARScene::GetLeftEyeView(){
	return leftEyeRenderer;
}

vtkRenderer* vtkVuzixARScene::GetRightEyeView(){
	return rightEyeRenderer;
}

void vtkVuzixARScene::SetLeftEyeSource( vtkImageData* eye ){
	this->leftEyeTexture->SetInput( (vtkDataObject*) eye );
	leftEyePhysicalWorld = eye;
}

void vtkVuzixARScene::SetRightEyeSource( vtkImageData* eye ){
	this->rightEyeTexture->SetInput( (vtkDataObject*) eye );
	rightEyePhysicalWorld = eye;

}

void vtkVuzixARScene::SetTrackedTransform( vtkTransform* t){
	trackedDevice = t;
	leftEyeCamera->SetUserTransform(t);
	rightEyeCamera->SetUserTransform(t);
}

void vtkVuzixARScene::SetLeftEyeTransform( vtkTransform* t){
	deviceToLeftEye = t;
	deviceToLeftEye->Inverse();

	//find the focal point of the left camera
	leftFocalPoint->Identity();
	leftFocalPoint->Translate( 0, 0, IdealLeftFocus );
	leftFocalPoint->Concatenate( deviceToLeftEye );

	//find the viewUp vector and position of the left camera
	double* leftViewUp = deviceToLeftEye->TransformDoublePoint(0,-1,0);
	double leftPosition[3];
	deviceToLeftEye->GetPosition(leftPosition);
	leftViewUp[0] -= leftPosition[0];
	leftViewUp[1] -= leftPosition[1];
	leftViewUp[2] -= leftPosition[2];

	//apply the poses to the camera
	leftEyeCamera->SetPosition( leftPosition );
	leftEyeCamera->SetViewUp( leftViewUp );
	leftEyeCamera->SetFocalPoint( leftFocalPoint->GetPosition() );

}

void vtkVuzixARScene::SetRightEyeTransform( vtkTransform* t){
	deviceToRightEye = t;
	deviceToRightEye->Inverse();

	//find the focal point of the right camera
	rightFocalPoint->Identity();
	rightFocalPoint->Translate( 0, 0, IdealRightFocus );
	rightFocalPoint->Concatenate( deviceToRightEye );

	//find the viewUp vector and position of the right camera
	double* rightViewUp = deviceToRightEye->TransformDoublePoint(0,-1,0);
	double rightPosition[3];
	deviceToRightEye->GetPosition(rightPosition);
	rightViewUp[0] -= rightPosition[0];
	rightViewUp[1] -= rightPosition[1];
	rightViewUp[2] -= rightPosition[2];

	//apply the poses to the camera
	rightEyeCamera->SetPosition( rightPosition );
	rightEyeCamera->SetViewUp( rightViewUp );
	rightEyeCamera->SetFocalPoint( rightFocalPoint->GetPosition() );
}

void vtkVuzixARScene::SetLeftEyePixelwiseIntrinsicParameters(	double fx,
																double fy,
																double cx,
																double cy ){
	this->leftEyeCamera->SetPixelwiseIntrinsicParameters(fx,fy,cx,cy);
	IdealLeftFocus = 0.5 * (fx+fy);

	//find the focal point of the left camera
	leftFocalPoint->Identity();
	leftFocalPoint->Translate( 0, 0, IdealLeftFocus );
	leftFocalPoint->Concatenate( deviceToLeftEye );

	//find the viewUp vector and position of the left camera
	double* leftViewUp = deviceToLeftEye->TransformDoublePoint(0,-1,0);
	double leftPosition[3];
	deviceToLeftEye->GetPosition(leftPosition);
	leftViewUp[0] -= leftPosition[0];
	leftViewUp[1] -= leftPosition[1];
	leftViewUp[2] -= leftPosition[2];

	//apply the poses to the camera
	leftEyeCamera->SetPosition( leftPosition );
	leftEyeCamera->SetViewUp( leftViewUp );
	leftEyeCamera->SetFocalPoint( leftFocalPoint->GetPosition() );
}

void vtkVuzixARScene::SetRightEyePixelwiseIntrinsicParameters(	double fx,
																double fy,
																double cx,
																double cy ){
	this->rightEyeCamera->SetPixelwiseIntrinsicParameters(fx,fy,cx,cy);
	IdealRightFocus = 0.5 * (fx+fy);

	//find the focal point of the right camera
	rightFocalPoint->Identity();
	rightFocalPoint->Translate( 0, 0, IdealRightFocus );
	rightFocalPoint->Concatenate( deviceToRightEye );

	//find the viewUp vector and position of the right camera
	double* rightViewUp = deviceToRightEye->TransformDoublePoint(0,-1,0);
	double rightPosition[3];
	deviceToRightEye->GetPosition(rightPosition);
	rightViewUp[0] -= rightPosition[0];
	rightViewUp[1] -= rightPosition[1];
	rightViewUp[2] -= rightPosition[2];

	//apply the poses to the camera
	rightEyeCamera->SetPosition( rightPosition );
	rightEyeCamera->SetViewUp( rightViewUp );
	rightEyeCamera->SetFocalPoint( rightFocalPoint->GetPosition() );

}<|endoftext|>


<commit_before>/*
*   Copyright 2020 Google LLC
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       https://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

#include "request_handler.h"

#include <vector>
#include <sstream>

namespace wireless_android_play_analytics {

void RequestHandler::GetLastRefreshed(const Pistache::Rest::Request& request,
    Pistache::Http::ResponseWriter response) {
    // Information within the request is unnecessary.
    UNUSED(request);
    response.send(Pistache::Http::Code::Ok, "Wed May 19 15:46:11 2020");
}

void RequestHandler::GetDashboard(const Pistache::Rest::Request& request,
    Pistache::Http::ResponseWriter response) {
    // TODO(alexanderlin): Use real data once I get access to them.
    std::vector<std::string> dataSources {"SPAM", "PLAY_COUNTRY",
        "APP_COUNTRY_PUBLISH_TIME", "QUERY_CATEGORY_SOURCE",
            "UNIFIED_USER_DATA_SOURCE"};
    std::vector<std::string> dates {"5/19/2020", "5/18/2020", "5/17/2020", "5/16/2020",
        "5/15/2020", "5/14/2020", "5/13/2020"};
    std::string system_in = request.param(":system").as<std::string>();
    std::string status = "111010111110001011100100111000100110001010000010100111010";
    auto stream = response.stream(Pistache::Http::Code::Ok);
    const char* system = system_in.c_str();
    // track the online or offline bits
    int i = 0;

    // Since the html file may be large, stream the data as we write it for
    // more efficiency
    stream << "<table id=\"" << system << "%TEXT\">\n";
    stream << "\t
\n\t
" << system << "
\n";

    for(const std::string &data : dataSources) {
        stream << "\t
\n";
        stream << "\t\t" << data.c_str() << "&nbsp&nbsp	\n";
        for(const std::string& date : dates) {
            stream << "\t\t<td class=";
            if (status[i++] == '1') {
                stream << "\"online\"";
            }
            else {
                stream << "\"offline\"";
            }
            stream << " title=\"" << date.c_str() << "\" id=\"" << data.c_str()
                << "%" << date.c_str() << "%" << system << "\">	\n";
        }
        stream << "\t
\n\n";
    }
    stream << "
\n";
    stream.ends();
}

void RequestHandler::PopulateBackfillCommand
    (const Pistache::Rest::Request& request,
        Pistache::Http::ResponseWriter response) {
        std::string date = request.param(":date").as<std::string>();
        std::string system = request.param(":system").as<std::string>();
        std::string source = request.param(":source").as<std::string>();
        std::string command = "sample command to run backfill for " + source
            + " on " + system + " for " + date;
        response.send(Pistache::Http::Code::Ok, command);
}

} // namespace wireless_android_play_analytics<commit_msg>changed what the server sends<commit_after>/*
*   Copyright 2020 Google LLC
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       https://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

#include "request_handler.h"

#include <vector>
#include <sstream>

namespace wireless_android_play_analytics {

void RequestHandler::GetLastRefreshed(const Pistache::Rest::Request& request,
    Pistache::Http::ResponseWriter response) {
    // Information within the request is unnecessary.
    UNUSED(request);
    response.send(Pistache::Http::Code::Ok, "Wed May 19 15:46:11 2020");
}

void RequestHandler::GetDashboard(const Pistache::Rest::Request& request,
    Pistache::Http::ResponseWriter response) {
    // TODO(alexanderlin): Use real data once I get access to them.
    std::vector<std::string> dataSources {"SPAM", "PLAY_COUNTRY",
        "APP_COUNTRY_PUBLISH_TIME", "QUERY_CATEGORY_SOURCE",
            "UNIFIED_USER_DATA_SOURCE"};
    std::vector<std::string> dates {"5/19/2020", "5/18/2020", "5/17/2020", "5/16/2020",
        "5/15/2020", "5/14/2020", "5/13/2020"};
    std::string system_in = request.param(":system").as<std::string>();
    std::string status = "111010111110001011100100111000100110001010000010100111010";
    response.send(Pistache::Http::Code::Ok, "{\"message\": \"Hello World\"}");
}

void RequestHandler::PopulateBackfillCommand
    (const Pistache::Rest::Request& request,
        Pistache::Http::ResponseWriter response) {
        std::string date = request.param(":date").as<std::string>();
        std::string system = request.param(":system").as<std::string>();
        std::string source = request.param(":source").as<std::string>();
        std::string command = "sample command to run backfill for " + source
            + " on " + system + " for " + date;
        response.send(Pistache::Http::Code::Ok, command);
}

} // namespace wireless_android_play_analytics<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkImageDataStreamer.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 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 "vtkImageDataStreamer.h"

#include "vtkCommand.h"
#include "vtkExtentTranslator.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkImageDataStreamer, "1.27");
vtkStandardNewMacro(vtkImageDataStreamer);
vtkCxxSetObjectMacro(vtkImageDataStreamer,ExtentTranslator,vtkExtentTranslator);

//----------------------------------------------------------------------------
vtkImageDataStreamer::vtkImageDataStreamer()
{
  // default to 10 divisions
  this->NumberOfStreamDivisions = 10;

  // create default translator
  this->ExtentTranslator = vtkExtentTranslator::New();
}

vtkImageDataStreamer::~vtkImageDataStreamer()
{
  if (this->ExtentTranslator)
    {
    this->ExtentTranslator->Delete();
    }
}

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

  os << indent << "NumberOfStreamDivisions: " << this->NumberOfStreamDivisions << endl;
  if ( this->ExtentTranslator )
    {
    os << indent << "ExtentTranslator:\n";
    this->ExtentTranslator->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "ExtentTranslator: (none)\n";
    }
}

//----------------------------------------------------------------------------
void vtkImageDataStreamer::UpdateData(vtkDataObject *vtkNotUsed(out))
{
  int idx;
  vtkImageData *input = this->GetInput();
  vtkImageData *output = this->GetOutput();
  int piece;

  // prevent chasing our tail
  if (this->Updating)
    {
    return;
    }

  // Propagate the update call - make sure everything we
  // might rely on is up-to-date
  // Must call PropagateUpdateExtent before UpdateData if multiple
  // inputs since they may lead back to the same data object.
  this->Updating = 1;

  if (!input || !output)
    {
    vtkWarningMacro("ImageDataStreamer Requires an input to execute!");
    return;
    }

  // Initialize all the outputs
  vtkExtentTranslator *translator = this->GetExtentTranslator();
  output->PrepareForNewData();

  // If there is a start method, call it
  this->AbortExecute = 0;
  this->Progress = 0.0;
  this->InvokeEvent(vtkCommand::StartEvent,NULL);
  output->SetExtent(output->GetUpdateExtent());
  output->AllocateScalars();

  // now start the loop over the number of pieces
  translator->SetWholeExtent(output->GetUpdateExtent());
  translator->SetNumberOfPieces(this->NumberOfStreamDivisions);
  for (piece = 0;
       piece < this->NumberOfStreamDivisions && !this->AbortExecute;
       piece++)
    {
    translator->SetPiece(piece);
    if (translator->PieceToExtentByPoints())
      {
      input->SetUpdateExtent(translator->GetExtent());
      input->PropagateUpdateExtent();
      input->UpdateData();
      // copy the resulting data into the output buffer
      output->CopyAndCastFrom(input, translator->GetExtent());
      this->UpdateProgress((float)piece/(this->NumberOfStreamDivisions - 1.0));
      }
    }

  this->Updating = 0;

  // If we ended due to aborting, push the progress up to 1.0 (since
  // it probably didn't end there)
  if ( !this->AbortExecute )
    {
    this->UpdateProgress(1.0);
    }

  // Call the end method, if there is one
  this->InvokeEvent(vtkCommand::EndEvent,NULL);

  // Now we have to mark the data as up to data.
  for (idx = 0; idx < this->NumberOfOutputs; ++idx)
    {
    if (this->Outputs[idx])
      {
      this->Outputs[idx]->DataHasBeenGenerated();
      }
    }

  // Release any inputs if marked for release
  for (idx = 0; idx < this->NumberOfInputs; ++idx)
    {
    if (this->Inputs[idx] != NULL)
      {
      if ( this->Inputs[idx]->ShouldIReleaseData() )
        {
        this->Inputs[idx]->ReleaseData();
        }
      }
    }

  // Information gets invalidated as soon as Update is called,
  // so validate it again here.
  this->InformationTime.Modified();
}

<commit_msg>ERR: was not passing through data other than scalars.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageDataStreamer.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 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 "vtkImageDataStreamer.h"

#include "vtkCommand.h"
#include "vtkExtentTranslator.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkImageDataStreamer, "1.28");
vtkStandardNewMacro(vtkImageDataStreamer);
vtkCxxSetObjectMacro(vtkImageDataStreamer,ExtentTranslator,vtkExtentTranslator);

//----------------------------------------------------------------------------
vtkImageDataStreamer::vtkImageDataStreamer()
{
  // default to 10 divisions
  this->NumberOfStreamDivisions = 10;

  // create default translator
  this->ExtentTranslator = vtkExtentTranslator::New();
}

vtkImageDataStreamer::~vtkImageDataStreamer()
{
  if (this->ExtentTranslator)
    {
    this->ExtentTranslator->Delete();
    }
}

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

  os << indent << "NumberOfStreamDivisions: " << this->NumberOfStreamDivisions << endl;
  if ( this->ExtentTranslator )
    {
    os << indent << "ExtentTranslator:\n";
    this->ExtentTranslator->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "ExtentTranslator: (none)\n";
    }
}

//----------------------------------------------------------------------------
void vtkImageDataStreamer::UpdateData(vtkDataObject *vtkNotUsed(out))
{
  int idx;
  vtkImageData *input = this->GetInput();
  vtkImageData *output = this->GetOutput();
  int piece;

  // prevent chasing our tail
  if (this->Updating)
    {
    return;
    }

  // Propagate the update call - make sure everything we
  // might rely on is up-to-date
  // Must call PropagateUpdateExtent before UpdateData if multiple
  // inputs since they may lead back to the same data object.
  this->Updating = 1;

  if (!input || !output)
    {
    vtkWarningMacro("ImageDataStreamer Requires an input to execute!");
    return;
    }

  // Initialize all the outputs
  vtkExtentTranslator *translator = this->GetExtentTranslator();
  output->PrepareForNewData();

  // If there is a start method, call it
  this->AbortExecute = 0;
  this->Progress = 0.0;
  this->InvokeEvent(vtkCommand::StartEvent,NULL);
  output->SetExtent(output->GetUpdateExtent());
  //output->AllocateScalars();
  AllocateOutputData(output);

  // now start the loop over the number of pieces
  translator->SetWholeExtent(output->GetUpdateExtent());
  translator->SetNumberOfPieces(this->NumberOfStreamDivisions);
  for (piece = 0;
       piece < this->NumberOfStreamDivisions && !this->AbortExecute;
       piece++)
    {
    translator->SetPiece(piece);
    if (translator->PieceToExtentByPoints())
      {
      input->SetUpdateExtent(translator->GetExtent());
      input->PropagateUpdateExtent();
      input->UpdateData();
      // copy the resulting data into the output buffer
      output->CopyAndCastFrom(input, translator->GetExtent());
      this->UpdateProgress((float)piece/(this->NumberOfStreamDivisions - 1.0));
      }
    }

  this->Updating = 0;

  // If we ended due to aborting, push the progress up to 1.0 (since
  // it probably didn't end there)
  if ( !this->AbortExecute )
    {
    this->UpdateProgress(1.0);
    }

  // Call the end method, if there is one
  this->InvokeEvent(vtkCommand::EndEvent,NULL);

  // Now we have to mark the data as up to data.
  for (idx = 0; idx < this->NumberOfOutputs; ++idx)
    {
    if (this->Outputs[idx])
      {
      this->Outputs[idx]->DataHasBeenGenerated();
      }
    }

  // Release any inputs if marked for release
  for (idx = 0; idx < this->NumberOfInputs; ++idx)
    {
    if (this->Inputs[idx] != NULL)
      {
      if ( this->Inputs[idx]->ShouldIReleaseData() )
        {
        this->Inputs[idx]->ReleaseData();
        }
      }
    }

  // Information gets invalidated as soon as Update is called,
  // so validate it again here.
  this->InformationTime.Modified();
}

<|endoftext|>


<commit_before>#include "boost/python.hpp"
#include "boost/python/extract.hpp"
#include "boost/python/numeric.hpp"

// See http://docs.scipy.org/doc/numpy-dev/reference/c-api.deprecations.html
//#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#miscellaneous
#define PY_ARRAY_UNIQUE_SYMBOL bashes_ARRAY_API
#define NO_IMPORT_ARRAY
#include "numpy/arrayobject.h"

#include <iostream>

namespace bp = boost::python;
namespace bpn = boost::python::numeric;

namespace bashes {

namespace {

// Example using only boost::python::numeric::array
void printFirst(bpn::array data) {
    // Access a built-in type (an array)
    bpn::array a = data;
    // Need to <extract> array elements because their type is unknown
    std::cout << "First array item: " << bp::extract<int>(a[0]) << std::endl;
};

// Example using numpy c-api constructs
// see http://stackoverflow.com/questions/9128519/reading-many-values-from-numpy-c-api
bp::object timesTwo(bpn::array m){
    // access underlying numpy PyObject pointer of input array
    PyObject* m_obj = PyArray_FROM_OTF(m.ptr(), NPY_DOUBLE, NPY_IN_ARRAY);
    // to avoid memory leaks, let a Boost::Python object manage the array
    bp::object temp((bp::handle<>(m_obj)));
    // number of array dimensions
    int ndim = PyArray_NDIM(m_obj);
    std::cout << "bashes::timesTwo: ndim of input array: " << ndim << std::endl;
    // get direct access to the array data
    const double* data = static_cast<const double*>(PyArray_DATA(m_obj));
    // make the output array, and get access to its data
    PyObject* res = PyArray_SimpleNew(ndim, PyArray_DIMS(m_obj), NPY_DOUBLE);
    // access output array data
    double* res_data = static_cast<double*>(PyArray_DATA(res));
    // number of elements in array
    const unsigned size = PyArray_SIZE(m_obj);
    std::cout << "bashes::timesTwo: size of input array: " << size << std::endl;
    // times by two
    for (unsigned i = 0; i < size; ++i) {
        res_data[i] = 2*data[i];
    }
    // go back to using Boost::Python constructs
    return bp::object((bp::handle<>(res)));
};

} // anonymous

void pyExportEstimatorHelpers() {
    bp::def("printFirst", &printFirst);
    bp::def("timesTwo", &timesTwo);
}

} // bashes<commit_msg>expand bpn namespace abbreviation<commit_after>#include "boost/python.hpp"
#include "boost/python/extract.hpp"
#include "boost/python/numeric.hpp"

// See http://docs.scipy.org/doc/numpy-dev/reference/c-api.deprecations.html
//#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#miscellaneous
#define PY_ARRAY_UNIQUE_SYMBOL bashes_ARRAY_API
#define NO_IMPORT_ARRAY
#include "numpy/arrayobject.h"

#include <iostream>

namespace bp = boost::python;

namespace bashes {

namespace {

// Example using only boost::python::numeric::array
void printFirst(bp::numeric::array data) {
    // Access a built-in type (an array)
    bp::numeric::array a = data;
    // Need to <extract> array elements because their type is unknown
    std::cout << "First array item: " << bp::extract<int>(a[0]) << std::endl;
};

// Example using numpy c-api constructs
// see http://stackoverflow.com/questions/9128519/reading-many-values-from-numpy-c-api
bp::object timesTwo(bp::numeric::array m){
    // access underlying numpy PyObject pointer of input array
    PyObject* m_obj = PyArray_FROM_OTF(m.ptr(), NPY_DOUBLE, NPY_IN_ARRAY);
    // to avoid memory leaks, let a Boost::Python object manage the array
    bp::object temp((bp::handle<>(m_obj)));
    // number of array dimensions
    int ndim = PyArray_NDIM(m_obj);
    std::cout << "bashes::timesTwo: ndim of input array: " << ndim << std::endl;
    // get direct access to the array data
    const double* data = static_cast<const double*>(PyArray_DATA(m_obj));
    // make the output array, and get access to its data
    PyObject* res = PyArray_SimpleNew(ndim, PyArray_DIMS(m_obj), NPY_DOUBLE);
    // access output array data
    double* res_data = static_cast<double*>(PyArray_DATA(res));
    // number of elements in array
    const unsigned size = PyArray_SIZE(m_obj);
    std::cout << "bashes::timesTwo: size of input array: " << size << std::endl;
    // times by two
    for (unsigned i = 0; i < size; ++i) {
        res_data[i] = 2*data[i];
    }
    // go back to using Boost::Python constructs
    return bp::object((bp::handle<>(res)));
};

} // anonymous

void pyExportEstimatorHelpers() {
    bp::numeric::array::set_module_and_type("numpy", "ndarray");
    bp::def("printFirst", &printFirst);
    bp::def("timesTwo", &timesTwo);
}

} // bashes<|endoftext|>


<commit_before>#include <sstream>

#include "PyNumber.hh"

using namespace py;
using std::unique_ptr;

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

namespace {

ref<Unicode> tp_repr(PyNumber* self)
{
  auto const& args = self->fmt_->get_args();
  std::stringstream ss;
  ss << "String(" << args.size << ", " << args.precision
     << ", pad='" << args.pad << "', sign='" << args.sign
     << ", nan='" << args.nan << "', inf='" << args.inf
     << "', point='" << args.point << "', bad='" << args.bad << "')";
  return Unicode::from(ss.str());
}

int
get_precision(
  Object* arg)
{
  int precision;
  if (arg == Py_None)
    precision = fixfmt::Number::PRECISION_NONE;
  else {
    precision = arg->long_value();
    if (precision < 0)
      precision = fixfmt::Number::PRECISION_NONE;
  }
  return precision;
}

fixfmt::Number::Scale
get_scale(
  Object* arg)
{
  fixfmt::Number::Scale scale = {};
  auto const aliases = ((Object*) &PyNumber::type_)->GetAttrString("SCALES");
  if (Dict::Check(aliases)) {
    auto const alias = cast<Dict>(aliases)->GetItem(arg, false);
    if (alias != nullptr)
      arg = alias;
  }
  if (arg == Py_None)
    ;  // accept default
  else if (!Sequence::Check(arg))
    throw ValueError("scale must be a two-item sequence");
  else {
    Sequence* scale_seq = cast<Sequence>(arg);
    if (scale_seq->Length() != 2)
      throw ValueError("scale must be a two-item sequence");
    scale.factor = scale_seq->GetItem(0)->double_value();
    if (!(scale.factor > 0))
      throw ValueError("invalid scale factor");
    scale.suffix = scale_seq->GetItem(1)->Str()->as_utf8_string();
  }
  return scale;
}

// FIXME: Accept sign=None.
static void
tp_init(
  PyNumber* self,
  Tuple* args,
  Dict* kw_args)
{
  static char const* arg_names[] = {
    "size", "precision", "pad", "sign", "nan", "inf", "point", "bad",
    "scale", nullptr
  };

  int           size;
  Object*       precision_arg   = (Object*) Py_None;
#if PY3K
  int           pad             = fixfmt::Number::PAD_SPACE;
  int           sign            = fixfmt::Number::SIGN_NEGATIVE;
  int           point           = '.';
  int           bad             = '#';
#else
  char          pad             = fixfmt::Number::PAD_SPACE;
  char          sign            = fixfmt::Number::SIGN_NEGATIVE;
  char          point           = '.';
  char          bad             = '#';
#endif
  char const*   nan             = "NaN";
  char const*   inf             = "inf";
  Object*       scale_arg       = (Object*) Py_None;
  Arg::ParseTupleAndKeywords(
    args, kw_args,
#if PY3K
    "i|O$CCetetCCO",
#else
    "i|OccetetccO",
#endif
    arg_names,
    &size, &precision_arg, &pad, &sign, "utf-8", &nan, "utf-8", &inf,
    &point, &bad, &scale_arg);

  if (size < 0)
    throw ValueError("negative size");
  auto const precision = get_precision(precision_arg);
  if (   sign != fixfmt::Number::SIGN_NONE
      && sign != fixfmt::Number::SIGN_NEGATIVE
      && sign != fixfmt::Number::SIGN_ALWAYS)
    throw ValueError("invalid sign");
  if (! (pad == fixfmt::Number::PAD_SPACE || pad == fixfmt::Number::PAD_ZERO))
    throw ValueError("invalid pad");

  auto const scale = get_scale(scale_arg);

  new(self) PyNumber;
  self->fmt_ = std::make_unique<fixfmt::Number>(
      fixfmt::Number::Args{
        size, precision, (char) pad, (char) sign, scale, (char) point,
        (char) bad, nan, inf});
}

ref<Object> tp_call(PyNumber* self, Tuple* args, Dict* kw_args)
{
  static char const* arg_names[] = {"value", nullptr};
  double val;
  // FIXME: Handle integer types separately.
  Arg::ParseTupleAndKeywords(args, kw_args, "d", arg_names, &val);

  return Unicode::from((*self->fmt_)(val));
}

auto methods = Methods<PyNumber>()
;

ref<Object> get_bad(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().bad);
}

void set_bad(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const bad_str = val->Str();
  if (bad_str->Length() != 1)
    throw ValueError("invalid bad");

  auto args = self->fmt_->get_args();
  // FIXME: Wrong for multibyte characters.
  args.bad = bad_str->as_utf8_string()[0];
  self->fmt_->set_args(args);
}

ref<Object> get_inf(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().inf);
}

void set_inf(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.inf = val->Str()->as_utf8_string().c_str();
  self->fmt_->set_args(args);
}

ref<Object> get_nan(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().nan);
}

void set_nan(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.nan = val->Str()->as_utf8_string().c_str();
  self->fmt_->set_args(args);
}

ref<Object> get_pad(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().pad);
}

void set_pad(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const pad_str = val->Str();
  if (pad_str->Length() != 1)
    throw ValueError("invalid pad");
  // FIXME: Wrong for multibyte characters.
  auto const pad = pad_str->as_utf8_string()[0];
  if (   pad != fixfmt::Number::PAD_SPACE
      && pad != fixfmt::Number::PAD_ZERO)
    throw ValueError("invalid pad");

  auto args = self->fmt_->get_args();
  args.pad = pad;
  self->fmt_->set_args(args);
}

ref<Object> get_point(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().point);
}

void set_point(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const point_str = val->Str();
  if (point_str->Length() != 1)
    throw ValueError("invalid point");

  auto args = self->fmt_->get_args();
  // FIXME: Wrong for multibyte characters.
  args.point = point_str->as_utf8_string()[0];
  self->fmt_->set_args(args);
}

ref<Object> get_precision(PyNumber* const self, void* /* closure */)
{
  int const precision = self->fmt_->get_args().precision;
  return
    precision == fixfmt::Number::PRECISION_NONE ? none_ref()
    : (ref<Object>) Long::FromLong(precision);
}

void set_precision(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.precision = get_precision(val);
  self->fmt_->set_args(args);
}

ref<Object>
get_scale(
  PyNumber* const self,
  void* /* closure */)
{
  auto const& scale = self->fmt_->get_args().scale;
  if (scale.enabled())
    return Tuple::builder
      << Float::from(scale.factor)
      << Unicode::from(scale.suffix);
  else
    return none_ref();
}

void set_scale(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.scale = get_scale(val);
  self->fmt_->set_args(args);
}

ref<Object> get_sign(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().sign);
}

void set_sign(PyNumber* const self, Object* const val, void* /* closure */)
{
  auto const sign_str = val->Str();
  if (sign_str->Length() != 1)
    throw ValueError("invalid sign");
  auto const sign = sign_str->as_utf8_string()[0];
  if (   sign != fixfmt::Number::SIGN_NONE
      && sign != fixfmt::Number::SIGN_NEGATIVE
      && sign != fixfmt::Number::SIGN_ALWAYS)
    throw ValueError("invalid sign");

  auto args = self->fmt_->get_args();
  args.sign = sign;
  self->fmt_->set_args(args);
}

ref<Object> get_size(PyNumber* const self, void* /* closure */)
{
  return Long::FromLong(self->fmt_->get_args().size);
}

void set_size(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const size = val->long_value();
  if (size < 0)
    throw ValueError("size out of range");
  auto args = self->fmt_->get_args();
  args.size = size;
  self->fmt_->set_args(args);
}

ref<Object> get_width(PyNumber* const self, void* /* closure */)
{
  return Long::FromLong(self->fmt_->get_width());
}

auto getsets = GetSets<PyNumber>()
  .add_getset<get_bad       , set_bad       >("bad")
  .add_getset<get_inf       , set_inf       >("inf")
  .add_getset<get_nan       , set_nan       >("nan")
  .add_getset<get_pad       , set_pad       >("pad")
  .add_getset<get_point     , set_point     >("point")
  .add_getset<get_precision , set_precision >("precision")
  .add_getset<get_scale     , set_scale     >("scale")
  .add_getset<get_sign      , set_sign      >("sign")
  .add_getset<get_size      , set_size      >("size")
  .add_get<get_width>                        ("width")
  ;

}  // anonymous namespace

Type PyNumber::type_ = PyTypeObject{
  PyVarObject_HEAD_INIT(nullptr, 0)
  (char const*)         "fixfmt._ext.Number",               // tp_name
  (Py_ssize_t)          sizeof(PyNumber),                   // tp_basicsize
  (Py_ssize_t)          0,                                  // tp_itemsize
  (destructor)          nullptr,                            // tp_dealloc
  (printfunc)           nullptr,                            // tp_print
  (getattrfunc)         nullptr,                            // tp_getattr
  (setattrfunc)         nullptr,                            // tp_setattr
#if PY3K
  (PyAsyncMethods*)     nullptr,                            // tp_as_async
#else
  (cmpfunc)             nullptr,                            // tp_compare
#endif
  (reprfunc)            wrap<PyNumber, tp_repr>,            // tp_repr
  (PyNumberMethods*)    nullptr,                            // tp_as_number
  (PySequenceMethods*)  nullptr,                            // tp_as_sequence
  (PyMappingMethods*)   nullptr,                            // tp_as_mapping
  (hashfunc)            nullptr,                            // tp_hash
  (ternaryfunc)         wrap<PyNumber, tp_call>,            // tp_call
  (reprfunc)            nullptr,                            // tp_str
  (getattrofunc)        nullptr,                            // tp_getattro
  (setattrofunc)        nullptr,                            // tp_setattro
  (PyBufferProcs*)      nullptr,                            // tp_as_buffer
  (unsigned long)       Py_TPFLAGS_DEFAULT
                        | Py_TPFLAGS_BASETYPE,              // tp_flags
  (char const*)         nullptr,                            // tp_doc
  (traverseproc)        nullptr,                            // tp_traverse
  (inquiry)             nullptr,                            // tp_clear
  (richcmpfunc)         nullptr,                            // tp_richcompare
  (Py_ssize_t)          0,                                  // tp_weaklistoffset
  (getiterfunc)         nullptr,                            // tp_iter
  (iternextfunc)        nullptr,                            // tp_iternext
  (PyMethodDef*)        methods,                            // tp_methods
  (PyMemberDef*)        nullptr,                            // tp_members
  (PyGetSetDef*)        getsets,                            // tp_getset
  (_typeobject*)        nullptr,                            // tp_base
  (PyObject*)           nullptr,                            // tp_dict
  (descrgetfunc)        nullptr,                            // tp_descr_get
  (descrsetfunc)        nullptr,                            // tp_descr_set
  (Py_ssize_t)          0,                                  // tp_dictoffset
  (initproc)            wrap<PyNumber, tp_init>,            // tp_init
  (allocfunc)           nullptr,                            // tp_alloc
  (newfunc)             PyType_GenericNew,                  // tp_new
  (freefunc)            nullptr,                            // tp_free
  (inquiry)             nullptr,                            // tp_is_gc
  (PyObject*)           nullptr,                            // tp_bases
  (PyObject*)           nullptr,                            // tp_mro
  (PyObject*)           nullptr,                            // tp_cache
  (PyObject*)           nullptr,                            // tp_subclasses
  (PyObject*)           nullptr,                            // tp_weaklist
  (destructor)          nullptr,                            // tp_del
  (unsigned int)        0,                                  // tp_version_tag
#if PY3K
  (destructor)          nullptr,                            // tp_finalize
#endif
};

<commit_msg>Fix repr.<commit_after>#include <sstream>

#include "PyNumber.hh"

using namespace py;
using std::unique_ptr;

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

namespace {

ref<Unicode> tp_repr(PyNumber* self)
{
  auto const& args = self->fmt_->get_args();
  std::stringstream ss;
  ss << "Number(" << args.size << ", " << args.precision
     << ", pad='" << args.pad << "', sign='" << args.sign
     << ", nan='" << args.nan << "', inf='" << args.inf
     << "', point='" << args.point << "', bad='" << args.bad << "')";
  return Unicode::from(ss.str());
}

int
get_precision(
  Object* arg)
{
  int precision;
  if (arg == Py_None)
    precision = fixfmt::Number::PRECISION_NONE;
  else {
    precision = arg->long_value();
    if (precision < 0)
      precision = fixfmt::Number::PRECISION_NONE;
  }
  return precision;
}

fixfmt::Number::Scale
get_scale(
  Object* arg)
{
  fixfmt::Number::Scale scale = {};
  auto const aliases = ((Object*) &PyNumber::type_)->GetAttrString("SCALES");
  if (Dict::Check(aliases)) {
    auto const alias = cast<Dict>(aliases)->GetItem(arg, false);
    if (alias != nullptr)
      arg = alias;
  }
  if (arg == Py_None)
    ;  // accept default
  else if (!Sequence::Check(arg))
    throw ValueError("scale must be a two-item sequence");
  else {
    Sequence* scale_seq = cast<Sequence>(arg);
    if (scale_seq->Length() != 2)
      throw ValueError("scale must be a two-item sequence");
    scale.factor = scale_seq->GetItem(0)->double_value();
    if (!(scale.factor > 0))
      throw ValueError("invalid scale factor");
    scale.suffix = scale_seq->GetItem(1)->Str()->as_utf8_string();
  }
  return scale;
}

// FIXME: Accept sign=None.
static void
tp_init(
  PyNumber* self,
  Tuple* args,
  Dict* kw_args)
{
  static char const* arg_names[] = {
    "size", "precision", "pad", "sign", "nan", "inf", "point", "bad",
    "scale", nullptr
  };

  int           size;
  Object*       precision_arg   = (Object*) Py_None;
#if PY3K
  int           pad             = fixfmt::Number::PAD_SPACE;
  int           sign            = fixfmt::Number::SIGN_NEGATIVE;
  int           point           = '.';
  int           bad             = '#';
#else
  char          pad             = fixfmt::Number::PAD_SPACE;
  char          sign            = fixfmt::Number::SIGN_NEGATIVE;
  char          point           = '.';
  char          bad             = '#';
#endif
  char const*   nan             = "NaN";
  char const*   inf             = "inf";
  Object*       scale_arg       = (Object*) Py_None;
  Arg::ParseTupleAndKeywords(
    args, kw_args,
#if PY3K
    "i|O$CCetetCCO",
#else
    "i|OccetetccO",
#endif
    arg_names,
    &size, &precision_arg, &pad, &sign, "utf-8", &nan, "utf-8", &inf,
    &point, &bad, &scale_arg);

  if (size < 0)
    throw ValueError("negative size");
  auto const precision = get_precision(precision_arg);
  if (   sign != fixfmt::Number::SIGN_NONE
      && sign != fixfmt::Number::SIGN_NEGATIVE
      && sign != fixfmt::Number::SIGN_ALWAYS)
    throw ValueError("invalid sign");
  if (! (pad == fixfmt::Number::PAD_SPACE || pad == fixfmt::Number::PAD_ZERO))
    throw ValueError("invalid pad");

  auto const scale = get_scale(scale_arg);

  new(self) PyNumber;
  self->fmt_ = std::make_unique<fixfmt::Number>(
      fixfmt::Number::Args{
        size, precision, (char) pad, (char) sign, scale, (char) point,
        (char) bad, nan, inf});
}

ref<Object> tp_call(PyNumber* self, Tuple* args, Dict* kw_args)
{
  static char const* arg_names[] = {"value", nullptr};
  double val;
  // FIXME: Handle integer types separately.
  Arg::ParseTupleAndKeywords(args, kw_args, "d", arg_names, &val);

  return Unicode::from((*self->fmt_)(val));
}

auto methods = Methods<PyNumber>()
;

ref<Object> get_bad(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().bad);
}

void set_bad(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const bad_str = val->Str();
  if (bad_str->Length() != 1)
    throw ValueError("invalid bad");

  auto args = self->fmt_->get_args();
  // FIXME: Wrong for multibyte characters.
  args.bad = bad_str->as_utf8_string()[0];
  self->fmt_->set_args(args);
}

ref<Object> get_inf(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().inf);
}

void set_inf(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.inf = val->Str()->as_utf8_string().c_str();
  self->fmt_->set_args(args);
}

ref<Object> get_nan(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().nan);
}

void set_nan(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.nan = val->Str()->as_utf8_string().c_str();
  self->fmt_->set_args(args);
}

ref<Object> get_pad(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().pad);
}

void set_pad(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const pad_str = val->Str();
  if (pad_str->Length() != 1)
    throw ValueError("invalid pad");
  // FIXME: Wrong for multibyte characters.
  auto const pad = pad_str->as_utf8_string()[0];
  if (   pad != fixfmt::Number::PAD_SPACE
      && pad != fixfmt::Number::PAD_ZERO)
    throw ValueError("invalid pad");

  auto args = self->fmt_->get_args();
  args.pad = pad;
  self->fmt_->set_args(args);
}

ref<Object> get_point(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().point);
}

void set_point(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const point_str = val->Str();
  if (point_str->Length() != 1)
    throw ValueError("invalid point");

  auto args = self->fmt_->get_args();
  // FIXME: Wrong for multibyte characters.
  args.point = point_str->as_utf8_string()[0];
  self->fmt_->set_args(args);
}

ref<Object> get_precision(PyNumber* const self, void* /* closure */)
{
  int const precision = self->fmt_->get_args().precision;
  return
    precision == fixfmt::Number::PRECISION_NONE ? none_ref()
    : (ref<Object>) Long::FromLong(precision);
}

void set_precision(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.precision = get_precision(val);
  self->fmt_->set_args(args);
}

ref<Object>
get_scale(
  PyNumber* const self,
  void* /* closure */)
{
  auto const& scale = self->fmt_->get_args().scale;
  if (scale.enabled())
    return Tuple::builder
      << Float::from(scale.factor)
      << Unicode::from(scale.suffix);
  else
    return none_ref();
}

void set_scale(PyNumber* const self, Object* val, void* /* closure */)
{
  auto args = self->fmt_->get_args();
  args.scale = get_scale(val);
  self->fmt_->set_args(args);
}

ref<Object> get_sign(PyNumber* const self, void* /* closure */)
{
  return Unicode::from(self->fmt_->get_args().sign);
}

void set_sign(PyNumber* const self, Object* const val, void* /* closure */)
{
  auto const sign_str = val->Str();
  if (sign_str->Length() != 1)
    throw ValueError("invalid sign");
  auto const sign = sign_str->as_utf8_string()[0];
  if (   sign != fixfmt::Number::SIGN_NONE
      && sign != fixfmt::Number::SIGN_NEGATIVE
      && sign != fixfmt::Number::SIGN_ALWAYS)
    throw ValueError("invalid sign");

  auto args = self->fmt_->get_args();
  args.sign = sign;
  self->fmt_->set_args(args);
}

ref<Object> get_size(PyNumber* const self, void* /* closure */)
{
  return Long::FromLong(self->fmt_->get_args().size);
}

void set_size(PyNumber* const self, Object* val, void* /* closure */)
{
  auto const size = val->long_value();
  if (size < 0)
    throw ValueError("size out of range");
  auto args = self->fmt_->get_args();
  args.size = size;
  self->fmt_->set_args(args);
}

ref<Object> get_width(PyNumber* const self, void* /* closure */)
{
  return Long::FromLong(self->fmt_->get_width());
}

auto getsets = GetSets<PyNumber>()
  .add_getset<get_bad       , set_bad       >("bad")
  .add_getset<get_inf       , set_inf       >("inf")
  .add_getset<get_nan       , set_nan       >("nan")
  .add_getset<get_pad       , set_pad       >("pad")
  .add_getset<get_point     , set_point     >("point")
  .add_getset<get_precision , set_precision >("precision")
  .add_getset<get_scale     , set_scale     >("scale")
  .add_getset<get_sign      , set_sign      >("sign")
  .add_getset<get_size      , set_size      >("size")
  .add_get<get_width>                        ("width")
  ;

}  // anonymous namespace

Type PyNumber::type_ = PyTypeObject{
  PyVarObject_HEAD_INIT(nullptr, 0)
  (char const*)         "fixfmt._ext.Number",               // tp_name
  (Py_ssize_t)          sizeof(PyNumber),                   // tp_basicsize
  (Py_ssize_t)          0,                                  // tp_itemsize
  (destructor)          nullptr,                            // tp_dealloc
  (printfunc)           nullptr,                            // tp_print
  (getattrfunc)         nullptr,                            // tp_getattr
  (setattrfunc)         nullptr,                            // tp_setattr
#if PY3K
  (PyAsyncMethods*)     nullptr,                            // tp_as_async
#else
  (cmpfunc)             nullptr,                            // tp_compare
#endif
  (reprfunc)            wrap<PyNumber, tp_repr>,            // tp_repr
  (PyNumberMethods*)    nullptr,                            // tp_as_number
  (PySequenceMethods*)  nullptr,                            // tp_as_sequence
  (PyMappingMethods*)   nullptr,                            // tp_as_mapping
  (hashfunc)            nullptr,                            // tp_hash
  (ternaryfunc)         wrap<PyNumber, tp_call>,            // tp_call
  (reprfunc)            nullptr,                            // tp_str
  (getattrofunc)        nullptr,                            // tp_getattro
  (setattrofunc)        nullptr,                            // tp_setattro
  (PyBufferProcs*)      nullptr,                            // tp_as_buffer
  (unsigned long)       Py_TPFLAGS_DEFAULT
                        | Py_TPFLAGS_BASETYPE,              // tp_flags
  (char const*)         nullptr,                            // tp_doc
  (traverseproc)        nullptr,                            // tp_traverse
  (inquiry)             nullptr,                            // tp_clear
  (richcmpfunc)         nullptr,                            // tp_richcompare
  (Py_ssize_t)          0,                                  // tp_weaklistoffset
  (getiterfunc)         nullptr,                            // tp_iter
  (iternextfunc)        nullptr,                            // tp_iternext
  (PyMethodDef*)        methods,                            // tp_methods
  (PyMemberDef*)        nullptr,                            // tp_members
  (PyGetSetDef*)        getsets,                            // tp_getset
  (_typeobject*)        nullptr,                            // tp_base
  (PyObject*)           nullptr,                            // tp_dict
  (descrgetfunc)        nullptr,                            // tp_descr_get
  (descrsetfunc)        nullptr,                            // tp_descr_set
  (Py_ssize_t)          0,                                  // tp_dictoffset
  (initproc)            wrap<PyNumber, tp_init>,            // tp_init
  (allocfunc)           nullptr,                            // tp_alloc
  (newfunc)             PyType_GenericNew,                  // tp_new
  (freefunc)            nullptr,                            // tp_free
  (inquiry)             nullptr,                            // tp_is_gc
  (PyObject*)           nullptr,                            // tp_bases
  (PyObject*)           nullptr,                            // tp_mro
  (PyObject*)           nullptr,                            // tp_cache
  (PyObject*)           nullptr,                            // tp_subclasses
  (PyObject*)           nullptr,                            // tp_weaklist
  (destructor)          nullptr,                            // tp_del
  (unsigned int)        0,                                  // tp_version_tag
#if PY3K
  (destructor)          nullptr,                            // tp_finalize
#endif
};

<|endoftext|>


<commit_before>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: python/pybind11_Image.hpp
 *
 * Copyright 2017 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#ifndef EOS_PYBIND11_IMAGE_HPP_
#define EOS_PYBIND11_IMAGE_HPP_

#include "pybind11/numpy.h"

#include "Eigen/Core"

#include <cstddef>
#include <vector>

NAMESPACE_BEGIN(pybind11)
NAMESPACE_BEGIN(detail)

/**
 * @file python/pybind11_Image.hpp
 * @brief Transparent conversion to and from Python for eos::core::Image.
 *
 * Numpy uses row-major storage order by default.
 * eos::core::Image uses col-major storage (like Eigen).
 *
 * If given non-standard strides or something from numpy, probably doesn't work.
 * May need to .clone()? in numpy before passing to the C++ function.
 */

/**
 * @brief Transparent conversion for eos::core::Image3u to and from Python.
 *
 * Converts an eos::core::Image3u to and from Python. Can construct a eos::core::Image3u from numpy arrays,
 * as well as potentially other Python array types.
 *
 * Note: Not sure what happens if the given numpy array is not contiguous, not in default (row-major) storage
 *       order, or has non-standard strides. It may or may not work.
 */
template<>
struct type_caster<eos::core::Image3u>
{
	bool load(handle src, bool)
	{
		auto buf = pybind11::array::ensure(src);
		if (!buf)
			return false;

		// Todo: We should probably check that buf.strides(i) is "default", by dividing it by the Scalar type or something.

		if (!pybind11::isinstance<pybind11::array_t<std::uint8_t>>(buf))
		{
			return false; // we only convert uint8_t for now.
		}

		if (buf.ndim() != 3) {
			return false; // we expected a numpy array with 3 dimensions.
		}
		// We got something with 3 dimensions, i.e. an image with 2, 3 or 4 channels (or 'k' for that matter):
		if (buf.shape(2) != 3) {
			return false; // We expected a 3-channel image.
		}

		// Note: If our Image class had support for col/row major, we could just map buf.mutable_data().
		// Like with OpenCV: value = cv::Mat(buf.shape(0), buf.shape(1), opencv_type, buf.mutable_data());
		// But since it doesn't, we just copy the data for now:
		value = eos::core::Image3u(buf.shape(0), buf.shape(1));
		array_t<std::uint8_t> buf_as_array(buf);
		for (int r = 0; r < buf.shape(0); ++r) {
			for (int c = 0; c < buf.shape(1); ++c) {
				value(r, c)[0] = buf_as_array.at(r, c, 0);
				value(r, c)[1] = buf_as_array.at(r, c, 1);
				value(r, c)[2] = buf_as_array.at(r, c, 2);
			}
		}
		return true;
	};

    static handle cast(const eos::core::Image3u& src, return_value_policy /* policy */, handle /* parent */)
	{
		const std::size_t num_channels = 3;
		std::vector<std::size_t> shape = { static_cast<std::size_t>(src.height()), static_cast<std::size_t>(src.width()), num_channels };

		// (2048, 4, 1) is default which results in transposed image
		// Below line works now. In numpy the strides are (2048, 4, 1) though. I think a copy gets created nevertheless?
		std::vector<std::size_t> strides = { num_channels, num_channels * src.height(), 1 }; // might be cols or rows...? I think rows?
		// Note: I think with the change to the new Image class (July 2018), which is now row-major by default, the strides here might have changed. I didn't check.
		// Also, since the new Image stores a vector of Pixels, the question is whether there's any padding added by the compiler, but probably not, since all types that we use are 1 byte or a multiple thereof.
		// numpy: 'f' = fortran = col-major
		//        'c' = c = row-major = default I think.
		return array(pybind11::dtype::of<std::uint8_t>(), shape, strides, &src(0, 0).data()[0]).release();
	};

    PYBIND11_TYPE_CASTER(eos::core::Image3u, _("numpy.ndarray[uint8[m, n, 3]]"));
};

/**
 * @brief Transparent conversion for eos::core::Image4u to and from Python.
 *
 * Converts an eos::core::Image4u to and from Python. Can construct a eos::core::Image4u from numpy arrays,
 * as well as potentially other Python array types.
 *
 * Note: Not sure what happens if the given numpy array is not contiguous, not in default (row-major) storage
 *       order, or has non-standard strides. It may or may not work.
 */
template<>
struct type_caster<eos::core::Image4u>
{
	bool load(handle src, bool)
	{
		auto buf = pybind11::array::ensure(src);
		if (!buf)
			return false;

		// Todo: We should probably check that buf.strides(i) is "default", by dividing it by the Scalar type or something.

		if (!pybind11::isinstance<pybind11::array_t<std::uint8_t>>(buf))
		{
			return false; // we only convert uint8_t for now.
		}

		if (buf.ndim() != 3) {
			return false; // we expected a numpy array with 3 dimensions.
		}
		// We got something with 3 dimensions, i.e. an image with 2, 3 or 4 channels (or 'k' for that matter):
		if (buf.shape(2) != 4) {
			return false; // We expected a 4-channel image.
		}

		// Note: If our Image class had support for col/row major, we could just map buf.mutable_data().
		// Like with OpenCV: value = cv::Mat(buf.shape(0), buf.shape(1), opencv_type, buf.mutable_data());
		// But since it doesn't, we just copy the data for now:
		value = eos::core::Image4u(buf.shape(0), buf.shape(1));
		array_t<std::uint8_t> buf_as_array(buf);
		for (int r = 0; r < buf.shape(0); ++r) {
			for (int c = 0; c < buf.shape(1); ++c) {
				value(r, c)[0] = buf_as_array.at(r, c, 0);
				value(r, c)[1] = buf_as_array.at(r, c, 1);
				value(r, c)[2] = buf_as_array.at(r, c, 2);
				value(r, c)[3] = buf_as_array.at(r, c, 3);
			}
		}
		return true;
	};

    static handle cast(const eos::core::Image4u& src, return_value_policy /* policy */, handle /* parent */)
	{
		const std::size_t num_channels = 4;
		std::vector<std::size_t> shape;
		shape = { static_cast<std::size_t>(src.height()), static_cast<std::size_t>(src.width()), num_channels };

		// (2048, 4, 1) is default which results in transposed image
		// Below line works now. In numpy the strides are (2048, 4, 1) though. I think a copy gets created nevertheless?
		std::vector<size_t> strides = { num_channels, num_channels * src.height(), 1 }; // might be cols or rows...? I think rows?
		// Note: I think with the change to the new Image class (July 2018), which is now row-major by default, the strides here might have changed. I didn't check.
		// Also, since the new Image stores a vector of Pixels, the question is whether there's any padding added by the compiler, but probably not, since all types that we use are 1 byte or a multiple thereof.
		return array(pybind11::dtype::of<std::uint8_t>(), shape, strides, &src(0, 0).data()[0]).release();
	};

    PYBIND11_TYPE_CASTER(eos::core::Image4u, _("numpy.ndarray[uint8[m, n, 4]]"));
};

NAMESPACE_END(detail)
NAMESPACE_END(pybind11)

#endif /* EOS_PYBIND11_IMAGE_HPP_ */
<commit_msg>Changed strides in Image python bindings to account for row-major Image class<commit_after>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: python/pybind11_Image.hpp
 *
 * Copyright 2017 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#ifndef EOS_PYBIND11_IMAGE_HPP_
#define EOS_PYBIND11_IMAGE_HPP_

#include "pybind11/numpy.h"

#include "Eigen/Core"

#include <cstddef>
#include <vector>

NAMESPACE_BEGIN(pybind11)
NAMESPACE_BEGIN(detail)

/**
 * @file python/pybind11_Image.hpp
 * @brief Transparent conversion to and from Python for eos::core::Image.
 *
 * Numpy uses row-major storage order by default.
 * eos::core::Image uses col-major storage (like Eigen).
 *
 * If given non-standard strides or something from numpy, probably doesn't work.
 * May need to .clone()? in numpy before passing to the C++ function.
 */

/**
 * @brief Transparent conversion for eos::core::Image3u to and from Python.
 *
 * Converts an eos::core::Image3u to and from Python. Can construct a eos::core::Image3u from numpy arrays,
 * as well as potentially other Python array types.
 *
 * Note: Not sure what happens if the given numpy array is not contiguous, not in default (row-major) storage
 *       order, or has non-standard strides. It may or may not work.
 */
template<>
struct type_caster<eos::core::Image3u>
{
	bool load(handle src, bool)
	{
		auto buf = pybind11::array::ensure(src);
		if (!buf)
			return false;

		// Todo: We should probably check that buf.strides(i) is "default", by dividing it by the Scalar type or something.

		if (!pybind11::isinstance<pybind11::array_t<std::uint8_t>>(buf))
		{
			return false; // we only convert uint8_t for now.
		}

		if (buf.ndim() != 3) {
			return false; // we expected a numpy array with 3 dimensions.
		}
		// We got something with 3 dimensions, i.e. an image with 2, 3 or 4 channels (or 'k' for that matter):
		if (buf.shape(2) != 3) {
			return false; // We expected a 3-channel image.
		}

		// Note: If our Image class had support for col/row major, we could just map buf.mutable_data().
		// Like with OpenCV: value = cv::Mat(buf.shape(0), buf.shape(1), opencv_type, buf.mutable_data());
		// But since it doesn't, we just copy the data for now:
		value = eos::core::Image3u(buf.shape(0), buf.shape(1));
		array_t<std::uint8_t> buf_as_array(buf);
		for (int r = 0; r < buf.shape(0); ++r) {
			for (int c = 0; c < buf.shape(1); ++c) {
				value(r, c)[0] = buf_as_array.at(r, c, 0);
				value(r, c)[1] = buf_as_array.at(r, c, 1);
				value(r, c)[2] = buf_as_array.at(r, c, 2);
			}
		}
		return true;
	};

    static handle cast(const eos::core::Image3u& src, return_value_policy /* policy */, handle /* parent */)
	{
		const std::size_t num_channels = 3;
		std::vector<std::size_t> shape = { static_cast<std::size_t>(src.height()), static_cast<std::size_t>(src.width()), num_channels };

		// (2048, 4, 1) is default which results in transposed image
		// Below line works now. In numpy the strides are (2048, 4, 1) though. I think a copy gets created nevertheless?
		//std::vector<std::size_t> strides = { num_channels, num_channels * src.height(), 1 }; // might be cols or rows...? I think rows?
		std::vector<std::size_t> strides = { num_channels * src.width(), num_channels, 1 }; // This seems to work with the row-major Image class. I just returned the same strides as the ones we got from NumPy.
		// Note: I think with the change to the new Image class (July 2018), which is now row-major by default, the strides here might have changed. I didn't check.
		// Also, since the new Image stores a vector of Pixels, the question is whether there's any padding added by the compiler, but probably not, since all types that we use are 1 byte or a multiple thereof.
		// numpy: 'f' = fortran = col-major
		//        'c' = c = row-major = default I think.
		return array(pybind11::dtype::of<std::uint8_t>(), shape, strides, &src(0, 0).data()[0]).release();
	};

    PYBIND11_TYPE_CASTER(eos::core::Image3u, _("numpy.ndarray[uint8[m, n, 3]]"));
};

/**
 * @brief Transparent conversion for eos::core::Image4u to and from Python.
 *
 * Converts an eos::core::Image4u to and from Python. Can construct a eos::core::Image4u from numpy arrays,
 * as well as potentially other Python array types.
 *
 * Note: Not sure what happens if the given numpy array is not contiguous, not in default (row-major) storage
 *       order, or has non-standard strides. It may or may not work.
 */
template<>
struct type_caster<eos::core::Image4u>
{
	bool load(handle src, bool)
	{
		auto buf = pybind11::array::ensure(src);
		if (!buf)
			return false;

		// Todo: We should probably check that buf.strides(i) is "default", by dividing it by the Scalar type or something.

		if (!pybind11::isinstance<pybind11::array_t<std::uint8_t>>(buf))
		{
			return false; // we only convert uint8_t for now.
		}

		if (buf.ndim() != 3) {
			return false; // we expected a numpy array with 3 dimensions.
		}
		// We got something with 3 dimensions, i.e. an image with 2, 3 or 4 channels (or 'k' for that matter):
		if (buf.shape(2) != 4) {
			return false; // We expected a 4-channel image.
		}

		// Note: If our Image class had support for col/row major, we could just map buf.mutable_data().
		// Like with OpenCV: value = cv::Mat(buf.shape(0), buf.shape(1), opencv_type, buf.mutable_data());
		// But since it doesn't, we just copy the data for now:
		value = eos::core::Image4u(buf.shape(0), buf.shape(1));
		array_t<std::uint8_t> buf_as_array(buf);
		for (int r = 0; r < buf.shape(0); ++r) {
			for (int c = 0; c < buf.shape(1); ++c) {
				value(r, c)[0] = buf_as_array.at(r, c, 0);
				value(r, c)[1] = buf_as_array.at(r, c, 1);
				value(r, c)[2] = buf_as_array.at(r, c, 2);
				value(r, c)[3] = buf_as_array.at(r, c, 3);
			}
		}
		return true;
	};

    static handle cast(const eos::core::Image4u& src, return_value_policy /* policy */, handle /* parent */)
	{
		const std::size_t num_channels = 4;
		std::vector<std::size_t> shape;
		shape = { static_cast<std::size_t>(src.height()), static_cast<std::size_t>(src.width()), num_channels };

		// (2048, 4, 1) is default which results in transposed image
		// Below line works now. In numpy the strides are (2048, 4, 1) though. I think a copy gets created nevertheless?
		std::vector<size_t> strides = { num_channels * src.width(), num_channels, 1 }; // might be cols or rows...? I think rows?
		// Note: I think with the change to the new Image class (July 2018), which is now row-major by default, the strides here might have changed. I didn't check.
		// Also, since the new Image stores a vector of Pixels, the question is whether there's any padding added by the compiler, but probably not, since all types that we use are 1 byte or a multiple thereof.
		return array(pybind11::dtype::of<std::uint8_t>(), shape, strides, &src(0, 0).data()[0]).release();
	};

    PYBIND11_TYPE_CASTER(eos::core::Image4u, _("numpy.ndarray[uint8[m, n, 4]]"));
};

NAMESPACE_END(detail)
NAMESPACE_END(pybind11)

#endif /* EOS_PYBIND11_IMAGE_HPP_ */
<|endoftext|>