<commit_before>/*
 *
 * Author: Jeffrey Leung
 * Last edited: 2015-12-31
 *
 * This C++ file contains the implementation of the Labyrinth class, which uses
 * the Room class to create a 2-d mapping for a game.
 *
 */

#include <cmath>
#include <iostream>
#include <stdexcept>

#include "../include/room_properties.hpp"
#include "../include/room.hpp"
#include "../include/coordinate.hpp"
#include "../include/labyrinth.hpp"

// CONSTRUCTOR/DESTRUCTOR:

// Parameterized constructor
// An exception is thrown if:
//   A size of 0 is given (invalid_argument)
Labyrinth::Labyrinth( unsigned int x_size, unsigned int y_size )
{
  if( x_size == 0 )
  {
    if( y_size == 0 )
    {
      throw std::invalid_argument( "Error: Labyrinth() was given empty x and "\
        "y sizes.\n" );
    }
    else
    {
      throw std::invalid_argument( "Error: Labyrinth() was given an empty "\
        "x size.\n" );
    }
  }
  else if( y_size == 0 )
  {
    throw std::invalid_argument( "Error: Labyrinth() was given an empty "\
      "y size.\n" );
  }

  rooms_ = new Room*[ y_size ];
  for( unsigned int i = 0; i < y_size; ++i )
  {
    rooms_[i] = new Room[ x_size ];
  }

  x_size_ = x_size;
  y_size_ = y_size;
}

// Destructor
Labyrinth::~Labyrinth()
{
  for( unsigned int i = 0; i < y_size_; ++i )
  {
    delete [] rooms_[i];
  }
  delete [] rooms_;
}

// SETUP:

// This method connects two Rooms by breaking their walls.
// An exception is thrown if:
//   The Rooms are already connected (logic_error)
//   The Rooms are the same (logic_error)
//   The Rooms are not adjacent (logic_error)
//   One or both Rooms are outside the Labyrinth (invalid_argument)
void Labyrinth::ConnectRooms( Coordinate rm_1, Coordinate rm_2 )
{
  if( rm_1 == rm_2 )
  {
    throw std::logic_error( "Error: ConnectRooms() was given the same "\
      "coordinate for the two Rooms.\n" );
  }

  else if( !WithinBounds(rm_1) || !WithinBounds(rm_2) )
  {
    if( !WithinBounds(rm_1) )
    {
      if( !WithinBounds(rm_2) )
      {
        throw std::invalid_argument( "Error: ConnectRooms() was given invalid "\
          "coordinates for both rm_1 and rm_2.\n" );
      }
      else
      {
        throw std::invalid_argument( "Error: ConnectRooms() was given "\
          "an invalid coordinate for rm_1.\n" );
      }
    }

    else
    {
      throw std::invalid_argument( "Error: ConnectRooms() was given an "\
        "invalid coordinate for rm_2.\n" );
    }
  }

  else if( !IsAdjacent(rm_1, rm_2) )
  {
    throw std::logic_error( "Error: ConnectRooms() was given two coordinates "\
      "which are not adjacent, and therefore cannot be connected.\n" );
  }

  int x_distance = (int)(rm_2.x) - (int)(rm_1.x);
  int y_distance = (int)(rm_2.y) - (int)(rm_1.y);

  Direction break_wall_1;
  Direction break_wall_2;

  if( x_distance == 0 )
  {
    if( y_distance > 0 )  // rm_1 is north of rm_2
    {
      break_wall_1 = Direction::kSouth;
      break_wall_2 = Direction::kNorth;
    }
    else  // rm_1 is south of rm_2
    {
      break_wall_1 = Direction::kNorth;
      break_wall_2 = Direction::kSouth;
    }
  }

  else if( y_distance == 0 )
  {
    if( x_distance > 0 )  // rm_1 is west of rm_2
    {
      break_wall_1 = Direction::kEast;
      break_wall_2 = Direction::kWest;
    }
    else  // rm_1 is east of rm_2
    {
      break_wall_1 = Direction::kWest;
      break_wall_2 = Direction::kEast;
    }
  }

  else
  {
    throw std::logic_error( "Error: ConnectRooms() called IsAdjacent(), "\
      "which should have evaluated to false, but did not.\n" );
  }

  RoomAt(rm_1).BreakWall(break_wall_1);
  RoomAt(rm_2).BreakWall(break_wall_2);
  return;
}

// PLAY:

// This method returns the current Inhabitant of the Room.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
Inhabitant Labyrinth::GetInhabitant( Coordinate rm ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: GetInhabitant() was given a "\
      "Coordinate outside of the Labyrinth.\n" );
  }
  return RoomAt(rm).GetInhabitant();
}

// This method returns the current Item in the room, but does not
// change it.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
Item Labyrinth::GetItem( Coordinate rm ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: GetItem() was given a "\
      "Coordinate outside of the Labyrinth.\n" );
  }
  return RoomAt(rm).GetItem();
}

// This method returns the type of RoomBorder in the given direction.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
//   Direction d is kNone (invalid_argument)
RoomBorder Labyrinth::DirectionCheck( Coordinate rm, Direction d ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: DirectionCheck() was given a "\
      "Coordinate outside of the Labyrinth.\n" );
  }
  else if( d == Direction::kNone )
  {
    throw std::invalid_argument( "Error: DirectionCheck() was given an "\
      "invalid direction (kNone).\n" );
  }

  return RoomAt(rm).DirectionCheck(d);
}

// PRIVATE METHODS:

// This private method returns a reference to the Room at the given
// coordinate.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
Room& Labyrinth::RoomAt( Coordinate rm ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: RoomAt() was given an invalid "\
      "coordinate for rm.\n" );
  }
  return rooms_[rm.y][rm.x];
}

// This private method returns true if the Room is within the bounds of
// the Labyrinth, and false otherwise.
bool Labyrinth::WithinBounds( Coordinate rm ) const
{
  return( rm.x < x_size_ && rm.y < y_size_ );
}

// This private method returns true if the two Rooms are adjacent, and
// false otherwise.
// An exception is thrown if:
//   One or both Rooms are outside the Labyrinth (invalid_argument)
//   The same Room is given twice (logic_error)
bool Labyrinth::IsAdjacent( Coordinate rm_1, Coordinate rm_2 ) const
{
  if( !WithinBounds(rm_1) )
  {
    if( !WithinBounds(rm_2) )
    {
      throw std::invalid_argument( "Error: IsAdjacent() was given invalid "\
      "coordinates for both rm_1 and rm_2.\n" );
    }
    else
    {
      throw std::invalid_argument( "Error: IsAdjacent() was given an invalid "\
      "coordinate for rm_1.\n" );
    }
  }
  else if( !WithinBounds(rm_2) )
  {
    throw std::invalid_argument( "Error: IsAdjacent() was given an invalid "\
      "coordinate for rm_2.\n" );
  }

  if( rm_1 == rm_2 )
  {
    throw std::logic_error( "Error: IsAdjacent() was given the same "\
      "coordinate for the Rooms.\n" );
  }

  unsigned int x_distance;
  if( rm_1.x > rm_2.x )
  {
    x_distance = rm_1.x - rm_2.x;
  }
  else
  {
    x_distance = rm_2.x - rm_1.x;
  }

  unsigned int y_distance;
  if( rm_1.y > rm_2.y )
  {
    y_distance = rm_1.y - rm_2.y;
  }
  else
  {
    y_distance = rm_2.y - rm_1.y;
  }

  if( ( x_distance == 0 && y_distance == 1 ) ||
      ( x_distance == 1 && y_distance == 0 ) )
  {
    return true;
  }
  return false;
}
<commit_msg>Laby SetInhabitant(): Implementing.<commit_after>/*
 *
 * Author: Jeffrey Leung
 * Last edited: 2015-12-31
 *
 * This C++ file contains the implementation of the Labyrinth class, which uses
 * the Room class to create a 2-d mapping for a game.
 *
 */

#include <cmath>
#include <iostream>
#include <stdexcept>

#include "../include/room_properties.hpp"
#include "../include/room.hpp"
#include "../include/coordinate.hpp"
#include "../include/labyrinth.hpp"

// CONSTRUCTOR/DESTRUCTOR:

// Parameterized constructor
// An exception is thrown if:
//   A size of 0 is given (invalid_argument)
Labyrinth::Labyrinth( unsigned int x_size, unsigned int y_size )
{
  if( x_size == 0 )
  {
    if( y_size == 0 )
    {
      throw std::invalid_argument( "Error: Labyrinth() was given empty x and "\
        "y sizes.\n" );
    }
    else
    {
      throw std::invalid_argument( "Error: Labyrinth() was given an empty "\
        "x size.\n" );
    }
  }
  else if( y_size == 0 )
  {
    throw std::invalid_argument( "Error: Labyrinth() was given an empty "\
      "y size.\n" );
  }

  rooms_ = new Room*[ y_size ];
  for( unsigned int i = 0; i < y_size; ++i )
  {
    rooms_[i] = new Room[ x_size ];
  }

  x_size_ = x_size;
  y_size_ = y_size;
}

// Destructor
Labyrinth::~Labyrinth()
{
  for( unsigned int i = 0; i < y_size_; ++i )
  {
    delete [] rooms_[i];
  }
  delete [] rooms_;
}

// SETUP:

// This method connects two Rooms by breaking their walls.
// An exception is thrown if:
//   The Rooms are already connected (logic_error)
//   The Rooms are the same (logic_error)
//   The Rooms are not adjacent (logic_error)
//   One or both Rooms are outside the Labyrinth (invalid_argument)
void Labyrinth::ConnectRooms( Coordinate rm_1, Coordinate rm_2 )
{
  if( rm_1 == rm_2 )
  {
    throw std::logic_error( "Error: ConnectRooms() was given the same "\
      "coordinate for the two Rooms.\n" );
  }

  else if( !WithinBounds(rm_1) || !WithinBounds(rm_2) )
  {
    if( !WithinBounds(rm_1) )
    {
      if( !WithinBounds(rm_2) )
      {
        throw std::invalid_argument( "Error: ConnectRooms() was given invalid "\
          "coordinates for both rm_1 and rm_2.\n" );
      }
      else
      {
        throw std::invalid_argument( "Error: ConnectRooms() was given "\
          "an invalid coordinate for rm_1.\n" );
      }
    }

    else
    {
      throw std::invalid_argument( "Error: ConnectRooms() was given an "\
        "invalid coordinate for rm_2.\n" );
    }
  }

  else if( !IsAdjacent(rm_1, rm_2) )
  {
    throw std::logic_error( "Error: ConnectRooms() was given two coordinates "\
      "which are not adjacent, and therefore cannot be connected.\n" );
  }

  int x_distance = (int)(rm_2.x) - (int)(rm_1.x);
  int y_distance = (int)(rm_2.y) - (int)(rm_1.y);

  Direction break_wall_1;
  Direction break_wall_2;

  if( x_distance == 0 )
  {
    if( y_distance > 0 )  // rm_1 is north of rm_2
    {
      break_wall_1 = Direction::kSouth;
      break_wall_2 = Direction::kNorth;
    }
    else  // rm_1 is south of rm_2
    {
      break_wall_1 = Direction::kNorth;
      break_wall_2 = Direction::kSouth;
    }
  }

  else if( y_distance == 0 )
  {
    if( x_distance > 0 )  // rm_1 is west of rm_2
    {
      break_wall_1 = Direction::kEast;
      break_wall_2 = Direction::kWest;
    }
    else  // rm_1 is east of rm_2
    {
      break_wall_1 = Direction::kWest;
      break_wall_2 = Direction::kEast;
    }
  }

  else
  {
    throw std::logic_error( "Error: ConnectRooms() called IsAdjacent(), "\
      "which should have evaluated to false, but did not.\n" );
  }

  RoomAt(rm_1).BreakWall(break_wall_1);
  RoomAt(rm_2).BreakWall(break_wall_2);
  return;
}

