<commit_before>// __BEGIN_LICENSE__
//
// Copyright (C) 2008 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2008 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__

/// \file ControlNetworkLoader.cc
///
/// Control Network Loader has one function available to the public
/// and that is build_control_network at the bottom. It will load all
/// match files and triangulate all control points for the control
/// network giving by pointer.

/// Control Network Loader aims to be faster than previous method by
/// using an intermediate data struct called the Camera Relations
/// Network. It reduces the search length of inserting a new match
/// file by organizing it's base layer by camera. Compared to the
/// previous method this should reduce the search length 1/(# cameras)
/// * what ever it was before.

#include "ControlNetworkLoader.h"

// Standard
#include <vector>
#include <iostream>
#include <string>

// VW
#include <vw/Camera/ControlNetwork.h>
#include <vw/Camera/CameraModel.h>
#include <vw/Stereo/StereoModel.h>
#include <vw/Cartography.h>
#include <vw/InterestPoint.h>
#include <vw/Math.h>
#include <vw/Core.h>

// Boost (for good measure)
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/fstream.hpp"
#include <boost/algorithm/string.hpp>
namespace fs = boost::filesystem;

using namespace vw;
using namespace vw::camera;
using namespace vw::stereo;
using namespace vw::ip;

  /////////////////////////////
 // Prototypes and Snippets //
/////////////////////////////

static std::string prefix_from_filename( std::string const& filename ){
  std::string result = filename;
  int index = result.find(".");
  if (index != -1)
    result.erase(index, result.size());
  return result;
}

// Secondary Layer of Camera Relations Network. This contains the
// match relations and is doubly linked.
struct InterestPtRelation {
  boost::shared_ptr<InterestPoint> ip;
  typedef boost::shared_ptr<InterestPtRelation> ipr;
  std::list<ipr> matches;
  unsigned camera_id;

  InterestPtRelation ( InterestPoint& mine, unsigned& camera ) : camera_id(camera) { ip = boost::shared_ptr<InterestPoint>(new InterestPoint(mine)); }
  void AttachIpr( ipr& m );
  void RecursiveListing( std::list<ipr>& listing );
};

// Base Layer of Camera Relations Network
struct CameraRelation {
  typedef boost::shared_ptr<InterestPtRelation> ipr;
  int id;
  std::string name;
  std::list<ipr> relations;

  CameraRelation ( int tid, std::string tname ): id(tid), name(tname) {}
  ipr FindMatching( InterestPoint const& key );
  void AttachIpr( boost::shared_ptr<InterestPtRelation>& m );

};

  /////////////////////////////
 // Comparisons             //
/////////////////////////////

inline bool operator==( InterestPtRelation const& ipr1,
			InterestPtRelation const& ipr2 ) {
  if ( ipr1.ip->ix == ipr2.ip->ix &&
       ipr1.ip->iy == ipr2.ip->iy )
    return true;
  return false;
}

inline bool operator==( InterestPtRelation const& ipr1,
			InterestPoint const& ip2 ) {
  if ( ipr1.ip->ix == ip2.ix &&
       ipr1.ip->iy == ip2.iy )
    return true;
  return false;
}

  /////////////////////////////
 // Implementations         //
/////////////////////////////

// Interest Pt Relations
//---------------------------

void InterestPtRelation::AttachIpr( ipr& m ) {
  for ( std::list<ipr>::iterator iter =
	  matches.begin(); iter != matches.end(); iter++ ) {
    if ( **iter == *m )
      return;
  }
  matches.push_back( m );
}

void InterestPtRelation::RecursiveListing( std::list<ipr>& listing ) {

  for ( std::list<ipr>::iterator iter = matches.begin();
	iter != matches.end(); iter++ ) {
    bool contains = false;
    for ( std::list<ipr>::iterator from_list = listing.begin();
	  from_list != listing.end(); from_list++ ) {
      if ( *from_list == *iter ) {
	contains = true;
	break;
      }
    }

    if ( !contains ) {
      listing.push_back( *iter );
      (*iter)->RecursiveListing( listing );
    }
  }
}

// Camera Relations
//---------------------------

boost::shared_ptr<InterestPtRelation> CameraRelation::FindMatching( InterestPoint const& key ) {
  for ( std::list<ipr>::iterator iter = relations.begin();
	iter != relations.end(); iter++ ) {
    if ( **iter == key )
      return *iter;
  }
  return ipr();
}

void CameraRelation::AttachIpr( boost::shared_ptr<InterestPtRelation>& m ) {
  /*
  for ( std::list<ipr>::iterator iter = m_relations.begin();
	iter != m_relations.end(); iter++ ) {
    if ( **iter == *m )
      return;
  }
  */
  relations.push_back( m );
}

// Functions for Users
//----------------------------
void build_control_network( boost::shared_ptr<ControlNetwork> cnet,
			    std::vector<boost::shared_ptr<vw::camera::CameraModel> > const& camera_models,
			    std::vector<std::string> image_files,
			    int min_matches ) {

  cnet->clear();

  // 1.) Build CRN and load matches
  std::vector<CameraRelation> crn;
  for ( unsigned i = 0; i < image_files.size(); i++ )
    crn.push_back( CameraRelation( i,
				   prefix_from_filename( image_files[i] )));
  std::cout << "Loading matches:\n";
  for ( unsigned i = 0; i < image_files.size(); ++i ) {
    for ( unsigned j = i+1; j < image_files.size(); ++j ) {
      std::string match_filename =
	prefix_from_filename( image_files[i] ) + "__" +
	prefix_from_filename( image_files[j] ) + ".match";

      if ( fs::exists( match_filename ) ) {
	std::vector<InterestPoint> ip1, ip2;
	read_binary_match_file( match_filename, ip1, ip2 );
	if ( int( ip1.size() ) < min_matches ) {
	  std::cout << "\t" << match_filename << "    " << i << " <-> "
		    << j << " : " << ip1.size() << " matches. [rejected]\n";
	} else {
	  std::cout << "\t" << match_filename << "    " << i << " <-> "
		    << j << " : " << ip1.size() << " matches.\n";

	  // Loading individual matches now
	  for ( unsigned k = 0; k < ip1.size(); k++ ) {
	    boost::shared_ptr<InterestPtRelation> ipr1, ipr2;
	    ipr1 = crn[i].FindMatching( ip1[k] );
	    ipr2 = crn[j].FindMatching( ip2[k] );

	    // Match hasn't been previously loaded
	    if ( ipr1 == boost::shared_ptr<InterestPtRelation>() ) {
	      ipr1 = boost::shared_ptr<InterestPtRelation>( new InterestPtRelation( ip1[k], i ) );
	      crn[i].AttachIpr( ipr1 );
	    }
	    if ( ipr2 == boost::shared_ptr<InterestPtRelation>() ) {
	      ipr2 = boost::shared_ptr<InterestPtRelation>( new InterestPtRelation( ip2[k], j ) );
	      crn[j].AttachIpr( ipr2 );
	    }

	    // Doubly linking
	    ipr1->AttachIpr( ipr2 );
	    ipr2->AttachIpr( ipr1 );
	  }
	}
      }
    }
  }

  // 2.) Build Control Network finally
  int spiral_error_count = 0;
  std::cout << "Assembling Control Network:\n";
  for ( unsigned i = 0; i < crn.size() -1; ++i ) {
    typedef boost::shared_ptr<InterestPtRelation> ipr;

    // Iterating over match relations and building control points for
    // them.
    for ( std::list<ipr>::iterator iter = crn[i].relations.begin();
	  iter != crn[i].relations.end(); iter++ ) {
      // 2.1) Building a listing of interest points for a control
      // point
      std::list<ipr> interestpts;
      interestpts.push_back(*iter);
      (*iter)->RecursiveListing( interestpts );

      ControlPoint cpoint( ControlPoint::TiePoint );

      // Now removing listed interest points from CRN, and then adding
      // control measure
      // 2.2) Adding this location
      {
	ControlMeasure m( (*iter)->ip->x,
			  (*iter)->ip->y,
			  (*iter)->ip->scale,
			  (*iter)->ip->scale,
			  (*iter)->camera_id );
	cpoint.add_measure( m );
      }
      // 2.3) Adding & Removing all the other locations
      std::list<ipr>::iterator measure = interestpts.begin();
      measure++;
      for ( ; measure != interestpts.end(); measure++ ) {
	crn[(*measure)->camera_id].relations.remove(*measure);
	ControlMeasure m( (*measure)->ip->x,
			  (*measure)->ip->y,
			  (*measure)->ip->scale,
			  (*measure)->ip->scale,
			  (*measure)->camera_id );
	cpoint.add_measure( m );
      }
      // 2.4) Removing this location
      iter = crn[i].relations.erase(iter);
      iter--;
      // 2.5) Checking for a spiral error
      {
	std::list<unsigned> previous_camera;
	bool match = false;
	for ( std::list<ipr>::iterator interest = interestpts.begin();
	      interest != interestpts.end(); interest++ ) {
	  for ( std::list<unsigned>::iterator previous = previous_camera.begin();
		previous != previous_camera.end(); previous++ ) {
	    if ((*previous) == (*interest)->camera_id) {
	      match = true;
	      break;
	    }
	  }
	  previous_camera.push_back( (*interest)->camera_id );
	  if ( match ) {
	    continue;
	  }
	}
	if ( match ) {
	  spiral_error_count++;
	  continue;
	}
      }

      // 2.6) If haven't left for spiral error, add new control point
      if ( cpoint.size() > 1 )
	cnet->add_control_point( cpoint );
    }
  }
  if ( spiral_error_count != 0 )
    std::cout << "\t" << spiral_error_count << " control points removed because of spiral errors.\n";

  VW_ASSERT( cnet->size() != 0, vw::Aborted() << "Failed to load any points, Control Network Empty\n");

  // 3.) Triangulating Positions
  for ( unsigned i = 0; i < cnet->size(); i++ ) {

    std::vector< Vector3 > positions;
    double error = 0, error_sum = 0;

    const double min_convergence_angle = 5.0*3.1415/180.0;

    // 3.1) Building a permutation listing of triangulation
    for ( unsigned j = 0; j < (*cnet)[i].size(); j++ ) {
      for ( unsigned k = j+1; k < (*cnet)[j].size(); k++ ) {

	StereoModel sm( *(camera_models[ (*cnet)[i][j].image_id()]),
			*(camera_models[ (*cnet)[i][k].image_id()]) );

	if ( sm.convergence_angle( (*cnet)[i][j].position(),
				   (*cnet)[i][k].position() ) >
	     min_convergence_angle ) {
	  positions.push_back( sm( (*cnet)[i][j].position(),
				   (*cnet)[i][k].position(),
				   error ) );
	  error_sum += error;
	}
      }
    }

    // 3.2) Summing, Averaging and Storing
    error_sum /= positions.size();
    Vector3 position_avg;
    for ( unsigned j = 0; j < positions.size(); j++ )
      position_avg += positions[j];
    position_avg /= positions.size();

    (*cnet)[i].set_position( position_avg );

  }
}