// This method places an Inhabitant in a Room.
// Cannot change an existing Inhabitant; use the EnemyAttacked() method
// for that.
// An exception is thrown if:
//   The Inhabitant of the Room has already been set (logic_error)
//   Inhabitant inh is a null Inhabitant (i.e. Inhabitant::kNone)
//     (invalid_argument)
//   The Room is outside the Labyrinth (invalid_argument)
void Labyrinth::SetInhabitant( Coordinate rm, Inhabitant inh )
{
  if( RoomAt(rm).GetInhabitant() != Inhabitant::kNone )
  {
    throw std::logic_error( "Error: SetInhabitant() cannot replace an "\
      "existing Inhabitant; EnemyAttacked() should be used instead.\n" );
  }
  else if( inh == Inhabitant::kNone )
  {
    throw std::invalid_argument( "Error: SetInhabitant() was given a null "\
      "Inhabitant.\n" );
  }
  else if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: SetInhabitant() was given an "\
      "invalid Coordinate.\n" );
  }

  RoomAt(rm).SetInhabitant(inh);
  return;
}

// PLAY:

// This method returns the current Inhabitant of the Room.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
Inhabitant Labyrinth::GetInhabitant( Coordinate rm ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: GetInhabitant() was given a "\
      "Coordinate outside of the Labyrinth.\n" );
  }
  return RoomAt(rm).GetInhabitant();
}

// This method returns the current Item in the room, but does not
// change it.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
Item Labyrinth::GetItem( Coordinate rm ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: GetItem() was given a "\
      "Coordinate outside of the Labyrinth.\n" );
  }
  return RoomAt(rm).GetItem();
}

// This method returns the type of RoomBorder in the given direction.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
//   Direction d is kNone (invalid_argument)
RoomBorder Labyrinth::DirectionCheck( Coordinate rm, Direction d ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: DirectionCheck() was given a "\
      "Coordinate outside of the Labyrinth.\n" );
  }
  else if( d == Direction::kNone )
  {
    throw std::invalid_argument( "Error: DirectionCheck() was given an "\
      "invalid direction (kNone).\n" );
  }

  return RoomAt(rm).DirectionCheck(d);
}

// PRIVATE METHODS:

// This private method returns a reference to the Room at the given
// coordinate.
// An exception is thrown if:
//   The Room is outside the Labyrinth (invalid_argument)
Room& Labyrinth::RoomAt( Coordinate rm ) const
{
  if( !WithinBounds(rm) )
  {
    throw std::invalid_argument( "Error: RoomAt() was given an invalid "\
      "coordinate for rm.\n" );
  }
  return rooms_[rm.y][rm.x];
}

// This private method returns true if the Room is within the bounds of
// the Labyrinth, and false otherwise.
bool Labyrinth::WithinBounds( Coordinate rm ) const
{
  return( rm.x < x_size_ && rm.y < y_size_ );
}

// This private method returns true if the two Rooms are adjacent, and
// false otherwise.
// An exception is thrown if:
//   One or both Rooms are outside the Labyrinth (invalid_argument)
//   The same Room is given twice (logic_error)
bool Labyrinth::IsAdjacent( Coordinate rm_1, Coordinate rm_2 ) const
{
  if( !WithinBounds(rm_1) )
  {
    if( !WithinBounds(rm_2) )
    {
      throw std::invalid_argument( "Error: IsAdjacent() was given invalid "\
      "coordinates for both rm_1 and rm_2.\n" );
    }
    else
    {
      throw std::invalid_argument( "Error: IsAdjacent() was given an invalid "\
      "coordinate for rm_1.\n" );
    }
  }
  else if( !WithinBounds(rm_2) )
  {
    throw std::invalid_argument( "Error: IsAdjacent() was given an invalid "\
      "coordinate for rm_2.\n" );
  }

  if( rm_1 == rm_2 )
  {
    throw std::logic_error( "Error: IsAdjacent() was given the same "\
      "coordinate for the Rooms.\n" );
  }

  unsigned int x_distance;
  if( rm_1.x > rm_2.x )
  {
    x_distance = rm_1.x - rm_2.x;
  }
  else
  {
    x_distance = rm_2.x - rm_1.x;
  }

  unsigned int y_distance;
  if( rm_1.y > rm_2.y )
  {
    y_distance = rm_1.y - rm_2.y;
  }
  else
  {
    y_distance = rm_2.y - rm_1.y;
  }

  if( ( x_distance == 0 && y_distance == 1 ) ||
      ( x_distance == 1 && y_distance == 0 ) )
  {
    return true;
  }
  return false;
}
<|endoftext|>


<commit_before>#include "include/Angel.h"
#include "cube.h"
#include "ball.h"
#include <iostream>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <algorithm>

using namespace std;
using namespace Angel;

const int TIMERMSECS = 100;

//mouse state variables
int last_mx = 0, last_my = 0, cur_mx = 0, cur_my = 0;
int arcball_on = false;

GLfloat screen_width = 600;
GLfloat screen_height = 600;

GLuint program;
GLuint vao;

GLuint P_loc, M_loc, V_loc, W_loc; // locations pointers of P, M, V, W matrices in shader

mat4 I_mat = mat4(1.0); // Identity matrix
mat4 M_mat = mat4(1.0); // Model matrix
mat4 V_mat = mat4(1.0); // View matrix
mat4 W_mat = mat4(1.0); // World matrix (rotation of cube by mouse)
mat4 P_mat = mat4(1.0); // projection matrix

//vec3 eye(2,10,-10);
vec3 eye(1, 10, 0);

// test cube for EPIC RADO :D :D
cube *test_cube;

const int lvl_width = 7;
const int lvl_height = 7;

GLuint cube_width = 1;
GLuint cube_height = 1;
GLuint uniform_tex_sampler;
float xangle = 0;
float zangle = 0;
char map[7][7] = { { '#', '#', '#', '#', '#', '#', '#' }, { '#', '.', '.', '#',
		'.', '.', '#' }, { '#', '.', '.', '#', '.', '.', '#' }, { '#', '.', '#',
		'#', '#', '#', '#' }, { '#', '.', '.', '#', '.', '.', '#' }, { '#', '#',
		'.', '.', '.', '.', '#' }, { '#', '#', '#', '#', '#', '#', '#' } };

//char map[1][1] = {{'#'}};

cube * walls[lvl_height][lvl_width];
ball * _ball;
//==================
//openGL functions
//==================

inline void create_buffer(GLuint* vbo, size_t pts_size, const GLvoid * pts,
		size_t color_size, const GLvoid * color) {
	// example code to be replaced with project customized code
	glGenBuffers(2, vbo); // generate buffers position, color
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, pts_size, pts, GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );

	//color
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, color_size, color, GL_STATIC_DRAW);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
}

void build_lvl() {
	for (int i = 0; i < lvl_height; ++i) {
		for (int j = 0; j < lvl_width; ++j) {
			if (map[i][j] == '#') { //wall
				walls[i][j] = new cube(program, 0);
				walls[i][j]->translation = Translate(
						(-1.0 * lvl_width / 2 + j) * cube_width, 0,
						(-1.0 * lvl_height / 2 + i) * cube_height);
			} else if (map[i][j] == '.') {	// empty
				//nothing to do here :P
			}
		}
	}
	_ball = new ball(program, 0.3, 1, 1);
	_ball->translation = Translate(
			(-1.0 * lvl_width / 2 + _ball->i) * cube_width, 0,
			(-1.0 * lvl_height / 2 + _ball->j) * cube_height);
}

void init_buffers() {
// Initializing  VAOs and VBOs
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	test_cube = new cube(program, 0);
}

void init(void) {

// Load shaders and use the resulting shader program
	program = InitShader("vshader.glsl", "fshader.glsl");
	glUseProgram(program);
	build_lvl();
	init_buffers();

	V_mat = LookAt(eye, vec3(0, 0, 0), vec3(0, 1, 0));
	P_mat = Perspective(45.0f, 1.0f * screen_width / screen_height, 1.0f,
			100.0f);

// matrices location in shader
	P_loc = glGetUniformLocation(program, "P");
	V_loc = glGetUniformLocation(program, "V");
	M_loc = glGetUniformLocation(program, "M");
	W_loc = glGetUniformLocation(program, "W");

	glUniformMatrix4fv(P_loc, 1, GL_TRUE, P_mat);
	glUniformMatrix4fv(V_loc, 1, GL_TRUE, V_mat);
	glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
	glUniformMatrix4fv(W_loc, 1, GL_TRUE, W_mat);

	glClearColor(1, 1, 1, 1.0); // grey background :/ not sure about the color

	glEnable(GL_DEPTH_TEST); // Enable depth test
	glDepthFunc(GL_LESS); // Accept fragment if it closer to the camera than the former one

	uniform_tex_sampler = glGetUniformLocation(program, "tex_sampler");
	glUniform1i(uniform_tex_sampler, /*GL_TEXTURE*/0);

}

void display(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the window//

	glEnableVertexAttribArray(vao);
	glBindVertexArray(vao);

// update rotation and translation matrices of each object before uploading to shader
//	glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
//	test_cube->draw();

	for (int i = 0; i < lvl_height; ++i) {
		for (int j = 0; j < lvl_width; ++j) {
			if (map[i][j] == '#') { //wall
				M_mat = walls[i][j]->translation * walls[i][j]->rotation;
				glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
				walls[i][j]->draw();
			} else if (map[i][j] == '.') { // empty
				//nothing to do here :P
			}
		}
	}
	M_mat = _ball->translation;
	glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
	_ball->draw();
	glDisableVertexAttribArray(vao);
	glutSwapBuffers(); // Double buffering
}

void keyboard(unsigned char key, int x, int y) {
	switch (key) {
	case 033: //esc
		cout << "exit" << endl;
		exit(EXIT_SUCCESS);
		break;
	}
}

void keyboard_special(int key, int x, int y) {
	switch (key) {
	case GLUT_KEY_RIGHT:
		break;
	case GLUT_KEY_LEFT:
		break;
	case GLUT_KEY_DOWN:
		break;
	case GLUT_KEY_UP:
		break;
	}
}

void onPassiveMotion(int x, int y) {
}

void onReshape(int width, int height) {
	screen_width = width;
	screen_height = height;
	glViewport(0, 0, screen_width, screen_height);
	P_mat = Perspective(45.0f, 1.0f * screen_width / screen_height, 1.0f,
			100.0f);
	glUniformMatrix4fv(P_loc, 1, GL_FALSE, P_mat);
}

vec3 get_arcball_vector(int x, int y) { // what is the purpose of this method?
//	convert the x,y screen coordinates to [-1,1] coordinates (and reverse y coordinates)
	vec3 P = vec3(1.0 * x / screen_width * 2 - 1.0,
			1.0 * y / screen_height * 2 - 1.0, 0);
	P.y = -P.y;

	float OP_squared = P.x * P.x + P.y * P.y;
// use Pythagorean theorem to get P.z
	if (OP_squared <= 1 * 1)
		P.z = sqrt(1 * 1 - OP_squared);  // Pythagore
	else
		P = normalize(P);  // nearest point

	return P;
}

void onMouse(int button, int state, int x, int y) {
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		arcball_on = true;
		last_mx = cur_mx = x;
		last_my = cur_my = y;
	} else {
		arcball_on = false;
	}
}

void onMotion(int x, int y) {
	if (arcball_on) {  // if left button is pressed
		cur_mx = x;
		cur_my = y;

		if (cur_mx != last_mx || cur_my != last_my) {
			xangle += (last_mx - cur_mx) / 5.0;
			zangle += (last_my - cur_my) / 5.0;
			if (abs(xangle) > 30)
				xangle -= (last_mx - cur_mx) / 5.0;
			if (abs(zangle) > 30)
				zangle -= (last_my - cur_my) / 5.0;

			W_mat = RotateX(xangle) * RotateZ(zangle);
//			cout << last_mx - cur_mx << "  " << last_my - cur_my << endl;
			last_mx = cur_mx;
			last_my = cur_my;

			glUniformMatrix4fv(W_loc, 1, GL_TRUE, W_mat);
			glutPostRedisplay();
		}
	}
}
void animate(int n) {
	mat4 tmp = _ball->translation;
	vec4 pos = tmp * vec3(0, 0, 0);
	tmp *= Translate(-zangle / 100.0, 0, 0);
	pos = tmp * vec3(0, 0, 0);
	pos[0] += lvl_width / 2.0;
	pos[2] += lvl_height / 2.0;
	cout << pos[2] << " " << pos[0] << endl;
	if (map[(int) ceil(pos[2] - 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) ceil(pos[0] - 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) ceil(pos[2] - 0.3)][(int) ceil(pos[0] - 0.3)] == '#') {
		tmp = _ball->translation;
	}
	mat4 tt = tmp;
	tmp *= Translate(0, 0, xangle / 100.0);
	pos = tmp * vec3(0, 0, 0);
	pos[0] += lvl_height / 2.0;
	pos[2] += lvl_width / 2.0;
	if (map[(int) ceil(pos[2] - 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) ceil(pos[0] - 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) ceil(pos[2] - 0.3)][(int) ceil(pos[0] - 0.3)] == '#') {
		tmp = tt;
	}
	_ball->translation = tmp;
	display();
	glutTimerFunc(TIMERMSECS, animate, 0);
}
//=========
//main loop
//=========