void add_ground_control_points( boost::shared_ptr<vw::camera::ControlNetwork> cnet,
				std::vector<std::string> image_files ) {
  std::cout << "\nLoading Ground Control Points:\n";
  for ( unsigned i = 0; i < image_files.size(); ++i ) {
    std::string potential_gcp = prefix_from_filename( image_files[i] ) + ".gcp";

    if ( fs::exists( potential_gcp ) ) {
      int count = 0;

      // Now Loading the Ground Control Points
      std::ifstream istr(potential_gcp.c_str());

      while (!istr.eof()) {
	Vector2 pix;
	Vector3 loc;
	Vector3 sigma;

	istr >> pix[0] >> pix[1] >> loc[0] >> loc[1] >> loc[2] >> sigma[0] >> sigma[1] >> sigma[2];
	if (loc[0] !=0) {  // ignore blank lines
	  Vector3 xyz = cartography::lon_lat_radius_to_xyz(loc);
	  std::cout << "GCP: " << xyz << "\n";

	  ControlMeasure m(pix[0], pix[1], 1.0, 1.0, i);
	  ControlPoint cpoint(ControlPoint::GroundControlPoint);
	  cpoint.set_position(xyz[0],xyz[1],xyz[2]);
	  cpoint.set_sigma(sigma[0],sigma[1],sigma[2]);
	  cpoint.add_measure(m);

	  // Deciding where to put it
	  bool just_append = true;
	  for ( unsigned p = 0; p < cnet->size(); ++p) {
	    if ((*cnet)[p].type() == ControlPoint::GroundControlPoint ) {
	      if (((*cnet)[p].position()[0] - xyz[0]) < .001 &&
		  ((*cnet)[p].position()[1] - xyz[1]) < .001 &&
		  ((*cnet)[p].position()[2] - xyz[2]) < .001) {
		// I'm not checking measures because there is only one GCP
		// file per camera
		just_append = false;
		(*cnet)[p].add_measure(m);
		break;
	      }

	    }
	  }

	  if (just_append)
	    cnet->add_control_point(cpoint);

	  ++count;
	}
      }
      istr.close();

      std::cout << "\t" << potential_gcp << "    " << " : "
	      << count << " GCPs.\n";
    }
  }
}
<commit_msg>Small change to allow me to run with cubes and match files in different directories on pleiades.<commit_after>// __BEGIN_LICENSE__
//
// Copyright (C) 2008 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2008 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__

/// \file ControlNetworkLoader.cc
///
/// Control Network Loader has one function available to the public
/// and that is build_control_network at the bottom. It will load all
/// match files and triangulate all control points for the control
/// network giving by pointer.

/// Control Network Loader aims to be faster than previous method by
/// using an intermediate data struct called the Camera Relations
/// Network. It reduces the search length of inserting a new match
/// file by organizing it's base layer by camera. Compared to the
/// previous method this should reduce the search length 1/(# cameras)
/// * what ever it was before.

#include "ControlNetworkLoader.h"

// Standard
#include <vector>
#include <iostream>
#include <string>

// VW
#include <vw/Camera/ControlNetwork.h>
#include <vw/Camera/CameraModel.h>
#include <vw/Stereo/StereoModel.h>
#include <vw/Cartography.h>
#include <vw/InterestPoint.h>
#include <vw/Math.h>
#include <vw/Core.h>

// Boost (for good measure)
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/fstream.hpp"
#include <boost/algorithm/string.hpp>
namespace fs = boost::filesystem;

using namespace vw;
using namespace vw::camera;
using namespace vw::stereo;
using namespace vw::ip;

  /////////////////////////////
 // Prototypes and Snippets //
/////////////////////////////

static std::string prefix_from_filename( std::string const& filename ){
  std::string result = filename;
  int index = result.find(".");
  if (index != -1)
    result.erase(index, result.size());
  return result;
}

static std::string remove_path( std::string const& filename ){
  std::string result = filename;
  int index = result.rfind("/");
  if (index != -1)
    result.erase(0,index+1);
  return result;
}

// Secondary Layer of Camera Relations Network. This contains the
// match relations and is doubly linked.
struct InterestPtRelation {
  boost::shared_ptr<InterestPoint> ip;
  typedef boost::shared_ptr<InterestPtRelation> ipr;
  std::list<ipr> matches;
  unsigned camera_id;

  InterestPtRelation ( InterestPoint& mine, unsigned& camera ) : camera_id(camera) { ip = boost::shared_ptr<InterestPoint>(new InterestPoint(mine)); }
  void AttachIpr( ipr& m );
  void RecursiveListing( std::list<ipr>& listing );
};

// Base Layer of Camera Relations Network
struct CameraRelation {
  typedef boost::shared_ptr<InterestPtRelation> ipr;
  int id;
  std::string name;
  std::list<ipr> relations;

  CameraRelation ( int tid, std::string tname ): id(tid), name(tname) {}
  ipr FindMatching( InterestPoint const& key );
  void AttachIpr( boost::shared_ptr<InterestPtRelation>& m );

};

  /////////////////////////////
 // Comparisons             //
/////////////////////////////

inline bool operator==( InterestPtRelation const& ipr1,
			InterestPtRelation const& ipr2 ) {
  if ( ipr1.ip->ix == ipr2.ip->ix &&
       ipr1.ip->iy == ipr2.ip->iy )
    return true;
  return false;
}

inline bool operator==( InterestPtRelation const& ipr1,
			InterestPoint const& ip2 ) {
  if ( ipr1.ip->ix == ip2.ix &&
       ipr1.ip->iy == ip2.iy )
    return true;
  return false;
}

  /////////////////////////////
 // Implementations         //
/////////////////////////////

// Interest Pt Relations
//---------------------------

void InterestPtRelation::AttachIpr( ipr& m ) {
  for ( std::list<ipr>::iterator iter =
	  matches.begin(); iter != matches.end(); iter++ ) {
    if ( **iter == *m )
      return;
  }
  matches.push_back( m );
}

void InterestPtRelation::RecursiveListing( std::list<ipr>& listing ) {

  for ( std::list<ipr>::iterator iter = matches.begin();
	iter != matches.end(); iter++ ) {
    bool contains = false;
    for ( std::list<ipr>::iterator from_list = listing.begin();
	  from_list != listing.end(); from_list++ ) {
      if ( *from_list == *iter ) {
	contains = true;
	break;
      }
    }

    if ( !contains ) {
      listing.push_back( *iter );
      (*iter)->RecursiveListing( listing );
    }
  }
}

// Camera Relations
//---------------------------

boost::shared_ptr<InterestPtRelation> CameraRelation::FindMatching( InterestPoint const& key ) {
  for ( std::list<ipr>::iterator iter = relations.begin();
	iter != relations.end(); iter++ ) {
    if ( **iter == key )
      return *iter;
  }
  return ipr();
}

void CameraRelation::AttachIpr( boost::shared_ptr<InterestPtRelation>& m ) {
  /*
  for ( std::list<ipr>::iterator iter = m_relations.begin();
	iter != m_relations.end(); iter++ ) {
    if ( **iter == *m )
      return;
  }
  */
  relations.push_back( m );
}

// Functions for Users
//----------------------------
void build_control_network( boost::shared_ptr<ControlNetwork> cnet,
			    std::vector<boost::shared_ptr<vw::camera::CameraModel> > const& camera_models,
			    std::vector<std::string> image_files,
			    int min_matches ) {

  cnet->clear();

  // 1.) Build CRN and load matches
  std::vector<CameraRelation> crn;
  for ( unsigned i = 0; i < image_files.size(); i++ )
    crn.push_back( CameraRelation( i,
				   prefix_from_filename( image_files[i] )));
  vw_out(0) << "Loading matches:\n";
  for ( unsigned i = 0; i < image_files.size(); ++i ) {
    for ( unsigned j = i+1; j < image_files.size(); ++j ) {
      std::string match_filename =
	prefix_from_filename( image_files[i] ) + "__" +
	prefix_from_filename( image_files[j] ) + ".match";

      if ( !fs::exists( match_filename ) ) {
	match_filename = remove_path(prefix_from_filename( image_files[i] ) )
	  + "__" + remove_path(prefix_from_filename(image_files[j]))+".match";
	if (!fs::exists( match_filename))
	  continue;
      }

      std::vector<InterestPoint> ip1, ip2;
      read_binary_match_file( match_filename, ip1, ip2 );
      if ( int( ip1.size() ) < min_matches ) {
	vw_out(0) << "\t" << match_filename << "    " << i << " <-> "
		  << j << " : " << ip1.size() << " matches. [rejected]\n";
      } else {
	vw_out(0) << "\t" << match_filename << "    " << i << " <-> "
		  << j << " : " << ip1.size() << " matches.\n";

	// Loading individual matches now
	for ( unsigned k = 0; k < ip1.size(); k++ ) {
	  boost::shared_ptr<InterestPtRelation> ipr1, ipr2;
	  ipr1 = crn[i].FindMatching( ip1[k] );
	  ipr2 = crn[j].FindMatching( ip2[k] );

	  // Match hasn't been previously loaded
	  if ( ipr1 == boost::shared_ptr<InterestPtRelation>() ) {
	    ipr1 = boost::shared_ptr<InterestPtRelation>( new InterestPtRelation( ip1[k], i ) );
	    crn[i].AttachIpr( ipr1 );
	  }
	  if ( ipr2 == boost::shared_ptr<InterestPtRelation>() ) {
	    ipr2 = boost::shared_ptr<InterestPtRelation>( new InterestPtRelation( ip2[k], j ) );
	    crn[j].AttachIpr( ipr2 );
	  }

	  // Doubly linking
	  ipr1->AttachIpr( ipr2 );
	  ipr2->AttachIpr( ipr1 );
	}
      }
    }
  }

  // 2.) Build Control Network finally
  int spiral_error_count = 0;
  vw_out(0) << "Assembling Control Network:\n";
  for ( unsigned i = 0; i < crn.size() -1; ++i ) {
    typedef boost::shared_ptr<InterestPtRelation> ipr;

    // Iterating over match relations and building control points for
    // them.
    for ( std::list<ipr>::iterator iter = crn[i].relations.begin();
	  iter != crn[i].relations.end(); iter++ ) {
      // 2.1) Building a listing of interest points for a control
      // point
      std::list<ipr> interestpts;
      interestpts.push_back(*iter);
      (*iter)->RecursiveListing( interestpts );

      ControlPoint cpoint( ControlPoint::TiePoint );

      // Now removing listed interest points from CRN, and then adding
      // control measure
      // 2.2) Adding this location
      {
	ControlMeasure m( (*iter)->ip->x,
			  (*iter)->ip->y,
			  (*iter)->ip->scale,
			  (*iter)->ip->scale,
			  (*iter)->camera_id );
	cpoint.add_measure( m );
      }
      // 2.3) Adding & Removing all the other locations
      std::list<ipr>::iterator measure = interestpts.begin();
      measure++;
      for ( ; measure != interestpts.end(); measure++ ) {
	crn[(*measure)->camera_id].relations.remove(*measure);
	ControlMeasure m( (*measure)->ip->x,
			  (*measure)->ip->y,
			  (*measure)->ip->scale,
			  (*measure)->ip->scale,
			  (*measure)->camera_id );
	cpoint.add_measure( m );
      }
      // 2.4) Removing this location
      iter = crn[i].relations.erase(iter);
      iter--;
      // 2.5) Checking for a spiral error
      {
	std::list<unsigned> previous_camera;
	bool match = false;
	for ( std::list<ipr>::iterator interest = interestpts.begin();
	      interest != interestpts.end(); interest++ ) {
	  for ( std::list<unsigned>::iterator previous = previous_camera.begin();
		previous != previous_camera.end(); previous++ ) {
	    if ((*previous) == (*interest)->camera_id) {
	      match = true;
	      break;
	    }
	  }
	  previous_camera.push_back( (*interest)->camera_id );
	  if ( match ) {
	    continue;
	  }
	}
	if ( match ) {
	  spiral_error_count++;
	  continue;
	}
      }

      // 2.6) If haven't left for spiral error, add new control point
      if ( cpoint.size() > 1 )
	cnet->add_control_point( cpoint );
    }
  }
  if ( spiral_error_count != 0 )
    vw_out(0) << "\t" << spiral_error_count << " control points removed because of spiral errors.\n";

  VW_ASSERT( cnet->size() != 0, vw::Aborted() << "Failed to load any points, Control Network Empty\n");

  // 3.) Triangulating Positions
  for ( unsigned i = 0; i < cnet->size(); i++ ) {

    std::vector< Vector3 > positions;
    double error = 0, error_sum = 0;

    const double min_convergence_angle = 5.0*3.1415/180.0;

    // 3.1) Building a permutation listing of triangulation
    for ( unsigned j = 0; j < (*cnet)[i].size(); j++ ) {
      for ( unsigned k = j+1; k < (*cnet)[j].size(); k++ ) {

	StereoModel sm( *(camera_models[ (*cnet)[i][j].image_id()]),
			*(camera_models[ (*cnet)[i][k].image_id()]) );

	if ( sm.convergence_angle( (*cnet)[i][j].position(),
				   (*cnet)[i][k].position() ) >
	     min_convergence_angle ) {
	  positions.push_back( sm( (*cnet)[i][j].position(),
				   (*cnet)[i][k].position(),
				   error ) );
	  error_sum += error;
	}
      }
    }

    // 3.2) Summing, Averaging and Storing
    error_sum /= positions.size();
    Vector3 position_avg;
    for ( unsigned j = 0; j < positions.size(); j++ )
      position_avg += positions[j];
    position_avg /= positions.size();

    (*cnet)[i].set_position( position_avg );

  }
}

void add_ground_control_points( boost::shared_ptr<vw::camera::ControlNetwork> cnet,
				std::vector<std::string> image_files ) {
  std::cout << "\nLoading Ground Control Points:\n";
  for ( unsigned i = 0; i < image_files.size(); ++i ) {
    std::string potential_gcp = prefix_from_filename( image_files[i] ) + ".gcp";

    if ( fs::exists( potential_gcp ) ) {
      int count = 0;

      // Now Loading the Ground Control Points
      std::ifstream istr(potential_gcp.c_str());

      while (!istr.eof()) {
	Vector2 pix;
	Vector3 loc;
	Vector3 sigma;

	istr >> pix[0] >> pix[1] >> loc[0] >> loc[1] >> loc[2] >> sigma[0] >> sigma[1] >> sigma[2];
	if (loc[0] !=0) {  // ignore blank lines
	  Vector3 xyz = cartography::lon_lat_radius_to_xyz(loc);
	  std::cout << "GCP: " << xyz << "\n";

	  ControlMeasure m(pix[0], pix[1], 1.0, 1.0, i);
	  ControlPoint cpoint(ControlPoint::GroundControlPoint);
	  cpoint.set_position(xyz[0],xyz[1],xyz[2]);
	  cpoint.set_sigma(sigma[0],sigma[1],sigma[2]);
	  cpoint.add_measure(m);

	  // Deciding where to put it
	  bool just_append = true;
	  for ( unsigned p = 0; p < cnet->size(); ++p) {
	    if ((*cnet)[p].type() == ControlPoint::GroundControlPoint ) {
	      if (((*cnet)[p].position()[0] - xyz[0]) < .001 &&
		  ((*cnet)[p].position()[1] - xyz[1]) < .001 &&
		  ((*cnet)[p].position()[2] - xyz[2]) < .001) {
		// I'm not checking measures because there is only one GCP
		// file per camera
		just_append = false;
		(*cnet)[p].add_measure(m);
		break;
	      }

	    }
	  }

	  if (just_append)
	    cnet->add_control_point(cpoint);

	  ++count;
	}
      }
      istr.close();

      std::cout << "\t" << potential_gcp << "    " << " : "
	      << count << " GCPs.\n";
    }
  }
}
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2010 Matthias Kretz <kretz@kde.org>

    Vc 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.

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

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/global.h>
#include <Vc/cpuid.h>
#include "common/support.h"

#ifdef VC_MSVC
#include <intrin.h>
#endif

namespace Vc
{

bool isImplementationSupported(Implementation impl)
{
    CpuId::init();
    // for AVX we need to check for OSXSAVE and AVX

    switch (impl) {
    case ScalarImpl:
        return true;
    case SSE2Impl:
        return CpuId::hasSse2();
    case SSE3Impl:
        return CpuId::hasSse3();
    case SSSE3Impl:
        return CpuId::hasSsse3();
    case SSE41Impl:
        return CpuId::hasSse41();
    case SSE42Impl:
        return CpuId::hasSse42();
    case SSE4aImpl:
        return CpuId::hasSse4a();
    case AVXImpl:
#if defined(VC_MSVC) && VC_MSVC >= 160040219 // MSVC 2010 SP1 introduced _xgetbv
        unsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
        return (xcrFeatureMask & 0x6) != 0;
#elif defined(VC_NO_XGETBV)
        if (CpuId::hasOsxsave() && CpuId::hasAvx()) {
            unsigned int eax;
            asm("xgetbv" : "=a"(eax) : "c"(0) : "edx");
            return (eax & 0x06) == 0x06;
        }
#endif
        return false;
    }
    return false;
}

} // namespace Vc

// vim: sw=4 sts=4 et tw=100
<commit_msg>fix logic - my bad<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2010 Matthias Kretz <kretz@kde.org>

    Vc 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.

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

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/global.h>
#include <Vc/cpuid.h>
#include "common/support.h"

#ifdef VC_MSVC
#include <intrin.h>
#endif

namespace Vc
{

bool isImplementationSupported(Implementation impl)
{
    CpuId::init();
    // for AVX we need to check for OSXSAVE and AVX

    switch (impl) {
    case ScalarImpl:
        return true;
    case SSE2Impl:
        return CpuId::hasSse2();
    case SSE3Impl:
        return CpuId::hasSse3();
    case SSSE3Impl:
        return CpuId::hasSsse3();
    case SSE41Impl:
        return CpuId::hasSse41();
    case SSE42Impl:
        return CpuId::hasSse42();
    case SSE4aImpl:
        return CpuId::hasSse4a();
    case AVXImpl:
#if defined(VC_MSVC) && VC_MSVC >= 160040219 // MSVC 2010 SP1 introduced _xgetbv
        unsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
        return (xcrFeatureMask & 0x6) != 0;
#elif !defined(VC_NO_XGETBV)
        if (CpuId::hasOsxsave() && CpuId::hasAvx()) {
            unsigned int eax;
            asm("xgetbv" : "=a"(eax) : "c"(0) : "edx");
            return (eax & 0x06) == 0x06;
        }
#endif
        return false;
    }
    return false;
}

} // namespace Vc

// vim: sw=4 sts=4 et tw=100
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <boost/test/unit_test.hpp>
#include "flat_mutation_reader.hh"

// Intended to be called in a seastar thread
class flat_reader_assertions {
    flat_mutation_reader _reader;
private:
    mutation_fragment_opt read_next() {
        return _reader().get0();
    }
public:
    flat_reader_assertions(flat_mutation_reader reader)
        : _reader(std::move(reader))
    { }