int main(int argc, char **argv) {

	glutInit(&argc, argv);
	glEnable(GL_DEPTH_TEST);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(screen_width, screen_height);

//----------------------------------------
// If you are using freeglut, the next two lines will check if
// the code is truly 3.2. Otherwise, comment them out

//glutInitContextVersion( 3, 2 );
//glutInitContextProfile( GLUT_CORE_PROFILE );
//----------------------------------------

	glutCreateWindow("Labyrinth :D");
	glewInit();
	init();
	glutTimerFunc(TIMERMSECS, animate, 0);
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	glutSpecialFunc(keyboard_special);
	glutMouseFunc(onMouse);
	glutMotionFunc(onMotion);
	glutReshapeFunc(onReshape);

	glutMainLoop();
	return 0;
}

<commit_msg>adding inertia, speed now increase/decay by time<commit_after>#include "include/Angel.h"
#include "cube.h"
#include "ball.h"
#include <iostream>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <algorithm>

using namespace std;
using namespace Angel;

int TIMERMSECS = 100;

//mouse state variables
int last_mx = 0, last_my = 0, cur_mx = 0, cur_my = 0;
int arcball_on = false;

GLfloat screen_width = 600;
GLfloat screen_height = 600;

GLuint program;
GLuint vao;

GLuint P_loc, M_loc, V_loc, W_loc; // locations pointers of P, M, V, W matrices in shader

mat4 I_mat = mat4(1.0); // Identity matrix
mat4 M_mat = mat4(1.0); // Model matrix
mat4 V_mat = mat4(1.0); // View matrix
mat4 W_mat = mat4(1.0); // World matrix (rotation of cube by mouse)
mat4 P_mat = mat4(1.0); // projection matrix

//vec3 eye(2,10,-10);
vec3 eye(1, 10, 0);

// test cube for EPIC RADO :D :D
cube *test_cube;

const int lvl_width = 7;
const int lvl_height = 7;

GLuint cube_width = 1;
GLuint cube_height = 1;
GLuint uniform_tex_sampler;
float xangle = 0;
float zangle = 0;
char map[7][7] = { { '#', '#', '#', '#', '#', '#', '#' }, { '#', '.', '.', '#',
		'.', '.', '#' }, { '#', '.', '.', '#', '.', '.', '#' }, { '#', '.', '#',
		'#', '#', '#', '#' }, { '#', '.', '.', '#', '.', '.', '#' }, { '#', '#',
		'.', '.', '.', '.', '#' }, { '#', '#', '#', '#', '#', '#', '#' } };

//char map[1][1] = {{'#'}};

cube * walls[lvl_height][lvl_width];
ball * _ball;
//==================
//openGL functions
//==================

inline void create_buffer(GLuint* vbo, size_t pts_size, const GLvoid * pts,
		size_t color_size, const GLvoid * color) {
	// example code to be replaced with project customized code
	glGenBuffers(2, vbo); // generate buffers position, color
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, pts_size, pts, GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );

	//color
	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, color_size, color, GL_STATIC_DRAW);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
}

void build_lvl() {
	for (int i = 0; i < lvl_height; ++i) {
		for (int j = 0; j < lvl_width; ++j) {
			if (map[i][j] == '#') { //wall
				walls[i][j] = new cube(program, 0);
				walls[i][j]->translation = Translate(
						(-1.0 * lvl_width / 2 + j) * cube_width, 0,
						(-1.0 * lvl_height / 2 + i) * cube_height);
			} else if (map[i][j] == '.') {	// empty
				//nothing to do here :P
			}
		}
	}
	_ball = new ball(program, 0.3, 1, 1);
	_ball->translation = Translate(
			(-1.0 * lvl_width / 2 + _ball->i) * cube_width, 0,
			(-1.0 * lvl_height / 2 + _ball->j) * cube_height);
}

void init_buffers() {
// Initializing  VAOs and VBOs
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	test_cube = new cube(program, 0);
}

void init(void) {

// Load shaders and use the resulting shader program
	program = InitShader("vshader.glsl", "fshader.glsl");
	glUseProgram(program);
	build_lvl();
	init_buffers();

	V_mat = LookAt(eye, vec3(0, 0, 0), vec3(0, 1, 0));
	P_mat = Perspective(45.0f, 1.0f * screen_width / screen_height, 1.0f,
			100.0f);

// matrices location in shader
	P_loc = glGetUniformLocation(program, "P");
	V_loc = glGetUniformLocation(program, "V");
	M_loc = glGetUniformLocation(program, "M");
	W_loc = glGetUniformLocation(program, "W");

	glUniformMatrix4fv(P_loc, 1, GL_TRUE, P_mat);
	glUniformMatrix4fv(V_loc, 1, GL_TRUE, V_mat);
	glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
	glUniformMatrix4fv(W_loc, 1, GL_TRUE, W_mat);

	glClearColor(1, 1, 1, 1.0); // grey background :/ not sure about the color

	glEnable(GL_DEPTH_TEST); // Enable depth test
	glDepthFunc(GL_LESS); // Accept fragment if it closer to the camera than the former one

	uniform_tex_sampler = glGetUniformLocation(program, "tex_sampler");
	glUniform1i(uniform_tex_sampler, /*GL_TEXTURE*/0);

}

void display(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the window//

	glEnableVertexAttribArray(vao);
	glBindVertexArray(vao);

// update rotation and translation matrices of each object before uploading to shader
//	glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
//	test_cube->draw();

	for (int i = 0; i < lvl_height; ++i) {
		for (int j = 0; j < lvl_width; ++j) {
			if (map[i][j] == '#') { //wall
				M_mat = walls[i][j]->translation * walls[i][j]->rotation;
				glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
				walls[i][j]->draw();
			} else if (map[i][j] == '.') { // empty
				//nothing to do here :P
			}
		}
	}
	M_mat = _ball->translation;
	glUniformMatrix4fv(M_loc, 1, GL_TRUE, M_mat);
	_ball->draw();
	glDisableVertexAttribArray(vao);
	glutSwapBuffers(); // Double buffering
}

void keyboard(unsigned char key, int x, int y) {
	switch (key) {
	case 033: //esc
		cout << "exit" << endl;
		exit(EXIT_SUCCESS);
		break;
	}
}

void keyboard_special(int key, int x, int y) {
	switch (key) {
	case GLUT_KEY_RIGHT:
		break;
	case GLUT_KEY_LEFT:
		break;
	case GLUT_KEY_DOWN:
		break;
	case GLUT_KEY_UP:
		break;
	}
}

void onPassiveMotion(int x, int y) {
}

void onReshape(int width, int height) {
	screen_width = width;
	screen_height = height;
	glViewport(0, 0, screen_width, screen_height);
	P_mat = Perspective(45.0f, 1.0f * screen_width / screen_height, 1.0f,
			100.0f);
	glUniformMatrix4fv(P_loc, 1, GL_FALSE, P_mat);
}

vec3 get_arcball_vector(int x, int y) { // what is the purpose of this method?
//	convert the x,y screen coordinates to [-1,1] coordinates (and reverse y coordinates)
	vec3 P = vec3(1.0 * x / screen_width * 2 - 1.0,
			1.0 * y / screen_height * 2 - 1.0, 0);
	P.y = -P.y;

	float OP_squared = P.x * P.x + P.y * P.y;
// use Pythagorean theorem to get P.z
	if (OP_squared <= 1 * 1)
		P.z = sqrt(1 * 1 - OP_squared);  // Pythagore
	else
		P = normalize(P);  // nearest point

	return P;
}

void onMouse(int button, int state, int x, int y) {
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		arcball_on = true;
		last_mx = cur_mx = x;
		last_my = cur_my = y;
	} else {
		arcball_on = false;
	}
}

void onMotion(int x, int y) {
	if (arcball_on) {  // if left button is pressed
		cur_mx = x;
		cur_my = y;

		if (cur_mx != last_mx || cur_my != last_my) {
			xangle += (last_mx - cur_mx) / 5.0;
			zangle += (last_my - cur_my) / 5.0;
			if (abs(xangle) > 30)
				xangle -= (last_mx - cur_mx) / 3.0;
			if (abs(zangle) > 30)
				zangle -= (last_my - cur_my) / 3.0;

			W_mat = RotateX(xangle) * RotateZ(zangle);
//			cout << last_mx - cur_mx << "  " << last_my - cur_my << endl;
			last_mx = cur_mx;
			last_my = cur_my;

			glUniformMatrix4fv(W_loc, 1, GL_TRUE, W_mat);
			glutPostRedisplay();
		}
	}
}
float speedz = 0;
float speedx = 0;

void animate(int n) {
	mat4 tmp = _ball->translation;
	vec4 pos = tmp * vec3(0, 0, 0);
	tmp *= Translate(speedz, 0, 0);
	pos = tmp * vec3(0, 0, 0);
	pos[0] += lvl_width / 2.0;
	pos[2] += lvl_height / 2.0;
//	cout << speedx << " "<< speedz << endl;
	if (map[(int) ceil(pos[2] - 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) ceil(pos[0] - 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) ceil(pos[2] - 0.3)][(int) ceil(pos[0] - 0.3)] == '#') {
		tmp = _ball->translation;
		speedz = 0;
	} else {
		speedz += -zangle / 500.0;
	}
	mat4 tt = tmp;
	tmp *= Translate(0, 0, speedx);
	pos = tmp * vec3(0, 0, 0);
	pos[0] += lvl_height / 2.0;
	pos[2] += lvl_width / 2.0;
	if (map[(int) ceil(pos[2] - 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) ceil(pos[0] - 0.3)] == '#'
			|| map[(int) floor(pos[2] + 0.3)][(int) floor(pos[0] + 0.3)] == '#'
			|| map[(int) ceil(pos[2] - 0.3)][(int) ceil(pos[0] - 0.3)] == '#') {
		tmp = tt;
		speedx = 0;
	} else {
		speedx += xangle / 500.0;
	}
	_ball->translation = tmp;
	display();
	glutTimerFunc(TIMERMSECS, animate, 0);
}
//=========
//main loop
//=========

int main(int argc, char **argv) {

	glutInit(&argc, argv);
	glEnable(GL_DEPTH_TEST);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(screen_width, screen_height);

//----------------------------------------
// If you are using freeglut, the next two lines will check if
// the code is truly 3.2. Otherwise, comment them out

//glutInitContextVersion( 3, 2 );
//glutInitContextProfile( GLUT_CORE_PROFILE );
//----------------------------------------

	glutCreateWindow("Labyrinth :D");
	glewInit();
	init();
	glutTimerFunc(TIMERMSECS, animate, 0);
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	glutSpecialFunc(keyboard_special);
	glutMouseFunc(onMouse);
	glutMotionFunc(onMotion);
	glutReshapeFunc(onReshape);

	glutMainLoop();
	return 0;
}

<|endoftext|>


<commit_before>#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
// #define BOOST_SPIRIT_QI_DEBUG

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <cassert>
#include <sstream>

#include "formast.hpp"

// upgrade structs to fusion sequences

BOOST_FUSION_ADAPT_STRUCT(
    formast::Attr,
    (std::string, class_name)
    (std::string, name)
    (boost::optional<formast::Doc>, doc)
)

BOOST_FUSION_ADAPT_STRUCT(
    formast::Class,
    (std::string, name)
    (boost::optional<std::string>, base_name)
    (boost::optional<formast::Doc>, doc)
    (boost::optional<formast::Stats>, stats)
)

BOOST_FUSION_ADAPT_STRUCT(
    formast::If,
    (formast::Expr, expr)
    (formast::Stats, then)
    (boost::optional<formast::Stats>, else_)
)

// a few shorthands

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace ast = formast::detail::ast;

// phoenix functions for constructing the abstract syntax tree with
// semantic actions