    flat_reader_assertions& produces_partition_start(const dht::decorated_key& dk) {
        BOOST_TEST_MESSAGE(sprint("Expecting partition start with key %s", dk));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got end of stream", dk));
        }
        if (!mfopt->is_partition_start()) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        if (!mfopt->as_partition_start().key().equal(*_reader.schema(), dk)) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_static_row() {
        BOOST_TEST_MESSAGE(sprint("Expecting static row"));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL("Expected static row, got end of stream");
        }
        if (!mfopt->is_static_row()) {
            BOOST_FAIL(sprint("Expected static row, got: %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_row_with_key(const clustering_key& ck) {
        BOOST_TEST_MESSAGE(sprint("Expect %s", ck));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected row with key %s, but got end of stream", ck));
        }
        if (!mfopt->is_clustering_row()) {
            BOOST_FAIL(sprint("Expected row with key %s, but got %s", ck, *mfopt));
        }
        auto& actual = mfopt->as_clustering_row().key();
        if (!actual.equal(*_reader.schema(), ck)) {
            BOOST_FAIL(sprint("Expected row with key %s, but key is %s", ck, actual));
        }
        return *this;
    }

    flat_reader_assertions& produces_partition_end() {
        BOOST_TEST_MESSAGE("Expecting partition end");
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected partition end but got end of stream"));
        }
        if (!mfopt->is_end_of_partition()) {
            BOOST_FAIL(sprint("Expected partition end but got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_end_of_stream() {
        BOOST_TEST_MESSAGE("Expecting end of stream");
        auto mfopt = read_next();
        if (bool(mfopt)) {
            BOOST_FAIL(sprint("Expected end of stream, got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& next_partition() {
        _reader.next_partition();
        return *this;
    }
};

inline
flat_reader_assertions assert_that(flat_mutation_reader r) {
    return { std::move(r) };
}
<commit_msg>tests/flat_mutation_reader_assertions: add fast_forward_to()<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <boost/test/unit_test.hpp>
#include "flat_mutation_reader.hh"

// Intended to be called in a seastar thread
class flat_reader_assertions {
    flat_mutation_reader _reader;
private:
    mutation_fragment_opt read_next() {
        return _reader().get0();
    }
public:
    flat_reader_assertions(flat_mutation_reader reader)
        : _reader(std::move(reader))
    { }

    flat_reader_assertions& produces_partition_start(const dht::decorated_key& dk) {
        BOOST_TEST_MESSAGE(sprint("Expecting partition start with key %s", dk));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got end of stream", dk));
        }
        if (!mfopt->is_partition_start()) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        if (!mfopt->as_partition_start().key().equal(*_reader.schema(), dk)) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_static_row() {
        BOOST_TEST_MESSAGE(sprint("Expecting static row"));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL("Expected static row, got end of stream");
        }
        if (!mfopt->is_static_row()) {
            BOOST_FAIL(sprint("Expected static row, got: %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_row_with_key(const clustering_key& ck) {
        BOOST_TEST_MESSAGE(sprint("Expect %s", ck));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected row with key %s, but got end of stream", ck));
        }
        if (!mfopt->is_clustering_row()) {
            BOOST_FAIL(sprint("Expected row with key %s, but got %s", ck, *mfopt));
        }
        auto& actual = mfopt->as_clustering_row().key();
        if (!actual.equal(*_reader.schema(), ck)) {
            BOOST_FAIL(sprint("Expected row with key %s, but key is %s", ck, actual));
        }
        return *this;
    }

    flat_reader_assertions& produces_partition_end() {
        BOOST_TEST_MESSAGE("Expecting partition end");
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected partition end but got end of stream"));
        }
        if (!mfopt->is_end_of_partition()) {
            BOOST_FAIL(sprint("Expected partition end but got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_end_of_stream() {
        BOOST_TEST_MESSAGE("Expecting end of stream");
        auto mfopt = read_next();
        if (bool(mfopt)) {
            BOOST_FAIL(sprint("Expected end of stream, got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& fast_forward_to(const dht::partition_range& pr) {
        _reader.fast_forward_to(pr);
        return *this;
    }

    flat_reader_assertions& next_partition() {
        _reader.next_partition();
        return *this;
    }
};

inline
flat_reader_assertions assert_that(flat_mutation_reader r) {
    return { std::move(r) };
}
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include "WPILib.h"
#include "gtest/gtest.h"
#include "TestBench.h"

static constexpr double kServoResetTime = 1.0;

static constexpr double kTestAngle = 180.0;

static constexpr double kTiltSetpoint0 = 0.16;
static constexpr double kTiltSetpoint45 = 0.385;
static constexpr double kTiltSetpoint90 = 0.61;
static constexpr double kTiltTime = 0.5;
static constexpr double kAccelerometerTolerance = 0.1;

/**
 * A fixture for the camera with two servos and a gyro
 * @author Thomas Clark
 */
class TiltPanCameraTest : public testing::Test {
protected:
	static Gyro *m_gyro;
	Servo *m_tilt, *m_pan;
	ADXL345_SPI *m_spiAccel;

	static void SetUpTestCase() {
		// The gyro object blocks for 5 seconds in the constructor, so only
		// construct it once for the whole test case
		m_gyro = new Gyro(TestBench::kCameraGyroChannel);
	}

	static void TearDownTestCase() {
		delete m_gyro;
	}

	virtual void SetUp() {
		m_tilt = new Servo(TestBench::kCameraTiltChannel);
		m_pan = new Servo(TestBench::kCameraPanChannel);
		m_spiAccel = new ADXL345_SPI(SPI::kOnboardCS0);
	}

	virtual void TearDown() {
		delete m_tilt;
		delete m_pan;
		delete m_spiAccel;
	}
};

Gyro *TiltPanCameraTest::m_gyro = 0;

/**
 * Test if the servo turns 180 degrees and the gyroscope measures this angle
 */
TEST_F(TiltPanCameraTest, GyroAngle) {
	Wait(kServoResetTime);

	for(int i = 0; i < 100; i++) {
		m_pan->Set(i / 100.0);
		Wait(0.05);
	}

	double gyroAngle = m_gyro->GetAngle();

	EXPECT_NEAR(gyroAngle, kTestAngle, 20.0) << "Gyro measured " << gyroAngle
		<< " degrees, servo should have turned " << kTestAngle <<  " degrees";
}

/**
 * Test if the accelerometer measures gravity along the correct axes when the
 * camera rotates
 */
TEST_F(TiltPanCameraTest, SPIAccelerometer) {
	m_tilt->Set(kTiltSetpoint0);
	Wait(kTiltTime);
	EXPECT_NEAR(-1.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_X), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_Y), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_Z), kAccelerometerTolerance);

	m_tilt->Set(kTiltSetpoint45);
	Wait(kTiltTime);
	EXPECT_NEAR(-std::sqrt(0.5), m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_X), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_Y), kAccelerometerTolerance);
	EXPECT_NEAR(std::sqrt(0.5), m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_Z), kAccelerometerTolerance);

	m_tilt->Set(kTiltSetpoint90);
	Wait(kTiltTime);
	EXPECT_NEAR(0.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_X), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_Y), kAccelerometerTolerance);
	EXPECT_NEAR(1.0, m_spiAccel->GetAcceleration(ADXL345_SPI::kAxis_Z), kAccelerometerTolerance);
}
<commit_msg>Updated the C++ TiltPanCameraTest<commit_after>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include "WPILib.h"
#include "gtest/gtest.h"
#include "TestBench.h"

static constexpr double kServoResetTime = 1.0;

static constexpr double kTestAngle = 180.0;

static constexpr double kTiltSetpoint0 = 0.16;
static constexpr double kTiltSetpoint45 = 0.385;
static constexpr double kTiltSetpoint90 = 0.61;
static constexpr double kTiltTime = 1.0;
static constexpr double kAccelerometerTolerance = 0.2;

/**
 * A fixture for the camera with two servos and a gyro
 * @author Thomas Clark
 */
class TiltPanCameraTest : public testing::Test {
protected:
	static Gyro *m_gyro;
	Servo *m_tilt, *m_pan;
	Accelerometer *m_spiAccel;

	static void SetUpTestCase() {
		// The gyro object blocks for 5 seconds in the constructor, so only
		// construct it once for the whole test case
		m_gyro = new Gyro(TestBench::kCameraGyroChannel);
		m_gyro->SetSensitivity(0.0134897058674);
	}

	static void TearDownTestCase() {
		delete m_gyro;
	}

	virtual void SetUp() {
		m_tilt = new Servo(TestBench::kCameraTiltChannel);
		m_pan = new Servo(TestBench::kCameraPanChannel);
		m_spiAccel = new ADXL345_SPI(SPI::kOnboardCS0);
	}

	virtual void TearDown() {
		delete m_tilt;
		delete m_pan;
		delete m_spiAccel;
	}
};

Gyro *TiltPanCameraTest::m_gyro = 0;

/**
 * Test if the servo turns 180 degrees and the gyroscope measures this angle
 */
TEST_F(TiltPanCameraTest, GyroAngle) {
	m_pan->Set(0.0f);
	Wait(kServoResetTime);

	m_gyro->Reset();

	for(int i = 0; i < 180; i++) {
		m_pan->SetAngle(i);

		Wait(0.05);
	}

	double gyroAngle = m_gyro->GetAngle();

	EXPECT_NEAR(gyroAngle, kTestAngle, 20.0) << "Gyro measured " << gyroAngle
		<< " degrees, servo should have turned " << kTestAngle <<  " degrees";
}

/**
 * Test if the accelerometer measures gravity along the correct axes when the
 * camera rotates
 */
TEST_F(TiltPanCameraTest, SPIAccelerometer) {
	m_tilt->Set(kTiltSetpoint0);
	Wait(kTiltTime);
	EXPECT_NEAR(-1.0, m_spiAccel->GetX(), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetY(), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetZ(), kAccelerometerTolerance);

	m_tilt->Set(kTiltSetpoint45);
	Wait(kTiltTime);
	EXPECT_NEAR(-std::sqrt(0.5), m_spiAccel->GetX(), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetY(), kAccelerometerTolerance);
	EXPECT_NEAR(std::sqrt(0.5), m_spiAccel->GetZ(), kAccelerometerTolerance);

	m_tilt->Set(kTiltSetpoint90);
	Wait(kTiltTime);
	EXPECT_NEAR(0.0, m_spiAccel->GetX(), kAccelerometerTolerance);
	EXPECT_NEAR(0.0, m_spiAccel->GetY(), kAccelerometerTolerance);
	EXPECT_NEAR(1.0, m_spiAccel->GetZ(), kAccelerometerTolerance);
}
<|endoftext|>


<commit_before>//===--- IncludeOrderCheck.cpp - clang-tidy -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IncludeOrderCheck.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"

namespace clang {
namespace tidy {

namespace {
class IncludeOrderPPCallbacks : public PPCallbacks {
public:
  explicit IncludeOrderPPCallbacks(ClangTidyCheck &Check, SourceManager &SM)
      : LookForMainModule(true), Check(Check), SM(SM) {}

  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                          StringRef FileName, bool IsAngled,
                          CharSourceRange FilenameRange, const FileEntry *File,
                          StringRef SearchPath, StringRef RelativePath,
                          const Module *Imported) override;
  void EndOfMainFile() override;

private:
  struct IncludeDirective {
    SourceLocation Loc;    ///< '#' location in the include directive
    CharSourceRange Range; ///< SourceRange for the file name
    StringRef Filename;    ///< Filename as a string
    bool IsAngled;         ///< true if this was an include with angle brackets
    bool IsMainModule;     ///< true if this was the first include in a file
  };
  std::vector<IncludeDirective> IncludeDirectives;
  bool LookForMainModule;

  ClangTidyCheck &Check;
  SourceManager &SM;
};
} // namespace

void IncludeOrderCheck::registerPPCallbacks(CompilerInstance &Compiler) {
  Compiler.getPreprocessor().addPPCallbacks(
      new IncludeOrderPPCallbacks(*this, Compiler.getSourceManager()));
}

static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
  // We leave the main module header at the top.
  if (IsMainModule)
    return 0;

  // LLVM and clang headers are in the penultimate position.
  if (Filename.startswith("llvm/") || Filename.startswith("llvm-c/") ||
      Filename.startswith("clang/") || Filename.startswith("clang-c/"))
    return 2;

  // System headers are sorted to the end.
  if (IsAngled || Filename.startswith("gtest/"))
    return 3;

  // Other headers are inserted between the main module header and LLVM headers.
  return 1;
}

void IncludeOrderPPCallbacks::InclusionDirective(
    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
    bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
    StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
  // We recognize the first include as a special main module header and want
  // to leave it in the top position.
  IncludeDirective ID = {HashLoc, FilenameRange, FileName, IsAngled, false};
  if (LookForMainModule && !IsAngled) {
    ID.IsMainModule = true;
    LookForMainModule = false;
  }
  IncludeDirectives.push_back(std::move(ID));
}

void IncludeOrderPPCallbacks::EndOfMainFile() {
  LookForMainModule = true;
  if (IncludeDirectives.empty())
    return;

  // TODO: find duplicated includes.

  // Form blocks of includes. We don't want to sort across blocks. This also
  // implicitly makes us never reorder over #defines or #if directives.
  // FIXME: We should be more careful about sorting below comments as we don't
  // know if the comment refers to the next include or the whole block that
  // follows.
  std::vector<unsigned> Blocks(1, 0);
  for (unsigned I = 1, E = IncludeDirectives.size(); I != E; ++I)
    if (SM.getExpansionLineNumber(IncludeDirectives[I].Loc) !=
        SM.getExpansionLineNumber(IncludeDirectives[I - 1].Loc) + 1)
      Blocks.push_back(I);
  Blocks.push_back(IncludeDirectives.size()); // Sentinel value.

  // Get a vector of indices.
  std::vector<unsigned> IncludeIndices;
  for (unsigned I = 0, E = IncludeDirectives.size(); I != E; ++I)
    IncludeIndices.push_back(I);

  // Sort the includes. We first sort by priority, then lexicographically.
  for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI)
    std::sort(&IncludeIndices[Blocks[BI]], &IncludeIndices[Blocks[BI + 1]],
              [this](unsigned LHSI, unsigned RHSI) {
      IncludeDirective &LHS = IncludeDirectives[LHSI];
      IncludeDirective &RHS = IncludeDirectives[RHSI];

      int PriorityLHS =
          getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule);
      int PriorityRHS =
          getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule);

      return std::tie(PriorityLHS, LHS.Filename) <
             std::tie(PriorityRHS, RHS.Filename);
    });

  // Emit a warning for each block and fixits for all changes within that block.
  for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) {
    // Find the first include that's not in the right position.
    unsigned I, E;
    for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I)
      if (IncludeIndices[I] != I)
        break;

    if (I == E)
      continue;

    // Emit a warning.
    auto D = Check.diag(IncludeDirectives[I].Loc,
                        "#includes are not sorted properly");

    // Emit fix-its for all following includes in this block.
    for (; I != E; ++I) {
      if (IncludeIndices[I] == I)
        continue;
      const IncludeDirective &CopyFrom = IncludeDirectives[IncludeIndices[I]];

      SourceLocation FromLoc = CopyFrom.Range.getBegin();
      const char *FromData = SM.getCharacterData(FromLoc);
      unsigned FromLen = std::strcspn(FromData, "\n");

      StringRef FixedName(FromData, FromLen);

      SourceLocation ToLoc = IncludeDirectives[I].Range.getBegin();
      const char *ToData = SM.getCharacterData(ToLoc);
      unsigned ToLen = std::strcspn(ToData, "\n");
      auto ToRange =
          CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen));

      D << FixItHint::CreateReplacement(ToRange, FixedName);
    }
  }

  IncludeDirectives.clear();
}

} // namespace tidy
} // namespace clang
<commit_msg>[clang-tidy] Don't index past the end of a vector.<commit_after>//===--- IncludeOrderCheck.cpp - clang-tidy -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IncludeOrderCheck.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"

namespace clang {
namespace tidy {

namespace {
class IncludeOrderPPCallbacks : public PPCallbacks {
public:
  explicit IncludeOrderPPCallbacks(ClangTidyCheck &Check, SourceManager &SM)
      : LookForMainModule(true), Check(Check), SM(SM) {}

  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                          StringRef FileName, bool IsAngled,
                          CharSourceRange FilenameRange, const FileEntry *File,
                          StringRef SearchPath, StringRef RelativePath,
                          const Module *Imported) override;
  void EndOfMainFile() override;

private:
  struct IncludeDirective {
    SourceLocation Loc;    ///< '#' location in the include directive
    CharSourceRange Range; ///< SourceRange for the file name
    StringRef Filename;    ///< Filename as a string
    bool IsAngled;         ///< true if this was an include with angle brackets
    bool IsMainModule;     ///< true if this was the first include in a file
  };
  std::vector<IncludeDirective> IncludeDirectives;
  bool LookForMainModule;

  ClangTidyCheck &Check;
  SourceManager &SM;
};
} // namespace

void IncludeOrderCheck::registerPPCallbacks(CompilerInstance &Compiler) {
  Compiler.getPreprocessor().addPPCallbacks(
      new IncludeOrderPPCallbacks(*this, Compiler.getSourceManager()));
}

static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
  // We leave the main module header at the top.
  if (IsMainModule)
    return 0;

  // LLVM and clang headers are in the penultimate position.
  if (Filename.startswith("llvm/") || Filename.startswith("llvm-c/") ||
      Filename.startswith("clang/") || Filename.startswith("clang-c/"))
    return 2;

  // System headers are sorted to the end.
  if (IsAngled || Filename.startswith("gtest/"))
    return 3;

  // Other headers are inserted between the main module header and LLVM headers.
  return 1;
}

void IncludeOrderPPCallbacks::InclusionDirective(
    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
    bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
    StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
  // We recognize the first include as a special main module header and want
  // to leave it in the top position.
  IncludeDirective ID = {HashLoc, FilenameRange, FileName, IsAngled, false};
  if (LookForMainModule && !IsAngled) {
    ID.IsMainModule = true;
    LookForMainModule = false;
  }
  IncludeDirectives.push_back(std::move(ID));
}

void IncludeOrderPPCallbacks::EndOfMainFile() {
  LookForMainModule = true;
  if (IncludeDirectives.empty())
    return;

  // TODO: find duplicated includes.

  // Form blocks of includes. We don't want to sort across blocks. This also
  // implicitly makes us never reorder over #defines or #if directives.
  // FIXME: We should be more careful about sorting below comments as we don't
  // know if the comment refers to the next include or the whole block that
  // follows.
  std::vector<unsigned> Blocks(1, 0);
  for (unsigned I = 1, E = IncludeDirectives.size(); I != E; ++I)
    if (SM.getExpansionLineNumber(IncludeDirectives[I].Loc) !=
        SM.getExpansionLineNumber(IncludeDirectives[I - 1].Loc) + 1)
      Blocks.push_back(I);
  Blocks.push_back(IncludeDirectives.size()); // Sentinel value.

  // Get a vector of indices.
  std::vector<unsigned> IncludeIndices;
  for (unsigned I = 0, E = IncludeDirectives.size(); I != E; ++I)
    IncludeIndices.push_back(I);

  // Sort the includes. We first sort by priority, then lexicographically.
  for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI)
    std::sort(IncludeIndices.begin() + Blocks[BI],
              IncludeIndices.begin() + Blocks[BI + 1],
              [this](unsigned LHSI, unsigned RHSI) {
      IncludeDirective &LHS = IncludeDirectives[LHSI];
      IncludeDirective &RHS = IncludeDirectives[RHSI];

      int PriorityLHS =
          getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule);
      int PriorityRHS =
          getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule);

      return std::tie(PriorityLHS, LHS.Filename) <
             std::tie(PriorityRHS, RHS.Filename);
    });

  // Emit a warning for each block and fixits for all changes within that block.
  for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) {
    // Find the first include that's not in the right position.
    unsigned I, E;
    for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I)
      if (IncludeIndices[I] != I)
        break;

    if (I == E)
      continue;

    // Emit a warning.
    auto D = Check.diag(IncludeDirectives[I].Loc,
                        "#includes are not sorted properly");

    // Emit fix-its for all following includes in this block.
    for (; I != E; ++I) {
      if (IncludeIndices[I] == I)
        continue;
      const IncludeDirective &CopyFrom = IncludeDirectives[IncludeIndices[I]];

      SourceLocation FromLoc = CopyFrom.Range.getBegin();
      const char *FromData = SM.getCharacterData(FromLoc);
      unsigned FromLen = std::strcspn(FromData, "\n");

      StringRef FixedName(FromData, FromLen);

      SourceLocation ToLoc = IncludeDirectives[I].Range.getBegin();
      const char *ToData = SM.getCharacterData(ToLoc);
      unsigned ToLen = std::strcspn(ToData, "\n");
      auto ToRange =
          CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen));

      D << FixItHint::CreateReplacement(ToRange, FixedName);
    }
  }

  IncludeDirectives.clear();
}

} // namespace tidy
} // namespace clang
<|endoftext|>