struct copy_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, ast::Expr const & right) const {
        assert(right != 0);
        left = right;
    }
};

struct trim_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(std::string & left, std::string const & right) const {
        left = right;
        boost::algorithm::trim(left);
    }
};

template <typename T> // T is a terminal type, i.e. uint64_t or std::string
struct assign_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, const T & right) const {
        left = ast::Expr(new ast::ExprNode(right));
    }
};

template <ast::op::type op_type>
struct binary_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, ast::Expr const & right) const {
        assert(left != 0);
        assert(right != 0);
        left = ast::Expr(new ast::ExprNode(ast::binary_op(op_type, left, right)));
    }
};

template <ast::op::type op_type>
struct unary_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, ast::Expr & right) const {
        assert(right != 0);
        left = ast::Expr(new ast::ExprNode(ast::unary_op(op_type, right)));
    }
};

boost::phoenix::function<binary_func<ast::op::logical_or> > const _logical_or;
boost::phoenix::function<binary_func<ast::op::logical_and> > const _logical_and;
boost::phoenix::function<binary_func<ast::op::bit_or> > const _bit_or;
boost::phoenix::function<binary_func<ast::op::bit_xor> > const _bit_xor;
boost::phoenix::function<binary_func<ast::op::bit_and> > const _bit_and;
boost::phoenix::function<binary_func<ast::op::equal> > const _equal;
boost::phoenix::function<binary_func<ast::op::not_equal> > const _not_equal;
boost::phoenix::function<binary_func<ast::op::less> > const _less;
boost::phoenix::function<binary_func<ast::op::less_equal> > const _less_equal;
boost::phoenix::function<binary_func<ast::op::greater> > const _greater;
boost::phoenix::function<binary_func<ast::op::greater_equal> > const _greater_equal;
boost::phoenix::function<binary_func<ast::op::shift_left> > const _shift_left;
boost::phoenix::function<binary_func<ast::op::shift_right> > const _shift_right;
boost::phoenix::function<binary_func<ast::op::plus> > const _add;
boost::phoenix::function<binary_func<ast::op::minus> > const _sub;
boost::phoenix::function<binary_func<ast::op::times> > const _mul;
boost::phoenix::function<binary_func<ast::op::divide> > const _div;
boost::phoenix::function<binary_func<ast::op::mod> > const _mod;
boost::phoenix::function<binary_func<ast::op::pow> > const _pow;
boost::phoenix::function<unary_func<ast::op::pos> > const _pos;
boost::phoenix::function<unary_func<ast::op::neg> > const _neg;
boost::phoenix::function<unary_func<ast::op::logical_not> > const _logical_not;
boost::phoenix::function<assign_func<std::string> > const _ident;
boost::phoenix::function<assign_func<boost::uint64_t> > const _uint;
boost::phoenix::function<copy_func> const _copy;
boost::phoenix::function<trim_func> const _trim;

// error handler

struct error_handler_ {
    template <typename, typename, typename>
    struct result {
        typedef void type;
    };

    template <typename Iterator>
    void operator()(
        qi::info const& what, Iterator err_pos, Iterator last) const {
        std::cerr
                << "Error! Expecting "
                << what
                << " here: \""
                << std::string(err_pos, last)
                << "\""
                << std::endl
                ;
    }
};

boost::phoenix::function<error_handler_> const error_handler = error_handler_();

// the actual grammar

template <typename Iterator>
struct expr_grammar : qi::grammar<Iterator, ast::Expr(), ascii::space_type> {

    expr_grammar() : expr_grammar::base_type(expr) {

    qi::lexeme_type lexeme;
    qi::char_type char_;
    qi::uint_type ulong_long;
    qi::_val_type _val;
    qi::_1_type _1;
    qi::_2_type _2;
    qi::_3_type _3;
    qi::_4_type _4;

    using qi::on_error;
    using qi::fail;

    expr = or_test.alias();

    or_test =
        and_test                        [_copy(_val, _1)]
        >> *("||" > and_test            [_logical_or(_val, _1)])
        ;

    and_test =
        not_test                        [_copy(_val, _1)]
        >> *("&&" > not_test            [_logical_and(_val, _1)])
        ;

    not_test =
        ('!' > not_test                 [_logical_not(_val, _1)])
        |   comparison                  [_copy(_val, _1)]
        ;

    comparison =
        bit_or_expr                     [_copy(_val, _1)]
        >> *(   ('<' > bit_or_expr      [_less(_val, _1)])
                |   ('>' > bit_or_expr  [_greater(_val, _1)])
                |   ("==" > bit_or_expr [_equal(_val, _1)])
                |   ("!=" > bit_or_expr [_not_equal(_val, _1)])
                |   (">=" > bit_or_expr [_greater_equal(_val, _1)])
                |   ("<=" > bit_or_expr [_less_equal(_val, _1)])
            )
        ;

    bit_or_expr =
        bit_xor_expr                    [_copy(_val, _1)]
        >> *('|' > bit_xor_expr         [_bit_or(_val, _1)])
        ;

    bit_xor_expr =
        bit_and_expr                    [_copy(_val, _1)]
        >> *('^' > bit_and_expr         [_bit_xor(_val, _1)])
        ;

    bit_and_expr =
        bit_shift_expr                  [_copy(_val, _1)]
        >> *('&' > bit_shift_expr       [_bit_and(_val, _1)])
        ;

    bit_shift_expr =
        arith_expr                      [_copy(_val, _1)]
        >> *(   (">>" > arith_expr      [_shift_right(_val, _1)])
                |   ("<<" > arith_expr  [_shift_left(_val, _1)])
            )
        ;

    arith_expr =
        term                            [_copy(_val, _1)]
        >> *(   ('+' > term             [_add(_val, _1)])
                |   ('-' > term         [_sub(_val, _1)])
            )
        ;

    term =
        factor                          [_copy(_val, _1)]
        >> *(   ('*' > factor           [_mul(_val, _1)])
                |   ('/' > factor       [_div(_val, _1)])
                |   ('%' > factor       [_mod(_val, _1)])
            )
        ;

    factor =
        power                           [_copy(_val, _1)]
        |   ('-' > factor               [_neg(_val, _1)])
        |   ('+' > factor               [_pos(_val, _1)])
        ;

    power =
        atom                            [_copy(_val, _1)]
        >> -("**" > factor              [_pow(_val, _1)])
        ;

    atom =
        ulong_long                      [_uint(_val, _1)]
        |   ident                       [_ident(_val, _1)]
        |   '(' > expr                  [_copy(_val, _1)] > ')'
        ;

    // also match trailing whitespace; _trim removes it
    ident_ws %= lexeme[(char_("a-zA-Z") >> *(char_(" ") | char_("0-9a-zA-Z")))];
    ident = ident_ws [_trim(_val, _1)];

    // Debugging and error handling and reporting support.
    BOOST_SPIRIT_DEBUG_NODE(expr);
    BOOST_SPIRIT_DEBUG_NODE(term);
    BOOST_SPIRIT_DEBUG_NODE(factor);

    // Error handling
    on_error<fail>(expr, error_handler(_4, _3, _2));
}

qi::rule<Iterator, ast::Expr(), ascii::space_type> expr, or_test, and_test, not_test, comparison, bit_or_expr, bit_xor_expr, bit_and_expr, bit_shift_expr, arith_expr, term, factor, power, atom;
qi::rule<Iterator, std::string(), ascii::space_type> ident, ident_ws;
};

// helper function for parsing expression from stream
void _expr_parse_stream(std::istream & is, ast::Expr & e)
{
    // disable white space skipping
    is.unsetf(std::ios::skipws);
    typedef boost::spirit::istream_iterator iterator_type;
    iterator_type iter(is);
    iterator_type end;
    expr_grammar<iterator_type> grammar;
    ascii::space_type space;

    bool success = qi::phrase_parse(iter, end, grammar, space, e);
    if (!success) {
        throw std::runtime_error("Syntax error.");
    }
    if (iter != end) {
        throw std::runtime_error("End of stream not reached.");
    }
}

// helper function for parsing expression from string
void _expr_parse_string(std::string const & s, ast::Expr & e)
{
    std::istringstream is(s);
    _expr_parse_stream(is, e);
}

formast::Parser::Parser()
{
}

void formast::Parser::parse_string(std::string const & s, ast::Top & top)
{
    std::istringstream is(s);
    parse_stream(is, top);
}

formast::XmlParser::XmlParser()
    : Parser()
{
}

void formast::XmlParser::parse_stream(std::istream & is, ast::Top & top)
{
    // disable skipping of whitespace
    is.unsetf(std::ios::skipws);

    // read xml into property tree
    boost::property_tree::ptree pt;
    boost::property_tree::xml_parser::read_xml(is, pt);
    //boost::property_tree::info_parser::write_info(std::cout, pt); // DEBUG

    BOOST_FOREACH(boost::property_tree::ptree::value_type & decl, pt.get_child("niftoolsxml")) {
        if (decl.first == "basic") {
            Class class_;
            class_.name = decl.second.get<std::string>("<xmlattr>.name");
            std::string doc = decl.second.data();
            boost::algorithm::trim(doc);
            if (!doc.empty()) {
                class_.doc = doc;
            }
            top.push_back(class_);
        } else if (decl.first == "compound" || decl.first == "niobject") {
            Class class_;
            class_.name = decl.second.get<std::string>("<xmlattr>.name");
            std::string doc = decl.second.data();
            boost::algorithm::trim(doc);
            if (!doc.empty()) {
                class_.doc = doc;
            }
            class_.base_name = decl.second.get_optional<std::string>("<xmlattr>.inherit");
            ast::Stats stats;
            BOOST_FOREACH(boost::property_tree::ptree::value_type & add, decl.second) {
                if (add.first == "add") {
                    Attr attr;
                    attr.class_name = add.second.get<std::string>("<xmlattr>.type");
                    attr.name = add.second.get<std::string>("<xmlattr>.name");
                    std::string doc = add.second.data();
                    boost::algorithm::trim(doc);
                    if (!doc.empty()) {
                        attr.doc = doc;
                    }
                    // conditioning disabled for now, can't parse it completely yet
                    boost::optional<std::string> cond = add.second.get_optional<std::string>("<xmlattr>.cond");
                    if  (!cond) {
                        stats.push_back(attr);
                    } else {
                        formast::If if_;
                        _expr_parse_string(cond.get(), if_.expr);
                        if_.then.push_back(attr);
                        stats.push_back(if_);
                    }
                };
            };
            if (!stats.empty()) {
                class_.stats = stats;
            };
            top.push_back(class_);
        };
    };
}
<commit_msg>Parse versions.<commit_after>#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
// #define BOOST_SPIRIT_QI_DEBUG

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <cassert>
#include <sstream>

#include "formast.hpp"

// upgrade structs to fusion sequences

BOOST_FUSION_ADAPT_STRUCT(
    formast::Attr,
    (std::string, class_name)
    (std::string, name)
    (boost::optional<formast::Doc>, doc)
)

BOOST_FUSION_ADAPT_STRUCT(
    formast::Class,
    (std::string, name)
    (boost::optional<std::string>, base_name)
    (boost::optional<formast::Doc>, doc)
    (boost::optional<formast::Stats>, stats)
)

BOOST_FUSION_ADAPT_STRUCT(
    formast::If,
    (formast::Expr, expr)
    (formast::Stats, then)
    (boost::optional<formast::Stats>, else_)
)

// a few shorthands

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace ast = formast::detail::ast;

// phoenix functions for constructing the abstract syntax tree with
// semantic actions

struct copy_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, ast::Expr const & right) const {
        assert(right != 0);
        left = right;
    }
};

struct trim_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(std::string & left, std::string const & right) const {
        left = right;
        boost::algorithm::trim(left);
    }
};

template <typename T> // T is a terminal type, i.e. uint64_t or std::string
struct assign_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, const T & right) const {
        left = ast::Expr(new ast::ExprNode(right));
    }
};

template <ast::op::type op_type>
struct binary_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, ast::Expr const & right) const {
        assert(left != 0);
        assert(right != 0);
        left = ast::Expr(new ast::ExprNode(ast::binary_op(op_type, left, right)));
    }
};

template <ast::op::type op_type>
struct unary_func {
    template <typename T1, typename T2 = void>
    struct result {
        typedef void type;
    };

    void operator()(ast::Expr & left, ast::Expr & right) const {
        assert(right != 0);
        left = ast::Expr(new ast::ExprNode(ast::unary_op(op_type, right)));
    }
};

boost::phoenix::function<binary_func<ast::op::logical_or> > const _logical_or;
boost::phoenix::function<binary_func<ast::op::logical_and> > const _logical_and;
boost::phoenix::function<binary_func<ast::op::bit_or> > const _bit_or;
boost::phoenix::function<binary_func<ast::op::bit_xor> > const _bit_xor;
boost::phoenix::function<binary_func<ast::op::bit_and> > const _bit_and;
boost::phoenix::function<binary_func<ast::op::equal> > const _equal;
boost::phoenix::function<binary_func<ast::op::not_equal> > const _not_equal;
boost::phoenix::function<binary_func<ast::op::less> > const _less;
boost::phoenix::function<binary_func<ast::op::less_equal> > const _less_equal;
boost::phoenix::function<binary_func<ast::op::greater> > const _greater;
boost::phoenix::function<binary_func<ast::op::greater_equal> > const _greater_equal;
boost::phoenix::function<binary_func<ast::op::shift_left> > const _shift_left;
boost::phoenix::function<binary_func<ast::op::shift_right> > const _shift_right;
boost::phoenix::function<binary_func<ast::op::plus> > const _add;
boost::phoenix::function<binary_func<ast::op::minus> > const _sub;
boost::phoenix::function<binary_func<ast::op::times> > const _mul;
boost::phoenix::function<binary_func<ast::op::divide> > const _div;
boost::phoenix::function<binary_func<ast::op::mod> > const _mod;
boost::phoenix::function<binary_func<ast::op::pow> > const _pow;
boost::phoenix::function<unary_func<ast::op::pos> > const _pos;
boost::phoenix::function<unary_func<ast::op::neg> > const _neg;
boost::phoenix::function<unary_func<ast::op::logical_not> > const _logical_not;
boost::phoenix::function<assign_func<std::string> > const _ident;
boost::phoenix::function<assign_func<boost::uint64_t> > const _uint;
boost::phoenix::function<copy_func> const _copy;
boost::phoenix::function<trim_func> const _trim;

// error handler

struct error_handler_ {
    template <typename, typename, typename>
    struct result {
        typedef void type;
    };

    template <typename Iterator>
    void operator()(
        qi::info const& what, Iterator err_pos, Iterator last) const {
        std::cerr
                << "Error! Expecting "
                << what
                << " here: \""
                << std::string(err_pos, last)
                << "\""
                << std::endl
                ;
    }
};

boost::phoenix::function<error_handler_> const error_handler = error_handler_();

// the actual grammar

template <typename Iterator>
struct expr_grammar : qi::grammar<Iterator, ast::Expr(), ascii::space_type> {

    expr_grammar() : expr_grammar::base_type(expr) {

    qi::lexeme_type lexeme;
    qi::char_type char_;
    qi::uint_type ulong_long;
    qi::_val_type _val;
    qi::_1_type _1;
    qi::_2_type _2;
    qi::_3_type _3;
    qi::_4_type _4;

    using qi::on_error;
    using qi::fail;

    expr = or_test.alias();

    or_test =
        and_test                        [_copy(_val, _1)]
        >> *("||" > and_test            [_logical_or(_val, _1)])
        ;

    and_test =
        not_test                        [_copy(_val, _1)]
        >> *("&&" > not_test            [_logical_and(_val, _1)])
        ;

    not_test =
        ('!' > not_test                 [_logical_not(_val, _1)])
        |   comparison                  [_copy(_val, _1)]
        ;

    comparison =
        bit_or_expr                     [_copy(_val, _1)]
        >> *(   ('<' > bit_or_expr      [_less(_val, _1)])
                |   ('>' > bit_or_expr  [_greater(_val, _1)])
                |   ("==" > bit_or_expr [_equal(_val, _1)])
                |   ("!=" > bit_or_expr [_not_equal(_val, _1)])
                |   (">=" > bit_or_expr [_greater_equal(_val, _1)])
                |   ("<=" > bit_or_expr [_less_equal(_val, _1)])
            )
        ;

    bit_or_expr =
        bit_xor_expr                    [_copy(_val, _1)]
        >> *('|' > bit_xor_expr         [_bit_or(_val, _1)])
        ;

    bit_xor_expr =
        bit_and_expr                    [_copy(_val, _1)]
        >> *('^' > bit_and_expr         [_bit_xor(_val, _1)])
        ;

    bit_and_expr =
        bit_shift_expr                  [_copy(_val, _1)]
        >> *('&' > bit_shift_expr       [_bit_and(_val, _1)])
        ;

    bit_shift_expr =
        arith_expr                      [_copy(_val, _1)]
        >> *(   (">>" > arith_expr      [_shift_right(_val, _1)])
                |   ("<<" > arith_expr  [_shift_left(_val, _1)])
            )
        ;

    arith_expr =
        term                            [_copy(_val, _1)]
        >> *(   ('+' > term             [_add(_val, _1)])
                |   ('-' > term         [_sub(_val, _1)])
            )
        ;

    term =
        factor                          [_copy(_val, _1)]
        >> *(   ('*' > factor           [_mul(_val, _1)])
                |   ('/' > factor       [_div(_val, _1)])
                |   ('%' > factor       [_mod(_val, _1)])
            )
        ;

    factor =
        power                           [_copy(_val, _1)]
        |   ('-' > factor               [_neg(_val, _1)])
        |   ('+' > factor               [_pos(_val, _1)])
        ;

    power =
        atom                            [_copy(_val, _1)]
        >> -("**" > factor              [_pow(_val, _1)])
        ;

    atom =
        ulong_long                      [_uint(_val, _1)]
        |   version                     [_uint(_val, _1)]
        |   ident                       [_ident(_val, _1)]
        |   '(' > expr                  [_copy(_val, _1)] > ')'
        ;

    // also match trailing whitespace; _trim removes it
    ident_ws %= lexeme[(char_("a-zA-Z") >> *(char_(" ") | char_("0-9a-zA-Z")))];
    ident = ident_ws [_trim(_val, _1)];

    version %=
        (ulong_long           [_val = _1])
        >> '.' >> (ulong_long [_val = _val * 256 + _1])
        >> '.' > (ulong_long  [_val = _val * 256 + _1])
        > '.' > (ulong_long   [_val = _val * 256 + _1])
        ;

    // Debugging and error handling and reporting support.
    BOOST_SPIRIT_DEBUG_NODE(expr);
    BOOST_SPIRIT_DEBUG_NODE(term);
    BOOST_SPIRIT_DEBUG_NODE(factor);

    // Error handling
    on_error<fail>(expr, error_handler(_4, _3, _2));
}

qi::rule<Iterator, ast::Expr(), ascii::space_type> expr, or_test, and_test, not_test, comparison, bit_or_expr, bit_xor_expr, bit_and_expr, bit_shift_expr, arith_expr, term, factor, power, atom;
qi::rule<Iterator, std::string(), ascii::space_type> ident, ident_ws;
qi::rule<Iterator, boost::uint64_t(), ascii::space_type> version;
};

// helper function for parsing expression from stream
void _expr_parse_stream(std::istream & is, ast::Expr & e)
{
    // disable white space skipping
    is.unsetf(std::ios::skipws);
    typedef boost::spirit::istream_iterator iterator_type;
    iterator_type iter(is);
    iterator_type end;
    expr_grammar<iterator_type> grammar;
    ascii::space_type space;

    bool success = qi::phrase_parse(iter, end, grammar, space, e);
    if (!success) {
        throw std::runtime_error("Syntax error.");
    }
    if (iter != end) {
        throw std::runtime_error("End of stream not reached.");
    }
}

// helper function for parsing expression from string
void _expr_parse_string(std::string const & s, ast::Expr & e)
{
    std::istringstream is(s);
    _expr_parse_stream(is, e);
}

formast::Parser::Parser()
{
}

void formast::Parser::parse_string(std::string const & s, ast::Top & top)
{
    std::istringstream is(s);
    parse_stream(is, top);
}

formast::XmlParser::XmlParser()
    : Parser()
{
}

void formast::XmlParser::parse_stream(std::istream & is, ast::Top & top)
{
    // disable skipping of whitespace
    is.unsetf(std::ios::skipws);

    // read xml into property tree
    boost::property_tree::ptree pt;
    boost::property_tree::xml_parser::read_xml(is, pt);
    //boost::property_tree::info_parser::write_info(std::cout, pt); // DEBUG

    BOOST_FOREACH(boost::property_tree::ptree::value_type & decl, pt.get_child("niftoolsxml")) {
        if (decl.first == "basic") {
            Class class_;
            class_.name = decl.second.get<std::string>("<xmlattr>.name");
            std::string doc = decl.second.data();
            boost::algorithm::trim(doc);
            if (!doc.empty()) {
                class_.doc = doc;
            }
            top.push_back(class_);
        } else if (decl.first == "compound" || decl.first == "niobject") {
            Class class_;
            class_.name = decl.second.get<std::string>("<xmlattr>.name");
            std::string doc = decl.second.data();
            boost::algorithm::trim(doc);
            if (!doc.empty()) {
                class_.doc = doc;
            }
            class_.base_name = decl.second.get_optional<std::string>("<xmlattr>.inherit");
            ast::Stats stats;
            BOOST_FOREACH(boost::property_tree::ptree::value_type & add, decl.second) {
                if (add.first == "add") {
                    Attr attr;
                    attr.class_name = add.second.get<std::string>("<xmlattr>.type");
                    attr.name = add.second.get<std::string>("<xmlattr>.name");
                    std::string doc = add.second.data();
                    boost::algorithm::trim(doc);
                    if (!doc.empty()) {
                        attr.doc = doc;
                    }
                    // conditioning disabled for now, can't parse it completely yet
                    boost::optional<std::string> cond = add.second.get_optional<std::string>("<xmlattr>.cond");
                    if  (!cond) {
                        stats.push_back(attr);
                    } else {
                        formast::If if_;
                        _expr_parse_string(cond.get(), if_.expr);
                        if_.then.push_back(attr);
                        stats.push_back(if_);
                    }
                };
            };
            if (!stats.empty()) {
                class_.stats = stats;
            };
            top.push_back(class_);
        };
    };
}
<|endoftext|>


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

#include "map.h"
#include <iostream>
#include <votca/tools/matrix.h>
#include <votca/tools/tokenizer.h>
#include <numeric>