<commit_before>#include "audio_device.h"
#include "clip_manager.h"
#include "engine/log.h"
#include "engine/engine.h"
#include "engine/iplugin.h"

namespace Lumix
{

class AudioDeviceImpl : public AudioDevice
{
public:
	BufferHandle createBuffer(const void* data,
		int size_bytes,
		int channels,
		int sample_rate,
		int flags) override
	{
		return INVALID_BUFFER_HANDLE;
	}
	void setEcho(BufferHandle handle,
		float wet_dry_mix,
		float feedback,
		float left_delay,
		float right_delay) override {}
	void play(BufferHandle buffer, bool looped) override {}
	bool isPlaying(BufferHandle buffer) override { return false; }
	void stop(BufferHandle buffer) override {}
	bool isEnd(BufferHandle buffer) override { return true; }
	void pause(BufferHandle buffer) override {}
	void setVolume(BufferHandle buffer, float volume) override {}
	void setFrequency(BufferHandle buffer, float frequency) override {}
	void setCurrentTime(BufferHandle buffer, float time_seconds) override {}
	float getCurrentTime(BufferHandle buffer) override { return -1; }
	void setListenerPosition(float x, float y, float z) override {}
	void setListenerOrientation(float front_x,
		float front_y,
		float front_z,
		float up_x,
		float up_y,
		float up_z) override {}
	void setSourcePosition(BufferHandle buffer, float x, float y, float z) override {}
	void update(float time_delta) override {}
};

static AudioDeviceImpl g_null_device;

AudioDevice* AudioDevice::create(Engine& engine)
{
	return &g_null_device;
}

void AudioDevice::destroy(AudioDevice& device)
{
}

const AudioDevice::BufferHandle AudioDevice::INVALID_BUFFER_HANDLE = -1;

} // namespace Lumix<commit_msg>fixed linux build #2<commit_after>#include "audio_device.h"
#include "clip_manager.h"
#include "engine/log.h"
#include "engine/engine.h"
#include "engine/iplugin.h"

namespace Lumix
{

class AudioDeviceImpl : public AudioDevice
{
public:
	BufferHandle createBuffer(const void* data,
		int size_bytes,
		int channels,
		int sample_rate,
		int flags) override
	{
		return INVALID_BUFFER_HANDLE;
	}
	void setEcho(BufferHandle handle,
		float wet_dry_mix,
		float feedback,
		float left_delay,
		float right_delay) override {}
	void play(BufferHandle buffer, bool looped) override {}
	bool isPlaying(BufferHandle buffer) override { return false; }
	void stop(BufferHandle buffer) override {}
	bool isEnd(BufferHandle buffer) override { return true; }
	void pause(BufferHandle buffer) override {}
	void setVolume(BufferHandle buffer, float volume) override {}
	void setFrequency(BufferHandle buffer, float frequency) override {}
	void setCurrentTime(BufferHandle buffer, float time_seconds) override {}
	float getCurrentTime(BufferHandle buffer) override { return -1; }
	void setListenerPosition(float x, float y, float z) override {}
	void setListenerOrientation(float front_x,
		float front_y,
		float front_z,
		float up_x,
		float up_y,
		float up_z) override {}
	void setSourcePosition(BufferHandle buffer, float x, float y, float z) override {}
	void update(float time_delta) override {}
};

static AudioDeviceImpl g_null_device;

AudioDevice* AudioDevice::create(Engine& engine)
{
	return &g_null_device;
}

void AudioDevice::destroy(AudioDevice& device)
{
}

} // namespace Lumix<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include "pbge/pbge.h"

#include "vbo_setup.h"
#include "TensorModel.h"
#include "Ellipses.h"
#include "Ellipsoids.h"
#include "FieldReader.h"

class CustomKeyboardEventHandler : public pbge::KeyboardEventHandler {
public:
    CustomKeyboardEventHandler(pbge::SceneGraph * graph, int cam_name) {
        this->cam_node = dynamic_cast<pbge::TransformationNode*>(graph->getGraphNode(cam_name));
    }

    bool keyDown(char key) {
        math3d::matrix44 m = cam_node->getTransformationMatrix();
        switch(key) {
            case 'W': cam_node->translate(0, 0.1f, 0); break;
            case 'S': cam_node->translate(0, -0.1f, 0); break;
            case 'A': cam_node->translate(-0.1f, 0, 0); break;
            case 'D': cam_node->translate(0.1f, 0, 0); break;
            case 'Q': cam_node->translate(0, 0, 0.1f); break;
            case 'E': cam_node->translate(0, 0, -0.1f); break;
        }
        return true;
    }

    bool keyUp(char key) {
        return true;
    }
private:
    pbge::TransformationNode * cam_node;
};

class CustomMouseEventHandler : public pbge::MouseEventHandler {
public:
    CustomMouseEventHandler(pbge::SceneGraph * graph, int cam_name) {
        this->cam_node = dynamic_cast<pbge::TransformationNode*>(graph->getGraphNode(cam_name));
		leftButtonDown = false;
        rightButtonDown = false;
        prev_x = 0;
        prev_y = 0;
		vertical_rotation = 0;
		horizontal_rotation = 0;
		degreeScale = 0.03f;
    }

    bool buttonDown(pbge::MouseButton button, int x, int y) {
        if(button == pbge::L_MOUSE_BUTTON) {
            leftButtonDown = true;
            prev_x = x;
            prev_y = y;
        }
        else if(button == pbge::R_MOUSE_BUTTON) rightButtonDown = true;
		return true;
    }
    bool buttonUp(pbge::MouseButton button, int x, int y) {
        if(button == pbge::L_MOUSE_BUTTON) {
            leftButtonDown = false;
            horizontal_rotation += (prev_x - x) * degreeScale;
			vertical_rotation += (prev_y - y) * degreeScale;
			prev_x = 0;
            prev_y = 0;
        }
        else if(button == pbge::R_MOUSE_BUTTON) rightButtonDown = false;
		return true;
    }
    bool move(int x, int y) {
        if(leftButtonDown) {
			math3d::matrix44 rotation = math3d::rotationMatrix(horizontal_rotation + (prev_x - x) * degreeScale, 0, 1.0f, 0);
            rotation = math3d::rotationMatrix(vertical_rotation + (prev_y - y) * degreeScale, 1.0f, 0, 0) * rotation;
            cam_node->setTransformationMatrix(rotation);
        }
		return true;
    }
private:
    bool leftButtonDown;
    bool rightButtonDown;
    int prev_x;
    int prev_y;
	float vertical_rotation;
	float horizontal_rotation;
	float degreeScale;
    pbge::TransformationNode * cam_node;
};

class CustomSceneInitializer : public pbge::SceneInitializer {

public:
    pbge::SceneGraph * operator () (pbge::GraphicAPI * gfx, pbge::Window * window) {
        pbge::SceneGraph * scene;
        int cam_node_name;
        // FIXME: remove the state change line
        gfx->enableMode(pbge::GraphicAPI::DEPTH_TEST);
        scene = new pbge::SceneGraph(new pbge::TransformationNode);
        createSceneTransformations(scene);
        createSceneLights(scene, cam_node->getSceneGraphIndex());
        createSceneModels(scene, gfx);
        cam_node_name = cam_node->getSceneGraphIndex();
        pbge::CameraNode * cam = dynamic_cast<pbge::CameraNode*>(scene->appendChildTo(cam_node_name, new pbge::CameraNode()));
        cam->lookAt(math3d::vector4(0,1,0), math3d::vector4(0,0,-1));
        cam->setPerspective(45.0f, 1.0f, 1.0f, 100.0f);

		window->getEventHandler()->addKeyboardHandler(new CustomKeyboardEventHandler(scene, cam_trans_node->getSceneGraphIndex()));
		window->getEventHandler()->addMouseHandler(new CustomMouseEventHandler(scene, cam_rot_node->getSceneGraphIndex()));
        return scene;
    }
private:
    void createSceneModels(pbge::SceneGraph * graph, pbge::GraphicAPI * gfx) {
        AnalyzeReader aReader(gfx);
        aReader.loadField("./Resources/dhelix_dti_tensor");
        aReader.generateFieldOn(graph, light_parent);
    }

    void createSceneLights(pbge::SceneGraph * graph, int cam_node_name) {
        pbge::Light * light1 = new pbge::PointLight;
        light1->setDiffuseColor(1,0,0,1);
        graph->appendChildTo(light_parent, light1);

        pbge::Light* light2 = new pbge::PointLight;
        light2->setDiffuseColor(0,1,1,1);
        graph->appendChildTo(cam_node_name, light2);
    }

    void createSceneTransformations(pbge::SceneGraph * graph) {
        child = pbge::TransformationNode::rotation(pbge::degToRad(60), 0,0,20)->scale(0.5f, 0.5f, 0.5f);
        graph->appendChildTo(pbge::SceneGraph::ROOT, child);

        light_parent = pbge::TransformationNode::translation(0.0f, 1.0f, 0.0f);
        graph->appendChildTo(pbge::SceneGraph::ROOT, light_parent);

        circle_parent = graph->appendChildTo(light_parent, pbge::TransformationNode::translation(1, 1, 0));

		cam_rot_node = graph->appendChildTo(pbge::SceneGraph::ROOT, pbge::TransformationNode::translation(0.0f, 0.0f, 0.0f));

		cam_trans_node = graph->appendChildTo(cam_rot_node, pbge::TransformationNode::translation(0.0f, 1.0f, 5.0f));

		cam_node = graph->appendChildTo(cam_trans_node, pbge::TransformationNode::translation(0.0f, 0.0f, 0.0f));

        sphereParent = graph->appendChildTo(child, pbge::TransformationNode::translation(-1.5f, 0.0f, 0.0f));
    }
    pbge::Node * light_parent;
    pbge::Node * child;
    pbge::Node * circle_parent;
    pbge::Node * cam_trans_node;
	pbge::Node * cam_rot_node;
	pbge::Node * cam_node;
    pbge::Node * sphereParent;
};