namespace votca { namespace csg {

using namespace std;

Map::~Map()
{
    vector<BeadMap *>::iterator iter;
    for(iter=_maps.begin();iter!=_maps.end();++iter)
        delete (*iter);
    _maps.clear();
}

void Map::Apply()
{
    vector<BeadMap *>::iterator iter;
    for(iter=_maps.begin();iter!=_maps.end();++iter)
        (*iter)->Apply();
}

void Map_Sphere::Initialize(Molecule *in, Bead *out, Property *opts_bead, Property *opts_map) {
    BeadMap::Initialize(in, out, opts_bead, opts_map);

    vector<string> beads;
    vector<double> weights;
    vector<double> fweights;

    // get the beads
    string s(_opts_bead->get("beads").value());
    Tokenizer tok_beads(s, " \n\t");
    tok_beads.ToVector(beads);

    // get vector of weights
    Tokenizer tok_weights(_opts_map->get("weights").value(), " \n\t");
    tok_weights.ConvertToVector<double>(weights);

    // check weather weights and # beads matches
    if (beads.size() != weights.size())
        throw runtime_error(string("number of subbeads in " +
                opts_bead->get("name").as<string>()
                + " and number of weights in map "
                + opts_map->get("name").as<string>() + " do not match"));

    // normalize the weights
    double norm = 1./ std::accumulate(weights.begin(), weights.end(), 0.);

    transform(weights.begin(), weights.end(), weights.begin(), bind2nd(multiplies<double>(), norm));
    // get the d vector if exists or initialize same as weights
    vector<double> d;
    if(_opts_map->exists("d")) {
        Tokenizer tok_weights(_opts_map->get("d").value(), " \n\t");
        tok_weights.ConvertToVector(d);
        // normalize d coefficients
        norm = 1./std::accumulate(d.begin(), d.end(), 0.);
        transform(d.begin(), d.end(), d.begin(), bind2nd(multiplies<double>(), norm));
    } else {
        // initialize force-weights with weights
        d.resize(weights.size());
        copy(weights.begin(), weights.end(), d.begin());
    }

    // check weather number of d coeffs is correct
    if (beads.size() != d.size()) {
        throw runtime_error(string("number of subbeads in " +
            opts_bead->get("name").as<string>()
            + " and number of d-coefficients in map "
            + opts_map->get("name").as<string>() + " do not match"));
    }

    fweights.resize(weights.size());
    // calculate force weights by d_i/w_i
    for(int i=0; i<weights.size(); ++i) {
        if(weights[i] == 0 && d[i]!=0) {
            throw runtime_error(
                "A d coefficient is nonzero while weights is zero in mapping "
                + opts_map->get("name").as<string>());
        }
        if(weights[i] != 0)
            fweights[i] = d[i] / weights[i];
        else
            fweights[i] = 0;
    }

    for (size_t i = 0; i < beads.size(); ++i) {
        int iin = in->getBeadByName(beads[i]);
        if (iin < 0)
            throw std::runtime_error(string("mapping error: molecule " + beads[i] + " does not exist"));
        AddElem(in->getBead(iin), weights[i], fweights[i]);
    }
}

void Map_Sphere::Apply()
{
    vector<element_t>::iterator iter;
    vec cg(0., 0., 0.), f(0.,0.,0.), vel(0.,0.,0.);
    bool bPos, bVel, bF;
    bPos=bVel=bF=false;
    _out->ParentBeads().clear();
    double M = 0;
    for(iter = _matrix.begin(); iter != _matrix.end(); ++iter) {
        Bead *bead = iter->_in;
        _out->ParentBeads().push_back(bead->getId());
        M+=bead->getM();
        if(bead->HasPos()) {
            cg += (*iter)._weight * bead->getPos();
            bPos=true;
        }
        if(bead->HasVel()) {
            vel += (*iter)._weight * bead->getVel();
            bVel = true;
        }
        if(bead->HasF()) {
            f += (*iter)._force_weight * bead->getF();
            bF = true;
        }
    }
    _out->setM(M);
    if(bPos)
        _out->setPos(cg);
    if(bVel)
        _out->setVel(vel);
    if(bF)
        _out->setF(f);
}

/// \todo implement this function
void Map_Ellipsoid::Apply()
{
    vector<element_t>::iterator iter;
    vec cg(0., 0., 0.), c(0., 0., 0.), f(0.,0.,0.), vel(0.,0.,0.);
    matrix m(0.);
     bool bPos, bVel, bF;
    bPos=bVel=bF=false;

    int n;
    n = 0;
    _out->ParentBeads().clear();
    for(iter = _matrix.begin(); iter != _matrix.end(); ++iter) {
       Bead *bead = iter->_in;
       _out->ParentBeads().push_back(bead->getId());
       if(bead->HasPos()) {
            cg += (*iter)._weight * bead->getPos();
            bPos=true;
        }
        if(bead->HasVel() == true) {
            vel += (*iter)._weight * bead->getVel();
            bVel = true;
        }
        if(bead->HasF()) {
            /// \todo fix me, right calculation should be F_i = m_cg / sum(w_i) * sum(w_i/m_i*F_i)
            //f += (*iter)._weight * _in->getBeadF((*iter)._in);
            f += (*iter)._force_weight * bead->getF();
            bF = true;
        }

        if((*iter)._weight>0 && bead->HasPos()) {
            c += bead->getPos();
            n++;
        }
    }

    if(bPos)
        _out->setPos(cg);
    if(bVel)
        _out->setVel(vel);
    if(bF)
        _out->setF(f);

    if(!_matrix[0]._in->HasPos()) {
        _out->setU(vec(1.0,0,0));
        _out->setV(vec(.0,1,0));
        _out->setW(vec(.0,0,1));
        return;
    }

    // calculate the tensor of gyration
    c=c/(double)n;
    for(iter = _matrix.begin(); iter != _matrix.end(); ++iter) {
        if((*iter)._weight == 0) continue;
        Bead *bead = iter->_in;
            vec v = bead->getPos() - c;
            //v = vec(1, 0.5, 0) * 0.*(drand48()-0.5)
            //    + vec(0.5, -1, 0) * (drand48()-0.5)
            //    + vec(0, 0, 1) * (drand48()-0.5);

            //Normalize the tensor with 1/number_of_atoms_per_bead
            m[0][0] += v.getX()*v.getX()/(double)_matrix.size();
            m[0][1] += v.getX()*v.getY()/(double)_matrix.size();
            m[0][2] += v.getX()*v.getZ()/(double)_matrix.size();
            m[1][1] += v.getY()*v.getY()/(double)_matrix.size();
            m[1][2] += v.getY()*v.getZ()/(double)_matrix.size();
            m[2][2] += v.getZ()*v.getZ()/(double)_matrix.size();

    }
    m[1][0] = m[0][1];
    m[2][0] = m[0][2];
    m[2][1] = m[1][2];

    // calculate the eigenvectors
    matrix::eigensystem_t es;
    m.SolveEigensystem(es);

    vec eigenv1=es.eigenvecs[0];
    vec eigenv2=es.eigenvecs[1];
    vec eigenv3=es.eigenvecs[2];

    _out->seteigenvec1(eigenv1);
    _out->seteigenvec2(eigenv2);
    _out->seteigenvec3(eigenv3);

    vec u = es.eigenvecs[0];
    vec v = _matrix[1]._in->getPos() - _matrix[0]._in->getPos();
    v.normalize();

    _out->setV(v);

    vec w = _matrix[2]._in->getPos() - _matrix[0]._in->getPos();
    w.normalize();

    //store the eigenvalues for the tensor of gyration
    double eigenvalue1 = es.eigenvalues[0];
    double eigenvalue2 = es.eigenvalues[1];
    double eigenvalue3 = es.eigenvalues[2];

    _out->setval1(eigenvalue1);
    _out->setval2(eigenvalue2);
    _out->setval3(eigenvalue3);

    if((v^w)*u < 0) u=vec(0.,0.,0.)-u;
    _out->setU(u);

    //write out w
    w=u^v;
    w.normalize();
    _out->setW(w);

    //out.BeadV(_out) = v;

    //out.BeadW(_out) = es.eigenvecs[2];
}

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

#include "map.h"
#include <iostream>
#include <votca/tools/matrix.h>
#include <votca/tools/tokenizer.h>
#include <numeric>

namespace votca { namespace csg {

using namespace std;

Map::~Map()
{
    vector<BeadMap *>::iterator iter;
    for(iter=_maps.begin();iter!=_maps.end();++iter)
        delete (*iter);
    _maps.clear();
}

void Map::Apply()
{
    vector<BeadMap *>::iterator iter;
    for(iter=_maps.begin();iter!=_maps.end();++iter)
        (*iter)->Apply();
}

void Map_Sphere::Initialize(Molecule *in, Bead *out, Property *opts_bead, Property *opts_map) {
    BeadMap::Initialize(in, out, opts_bead, opts_map);

    vector<string> beads;
    vector<double> weights;
    vector<double> fweights;

    // get the beads
    string s(_opts_bead->get("beads").value());
    Tokenizer tok_beads(s, " \n\t");
    tok_beads.ToVector(beads);

    // get vector of weights
    Tokenizer tok_weights(_opts_map->get("weights").value(), " \n\t");
    tok_weights.ConvertToVector<double>(weights);

    // check weather weights and # beads matches
    if (beads.size() != weights.size())
        throw runtime_error(string("number of subbeads in " +
                opts_bead->get("name").as<string>()
                + " and number of weights in map "
                + opts_map->get("name").as<string>() + " do not match"));

    // normalize the weights
    double norm = 1./ std::accumulate(weights.begin(), weights.end(), 0.);

    transform(weights.begin(), weights.end(), weights.begin(), bind2nd(multiplies<double>(), norm));
    // get the d vector if exists or initialize same as weights
    vector<double> d;
    if(_opts_map->exists("d")) {
        Tokenizer tok_weights(_opts_map->get("d").value(), " \n\t");
        tok_weights.ConvertToVector(d);
        // normalize d coefficients
        norm = 1./std::accumulate(d.begin(), d.end(), 0.);
        transform(d.begin(), d.end(), d.begin(), bind2nd(multiplies<double>(), norm));
    } else {
        // initialize force-weights with weights
        d.resize(weights.size());
        copy(weights.begin(), weights.end(), d.begin());
    }

    // check weather number of d coeffs is correct
    if (beads.size() != d.size()) {
        throw runtime_error(string("number of subbeads in " +
            opts_bead->get("name").as<string>()
            + " and number of d-coefficients in map "
            + opts_map->get("name").as<string>() + " do not match"));
    }

    fweights.resize(weights.size());
    // calculate force weights by d_i/w_i
    for(int i=0; i<weights.size(); ++i) {
        if(weights[i] == 0 && d[i]!=0) {
            throw runtime_error(
                "A d coefficient is nonzero while weights is zero in mapping "
                + opts_map->get("name").as<string>());
        }
        if(weights[i] != 0)
            fweights[i] = d[i] / weights[i];
        else
            fweights[i] = 0;
    }

    for (size_t i = 0; i < beads.size(); ++i) {
        int iin = in->getBeadByName(beads[i]);
        if (iin < 0)
            throw std::runtime_error(string("mapping error: molecule " + beads[i] + " does not exist"));
        AddElem(in->getBead(iin), weights[i], fweights[i]);
    }
}

void Map_Sphere::Apply()
{
    vector<element_t>::iterator iter;
    vec cg(0., 0., 0.), f(0.,0.,0.), vel(0.,0.,0.);
    bool bPos, bVel, bF;
    bPos=bVel=bF=false;
    _out->ParentBeads().clear();
    double M = 0;
    for(iter = _matrix.begin(); iter != _matrix.end(); ++iter) {
        Bead *bead = iter->_in;
        _out->ParentBeads().push_back(bead->getId());
        M+=bead->getM();
        if(bead->HasPos()) {
            cg += (*iter)._weight * bead->getPos();
            bPos=true;
        }
        if(bead->HasVel()) {
            vel += (*iter)._weight * bead->getVel();
            bVel = true;
        }
        if(bead->HasF()) {
            f += (*iter)._force_weight * bead->getF();
            bF = true;
        }
    }
    _out->setM(M);
    if(bPos)
        _out->setPos(cg);
    if(bVel)
        _out->setVel(vel);
    if(bF)
        _out->setF(f);
}

/// \todo implement this function
void Map_Ellipsoid::Apply()
{
    vector<element_t>::iterator iter;
    vec cg(0., 0., 0.), c(0., 0., 0.), f(0.,0.,0.), vel(0.,0.,0.);
    matrix m(0.);
     bool bPos, bVel, bF;
    bPos=bVel=bF=false;

    int n;
    n = 0;
    _out->ParentBeads().clear();
    for(iter = _matrix.begin(); iter != _matrix.end(); ++iter) {
       Bead *bead = iter->_in;
       _out->ParentBeads().push_back(bead->getId());
       if(bead->HasPos()) {
            cg += (*iter)._weight * bead->getPos();
            bPos=true;
        }
        if(bead->HasVel() == true) {
            vel += (*iter)._weight * bead->getVel();
            bVel = true;
        }
        if(bead->HasF()) {
            /// \todo fix me, right calculation should be F_i = m_cg / sum(w_i) * sum(w_i/m_i*F_i)
            //f += (*iter)._weight * _in->getBeadF((*iter)._in);
            f += (*iter)._force_weight * bead->getF();
            bF = true;
        }

        if((*iter)._weight>0 && bead->HasPos()) {
            c += bead->getPos();
            n++;
        }
    }

    if(bPos)
        _out->setPos(cg);
    if(bVel)
        _out->setVel(vel);
    if(bF)
        _out->setF(f);

    if(!_matrix[0]._in->HasPos()) {
        _out->setU(vec(1.0,0,0));
        _out->setV(vec(.0,1,0));
        _out->setW(vec(.0,0,1));
        return;
    }

    // calculate the tensor of gyration
    c=c/(double)n;
    for(iter = _matrix.begin(); iter != _matrix.end(); ++iter) {
        if((*iter)._weight == 0) continue;
        Bead *bead = iter->_in;
            vec v = bead->getPos() - c;
            //v = vec(1, 0.5, 0) * 0.*(drand48()-0.5)
            //    + vec(0.5, -1, 0) * (drand48()-0.5)
            //    + vec(0, 0, 1) * (drand48()-0.5);

            //Normalize the tensor with 1/number_of_atoms_per_bead
            m[0][0] += v.getX()*v.getX()/(double)_matrix.size();
            m[0][1] += v.getX()*v.getY()/(double)_matrix.size();
            m[0][2] += v.getX()*v.getZ()/(double)_matrix.size();
            m[1][1] += v.getY()*v.getY()/(double)_matrix.size();
            m[1][2] += v.getY()*v.getZ()/(double)_matrix.size();
            m[2][2] += v.getZ()*v.getZ()/(double)_matrix.size();

    }
    m[1][0] = m[0][1];
    m[2][0] = m[0][2];
    m[2][1] = m[1][2];

    // calculate the eigenvectors
    matrix::eigensystem_t es;
    m.SolveEigensystem(es);

    vec eigenv1=es.eigenvecs[0];
    vec eigenv2=es.eigenvecs[1];
    vec eigenv3=es.eigenvecs[2];

/*    _out->seteigenvec1(eigenv1);
    _out->seteigenvec2(eigenv2);
    _out->seteigenvec3(eigenv3);
  */

    vec u = es.eigenvecs[0];
    vec v = _matrix[1]._in->getPos() - _matrix[0]._in->getPos();
    v.normalize();

    _out->setV(v);

    vec w = _matrix[2]._in->getPos() - _matrix[0]._in->getPos();
    w.normalize();

    //store the eigenvalues for the tensor of gyration
    double eigenvalue1 = es.eigenvalues[0];
    double eigenvalue2 = es.eigenvalues[1];
    double eigenvalue3 = es.eigenvalues[2];

    /*_out->setval1(eigenvalue1);
    _out->setval2(eigenvalue2);
    _out->setval3(eigenvalue3);*/

    if((v^w)*u < 0) u=vec(0.,0.,0.)-u;
    _out->setU(u);

    //write out w
    w=u^v;
    w.normalize();
    _out->setW(w);

    //out.BeadV(_out) = v;

    //out.BeadW(_out) = es.eigenvecs[2];
}

}}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2017 Nicola Del Gobbo
 * 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
 *
 * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
 * IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 * MERCHANTABLITY OR NON-INFRINGEMENT.
 *
 * See the Apache Version 2.0 License for specific language governing
 * permissions and limitations under the License.
 *
 * Contributors - initial API implementation:
 * Nicola Del Gobbo <nicoladelgobbo@gmail.com>
 ******************************************************************************/

#include "magick-cli.h"

NAN_METHOD(Version)
{
    Nan::HandleScope();
    info.GetReturnValue().Set(Nan::New<String>(MagickLibVersionText).ToLocalChecked());
}

/*NAN_METHOD(Execute)
{
    //Callback *callback = new Callback(info[1].As<Function>());
    //Local<String> JScmd = Local<String>::Cast(info[0]);
    //string RAWcmd = *String::Utf8Value(JScmd);
    //AsyncQueueWorker(new GhostscriptWorker(callback, RAWcmd));
}*/

NAN_METHOD(ExecuteSync)
{
    Nan::HandleScope();
    /*if (info.Length() < 1)
    {
        return Nan::ThrowError("Sorry executeSync() method requires 1 argument that represent the ImageMagick command.");
    }
    if (!info[0]->IsString())
    {
        return Nan::ThrowError("Sorry executeSync() method's argument should be a string.");
    }

    Local<String> IMcmd = Local<String>::Cast(info[0]);
    string RAWcmd = *String::Utf8Value(IMcmd);
    vector<string> explodedCmd;
    istringstream iss(RAWcmd);
    for (string RAWcmd; iss >> RAWcmd;)
        explodedCmd.push_back(RAWcmd);*/

    MagickCoreGenesis("js.png", MagickFalse);

    {
        MagickBooleanType status;

        ImageInfo *image_info = AcquireImageInfo();
        ExceptionInfo *exception = AcquireExceptionInfo();

        int arg_count;
        char *args[] = {"magick", "js.png", "-resize", "50%",  "pippo.png", NULL};

        for (arg_count = 0; args[arg_count] != (char *)NULL; arg_count++)
            ;

        (void)MagickImageCommand(image_info, arg_count, args, NULL, exception);

        if (exception->severity != UndefinedException)
        {
            CatchException(exception);
            // TODO handle the error response
            //fprintf(stderr, "Major Error Detected\n");
        }

        image_info = DestroyImageInfo(image_info);
        exception = DestroyExceptionInfo(exception);
    }
    MagickCoreTerminus();

}

//////////////////////////// INIT & CONFIG MODULE //////////////////////////////

void Init(Local<Object> exports)
{
    exports->Set(Nan::New("version").ToLocalChecked(),
                 Nan::New<FunctionTemplate>(Version)->GetFunction());

    /*exports->Set(Nan::New("execute").ToLocalChecked(),
                 Nan::New<FunctionTemplate>(Execute)->GetFunction());*/

    exports->Set(Nan::New("executeSync").ToLocalChecked(),
                 Nan::New<FunctionTemplate>(ExecuteSync)->GetFunction());
}

NODE_MODULE(MagickCLI, Init)

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Set MagickCLI as execution environment for ImageMagick<commit_after>/*******************************************************************************
 * Copyright (c) 2017 Nicola Del Gobbo
 * 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
 *
 * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
 * IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 * MERCHANTABLITY OR NON-INFRINGEMENT.
 *
 * See the Apache Version 2.0 License for specific language governing
 * permissions and limitations under the License.
 *
 * Contributors - initial API implementation:
 * Nicola Del Gobbo <nicoladelgobbo@gmail.com>
 ******************************************************************************/

#include "magick-cli.h"

NAN_METHOD(Version)
{
    Nan::HandleScope();
    info.GetReturnValue().Set(Nan::New<String>(MagickLibVersionText).ToLocalChecked());
}

/*NAN_METHOD(Execute)
{
    //Callback *callback = new Callback(info[1].As<Function>());
    //Local<String> JScmd = Local<String>::Cast(info[0]);
    //string RAWcmd = *String::Utf8Value(JScmd);
    //AsyncQueueWorker(new GhostscriptWorker(callback, RAWcmd));
}*/

NAN_METHOD(ExecuteSync)
{
    Nan::HandleScope();
    /*if (info.Length() < 1)
    {
        return Nan::ThrowError("Sorry executeSync() method requires 1 argument that represent the ImageMagick command.");
    }
    if (!info[0]->IsString())
    {
        return Nan::ThrowError("Sorry executeSync() method's argument should be a string.");
    }

    Local<String> IMcmd = Local<String>::Cast(info[0]);
    string RAWcmd = *String::Utf8Value(IMcmd);
    vector<string> explodedCmd;
    istringstream iss(RAWcmd);
    for (string RAWcmd; iss >> RAWcmd;)
        explodedCmd.push_back(RAWcmd);*/

    MagickCoreGenesis("MagickCLI", MagickFalse);

    {
        MagickBooleanType status;

        ImageInfo *image_info = AcquireImageInfo();
        ExceptionInfo *exception = AcquireExceptionInfo();

        int arg_count;
        char *args[] = {"magick", "js.png", "-resize", "50%",  "pippo.png", NULL};

        for (arg_count = 0; args[arg_count] != (char *)NULL; arg_count++)
            ;

        (void)MagickImageCommand(image_info, arg_count, args, NULL, exception);

        if (exception->severity != UndefinedException)
        {
            CatchException(exception);
            // TODO handle the error response
            //fprintf(stderr, "Major Error Detected\n");
        }

        image_info = DestroyImageInfo(image_info);
        exception = DestroyExceptionInfo(exception);
    }
    MagickCoreTerminus();
}

//////////////////////////// INIT & CONFIG MODULE //////////////////////////////

void Init(Local<Object> exports)
{
    exports->Set(Nan::New("version").ToLocalChecked(),
                 Nan::New<FunctionTemplate>(Version)->GetFunction());

    /*exports->Set(Nan::New("execute").ToLocalChecked(),
                 Nan::New<FunctionTemplate>(Execute)->GetFunction());*/

    exports->Set(Nan::New("executeSync").ToLocalChecked(),
                 Nan::New<FunctionTemplate>(ExecuteSync)->GetFunction());
}

NODE_MODULE(MagickCLI, Init)

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>// Distributed under the BSD License, see accompanying LICENSE.txt
// (C) Copyright 2010 John-John Tedro et al.
#ifndef _BLOCKS_H_
#define _BLOCKS_H_

#include "image/color.hpp"

namespace mc {
  enum MaterialMode {
    Block,
    HalfBlock,
    TorchBlock
  };

  enum {
    Air = 0x00,
    Stone = 0x01,
    Grass = 0x02,
    Dirt = 0x03,
    Cobblestone = 0x04,
    Wood = 0x05,
    Sapling = 0x06,
    Bedrock = 0x07,
    Water = 0x08,
    StationaryWater = 0x09,
    Lava = 0x0A,
    StationaryLava = 0x0B,
    Sand = 0x0C,
    Gravel = 0x0D,
    GoldOre = 0x0E,
    IronOre = 0x0F,
    CoalOre = 0x10,
    Log = 0x11,
    Leaves = 0x12,
    Sponge = 0x13,
    Glass = 0x14,
    LapisLazuliOre = 0x15,
    LapisLazuliBlock = 0x16,
    Dispenser = 0x17,
    Sandstone = 0x18,
    NoteBlock = 0x19,
    BlackWool = 0x22,
    GrayWool = 0x23,
    WhiteWool = 0x24,
    YellowFlower = 0x25,
    RedRose = 0x26,
    BrownMushroom = 0x28,
    RedMushroom = 0x27,
    GoldBlock = 0x29,
    IronBlock = 0x2A,
    DoubleStep = 0x2B,
    Step = 0x2C,
    Brick = 0x2D,
    TNT = 0x2E,
    Bookcase = 0x2F,
    MossyCobblestone = 0x30,
    Obsidian = 0x31,
    Torch = 0x32,
    Fire = 0x33,
    MobSpawner = 0x34,
    WoodenStairs = 0x35,
    Chest = 0x36,
    RedstoneWire = 0x37,
    DiamondOre = 0x38,
    DiamondBlock = 0x39,
    Workbench = 0x3A,
    Crops = 0x3B,
    Soil = 0x3C,
    Furnace = 0x3D,
    BurningFurnace = 0x3E,
    SignPost = 0x3F,
    WoodenDoor = 0x40,
    Ladder = 0x41,
    MinecartTracks = 0x42,
    CobblestoneStairs = 0x43,
    WallSign = 0x44,
    Lever = 0x45,
    StonePressurePlate = 0x46,
    IronDoor = 0x47,
    WoodenPressurePlate = 0x48,
    RedstoneOre = 0x49,
    GlowingRedstoneOre = 0x4A,
    RedstoneTorchOff = 0x4B,
    RedstoneTorchOn = 0x4C,
    StoneButton = 0x4D,
    Snow = 0x4E,
    Ice = 0x4F,
    SnowBlock = 0x50,
    Cactus = 0x51,
    Clay = 0x52,
    Reed = 0x53,
    Jukebox = 0x54,
    Fence = 0x55,
    Pumpkin = 0x56,
    Bloodstone = 0x57,
    Slowsand = 0x58,
    Lightstone = 0x59,
    Portal = 0x5A,
    Jackolantern = 0x5B,
    PineLeaves = 0xEC,
    BirchLeaves = 0xED
    MaterialCount = 0xEE,
  };

  void initialize_constants();
  void deinitialize_constants();

  extern const int MapY;
  extern const int MapX;
  extern const int MapZ;
  extern const char **MaterialName;
  extern color* MaterialColor;
  extern color* MaterialSideColor;
  extern enum MaterialMode *MaterialModes;
}

#endif /* _BLOCKS_H_ */<commit_msg>Fixed typo<commit_after>// Distributed under the BSD License, see accompanying LICENSE.txt
// (C) Copyright 2010 John-John Tedro et al.
#ifndef _BLOCKS_H_
#define _BLOCKS_H_

#include "image/color.hpp"

namespace mc {
  enum MaterialMode {
    Block,
    HalfBlock,
    TorchBlock
  };