int main(int argc, char ** argv) {
    pbge::Manager * manager = new pbge::Manager;
    manager->setWindowDimensions(500, 500);
    manager->setFullscreen(false);
    manager->setWindowTitle("tensor_field");
    manager->setSceneInitializer(new CustomSceneInitializer);
    manager->printDebugInformation(true);
    manager->displayGraphics();
    delete manager;
    return 0;
}<commit_msg>more code cleanup<commit_after>#include <iostream>
#include <vector>
#include "pbge/pbge.h"

#include "vbo_setup.h"
#include "TensorModel.h"
#include "Ellipsoids.h"
#include "FieldReader.h"

class CustomKeyboardEventHandler : public pbge::KeyboardEventHandler {
public:
    CustomKeyboardEventHandler(pbge::SceneGraph * graph, int cam_name) {
        this->cam_node = dynamic_cast<pbge::TransformationNode*>(graph->getGraphNode(cam_name));
    }

    bool keyDown(char key) {
        math3d::matrix44 m = cam_node->getTransformationMatrix();
        switch(key) {
            case 'W': cam_node->translate(0, 0.1f, 0); break;
            case 'S': cam_node->translate(0, -0.1f, 0); break;
            case 'A': cam_node->translate(-0.1f, 0, 0); break;
            case 'D': cam_node->translate(0.1f, 0, 0); break;
            case 'Q': cam_node->translate(0, 0, 0.1f); break;
            case 'E': cam_node->translate(0, 0, -0.1f); break;
        }
        return true;
    }

    bool keyUp(char key) {
        return true;
    }
private:
    pbge::TransformationNode * cam_node;
};

class CustomMouseEventHandler : public pbge::MouseEventHandler {
public:
    CustomMouseEventHandler(pbge::SceneGraph * graph, int cam_name) {
        this->cam_node = dynamic_cast<pbge::TransformationNode*>(graph->getGraphNode(cam_name));
		leftButtonDown = false;
        rightButtonDown = false;
        prev_x = 0;
        prev_y = 0;
		vertical_rotation = 0;
		horizontal_rotation = 0;
		degreeScale = 0.03f;
    }

    bool buttonDown(pbge::MouseButton button, int x, int y) {
        if(button == pbge::L_MOUSE_BUTTON) {
            leftButtonDown = true;
            prev_x = x;
            prev_y = y;
        }
        else if(button == pbge::R_MOUSE_BUTTON) rightButtonDown = true;
		return true;
    }
    bool buttonUp(pbge::MouseButton button, int x, int y) {
        if(button == pbge::L_MOUSE_BUTTON) {
            leftButtonDown = false;
            horizontal_rotation += (prev_x - x) * degreeScale;
			vertical_rotation += (prev_y - y) * degreeScale;
			prev_x = 0;
            prev_y = 0;
        }
        else if(button == pbge::R_MOUSE_BUTTON) rightButtonDown = false;
		return true;
    }
    bool move(int x, int y) {
        if(leftButtonDown) {
			math3d::matrix44 rotation = math3d::rotationMatrix(horizontal_rotation + (prev_x - x) * degreeScale, 0, 1.0f, 0);
            rotation = math3d::rotationMatrix(vertical_rotation + (prev_y - y) * degreeScale, 1.0f, 0, 0) * rotation;
            cam_node->setTransformationMatrix(rotation);
        }
		return true;
    }
private:
    bool leftButtonDown;
    bool rightButtonDown;
    int prev_x;
    int prev_y;
	float vertical_rotation;
	float horizontal_rotation;
	float degreeScale;
    pbge::TransformationNode * cam_node;
};

class CustomSceneInitializer : public pbge::SceneInitializer {

public:
    pbge::SceneGraph * operator () (pbge::GraphicAPI * gfx, pbge::Window * window) {
        pbge::SceneGraph * scene;
        int cam_node_name;
        // FIXME: remove the state change line
        gfx->enableMode(pbge::GraphicAPI::DEPTH_TEST);
        scene = new pbge::SceneGraph(new pbge::TransformationNode);
        createSceneTransformations(scene);
        createSceneLights(scene, cam_node->getSceneGraphIndex());
        createSceneModels(scene, gfx);
        cam_node_name = cam_node->getSceneGraphIndex();
        pbge::CameraNode * cam = dynamic_cast<pbge::CameraNode*>(scene->appendChildTo(cam_node_name, new pbge::CameraNode()));
        cam->lookAt(math3d::vector4(0,1,0), math3d::vector4(0,0,-1));
        cam->setPerspective(45.0f, 1.0f, 1.0f, 100.0f);

		window->getEventHandler()->addKeyboardHandler(new CustomKeyboardEventHandler(scene, cam_trans_node->getSceneGraphIndex()));
		window->getEventHandler()->addMouseHandler(new CustomMouseEventHandler(scene, cam_rot_node->getSceneGraphIndex()));
        return scene;
    }
private:
    void createSceneModels(pbge::SceneGraph * graph, pbge::GraphicAPI * gfx) {
        AnalyzeReader aReader(gfx);
        aReader.loadField("./Resources/dhelix_dti_tensor");
        aReader.generateFieldOn(graph, light_parent);
    }

    void createSceneLights(pbge::SceneGraph * graph, int cam_node_name) {
        pbge::Light * light1 = new pbge::PointLight;
        light1->setDiffuseColor(1,0,0,1);
        graph->appendChildTo(light_parent, light1);

        pbge::Light* light2 = new pbge::PointLight;
        light2->setDiffuseColor(0,1,1,1);
        graph->appendChildTo(cam_node_name, light2);
    }

    void createSceneTransformations(pbge::SceneGraph * graph) {
        child = pbge::TransformationNode::rotation(pbge::degToRad(60), 0,0,20)->scale(0.5f, 0.5f, 0.5f);
        graph->appendChildTo(pbge::SceneGraph::ROOT, child);

        light_parent = pbge::TransformationNode::translation(0.0f, 1.0f, 0.0f);
        graph->appendChildTo(pbge::SceneGraph::ROOT, light_parent);

        circle_parent = graph->appendChildTo(light_parent, pbge::TransformationNode::translation(1, 1, 0));

		cam_rot_node = graph->appendChildTo(pbge::SceneGraph::ROOT, pbge::TransformationNode::translation(0.0f, 0.0f, 0.0f));

		cam_trans_node = graph->appendChildTo(cam_rot_node, pbge::TransformationNode::translation(0.0f, 1.0f, 5.0f));

		cam_node = graph->appendChildTo(cam_trans_node, pbge::TransformationNode::translation(0.0f, 0.0f, 0.0f));

        sphereParent = graph->appendChildTo(child, pbge::TransformationNode::translation(-1.5f, 0.0f, 0.0f));
    }
    pbge::Node * light_parent;
    pbge::Node * child;
    pbge::Node * circle_parent;
    pbge::Node * cam_trans_node;
	pbge::Node * cam_rot_node;
	pbge::Node * cam_node;
    pbge::Node * sphereParent;
};

int main(int argc, char ** argv) {
    pbge::Manager * manager = new pbge::Manager;
    manager->setWindowDimensions(500, 500);
    manager->setFullscreen(false);
    manager->setWindowTitle("tensor_field");
    manager->setSceneInitializer(new CustomSceneInitializer);
    manager->printDebugInformation(true);
    manager->displayGraphics();
    delete manager;
    return 0;
}<|endoftext|>


<commit_before>#include <tudocomp_driver/registry.h>

#include <tudocomp/lz78/lz78_compressor.h>
#include <tudocomp/lz78/dummy_coder.h>
#include <tudocomp/lz78/bit_coder.h>

#include <tudocomp/lzw/lzw_compressor.h>
#include <tudocomp/lzw/dummy_coder.h>
#include <tudocomp/lzw/bit_coder.h>

#include <tudocomp/lz78/Lz78Compressor.hpp>
#include <tudocomp/lz78/Lz78DebugCoder.hpp>
#include <tudocomp/lz78/Lz78BitCoder.hpp>

#include <tudocomp/lzw/LzwCompressor.hpp>
#include <tudocomp/lzw/LzwDebugCoder.hpp>
#include <tudocomp/lzw/LzwBitCoder.hpp>

//TODO: esacomp needs to be re-inserted!
/*
#include "lz_compressor.h"
#include "esacomp/esacomp_rule_compressor.h"
#include "esa_compressor.h"
#include "max_lcp_sorted_suffix_list.h"
#include "max_lcp_heap.h"
#include "dummy_compressor.h"

#include "code0.h"
#include "code1.h"
#include "code2.h"
#include "dummy_encoder.h"
*/