  enum {
    Air = 0x00,
    Stone = 0x01,
    Grass = 0x02,
    Dirt = 0x03,
    Cobblestone = 0x04,
    Wood = 0x05,
    Sapling = 0x06,
    Bedrock = 0x07,
    Water = 0x08,
    StationaryWater = 0x09,
    Lava = 0x0A,
    StationaryLava = 0x0B,
    Sand = 0x0C,
    Gravel = 0x0D,
    GoldOre = 0x0E,
    IronOre = 0x0F,
    CoalOre = 0x10,
    Log = 0x11,
    Leaves = 0x12,
    Sponge = 0x13,
    Glass = 0x14,
    LapisLazuliOre = 0x15,
    LapisLazuliBlock = 0x16,
    Dispenser = 0x17,
    Sandstone = 0x18,
    NoteBlock = 0x19,
    BlackWool = 0x22,
    GrayWool = 0x23,
    WhiteWool = 0x24,
    YellowFlower = 0x25,
    RedRose = 0x26,
    BrownMushroom = 0x28,
    RedMushroom = 0x27,
    GoldBlock = 0x29,
    IronBlock = 0x2A,
    DoubleStep = 0x2B,
    Step = 0x2C,
    Brick = 0x2D,
    TNT = 0x2E,
    Bookcase = 0x2F,
    MossyCobblestone = 0x30,
    Obsidian = 0x31,
    Torch = 0x32,
    Fire = 0x33,
    MobSpawner = 0x34,
    WoodenStairs = 0x35,
    Chest = 0x36,
    RedstoneWire = 0x37,
    DiamondOre = 0x38,
    DiamondBlock = 0x39,
    Workbench = 0x3A,
    Crops = 0x3B,
    Soil = 0x3C,
    Furnace = 0x3D,
    BurningFurnace = 0x3E,
    SignPost = 0x3F,
    WoodenDoor = 0x40,
    Ladder = 0x41,
    MinecartTracks = 0x42,
    CobblestoneStairs = 0x43,
    WallSign = 0x44,
    Lever = 0x45,
    StonePressurePlate = 0x46,
    IronDoor = 0x47,
    WoodenPressurePlate = 0x48,
    RedstoneOre = 0x49,
    GlowingRedstoneOre = 0x4A,
    RedstoneTorchOff = 0x4B,
    RedstoneTorchOn = 0x4C,
    StoneButton = 0x4D,
    Snow = 0x4E,
    Ice = 0x4F,
    SnowBlock = 0x50,
    Cactus = 0x51,
    Clay = 0x52,
    Reed = 0x53,
    Jukebox = 0x54,
    Fence = 0x55,
    Pumpkin = 0x56,
    Bloodstone = 0x57,
    Slowsand = 0x58,
    Lightstone = 0x59,
    Portal = 0x5A,
    Jackolantern = 0x5B,
    PineLeaves = 0xEC,
    BirchLeaves = 0xED,
    MaterialCount = 0xEE
  };

  void initialize_constants();
  void deinitialize_constants();

  extern const int MapY;
  extern const int MapX;
  extern const int MapZ;
  extern const char **MaterialName;
  extern color* MaterialColor;
  extern color* MaterialSideColor;
  extern enum MaterialMode *MaterialModes;
}

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


<commit_before>#include <vector>

#include "slicer.h"

using namespace mgl;

Slicer::Slicer(const SlicerConfig &slicerCfg, ProgressBar *progress)
	:Progressive(progress)
{
	layerCfg.firstLayerZ = slicerCfg.firstLayerZ;
	layerCfg.layerH = slicerCfg.layerH;
}
void Slicer::generateLoops(const Segmenter& seg, LayerLoops& layerloops) {
	unsigned int sliceCount = seg.readSliceTable().size();
	initProgress("outlines", sliceCount);

	layerloops.layerMeasure = seg.readLayerMeasure();
	layerloops.layerMeasure.getLayerAttributes(0).delta = layerCfg.firstLayerZ;

	for (size_t sliceId = 0; sliceId < sliceCount; sliceId++) {
		tick();
		LayerLoops::Layer currentLayer(layerloops.layerMeasure.createAttributes());
		layerloops.layerMeasure.getLayerAttributes(currentLayer.getIndex()) =
				LayerMeasure::LayerAttributes(
				layerloops.layerMeasure.sliceIndexToHeight(sliceId),
				layerloops.layerMeasure.getLayerH());
		libthing::SegmentTable segments;
		/*
		 Function outlinesForSlice is designed to use segmentTable rather than
		 the new Loop class. It makes use of clipper.cc, which was machine
		 translated from Delphi, and is not currently practical to quickly
		 convert to using new types. For this reason, we elected to
		 use this function as is, and to convert its resulting SegmentTables
		 into lists of loops.
		 */
		outlinesForSlice(seg, sliceId, segments);
		//convert all SegmentTables into loops
		for(libthing::SegmentTable::iterator it = segments.begin();
				it != segments.end();
				++it){
			Loop currentLoop;
			Loop::cw_iterator iter = currentLoop.clockwiseEnd();
			//convert current SegmentTable into a loop
			for(std::vector<libthing::LineSegment2>::iterator it2 = it->begin();
					it2 != it->end();
					++it2){
				//add points 1 - N
				iter = currentLoop.insertPointAfter(it2->b, iter);
			}
			if(!it->empty())
				//add point 0
				iter = currentLoop.insertPointAfter(it->begin()->a, iter);
			//add the loop to the current layer
			currentLayer.push_back(currentLoop);
		}
		//finally, add the loop layer to the new data structure
		layerloops.push_back(currentLayer);
	}
//	Scalar gridSpacing = layerCfg.layerW * layerCfg.gridSpacingMultiplier;
//	Limits limits = seg.readLimits();
////	Scalar xSpan = limits.xMax - limits.xMin;
////	Scalar ySpan = limits.yMax - limits.yMin;
////	Scalar xCenter = (limits.xMax + limits.xMin) * 0.5;
////	Scalar yCenter = (limits.yMax + limits.yMin) * 0.5;
////	limits.xMin = xCenter - xSpan;
////	limits.xMax = xCenter + xSpan;
////	limits.yMin = yCenter - ySpan;
////	limits.yMax = yCenter + ySpan;
//
//	limits.inflate(100.0, 100.0, 0);
//	layerloops.grid.init(limits, gridSpacing);
}

void Slicer::outlinesForSlice(const Segmenter& seg, size_t sliceId, libthing::SegmentTable & segments)
{
	Scalar tol = 1e-6;
	const LayerMeasure & layerMeasure = seg.readLayerMeasure();
	Scalar z = layerMeasure.sliceIndexToHeight(sliceId) +
			0.5 * layerMeasure.getLayerH();
	const std::vector<libthing::Triangle3> & allTriangles = seg.readAllTriangles();
	const TriangleIndices & trianglesForSlice = seg.readSliceTable()[sliceId];
	std::vector<libthing::LineSegment2> unorderedSegments;
	segmentationOfTriangles(trianglesForSlice, allTriangles, z, unorderedSegments);
	assert(segments.size() ==0);

	// dumpSegments("unordered_", unorderedSegments);
	// cout << segments << endl;
	loopsFromLineSegments(unorderedSegments, tol, segments);
	// cout << " done " << endl;
}

void Slicer::loopsFromLineSegments(const std::vector<libthing::LineSegment2>& unorderedSegments, Scalar tol, libthing::SegmentTable & segments)
{
	// dumpSegments("unordered_", unorderedSegments);
	// cout << segments << endl;
	if(unorderedSegments.size() > 0){
		//cout << " loopsAndHoleOgy " << endl;
		std::vector<libthing::LineSegment2> segs =  unorderedSegments;
		loopsAndHoleOgy(segs, tol, segments);
	}
}
<commit_msg>Fix for firstlayerz affecting shape of model<commit_after>#include <vector>

#include "slicer.h"

using namespace mgl;

Slicer::Slicer(const SlicerConfig &slicerCfg, ProgressBar *progress)
	:Progressive(progress)
{
	layerCfg.firstLayerZ = slicerCfg.firstLayerZ;
	layerCfg.layerH = slicerCfg.layerH;
}
void Slicer::generateLoops(const Segmenter& seg, LayerLoops& layerloops) {
	unsigned int sliceCount = seg.readSliceTable().size();
	initProgress("outlines", sliceCount);

	layerloops.layerMeasure = seg.readLayerMeasure();
	layerloops.layerMeasure.getLayerAttributes(0).delta = layerCfg.firstLayerZ;

	for (size_t sliceId = 0; sliceId < sliceCount; sliceId++) {
		tick();
		LayerLoops::Layer currentLayer(layerloops.layerMeasure.createAttributes());
		layerloops.layerMeasure.getLayerAttributes(currentLayer.getIndex()) =
				LayerMeasure::LayerAttributes(
				layerloops.layerMeasure.sliceIndexToHeight(sliceId),
				layerloops.layerMeasure.getLayerH());
		libthing::SegmentTable segments;
		/*
		 Function outlinesForSlice is designed to use segmentTable rather than
		 the new Loop class. It makes use of clipper.cc, which was machine
		 translated from Delphi, and is not currently practical to quickly
		 convert to using new types. For this reason, we elected to
		 use this function as is, and to convert its resulting SegmentTables
		 into lists of loops.
		 */
		outlinesForSlice(seg, sliceId, segments);
		//convert all SegmentTables into loops
		for(libthing::SegmentTable::iterator it = segments.begin();
				it != segments.end();
				++it){
			Loop currentLoop;
			Loop::cw_iterator iter = currentLoop.clockwiseEnd();
			//convert current SegmentTable into a loop
			for(std::vector<libthing::LineSegment2>::iterator it2 = it->begin();
					it2 != it->end();
					++it2){
				//add points 1 - N
				iter = currentLoop.insertPointAfter(it2->b, iter);
			}
			if(!it->empty())
				//add point 0
				iter = currentLoop.insertPointAfter(it->begin()->a, iter);
			//add the loop to the current layer
			currentLayer.push_back(currentLoop);
		}
		//finally, add the loop layer to the new data structure
		layerloops.push_back(currentLayer);
	}
//	Scalar gridSpacing = layerCfg.layerW * layerCfg.gridSpacingMultiplier;
//	Limits limits = seg.readLimits();
////	Scalar xSpan = limits.xMax - limits.xMin;
////	Scalar ySpan = limits.yMax - limits.yMin;
////	Scalar xCenter = (limits.xMax + limits.xMin) * 0.5;
////	Scalar yCenter = (limits.yMax + limits.yMin) * 0.5;
////	limits.xMin = xCenter - xSpan;
////	limits.xMax = xCenter + xSpan;
////	limits.yMin = yCenter - ySpan;
////	limits.yMax = yCenter + ySpan;
//
//	limits.inflate(100.0, 100.0, 0);
//	layerloops.grid.init(limits, gridSpacing);
}

void Slicer::outlinesForSlice(const Segmenter& seg, size_t sliceId, libthing::SegmentTable & segments)
{
	Scalar tol = 1e-6;
	const LayerMeasure & layerMeasure = seg.readLayerMeasure();
	Scalar z = layerMeasure.sliceIndexToHeight(sliceId) +
			0.5 * layerMeasure.getLayerH() - layerMeasure.sliceIndexToHeight(0);
	const std::vector<libthing::Triangle3> & allTriangles = seg.readAllTriangles();
	const TriangleIndices & trianglesForSlice = seg.readSliceTable()[sliceId];
	std::vector<libthing::LineSegment2> unorderedSegments;
	segmentationOfTriangles(trianglesForSlice, allTriangles, z, unorderedSegments);
	assert(segments.size() ==0);

	// dumpSegments("unordered_", unorderedSegments);
	// cout << segments << endl;
	loopsFromLineSegments(unorderedSegments, tol, segments);
	// cout << " done " << endl;
}

void Slicer::loopsFromLineSegments(const std::vector<libthing::LineSegment2>& unorderedSegments, Scalar tol, libthing::SegmentTable & segments)
{
	// dumpSegments("unordered_", unorderedSegments);
	// cout << segments << endl;
	if(unorderedSegments.size() > 0){
		//cout << " loopsAndHoleOgy " << endl;
		std::vector<libthing::LineSegment2> segs =  unorderedSegments;
		loopsAndHoleOgy(segs, tol, segments);
	}
}
<|endoftext|>