namespace tudocomp_driver {

using namespace tudocomp;

// Algorithm interfaces

//TODO: esacomp needs to be re-inserted!
/*
using esacomp::EsacompRuleCompressor;
using esacomp::EsacompCompressStrategy;
using esacomp::EsacompEncodeStrategy;
*/

using ::lz78::Lz78Rule;
using ::lz78::Lz78RuleCoder;

using ::lzw::LzwRule;
using ::lzw::LzwRuleCoder;

// Algorithm implementations

using ::lz78::LZ78DebugCode;
using ::lz78::LZ78BitCode;

using ::lzw::LZWDebugCode;
using ::lzw::LZWBitCode;

using ::tudocomp::lzw::LzwCompressor;
using ::tudocomp::lzw::LzwDebugCoder;
using ::tudocomp::lzw::LzwBitCoder;

using ::tudocomp::lz78::Lz78Compressor;
using ::tudocomp::lz78::Lz78DebugCoder;
using ::tudocomp::lz78::Lz78BitCoder;

//TODO: esacomp needs to be re-inserted!
/*
using esacomp::LZCompressor;
using esacomp::DummyCompressor;
using esacomp::DummyCoder;
*/

// All compression and encoding algorithms exposed by the command
// line interface.
//
// The format of the initializers is a tuple of three things:
// - Display name: Used in the UI for displaying the name of a algorithm
// - ID string: Used in the command line interface and the output file name
//   for identifying an algorithm
// - Description: Text describing what kind of algorithm this is.
// - Algorithm: A function pointer that constructs the base class of a
//   Compressor or Encoder.

void register_algos(AlgorithmRegistry<Compressor>& registry) {
    //TODO: esacomp needs to be re-inserted!
    /*
    registry.with_info<EsacompRuleCompressor>(
        // TODO: Name right
        // - lz77rule ~ LZSS rules with implicit escape bits
        // - lz ~ unknown named variant of lz with suffix array
        "Esacomp rules", "esacomp",
        "A Family of compression algorithms making use "
        "of esacomp-like replacement rules.")
    .with_sub_algos<EsacompCompressStrategy>([](AlgorithmRegistry<EsacompCompressStrategy>& registry) {
        registry.set_name("Compressor");

        registry.with_info<DummyCompressor>(
            "Dummy", "dummy",
            "Dummy compressor that does not produce any rules.").do_register();

        registry.with_info<LZCompressor>(
            "LZ SA", "lz",
            "LZ impl included in esacomp. Uses a suffix array to determine the LZ factorisation up-front").do_register();

        registry.with_info<ESACompressor<>>(
            "ESA", "esa",
            "Esacomp (defaults to using a suffix list internally).").do_register();

        registry.with_info<ESACompressor<MaxLCPSortedSuffixList>>(
            "ESA (Sorted Suffix List)", "esa_list",
            "Esacomp using a suffix list internally.").do_register();

    })
    .with_sub_algos<EsacompEncodeStrategy>([](AlgorithmRegistry<EsacompEncodeStrategy>& registry) {
        registry.set_name("Coder");

        registry.with_info<DummyCoder>(
            "Dummy", "dummy",
            "Dummy encoding, outputs input text unchanged.").do_register();

        registry.with_info<Code0Coder>(
            "Code0", "debug",
            "Human readable output of text and rules.").do_register();

        registry.with_info<Code1Coder>(
            "Code1", "code1",
            "Byte based encoding.").do_register();

        registry.with_info<Code2Coder>(
            "Code2", "code2",
            "Bit based encoding.").do_register();
    })
    .do_register();*/

    registry.with_info<Lz78Rule>(
        "LZ78 rule-like", "lz78rule",
        "A Family of compression algorithms making use "
        "of LZ78-like replacement rules.")
    .with_sub_algos<Lz78RuleCoder>([](AlgorithmRegistry<Lz78RuleCoder>& registry) {
        registry.set_name("Coder");

        registry.with_info<LZ78DebugCode>(
            "Debug", "debug",
            "Debug encoding, each rule is emitted as a string of the form `(<idx>,<chr>)`").do_register();

        registry.with_info<LZ78BitCode>(
            "Bit", "bit",
            "Bit encoding, each rule is emitted a bitstream of the "
            "minimum amount of bits needed to encode the index and the char").do_register();
    })
    .do_register();

    registry.with_info<LzwRule>(
        "LZW rule-like", "lzwrule",
        "A Family of compression algorithms making use "
        "of LZW-like dictionary entries.")
    .with_sub_algos<LzwRuleCoder>([](AlgorithmRegistry<LzwRuleCoder>& registry) {
        registry.set_name("Coder");

        registry.with_info<LZWDebugCode>(
            "Debug", "debug",
            "Debug encoding, each rule is emitted as a string of the form `<idx>,...` where <idx> is either a integer or a char literal").do_register();

        registry.with_info<LZWBitCode>(
            "Bit", "bit",
            "Bit encoding, each rule is emitted a bitstream of the "
            "minimum amount of bits needed to encode the index and the char").do_register();
    })
    .do_register();
}

}
<commit_msg>Added neww template based lz78/lzw impls to registry<commit_after>#include <tudocomp_driver/registry.h>

#include <tudocomp/lz78/lz78_compressor.h>
#include <tudocomp/lz78/dummy_coder.h>
#include <tudocomp/lz78/bit_coder.h>

#include <tudocomp/lzw/lzw_compressor.h>
#include <tudocomp/lzw/dummy_coder.h>
#include <tudocomp/lzw/bit_coder.h>

#include <tudocomp/lz78/Lz78Compressor.hpp>
#include <tudocomp/lz78/Lz78DebugCoder.hpp>
#include <tudocomp/lz78/Lz78BitCoder.hpp>

#include <tudocomp/lzw/LzwCompressor.hpp>
#include <tudocomp/lzw/LzwDebugCoder.hpp>
#include <tudocomp/lzw/LzwBitCoder.hpp>

//TODO: esacomp needs to be re-inserted!
/*
#include "lz_compressor.h"
#include "esacomp/esacomp_rule_compressor.h"
#include "esa_compressor.h"
#include "max_lcp_sorted_suffix_list.h"
#include "max_lcp_heap.h"
#include "dummy_compressor.h"

#include "code0.h"
#include "code1.h"
#include "code2.h"
#include "dummy_encoder.h"
*/

namespace tudocomp_driver {

using namespace tudocomp;

// Algorithm interfaces

//TODO: esacomp needs to be re-inserted!
/*
using esacomp::EsacompRuleCompressor;
using esacomp::EsacompCompressStrategy;
using esacomp::EsacompEncodeStrategy;
*/

using ::lz78::Lz78Rule;
using ::lz78::Lz78RuleCoder;

using ::lzw::LzwRule;
using ::lzw::LzwRuleCoder;

// Algorithm implementations

using ::lz78::LZ78DebugCode;
using ::lz78::LZ78BitCode;

using ::lzw::LZWDebugCode;
using ::lzw::LZWBitCode;

using ::tudocomp::lzw::LzwCompressor;
using ::tudocomp::lzw::LzwDebugCoder;
using ::tudocomp::lzw::LzwBitCoder;

using ::tudocomp::lz78::Lz78Compressor;
using ::tudocomp::lz78::Lz78DebugCoder;
using ::tudocomp::lz78::Lz78BitCoder;

//TODO: esacomp needs to be re-inserted!
/*
using esacomp::LZCompressor;
using esacomp::DummyCompressor;
using esacomp::DummyCoder;
*/

// All compression and encoding algorithms exposed by the command
// line interface.
//
// The format of the initializers is a tuple of three things:
// - Display name: Used in the UI for displaying the name of a algorithm
// - ID string: Used in the command line interface and the output file name
//   for identifying an algorithm
// - Description: Text describing what kind of algorithm this is.
// - Algorithm: A function pointer that constructs the base class of a
//   Compressor or Encoder.

void register_algos(AlgorithmRegistry<Compressor>& registry) {
    //TODO: esacomp needs to be re-inserted!
    /*
    registry.with_info<EsacompRuleCompressor>(
        // TODO: Name right
        // - lz77rule ~ LZSS rules with implicit escape bits
        // - lz ~ unknown named variant of lz with suffix array
        "Esacomp rules", "esacomp",
        "A Family of compression algorithms making use "
        "of esacomp-like replacement rules.")
    .with_sub_algos<EsacompCompressStrategy>([](AlgorithmRegistry<EsacompCompressStrategy>& registry) {
        registry.set_name("Compressor");

        registry.with_info<DummyCompressor>(
            "Dummy", "dummy",
            "Dummy compressor that does not produce any rules.").do_register();

        registry.with_info<LZCompressor>(
            "LZ SA", "lz",
            "LZ impl included in esacomp. Uses a suffix array to determine the LZ factorisation up-front").do_register();

        registry.with_info<ESACompressor<>>(
            "ESA", "esa",
            "Esacomp (defaults to using a suffix list internally).").do_register();

        registry.with_info<ESACompressor<MaxLCPSortedSuffixList>>(
            "ESA (Sorted Suffix List)", "esa_list",
            "Esacomp using a suffix list internally.").do_register();

    })
    .with_sub_algos<EsacompEncodeStrategy>([](AlgorithmRegistry<EsacompEncodeStrategy>& registry) {
        registry.set_name("Coder");

        registry.with_info<DummyCoder>(
            "Dummy", "dummy",
            "Dummy encoding, outputs input text unchanged.").do_register();

        registry.with_info<Code0Coder>(
            "Code0", "debug",
            "Human readable output of text and rules.").do_register();

        registry.with_info<Code1Coder>(
            "Code1", "code1",
            "Byte based encoding.").do_register();

        registry.with_info<Code2Coder>(
            "Code2", "code2",
            "Bit based encoding.").do_register();
    })
    .do_register();*/

    registry.with_info<Lz78Rule>(
        "LZ78 rule-like", "lz78rule",
        "A Family of compression algorithms making use "
        "of LZ78-like replacement rules.")
    .with_sub_algos<Lz78RuleCoder>([](AlgorithmRegistry<Lz78RuleCoder>& registry) {
        registry.set_name("Coder");

        registry.with_info<LZ78DebugCode>(
            "Debug", "debug",
            "Debug encoding, each rule is emitted as a string of the form `(<idx>,<chr>)`").do_register();

        registry.with_info<LZ78BitCode>(
            "Bit", "bit",
            "Bit encoding, each rule is emitted a bitstream of the "
            "minimum amount of bits needed to encode the index and the char").do_register();
    })
    .do_register();

    registry.with_info<LzwRule>(
        "LZW rule-like", "lzwrule",
        "A Family of compression algorithms making use "
        "of LZW-like dictionary entries.")
    .with_sub_algos<LzwRuleCoder>([](AlgorithmRegistry<LzwRuleCoder>& registry) {
        registry.set_name("Coder");

        registry.with_info<LZWDebugCode>(
            "Debug", "debug",
            "Debug encoding, each rule is emitted as a string of the form `<idx>,...` where <idx> is either a integer or a char literal").do_register();

        registry.with_info<LZWBitCode>(
            "Bit", "bit",
            "Bit encoding, each rule is emitted a bitstream of the "
            "minimum amount of bits needed to encode the index and the char").do_register();
    })
    .do_register();

    registry.with_info<Lz78Compressor<Lz78DebugCoder>>(
        "lz78 debug coder", "t_lz78_debug",
        "Template-based implementation of a lz78 coder with human readable"
        "debug output")
    .do_register();
    registry.with_info<Lz78Compressor<Lz78BitCoder>>(
        "lz78 bit coder", "t_lz78_bit",
        "Template-based implementation of a lz78 coder with naive bit"
        "compressed output")
    .do_register();
    registry.with_info<LzwCompressor<LzwDebugCoder>>(
        "lzw debug coder", "t_lzw_debug",
        "Template-based implementation of a lzw coder with human readable"
        "debug output")
    .do_register();
    registry.with_info<LzwCompressor<LzwBitCoder>>(
        "lzw bit coder", "t_lzw_bit",
        "Template-based implementation of a lzw coder with naive bit"
        "compressed output")
    .do_register();
}

}
<|endoftext|>