text:
/*ckwg +29
 * Copyright 2018 by Kitware, SAS.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither name of Kitware, Inc. nor the names of any contributors may be used
 *    to endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * \file
 * \brief Implementation for mesh uv unwrapping
 */

#include "uv_unwrap_mesh.h"

#include <algorithm>
#include <iostream>
#include <numeric>
#include <Eigen/Dense>
#include <vital/exceptions.h>

using namespace kwiver::vital;

namespace {

/// This structure is used to represent a 2D triangle
struct triangle_t
{
  kwiver::vital::vector_2d a;
  kwiver::vital::vector_2d b;
  kwiver::vital::vector_2d c;
  unsigned int face_id;
  double height;
  double width;
};
}

namespace kwiver {
namespace arrows {
namespace core {

/// Private implementation class
class uv_unwrap_mesh::priv
{
public:
  /// Constructor
  priv() : spacing(0.005)
  {
  }

  priv(const priv& other)
  {
  }

  double spacing;
};

// Constructor
uv_unwrap_mesh::uv_unwrap_mesh()
  : d_(new priv)
{
  attach_logger( "arrows.core.uv_unwrap_mesh" );
}

// Copy constructor
uv_unwrap_mesh
::uv_unwrap_mesh(const uv_unwrap_mesh& other)
  : d_(new priv(*other.d_))
{
}

// Destructor
uv_unwrap_mesh
::~uv_unwrap_mesh()
{
}

// Get this algorithm's \link vital::config_block configuration block \endlink
vital::config_block_sptr
uv_unwrap_mesh::get_configuration() const
{
  vital::config_block_sptr config =
      vital::algo::uv_unwrap_mesh::get_configuration();
   config->set_value("spacing", d_->spacing,
                     "Spacing between triangles. It is a percentage of the texture size "
                     "and should be relatively small (default is 0.005).");
  return config;
}

// Set the configuration
void uv_unwrap_mesh
::set_configuration(vital::config_block_sptr in_config)
{
  vital::config_block_sptr config = this->get_configuration();
  config->merge_config(in_config);
  d_->spacing = config->get_value<double>("spacing", d_->spacing);
}

// Check that the algorithm's configuration vital::config_block is valid
bool uv_unwrap_mesh
::check_configuration(vital::config_block_sptr config) const
{
  double spacing = config->get_value<double>("spacing", d_->spacing);
  if( spacing <= 0.0 || spacing > 1.0 )
  {
    LOG_ERROR( logger(),
             "spacing parameter is " << spacing << ", needs to be in (0.0, 1.0].");
    return false;
  }
  return true;
}

// Unwrap a mesh
void uv_unwrap_mesh::unwrap(kwiver::vital::mesh_sptr mesh) const
{
  if (mesh->faces().regularity() != 3)
  {
    VITAL_THROW( algorithm_exception, this->type_name(), this->impl_name(),
                 "This algorithm expects a regular mesh with triangular faces.");
  }

  const mesh_face_array_base& faces = mesh->faces();
  const mesh_vertex_array<3>& vertices = dynamic_cast<const mesh_vertex_array<3>&>(mesh->vertices());

  // Map each triangle in 2d. The longest edge should be horizontal and its left point is (0, 0)
  std::vector<triangle_t> triangles(mesh->num_faces());
  double total_area = 0.0;
  for (unsigned int f = 0; f < mesh->num_faces(); ++f)
  {
    // face 3d points
    vector_3d pt1 = vertices[faces(f, 0)];
    vector_3d pt2 = vertices[faces(f, 1)];
    vector_3d pt3 = vertices[faces(f, 2)];

    // triangle edges
    vector_3d pt1pt2 = pt2 - pt1;
    vector_3d pt1pt3 = pt3 - pt1;
    vector_3d pt2pt3 = pt3 - pt2;

    // find the longest edge and assign it to AB, C is the other point
    vector_3d AB, AC;
    int longest_edge;
    if (pt1pt2.norm() >= pt1pt3.norm() && pt1pt2.norm() >= pt2pt3.norm())
    {
      // pt1 is A, pt2 is B, pt3 is C
      AB = pt1pt2;
      AC = pt1pt3;
      longest_edge = 0;
    }
    else if (pt2pt3.norm() >= pt1pt3.norm())
    {
      // pt1 is C, pt2 is A, pt3 is B
      AB = pt2pt3;
      AC = -pt1pt2;
      longest_edge = 1;
    }
    else
    {
      // pt1 is B, pt2 is C, pt3 is A
      AB = -pt1pt3;
      AC = -pt2pt3;
      longest_edge = 2;
    }
    // transform the face to 2d
    vector_2d a(0.0, 0.0);
    vector_2d b(AB.norm(), 0.0);
    double proj = AC.dot(AB) / AB.norm();
    vector_2d c(proj, (AC - proj * AB.normalized()).norm());
    // scale B and C by the resolution
    total_area += b(0) * c(1);
    double w = b(0);
    double h = c(1);
    if (longest_edge == 0)
    {
      // pt1 is A, pt2 is B, pt3 is C
      triangles[f] = {a, b, c, f, h, w};
    }
    else if (longest_edge == 1)
    {
      // pt1 is C, pt2 is A, pt3 is B
      triangles[f] = {c, a, b, f, h, w};
    }
    else if (longest_edge == 2)
    {
      // pt1 is B, pt2 is C, pt3 is A
      triangles[f] = {b, c, a, f, h, w};
    }
  }

  // Sort triangles by height
  std::vector<unsigned int> face_indices(triangles.size(), 0);
  std::iota(face_indices.begin(), face_indices.end(), 0);

  std::sort(face_indices.begin(), face_indices.end(), [&triangles](unsigned int i, unsigned int j)
  {
    return triangles[i].height < triangles[j].height;
  });

  // Estimate max width to have a more or less square texture atlas
  double max_width = (std::ceil(sqrt(total_area)));
  double margin = max_width * d_->spacing;    // margin between triangles
  // Update max_width with margins
  double correction = 0.0;
  for (auto& t : triangles)
    correction += margin * (t.width + t.height);
  max_width = std::ceil(sqrt(total_area + correction));

  // Pack triangles
  std::vector<vector_2d> tcoords(mesh->num_faces() * 3);
  double current_u = margin;
  double current_v = margin;
  double next_v = current_v;
  vital::vector_2d shift(0.0, 0.0);
  double max_u = 0.0, max_v = 0.0;
  for (unsigned int f : face_indices)
  {
    if (current_u + triangles[f].width + margin> max_width)
    {
      current_u = margin;
      current_v = next_v + margin;
    }
    shift(0) = current_u;
    shift(1) = current_v;
    triangles[f].a += shift;
    triangles[f].b += shift;
    triangles[f].c += shift;

    if (current_u + triangles[f].width > max_u)
      max_u = current_u + triangles[f].width;
    if (current_v + triangles[f].height > max_v)
      max_v = current_v + triangles[f].height;

    next_v = std::max(next_v, current_v + triangles[f].height);
    current_u += triangles[f].width + margin;
  }
  double width = max_u + margin;
  double height = max_v + margin;

  // Normalize texture coordinates
  double normalize = 1.0 / std::max(width, height);
  for (unsigned int i = 0; i < triangles.size(); ++i)
  {
    tcoords[i * 3 + 0] = triangles[i].a * normalize;
    tcoords[i * 3 + 1] = triangles[i].b * normalize;
    tcoords[i * 3 + 2] = triangles[i].c * normalize;
  }
  mesh->set_tex_coords(tcoords);
}

}
}
}

ext: cxx

max_stars_repo_name: neal-siekierski/kwiver

max_issues_repo_name: neal-siekierski/kwiver

max_forks_repo_name: neal-siekierski/kwiver


text:
/******************************************************************************
The MIT License(MIT)
https://github.com/adarwoo/cyclo

Copyright(c) 2021 Guillaume ARRECKX - software@arreckx.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ui_controller_h_included
#define ui_controller_h_included

#include <boost/sml.hpp>

#include <logger.h>

#include "ui_model.hpp"
#include "ui_view.hpp"

namespace sml = boost::sml;

// Create those simple events
struct up
{};
struct down
{};
struct push
{};
struct usb_on
{};
struct usb_off
{};
struct splash_timeout
{};
struct pgm_stopped
{};

namespace
{
   ///< Dummy event to all processing forks in SM
   struct next
   {};

   ///< Marker to force the SM to evaluate 'next'
   bool controller_process_next{ false };
}  // namespace

///< Like process but allow re-entry
template<class TSM, class TEvent>
void process_event( TSM &sm, TEvent &&evt )
{
   LOG_HEADER( "sm" );

   sm.process_event( evt );

   while ( controller_process_next )
   {
      controller_process_next = false;
      sm.process_event( next{} );
   }
};

/** Set the next flag so the process event keeps pumping the SM */
inline auto call_next = []() { controller_process_next = true; };

/*
 * Common guards
 */
struct walkman
{
   auto operator()() const noexcept
   {
      using namespace sml;

      auto is_running = []( UIModel &m ) {
         return m.get_state() == UIModel::program_state_t::running;
      };
      auto is_stopped = []( UIModel &m ) {
         return m.get_state() == UIModel::program_state_t::stopped;
      };

      return make_transition_table(
         *"select"_s
            + sml::on_entry<_> /
                 []( UIView &v ) {
#if CURSOR_ALWAYS
                    v.draw_cursor( 1 );
#endif
                    call_next();
                 },
         "select"_s + event<next>[ is_running ] = "do_pause"_s,
         "select"_s + event<next>[ is_stopped ] = "do_play"_s,
         "select"_s + event<next>               = "do_play_or_stop"_s

         ,
         "do_play"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_walkman( 1 ); },
         "do_play"_s
            + event<push> /
                 []( UIModel &m ) {
                    // Load the program
                    m.load_command();

                    // Start the sequencer
                    fx::publish( msg::StartProgram{ true } );
                    m.set_state( UIModel::program_state_t::running );
                 } = "do_pause"_s

         ,
         "do_pause"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_walkman( 1 ); },
         "do_pause"_s
            + event<push> /
                 []( UIModel &m ) {
                    m.set_state( UIModel::program_state_t::paused );
                    fx::publish( msg::StopProgram{} );
                 } = "do_play_or_stop"_s,
         "do_pause"_s + event<up>[ is_running ], "do_pause"_s + event<pgm_stopped> = "do_play"_s,

         "do_play_or_stop"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_walkman( 1 ); },
         "do_play_or_stop"_s
            + event<push> /
                 []( UIModel &m ) {
                    fx::publish( msg::StartProgram{ false } );
                    m.set_state( UIModel::program_state_t::running );
                 }                         = "do_pause"_s,
         "do_play_or_stop"_s + event<down> = "do_stop"_s

         ,
         "do_stop"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_walkman( 2 ); },
         "do_stop"_s + event<up> = "do_play_or_stop"_s,
         "do_stop"_s
            + event<push> /
                 []( UIModel &m, UIView &v ) {
                    m.reset_counter( true );
                    v.draw_counter();
                    m.set_state( UIModel::program_state_t::stopped );
                    fx::publish( msg::StopProgram{} );
                 } = "do_play"_s );
   }
};

struct program_setup
{
   auto operator()() const noexcept
   {
      using namespace sml;

      auto on_seconds_top     = []( UIModel &m ) { return m.on_sec == 59; };
      auto on_seconds_bottom  = []( UIModel &m ) { return m.on_sec == 0; };
      auto on_minutes_top     = []( UIModel &m ) { return m.on_min == 99; };
      auto on_minutes_bottom  = []( UIModel &m ) { return m.on_min == 0; };
      auto off_seconds_top    = []( UIModel &m ) { return m.off_sec == 99; };
      auto off_seconds_bottom = []( UIModel &m ) { return m.off_sec == 0; };
      auto off_minutes_top    = []( UIModel &m ) { return m.off_min == 59; };
      auto off_minutes_bottom = []( UIModel &m ) { return m.off_min == 0; };

      return make_transition_table(
         *"setup_on_min"_s + event<up>[ on_minutes_top ],
         "setup_on_min"_s
            + event<up> /
                 []( UIModel &m, UIView &v ) {
                    ++m.on_min;
                    v.manual_program_draw_digit( UIView::next_highlight, 0, 0 );
                 },
         "setup_on_min"_s + event<down>[ on_minutes_bottom ],
         "setup_on_min"_s
            + event<down> /
                 []( UIModel &m, UIView &v ) {
                    --m.on_min;
                    v.manual_program_draw_digit( UIView::next_highlight, 0, 0 );
                 },
         "setup_on_min"_s
            + event<push> /
                 []( UIView &v ) {
                    v.manual_program_draw_digit( UIView::back_to_normal, 0, 0 );
                    v.manual_program_draw_digit( UIView::first_highlight, 0, 1 );
                 } = "setup_on_sec"_s

         ,
         "setup_on_sec"_s + event<up>[ on_seconds_top ],
         "setup_on_sec"_s
            + event<up> /
                 []( UIModel &m, UIView &v ) {
                    ++m.on_sec;
                    v.manual_program_draw_digit( UIView::next_highlight, 0, 1 );
                 },
         "setup_on_sec"_s + event<down>[ on_seconds_bottom ],
         "setup_on_sec"_s
            + event<down> /
                 []( UIModel &m, UIView &v ) {
                    --m.on_sec;
                    v.manual_program_draw_digit( UIView::next_highlight, 0, 1 );
                 },
         "setup_on_sec"_s
            + event<push> /
                 []( UIView &v ) {
                    v.manual_program_draw_digit( UIView::back_to_normal, 0, 1 );
                    v.manual_program_draw_digit( UIView::first_highlight, 1, 0 );
                 } = "setup_off_min"_s

         ,
         "setup_off_min"_s + event<up>[ off_minutes_top ],
         "setup_off_min"_s
            + event<up> /
                 []( UIModel &m, UIView &v ) {
                    ++m.off_min;
                    v.manual_program_draw_digit( UIView::next_highlight, 1, 0 );
                 },
         "setup_off_min"_s + event<down>[ off_minutes_bottom ],
         "setup_off_min"_s
            + event<down> /
                 []( UIModel &m, UIView &v ) {
                    --m.off_min;
                    v.manual_program_draw_digit( UIView::next_highlight, 1, 0 );
                 },
         "setup_off_min"_s
            + event<push> /
                 []( UIView &v ) {
                    v.manual_program_draw_digit( UIView::back_to_normal, 1, 0 );
                    v.manual_program_draw_digit( UIView::first_highlight, 1, 1 );
                 } = "setup_off_sec"_s

         ,
         "setup_off_sec"_s + event<up>[ off_seconds_top ],
         "setup_off_sec"_s
            + event<up> /
                 []( UIModel &m, UIView &v ) {
                    ++m.off_sec;
                    v.manual_program_draw_digit( UIView::next_highlight, 1, 1 );
                 },
         "setup_off_sec"_s + event<down>[ off_seconds_bottom ],
         "setup_off_sec"_s
            + event<down> /
                 []( UIModel &m, UIView &v ) {
                    --m.off_sec;
                    v.manual_program_draw_digit( UIView::next_highlight, 1, 1 );
                 },
         "setup_off_sec"_s + event<push> / call_next = X

      );
   }
};

struct program_selection
{
   auto operator()() const noexcept
   {
      using namespace sml;

      auto program_is_man = []( UIModel &m ) { return m.get_pgm() == 0; };
      auto prev_is_same   = []( UIModel &m ) { return m.get_pgm() == m.get_prev(); };
      auto next_is_same   = []( UIModel &m ) { return m.get_pgm() == m.get_next(); };

      return make_transition_table(
        * "program_selection_initial"_s + event<push> / [] (UIView &v) {
           v.draw_prog(true); } = "program_selected"_s
        , "program_selection_initial"_s + sml::on_entry<_> / [] (UIView &v) {
           v.draw_cursor(0); }
        , "program_selection_initial"_s + sml::on_exit<_> / [] (UIView &v) {
           v.erase_cursor(0); }
        , "program_selected"_s + event<up> [ prev_is_same ]
        , "program_selected"_s + event<up> / [] (UIModel &m, UIView &v) {
           m.set_pgm(m.get_prev());
           v.draw_prog(true); }
        , "program_selected"_s + event<down> [ next_is_same ]
        , "program_selected"_s + event<down> / [] (UIModel &m, UIView &v) {
           m.set_pgm(m.get_next());
           v.draw_prog(true); }
        , "program_selected"_s + event<push> [ program_is_man ] = state<program_setup>

        , state<program_setup> + sml::on_entry<_> / [] (UIView& v) {
           v.draw_program_setup_dialog(); }
        , state<program_setup> + sml::on_exit<_> / [] (UIModel &m, UIView& v) {
           m.store_manual_pgm();
           v.draw(); }
         , state<program_setup> +           event<next> / call_next = X
    );
   }
};

struct mode_manual
{
   auto operator()() const noexcept
   {
      using namespace sml;

      auto is_running = []( UIModel &m ) {
         return m.get_state() == UIModel::program_state_t::running;
      };
      auto is_paused = []( UIModel &m ) {
         return m.get_state() == UIModel::program_state_t::paused;
      };
      auto is_stopped = []( UIModel &m ) {
         return m.get_state() == UIModel::program_state_t::stopped;
      };

      auto counter_active = []( UIModel &m ) { return m.get_counter() >= 0; };

      return make_transition_table(
         *"select"_s + sml::on_entry<_> / call_next,
         "select"_s + event<next>[ is_running ] = state<walkman>,
         "select"_s + event<next>               = state<program_selection>

         ,
         state<walkman> + sml::on_exit<_> / []( UIView &v ) {
#if CURSOR_ALWAYS
             v.erase_cursor(1);
#endif
             v.draw_walkman(); },
         state<program_selection> + sml::on_exit<_> / []( UIView &v ) { v.erase_cursor( 1 ); },
         state<program_selection> + event<next> / []( UIModel &m ) { m.load_command(); } =
            state<walkman>

         ,
         "counter"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_cursor( 2 ); },
         "counter"_s + sml::on_exit<_> / []( UIView &v ) { v.erase_cursor( 2 ); },
         "counter"_s + event<down> = "contact"_s, "counter"_s + event<up> = state<walkman>,
         "counter"_s
            + event<push> /
                 []( UIModel &m, UIView &v ) {
                    m.reset_counter();
                    v.draw_counter();
                 }

         ,
         "contact"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_cursor( 3 ); },
         "contact"_s + sml::on_exit<_> / []( UIView &v ) { v.erase_cursor( 3 ); },
         "contact"_s + event<up>[ is_paused and not counter_active ] = state<walkman>,
         "contact"_s + event<up>[ is_paused ] = "counter"_s,
         "contact"_s + event<up>              = state<walkman>,
         "contact"_s + event<push> / []( UIModel &m ) { m.flip_contact(); }

         ,
         state<program_selection> + event<down> = state<walkman>,
         state<program_selection> + event<push> / []( UIModel &m, UIView &v ) {
            m.select_pgm();
            v.draw_prog( false );
         } =state<walkman>,
         state<walkman> + event<down>[ is_paused and not counter_active ]  = "contact"_s,
         state<walkman> + event<down>[ is_paused ] = "counter"_s,
         state<walkman> + event<down>[ is_stopped or is_paused ] = "contact"_s,
         state<walkman> + event<up>[ is_stopped ]   = state<program_selection> );
   }
};

struct mode_usb
{};

struct sm_cyclo
{
   auto operator()() const noexcept
   {
      using namespace sml;

      return make_transition_table(
         *"splash"_s + event<splash_timeout> = state<mode_manual>,
         "splash"_s + sml::on_entry<_> / []( UIView &v ) { v.draw_splash(); }

         ,
         state<mode_manual> + sml::on_entry<_> / []( UIView &v ) { v.draw(); },
         state<mode_manual> + event<usb_on> / []( UIView &v ) { v.draw_usb(); } = state<mode_usb>,
         state<mode_usb> + event<usb_off> = state<mode_manual> );
   }
};

#endif  // ui_controller_h_included

ext: hpp


text:
/*

Copyright (c) 2005-2022, University of Oxford.
All rights reserved.

University of Oxford means the Chancellor, Masters and Scholars of the
University of Oxford, having an administrative office at Wellington
Square, Oxford OX1 2JD, UK.

This file is part of Chaste.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 * Neither the name of the University of Oxford nor the names of its
   contributors may be used to endorse or promote products derived from this
   software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef PLANESTIMULUSCELLFACTORY_HPP_
#define PLANESTIMULUSCELLFACTORY_HPP_

#include <boost/shared_ptr.hpp>

#include "AbstractCardiacCellFactory.hpp"
#include "LogFile.hpp"
#include "SimpleStimulus.hpp"

/**
 * PlaneStimulusCellFactory provides cells within 1e-5 of x=0 with a SimpleStimulus.
 */
template<class CELL, unsigned ELEMENT_DIM, unsigned SPACE_DIM = ELEMENT_DIM>
class PlaneStimulusCellFactory : public AbstractCardiacCellFactory<ELEMENT_DIM,SPACE_DIM>
{
protected:
    /** The stimulus to apply at stimulated nodes */
    boost::shared_ptr<SimpleStimulus> mpStimulus;

public:
    /**
     * Constructor
     * @param stimulusMagnitude  The magnitude of the simple stimulus to be applied (defaults to -600).
     * @param stimulusDuration  The duration of the simple stimulus to be applied (defaults to 0.5ms).
     */
    PlaneStimulusCellFactory(double stimulusMagnitude=-600, double stimulusDuration=0.5)
        : AbstractCardiacCellFactory<ELEMENT_DIM,SPACE_DIM>()
    {
        mpStimulus.reset(new SimpleStimulus(stimulusMagnitude, stimulusDuration));
        LOG(1, "Defined a PlaneStimulusCellFactory<"<<SPACE_DIM<<"> with SimpleStimulus("<<stimulusMagnitude<<","<< stimulusDuration<< ")\n");
    }

    /**
     * @param pNode  Pointer to the node.
     * @return  A cardiac cell which corresponds to this node.
     */
    AbstractCardiacCellInterface* CreateCardiacCellForTissueNode(Node<SPACE_DIM>* pNode)
    {
        double x = pNode->GetPoint()[0];

        ///\todo remove magic number? (#1884)
        if (x*x<=1e-10)
        {
            return new CELL(this->mpSolver, mpStimulus);
        }
        else
        {
            return new CELL(this->mpSolver, this->mpZeroStimulus);
        }
    }
};

#endif /*PLANESTIMULUSCELLFACTORY_HPP_*/

max_stars_repo_name: stu-l/Chaste

max_issues_repo_name: stu-l/Chaste

max_forks_repo_name: stu-l/Chaste


text:
// Copyright (C) 2005  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.

#include <string>
#include <sstream>

#include <dlib/tokenizer.h>
#include "tester.h"

namespace
{
    using namespace test;
    using namespace std;
    using namespace dlib;

    logger dlog("test.tokenizer");

    template <
        typename tok
        >
    void tokenizer_kernel_test (
    )
    /*!
        requires
            - tok is an implementation of tokenizer_kernel_abstract.h
        ensures
            - runs tests on tok for compliance with the specs
    !*/
    {

        print_spinner();

        tok test;

        DLIB_TEST(test.numbers() == "0123456789");
        DLIB_TEST(test.uppercase_letters() == "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        DLIB_TEST(test.lowercase_letters() == "abcdefghijklmnopqrstuvwxyz");

        DLIB_TEST_MSG(test.get_identifier_body() == "_" + test.lowercase_letters() +
                     test.uppercase_letters() + test.numbers(),"");
        DLIB_TEST_MSG(test.get_identifier_head() == "_" + test.lowercase_letters() +
                     test.uppercase_letters(),"");

        DLIB_TEST(test.stream_is_set() == false);
        test.clear();
        DLIB_TEST(test.stream_is_set() == false);

        DLIB_TEST_MSG(test.get_identifier_body() == "_" + test.lowercase_letters() +
                     test.uppercase_letters() + test.numbers(),"");
        DLIB_TEST_MSG(test.get_identifier_head() == "_" + test.lowercase_letters() +
                     test.uppercase_letters(),"");

        tok test2;

        ostringstream sout;
        istringstream sin;
        test2.set_stream(sin);

        DLIB_TEST(test2.stream_is_set());
        DLIB_TEST(&test2.get_stream() == &sin);

        int type;
        string token;

        test2.get_token(type,token);
        DLIB_TEST(type == tok::END_OF_FILE);
        test2.get_token(type,token);
        DLIB_TEST(type == tok::END_OF_FILE);
        test2.get_token(type,token);
        DLIB_TEST(type == tok::END_OF_FILE);

        sin.clear();
        sin.str("  The cat 123asdf1234 ._ \n test.");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == "  ");

        DLIB_TEST(test2.peek_type() == tok::IDENTIFIER);
        DLIB_TEST(test2.peek_token() == "The");
        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "The");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == " ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "cat");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == " ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::NUMBER);
        DLIB_TEST_MSG(token == "123","token: " << token);

        DLIB_TEST(test2.peek_type() == tok::IDENTIFIER);
        DLIB_TEST(test2.peek_token() == "asdf1234");
        DLIB_TEST(test2.peek_type() == tok::IDENTIFIER);
        DLIB_TEST(test2.peek_token() == "asdf1234");
        DLIB_TEST(test2.peek_type() == tok::IDENTIFIER);
        DLIB_TEST(test2.peek_token() == "asdf1234");
        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "asdf1234");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == ".","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "_");

        DLIB_TEST(test2.peek_type() == tok::WHITE_SPACE);
        DLIB_TEST_MSG(test2.peek_token() == " ","token: \"" << token << "\"" <<
                     "\ntoken size: " << (unsigned int)token.size());

        swap(test,test2);

        DLIB_TEST(test2.stream_is_set() == false);

        DLIB_TEST(test.peek_type() == tok::WHITE_SPACE);
        DLIB_TEST_MSG(test.peek_token() == " ","token: \"" << token << "\"" <<
                     "\ntoken size: " << (unsigned int)token.size());
        test.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: \"" << token << "\"" <<
                     "\ntoken size: " << (unsigned int)token.size());

        test.get_token(type,token);
        DLIB_TEST_MSG(type == tok::END_OF_LINE,"token: " << token);
        DLIB_TEST_MSG(token == "\n","token: " << token);

        swap(test,test2);
        DLIB_TEST(test.stream_is_set() == false);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST_MSG(token == "test","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == ".","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::END_OF_FILE);

        test2.set_identifier_token("_" + test.uppercase_letters() +
                                   test.lowercase_letters(),test.numbers() + "_" + test.uppercase_letters()
                                   +test.lowercase_letters());

        sin.clear();
        sin.str("  The cat 123asdf1234 ._ \n\r test.");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == "  ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "The");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == " ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "cat");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == " ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::NUMBER);
        DLIB_TEST_MSG(token == "123","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "asdf1234");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == ".","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "_");

        swap(test,test2);

        DLIB_TEST(test2.stream_is_set() == false);

        test.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: \"" << token << "\"" <<
                     "\ntoken size: " << (unsigned int)token.size());

        test.get_token(type,token);
        DLIB_TEST_MSG(type == tok::END_OF_LINE,"token: " << token);
        DLIB_TEST_MSG(token == "\n","token: " << token);

        swap(test,test2);
        DLIB_TEST(test.stream_is_set() == false);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == "\r ","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST_MSG(token == "test","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == ".","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::END_OF_FILE);

        test2.set_identifier_token(test.uppercase_letters() +
                                   test.lowercase_letters(),test.numbers() + test.uppercase_letters()
                                   +test.lowercase_letters());

        sin.clear();
        sin.str("  The cat 123as_df1234 ._ \n test.");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == "  ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "The");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == " ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "cat");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST(token == " ");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::NUMBER);
        DLIB_TEST_MSG(token == "123","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "as");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == "_","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST(token == "df1234");

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == ".","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST(token == "_");

        swap(test,test2);

        DLIB_TEST(test2.stream_is_set() == false);

        test.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: \"" << token << "\"" <<
                     "\ntoken size: " << (unsigned int)token.size());

        test.get_token(type,token);
        DLIB_TEST_MSG(type == tok::END_OF_LINE,"token: " << token);
        DLIB_TEST_MSG(token == "\n","token: " << token);

        swap(test,test2);
        DLIB_TEST(test.stream_is_set() == false);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::WHITE_SPACE);
        DLIB_TEST_MSG(token == " ","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::IDENTIFIER);
        DLIB_TEST_MSG(token == "test","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::CHAR);
        DLIB_TEST_MSG(token == ".","token: " << token);

        test2.get_token(type,token);
        DLIB_TEST(type == tok::END_OF_FILE);

    }

    class tokenizer_tester : public tester
    {
    public:
        tokenizer_tester (
        ) :
            tester ("test_tokenizer",
                    "Runs tests on the tokenizer component.")
        {}

        void perform_test (
        )
        {
            dlog << LINFO << "testing kernel_1a";
            tokenizer_kernel_test<tokenizer::kernel_1a>  ();
            dlog << LINFO << "testing kernel_1a_c";
            tokenizer_kernel_test<tokenizer::kernel_1a_c>();
        }
    } a;

}

ext: cpp


text:
/*  Sirikata Transfer -- Content Distribution Network
 *  CachedServiceLookup.hpp
 *
 *  Copyright (c) 2009, Patrick Reiter Horn
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*  Created on: Feb 8, 2009 */

#ifndef SIRIKATA_CachedServiceLookup_HPP__
#define SIRIKATA_CachedServiceLookup_HPP__

#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>
#include "ServiceLookup.hpp"

namespace Sirikata {
namespace Transfer {

/** A ServiceLookup that keeps a local cache. This cache might not be
 * written to disk--it makes more sense to be in the options system.
 *
 * Currently, you can use addToCache to fill the cache.
 */
class CachedServiceLookup : public ServiceLookup {
	typedef std::map<URIContext, ListOfServicesPtr> ServiceMap;
	ServiceMap mLookupCache;
	boost::shared_mutex mMut;

public:
	virtual void addToCache(const URIContext &origService, const ListOfServicesPtr &toCache) {
		{
			boost::unique_lock<boost::shared_mutex> insertlock(mMut);
			mLookupCache.insert(ServiceMap::value_type(origService, toCache));
		}
		ServiceLookup::addToCache(origService, toCache);
	}

	virtual void lookupService(const URIContext &context, const Callback &cb) {
		ListOfServicesPtr found;
		{
			boost::shared_lock<boost::shared_mutex> lookuplock(mMut);
			ServiceMap::const_iterator iter = mLookupCache.find(context);
			if (iter != mLookupCache.end()) {
				found = (*iter).second;
			}
		}
		if (found) {
			cb(found);
		} else {
			ServiceLookup::lookupService(context, cb);
		}
	}
};

}
}

#endif /* SIRIKATA_CachedServiceLookup_HPP__ */

max_stars_repo_name: ericruth/sirikata

max_issues_repo_name: mullwaden/sirikata

max_forks_repo_name: mullwaden/sirikata


text:
#if defined(COMPILER_DIAGNOSTICS)
#include "compiler_diagnostics.hpp"
#endif

#if defined(BOOST_SUPPORT)
#include <boost/type_index.hpp>
#endif

#include <vector>
#include <iostream>

template<typename T>
void f(const T& param) {
#if defined(COMPILER_DIAGNOSTICS)
    TD<decltype(param)> t;
#endif

    std::cout << "-- reports by std:" << std::endl;
    std::cout << "typeid(T).name(): " << typeid(T).name() << std::endl;
    std::cout << "typeid(decltype(param)).name(): " << typeid(decltype(param)).name() << std::endl;
    std::cout << "std::is_const<T>(): " << std::is_const<T>()
        << ", std::is_reference<T>(): " << std::is_reference<T>() << std::endl;
    std::cout << "std::is_const<decltype(param)>(): " << std::is_const<decltype(param)>()
        << ", std::is_reference<decltype(param)>(): " << std::is_reference<decltype(param)>() << std::endl;
    std::cout << std::endl;

#if defined(BOOST_SUPPORT)
    std::cout << "-- reports by boost::type_index:" << std::endl;
    std::cout << "boost::typeindex::type_id_with_cvr<T>().pretty_name(): "
        << boost::typeindex::type_id_with_cvr<T>().pretty_name() << std::endl;
    std::cout << "boost::typeindex::type_id_with_cvr<decltype(param)>().pretty_name(): "
        << boost::typeindex::type_id_with_cvr<decltype(param)>().pretty_name() << std::endl;
#endif
}


text:
// dbshell.cpp

#include <stdio.h>

#ifdef USE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#include <setjmp.h>
jmp_buf jbuf;
#endif

#include "../scripting/engine.h"
#include "../client/dbclient.h"
#include "../util/unittest.h"
#include "utils.h"

using namespace std;
using namespace boost::filesystem;

extern const char * jsconcatcode;

string historyFile;
bool gotInterrupted = 0;
bool inMultiLine = 0;

#if defined(USE_READLINE) && !defined(__freebsd__) && !defined(_WIN32)
#define CTRLC_HANDLE
#endif

void shellHistoryInit(){
#ifdef USE_READLINE
    stringstream ss;
    char * h = getenv( "HOME" );
    if ( h )
        ss << h << "/";
    ss << ".dbshell";
    historyFile = ss.str();

    using_history();
    read_history( historyFile.c_str() );

#else
    cout << "type \"exit\" to exit" << endl;
#endif
}
void shellHistoryDone(){
#ifdef USE_READLINE
    write_history( historyFile.c_str() );
#endif
}
void shellHistoryAdd( const char * line ){
    if ( strlen(line) == 0 )
        return;
#ifdef USE_READLINE
    add_history( line );
#endif
}

void intr( int sig ){
#ifdef CTRLC_HANDLE
    longjmp( jbuf , 1 );
#endif
}

#if !defined(_WIN32)
void quitNicely( int sig ){
    if ( sig == SIGINT && inMultiLine ){
        gotInterrupted = 1;
        return;
    }
    if ( sig == SIGPIPE )
        mongo::rawOut( "mongo got signal SIGPIPE\n" );
    shellHistoryDone();
    exit(0);
}
#endif

char * shellReadline( const char * prompt , int handlesigint = 0 ){
#ifdef USE_READLINE

#ifdef CTRLC_HANDLE
    if ( ! handlesigint )
        return readline( prompt );
    if ( setjmp( jbuf ) ){
        gotInterrupted = 1;
        sigrelse(SIGINT);
        signal( SIGINT , quitNicely );
        return 0;
    }
    signal( SIGINT , intr );
#endif

    char * ret = readline( prompt );
    signal( SIGINT , quitNicely );
    return ret;
#else
    printf( prompt );
    char * buf = new char[1024];
    char * l = fgets( buf , 1024 , stdin );
    int len = strlen( buf );
    buf[len-1] = 0;
    return l;
#endif
}

#if !defined(_WIN32)
#include <string.h>

void quitAbruptly( int sig ) {
    ostringstream ossSig;
    ossSig << "mongo got signal " << sig << " (" << strsignal( sig ) << "), stack trace: " << endl;
    mongo::rawOut( ossSig.str() );

    ostringstream ossBt;
    mongo::printStackTrace( ossBt );
    mongo::rawOut( ossBt.str() );

    mongo::shellUtils::KillMongoProgramInstances();
    exit(14);
}

void setupSignals() {
    signal( SIGINT , quitNicely );
    signal( SIGTERM , quitNicely );
    signal( SIGPIPE , quitNicely ); // Maybe just log and continue?
    signal( SIGABRT , quitAbruptly );
    signal( SIGSEGV , quitAbruptly );
    signal( SIGBUS , quitAbruptly );
    signal( SIGFPE , quitAbruptly );
}
#else
inline void setupSignals() {}
#endif

string fixHost( string url , string host , string port ){
    //cout << "fixHost url: " << url << " host: " << host << " port: " << port << endl;

    if ( host.size() == 0 && port.size() == 0 ){
        if ( url.find( "/" ) == string::npos ){
            // check for ips
            if ( url.find( "." ) != string::npos )
                return url + "/test";

            if ( url.find( ":" ) != string::npos &&
                 isdigit( url[url.find(":")+1] ) )
                return url + "/test";
        }
        return url;
    }

    if ( url.find( "/" ) != string::npos ){
        cerr << "url can't have host or port if you specify them individually" << endl;
        exit(-1);
    }

    if ( host.size() == 0 )
        host = "127.0.0.1";

    string newurl = host;
    if ( port.size() > 0 )
        newurl += ":" + port;

    newurl += "/" + url;

    return newurl;
}

bool isBalanced( string code ){
    int brackets = 0;
    int parens = 0;

    for ( size_t i=0; i<code.size(); i++ ){
        switch( code[i] ){
        case '/':
            if ( i+1 < code.size() && code[i+1] == '/' ){
                while ( i<code.size() && code[i] != '\n' )
                    i++;
            }
            continue;
        case '{': brackets++; break;
        case '}': brackets--; break;
        case '(': parens++; break;
        case ')': parens--; break;
        case '"':
            i++;
            while ( i < code.size() && code[i] != '"' ) i++;
            break;
        case '\'':
            i++;
            while ( i < code.size() && code[i] != '\'' ) i++;
            break;
        }
    }

    return brackets == 0 && parens == 0;
}

using mongo::asserted;

struct BalancedTest : public mongo::UnitTest {
public:
    void run(){
        assert( isBalanced( "x = 5" ) );
        assert( isBalanced( "function(){}" ) );
        assert( isBalanced( "function(){\n}" ) );
        assert( ! isBalanced( "function(){" ) );
        assert( isBalanced( "x = \"{\";" ) );
        assert( isBalanced( "// {" ) );
        assert( ! isBalanced( "// \n {" ) );
        assert( ! isBalanced( "\"//\" {" ) );

    }
} balnaced_test;

string finishCode( string code ){
    while ( ! isBalanced( code ) ){
        inMultiLine = 1;
        code += "\n";
        char * line = shellReadline("... " , 1 );
        if ( gotInterrupted )
            return "";
        if ( ! line )
            return "";
        code += line;
    }
    return code;
}

#include <boost/program_options.hpp>
namespace po = boost::program_options;

void show_help_text(const char* name, po::options_description options) {
    cout << "MongoDB shell version: " << mongo::versionString << endl;
    cout << "usage: " << name << " [options] [db address] [file names (ending in .js)]" << endl
         << "db address can be:" << endl
         << "  foo                   foo database on local machine" << endl
         << "  192.169.0.5/foo       foo database on 192.168.0.5 machine" << endl
         << "  192.169.0.5:9999/foo  foo database on 192.168.0.5 machine on port 9999" << endl
         << options << endl
         << "file names: a list of files to run. files have to end in .js and will exit after "
         << "unless --shell is specified" << endl;
};

bool fileExists( string file ){
    try {
        path p(file);
        return boost::filesystem::exists( file );
    }
    catch (...){
        return false;
    }
}

int _main(int argc, char* argv[]) {
    setupSignals();

    mongo::shellUtils::RecordMyLocation( argv[ 0 ] );

    mongo::ScriptEngine::setup();
    auto_ptr< mongo::Scope > scope( mongo::globalScriptEngine->createScope() );

    string url = "test";
    string dbhost;
    string port;
    vector<string> files;

    string username;
    string password;

    bool runShell = false;
    bool nodb = false;

    string script;

    po::options_description shell_options("options");
    po::options_description hidden_options("Hidden options");
    po::options_description cmdline_options("Command line options");
    po::positional_options_description positional_options;

    shell_options.add_options()
        ("shell", "run the shell after executing files")
        ("nodb", "don't connect to mongod on startup - no 'db address' arg expected")
        ("port", po::value<string>(&port), "port to connect to")
        ("host", po::value<string>(&dbhost), "server to connect to")
        ("eval", po::value<string>(&script), "evaluate javascript")
        ("username,u", po::value<string>(&username), "username for authentication")
        ("password,p", po::value<string>(&password), "password for authentication")
        ("help,h", "show this usage information")
        ("version", "show version information")
        ;

    hidden_options.add_options()
        ("dbaddress", po::value<string>(), "dbaddress")
        ("files", po::value< vector<string> >(), "files")
        ;

    positional_options.add("dbaddress", 1);
    positional_options.add("files", -1);

    cmdline_options.add(shell_options).add(hidden_options);

    po::variables_map params;

    /* using the same style as db.cpp uses because eventually we're going
     * to merge some of this stuff. */
    int command_line_style = (((po::command_line_style::unix_style ^
                                po::command_line_style::allow_guessing) |
                               po::command_line_style::allow_long_disguise) ^
                              po::command_line_style::allow_sticky);

    try {
        po::store(po::command_line_parser(argc, argv).options(cmdline_options).
                  positional(positional_options).
                  style(command_line_style).run(), params);
        po::notify(params);
    } catch (po::error &e) {
        cout << "ERROR: " << e.what() << endl << endl;
        show_help_text(argv[0], shell_options);
        return mongo::EXIT_BADOPTIONS;
    }

    if (params.count("shell")) {
        runShell = true;
    }
    if (params.count("nodb")) {
        nodb = true;
    }
    if (params.count("help")) {
        show_help_text(argv[0], shell_options);
        return mongo::EXIT_CLEAN;
    }
    if (params.count("files")) {
        files = params["files"].as< vector<string> >();
    }
    if (params.count("version")) {
        cout << "MongoDB shell version: " << mongo::versionString << endl;
        return mongo::EXIT_CLEAN;
    }

    /* This is a bit confusing, here are the rules:
     *
     * if nodb is set then all positional parameters are files
     * otherwise the first positional parameter might be a dbaddress, but
     * only if one of these conditions is met:
     *   - it contains no '.' after the last appearance of '\' or '/'
     *   - it doesn't end in '.js' and it doesn't specify a path to an existing file */
    if (params.count("dbaddress")) {
        string dbaddress = params["dbaddress"].as<string>();
        if (nodb) {
            files.insert(files.begin(), dbaddress);
        } else {
            string basename = dbaddress.substr(dbaddress.find_last_of("/\\") + 1);
            if (basename.find_first_of('.') == string::npos ||
                (basename.find(".js", basename.size() - 3) == string::npos && !fileExists(dbaddress))) {
                url = dbaddress;
            } else {
                files.insert(files.begin(), dbaddress);
            }
        }
    }

    scope->externalSetup();
    mongo::shellUtils::installShellUtils( *scope );

    cout << "MongoDB shell version: " << mongo::versionString << endl;

    mongo::UnitTest::runTests();

    if ( !nodb ) { // connect to db
        cout << "url: " << url << endl;
        string setup = (string)"db = connect( \"" + fixHost( url , dbhost , port ) + "\")";
        if ( ! scope->exec( setup , "(connect)" , false , true , false ) )
            return -1;

        if ( username.size() && password.size() ){
            stringstream ss;
            ss << "if ( ! db.auth( \"" << username << "\" , \"" << password << "\" ) ){ throw 'login failed'; }";

            if ( ! scope->exec( ss.str() , "(auth)" , true , true , false ) ){
                cout << "login failed" << endl;
                return -1;
            }

        }

    }

    if ( !script.empty() ) {
        mongo::shellUtils::MongoProgramScope s;
        if ( ! scope->exec( script , "(shell eval)" , true , true , false ) )
            return -4;
    }

    for (size_t i = 0; i < files.size(); i++) {
        mongo::shellUtils::MongoProgramScope s;

        if ( files.size() > 1 )
            cout << "loading file: " << files[i] << endl;

        if ( ! scope->execFile( files[i] , false , true , false ) ){
            cout << "failed to load: " << files[i] << endl;
            return -3;
        }
    }

    if ( files.size() == 0 && script.empty() ) {
        runShell = true;
    }

    if ( runShell ){

        mongo::shellUtils::MongoProgramScope s;

        shellHistoryInit();

        cout << "type \"help\" for help" << endl;

        //v8::Handle<v8::Object> shellHelper = baseContext_->Global()->Get( v8::String::New( "shellHelper" ) )->ToObject();

        while ( 1 ){
            inMultiLine = 0;
            gotInterrupted = 0;
            char * line = shellReadline( "> " );

            if ( line )
                while ( line[0] == ' ' )
                    line++;

            if ( ! line || ( strlen(line) == 4 && strstr( line , "exit" ) ) ){
                cout << "bye" << endl;
                break;
            }

            string code = line;
            if ( code == "exit" ){
                break;
            }
            if ( code.size() == 0 )
                continue;

            code = finishCode( code );
            if ( gotInterrupted ){
                cout << endl;
                continue;
            }

            if ( code.size() == 0 )
                break;

            bool wascmd = false;
            {
                string cmd = line;
                if ( cmd.find( " " ) > 0 )
                    cmd = cmd.substr( 0 , cmd.find( " " ) );

                if ( cmd.find( "\"" ) == string::npos ){
                    scope->exec( (string)"__iscmd__ = shellHelper[\"" + cmd + "\"];" , "(shellhelp1)" , false , true , true );
                    if ( scope->getBoolean( "__iscmd__" )  ){
                        scope->exec( (string)"shellHelper( \"" + cmd + "\" , \"" + code.substr( cmd.size() ) + "\");" , "(shellhelp2)" , false , true , false );
                        wascmd = true;
                    }
                }

            }

            if ( ! wascmd ){
                try {
                    scope->exec( code.c_str() , "(shell)" , false , true , false );
                    scope->exec( "shellPrintHelper( __lastres__ );" , "(shell2)" , true , true , false );
                }
                catch ( std::exception& e ){
                    cout << "error:" << e.what() << endl;
                }
            }

            shellHistoryAdd( line );
        }

        shellHistoryDone();
    }

    return 0;
}

int main(int argc, char* argv[]) {
    try {
        return _main( argc , argv );
    }
    catch ( mongo::DBException& e ){
        cerr << "exception: " << e.what() << endl;
        return -1;
    }
}

namespace mongo {
    DBClientBase * createDirectClient(){
        uassert( "no createDirectClient in shell" , 0 );
        return 0;
    }
}

max_stars_repo_name: banker/mongulator

max_issues_repo_name: zoras/mongulator

max_forks_repo_name: zoras/mongulator


text:
/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_PNG_IO_HPP
#define MAPNIK_PNG_IO_HPP

// mapnik
#include <mapnik/palette.hpp>
#include <mapnik/octree.hpp>
#include <mapnik/hextree.hpp>
#include <mapnik/miniz_png.hpp>
#include <mapnik/image_data.hpp>

// zlib
#include <zlib.h>  // for Z_DEFAULT_COMPRESSION

// boost
#include <boost/scoped_array.hpp>

// stl
#include <cassert>

extern "C"
{
#include <png.h>
}

#define MAX_OCTREE_LEVELS 4

namespace mapnik {

template <typename T>
void write_data (png_structp png_ptr, png_bytep data, png_size_t length)
{
    T * out = static_cast<T*>(png_get_io_ptr(png_ptr));
    out->write(reinterpret_cast<char*>(data), length);
}

template <typename T>
void flush_data (png_structp png_ptr)
{
    T * out = static_cast<T*>(png_get_io_ptr(png_ptr));
    out->flush();
}

template <typename T1, typename T2>
void save_as_png(T1 & file,
                T2 const& image,
                int compression = Z_DEFAULT_COMPRESSION,
                int strategy = Z_DEFAULT_STRATEGY,
                int trans_mode = -1,
                bool use_miniz = false)

{
    if (use_miniz)
    {
        MiniZ::PNGWriter writer(compression,strategy);
        if (trans_mode == 0)
        {
            writer.writeIHDR(image.width(), image.height(), 24);
            writer.writeIDATStripAlpha(image);
        }
        else
        {
            writer.writeIHDR(image.width(), image.height(), 32);
            writer.writeIDAT(image);
        }
        writer.writeIEND();
        writer.toStream(file);
        return;
    }

    png_voidp error_ptr=0;
    png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                error_ptr,0, 0);

    if (!png_ptr) return;

    // switch on optimization only if supported
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
    png_uint_32 mask, flags;
    flags = png_get_asm_flags(png_ptr);
    mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
    png_set_asm_flags(png_ptr, flags | mask);
#endif
    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_write_struct(&png_ptr,(png_infopp)0);
        return;
    }
    jmp_buf* jmp_context = (jmp_buf*) png_get_error_ptr(png_ptr);
    if (jmp_context)
    {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return;
    }
    png_set_write_fn (png_ptr, &file, &write_data<T1>, &flush_data<T1>);

    png_set_compression_level(png_ptr, compression);
    png_set_compression_strategy(png_ptr, strategy);
    png_set_compression_buffer_size(png_ptr, 32768);

    png_set_IHDR(png_ptr, info_ptr,image.width(),image.height(),8,
                 (trans_mode == 0) ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
    boost::scoped_array<png_byte*> row_pointers(new png_bytep[image.height()]);
    for (unsigned int i = 0; i < image.height(); i++)
    {
        row_pointers[i] = (png_bytep)image.getRow(i);
    }
    png_set_rows(png_ptr, info_ptr, row_pointers.get());
    png_write_png(png_ptr, info_ptr, (trans_mode == 0) ? PNG_TRANSFORM_STRIP_FILLER_AFTER : PNG_TRANSFORM_IDENTITY, NULL);
    png_destroy_write_struct(&png_ptr, &info_ptr);
}

template <typename T>
void reduce_8(T const& in,
              image_data_8 & out,
              octree<rgb> trees[],
              unsigned limits[],
              unsigned levels,
              std::vector<unsigned> & alpha)
{
    unsigned width = in.width();
    unsigned height = in.height();

    std::vector<unsigned> alphaCount(alpha.size());
    for(unsigned i=0; i<alpha.size(); i++)
    {
        alpha[i] = 0;
        alphaCount[i] = 0;
    }
    for (unsigned y = 0; y < height; ++y)
    {
        mapnik::image_data_32::pixel_type const * row = in.getRow(y);
        mapnik::image_data_8::pixel_type  * row_out = out.getRow(y);
        for (unsigned x = 0; x < width; ++x)
        {
            unsigned val = row[x];
            byte index = 0;
            int idx = -1;
            for(int j=levels-1; j>0; j--)
            {
                if (U2ALPHA(val)>=limits[j] && trees[j].colors()>0)
                {
                    index = idx = trees[j].quantize(val);
                    break;
                }
            }
            if (idx>=0 && idx<(int)alpha.size())
            {
                alpha[idx]+=U2ALPHA(val);
                alphaCount[idx]++;
            }
            row_out[x] = index;
        }
    }
    for(unsigned i=0; i<alpha.size(); i++)
    {
        if (alphaCount[i]!=0)
        {
            alpha[i] /= alphaCount[i];
        }
    }
}

template <typename T>
void reduce_4(T const& in,
               image_data_8 & out,
               octree<rgb> trees[],
               unsigned limits[],
               unsigned levels,
               std::vector<unsigned> & alpha)
{
    unsigned width = in.width();
    unsigned height = in.height();

    std::vector<unsigned> alphaCount(alpha.size());
    for(unsigned i=0; i<alpha.size(); i++)
    {
        alpha[i] = 0;
        alphaCount[i] = 0;
    }
    for (unsigned y = 0; y < height; ++y)
    {
        mapnik::image_data_32::pixel_type const * row = in.getRow(y);
        mapnik::image_data_8::pixel_type  * row_out = out.getRow(y);
        for (unsigned x = 0; x < width; ++x)
        {
            unsigned val = row[x];
            byte index = 0;
            int idx=-1;
            for(int j=levels-1; j>0; j--)
            {
                if (U2ALPHA(val)>=limits[j] && trees[j].colors()>0)
                {
                    index = idx = trees[j].quantize(val);
                    break;
                }
            }
            if (idx>=0 && idx<(int)alpha.size())
            {
                alpha[idx]+=U2ALPHA(val);
                alphaCount[idx]++;
            }
            if (x%2 == 0)
            {
                index = index<<4;
            }
            row_out[x>>1] |= index;
        }
    }
    for(unsigned i=0; i<alpha.size(); i++)
    {
        if (alphaCount[i]!=0)
        {
            alpha[i] /= alphaCount[i];
        }
    }
}

// 1-bit but only one color.
template <typename T>
void reduce_1(T const&,
              image_data_8 & out,
              octree<rgb> /*trees*/[],
              unsigned /*limits*/[],
              std::vector<unsigned> & /*alpha*/)
{
    out.set(0); // only one color!!!
}

template <typename T>
void save_as_png(T & file, std::vector<mapnik::rgb> const& palette,
                 mapnik::image_data_8 const& image,
                 unsigned width,
                 unsigned height,
                 unsigned color_depth,
                 int compression,
                 int strategy,
                 std::vector<unsigned> const&alpha,
                 bool use_miniz)
{
    if (use_miniz)
    {
        MiniZ::PNGWriter writer(compression,strategy);
        // image.width()/height() does not reflect the actual image dimensions; it
        // refers to the quantized scanlines.
        writer.writeIHDR(width, height, color_depth);
        writer.writePLTE(palette);
        writer.writetRNS(alpha);
        writer.writeIDAT(image);
        writer.writeIEND();
        writer.toStream(file);
        return;
    }

    png_voidp error_ptr=0;
    png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                error_ptr,0, 0);

    if (!png_ptr)
    {
        return;
    }

    // switch on optimization only if supported
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
    png_uint_32 mask, flags;
    flags = png_get_asm_flags(png_ptr);
    mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
    png_set_asm_flags(png_ptr, flags | mask);
#endif
    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_write_struct(&png_ptr,(png_infopp)0);
        return;
    }
    jmp_buf* jmp_context = (jmp_buf*) png_get_error_ptr(png_ptr);
    if (jmp_context)
    {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return;
    }
    png_set_write_fn (png_ptr, &file, &write_data<T>, &flush_data<T>);

    png_set_compression_level(png_ptr, compression);
    png_set_compression_strategy(png_ptr, strategy);
    png_set_compression_buffer_size(png_ptr, 32768);

    png_set_IHDR(png_ptr, info_ptr,width,height,color_depth,
                 PNG_COLOR_TYPE_PALETTE,PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);

    png_color* pal = const_cast<png_color*>(reinterpret_cast<const png_color*>(&palette[0]));
    png_set_PLTE(png_ptr, info_ptr, pal, palette.size());

    // make transparent lowest indexes, so tRNS is small
    if (alpha.size()>0)
    {
        std::vector<png_byte> trans(alpha.size());
        unsigned alphaSize=0;//truncate to nonopaque values
        for(unsigned i=0; i < alpha.size(); i++)
        {
            trans[i]=alpha[i];
            if (alpha[i]<255)
            {
                alphaSize = i+1;
            }
        }
        if (alphaSize>0)
        {
            png_set_tRNS(png_ptr, info_ptr, (png_bytep)&trans[0], alphaSize, 0);
        }
    }

    png_write_info(png_ptr, info_ptr);
    for (unsigned i=0;i<height;i++)
    {
        png_write_row(png_ptr,(png_bytep)image.getRow(i));
    }

    png_write_end(png_ptr, info_ptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);
}

template <typename T1,typename T2>
void save_as_png8_oct(T1 & file,
                      T2 const& image,
                      const unsigned max_colors = 256,
                      int compression = Z_DEFAULT_COMPRESSION,
                      int strategy = Z_DEFAULT_STRATEGY,
                      int trans_mode = -1,
                      bool use_miniz = false)
{
    // number of alpha ranges in png8 format; 2 results in smallest image with binary transparency
    // 3 is minimum for semitransparency, 4 is recommended, anything else is worse
    const unsigned TRANSPARENCY_LEVELS = (trans_mode==2||trans_mode<0)?MAX_OCTREE_LEVELS:2;
    unsigned width = image.width();
    unsigned height = image.height();
    unsigned alphaHist[256];//transparency histogram
    unsigned semiCount = 0;//sum of semitransparent pixels
    unsigned meanAlpha = 0;

    if (trans_mode == 0)
    {
        meanAlpha = 255;
    }
    else
    {
        for(int i=0; i<256; i++)
        {
            alphaHist[i] = 0;
        }
        for (unsigned y = 0; y < height; ++y)
        {
            for (unsigned x = 0; x < width; ++x)
            {
                unsigned val = U2ALPHA((unsigned)image.getRow(y)[x]);
                alphaHist[val]++;
                meanAlpha += val;
                if (val>0 && val<255)
                {
                    semiCount++;
                }
            }
        }
        meanAlpha /= width*height;
    }

    // transparency ranges division points
    unsigned limits[MAX_OCTREE_LEVELS+1];
    limits[0] = 0;
    limits[1] = (trans_mode!=0 && alphaHist[0]>0)?1:0;
    limits[TRANSPARENCY_LEVELS] = 256;
    for(unsigned j=2; j<TRANSPARENCY_LEVELS; j++)
    {
        limits[j] = limits[1];
    }
    if (trans_mode != 0)
    {
        unsigned alphaHistSum = 0;
        for(unsigned i=1; i<256; i++)
        {
            alphaHistSum += alphaHist[i];
            for(unsigned j=1; j<TRANSPARENCY_LEVELS; j++)
            {
                if (alphaHistSum<semiCount*(j)/4)
                {
                    limits[j] = i;
                }
            }
        }
    }
    // avoid too wide full transparent range
    if (limits[1]>256/(TRANSPARENCY_LEVELS-1))
    {
        limits[1]=256/(TRANSPARENCY_LEVELS-1);
    }
    // avoid too wide full opaque range
    if (limits[TRANSPARENCY_LEVELS-1]<212)
    {
        limits[TRANSPARENCY_LEVELS-1]=212;
    }
    if (TRANSPARENCY_LEVELS==2)
    {
        limits[1]=127;
    }
    // estimated number of colors from palette assigned to chosen ranges
    unsigned cols[MAX_OCTREE_LEVELS];
    // count colors
    if (trans_mode == 0)
    {
        for (unsigned j=0; j<TRANSPARENCY_LEVELS; j++)
        {
            cols[j] = 0;
        }
        cols[TRANSPARENCY_LEVELS-1] = width * height;
    }
    else
    {
        for (unsigned j=0; j<TRANSPARENCY_LEVELS; j++)
        {
            cols[j] = 0;
            for (unsigned i=limits[j]; i<limits[j+1]; i++)
            {
                cols[j] += alphaHist[i];
            }
        }
    }

    unsigned divCoef = width*height-cols[0];
    if (divCoef==0)
    {
        divCoef = 1;
    }
    cols[0] = cols[0]>0?1:0; // fully transparent color (one or not at all)

    if (max_colors>=64)
    {
        // give chance less populated but not empty cols to have at least few colors(12)
        unsigned minCols = (12+1)*divCoef/(max_colors-cols[0]);
        for(unsigned j=1; j<TRANSPARENCY_LEVELS; j++)
        {
            if (cols[j]>12 && cols[j]<minCols)
            {
                divCoef += minCols-cols[j];
                cols[j] = minCols;
            }
        }
    }
    unsigned usedColors = cols[0];
    for(unsigned j=1; j<TRANSPARENCY_LEVELS-1; j++)
    {
        cols[j] = cols[j]*(max_colors-cols[0])/divCoef;
        usedColors += cols[j];
    }
    // use rest for most opaque group of pixels
    cols[TRANSPARENCY_LEVELS-1] = max_colors-usedColors;

    //no transparency
    if (trans_mode == 0)
    {
        limits[1] = 0;
        cols[0] = 0;
        cols[1] = max_colors;
    }

    // octree table for separate alpha range with 1-based index (0 is fully transparent: no color)
    octree<rgb> trees[MAX_OCTREE_LEVELS];
    for(unsigned j=1; j<TRANSPARENCY_LEVELS; j++)
    {
        trees[j].setMaxColors(cols[j]);
    }
    for (unsigned y = 0; y < height; ++y)
    {
        typename T2::pixel_type const * row = image.getRow(y);
        for (unsigned x = 0; x < width; ++x)
        {
            unsigned val = row[x];
            // insert to proper tree based on alpha range
            for(unsigned j=TRANSPARENCY_LEVELS-1; j>0; j--)
            {
                if (cols[j]>0 && U2ALPHA(val)>=limits[j])
                {
                    trees[j].insert(mapnik::rgb(U2RED(val), U2GREEN(val), U2BLUE(val)));
                    break;
                }
            }
        }
    }
    unsigned leftovers = 0;
    std::vector<rgb> palette;
    palette.reserve(max_colors);
    if (cols[0])
    {
        palette.push_back(rgb(0,0,0));
    }

    for(unsigned j=1; j<TRANSPARENCY_LEVELS; j++)
    {
        if (cols[j]>0)
        {
            if (leftovers>0)
            {
                cols[j] += leftovers;
                trees[j].setMaxColors(cols[j]);
                leftovers = 0;
            }
            std::vector<rgb> pal;
            trees[j].setOffset(palette.size());
            trees[j].create_palette(pal);
            assert(pal.size() <= max_colors);
            leftovers = cols[j]-pal.size();
            cols[j] = pal.size();
            for(unsigned i=0; i<pal.size(); i++)
            {
                palette.push_back(pal[i]);
            }
            assert(palette.size() <= 256);
        }
    }

    //transparency values per palette index
    std::vector<unsigned> alphaTable;
    //alphaTable.resize(palette.size());//allow semitransparency also in almost opaque range
    if (trans_mode != 0)
    {
        alphaTable.resize(palette.size() - cols[TRANSPARENCY_LEVELS-1]);
    }

    if (palette.size() > 16 )
    {
        // >16 && <=256 colors -> write 8-bit color depth
        image_data_8 reduced_image(width,height);
        reduce_8(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable);
        save_as_png(file,palette,reduced_image,width,height,8,compression,strategy,alphaTable,use_miniz);
    }
    else if (palette.size() == 1)
    {
        // 1 color image ->  write 1-bit color depth PNG
        unsigned image_width  = ((width + 15) >> 3) & ~1U; // 1-bit image, round up to 16-bit boundary
        unsigned image_height = height;
        image_data_8 reduced_image(image_width,image_height);
        reduce_1(image,reduced_image,trees, limits, alphaTable);
        if (meanAlpha<255 && cols[0]==0)
        {
            alphaTable.resize(1);
            alphaTable[0] = meanAlpha;
        }
        save_as_png(file,palette,reduced_image,width,height,1,compression,strategy,alphaTable,use_miniz);
    }
    else
    {
        // <=16 colors -> write 4-bit color depth PNG
        unsigned image_width  = ((width + 7) >> 1) & ~3U; // 4-bit image, round up to 32-bit boundary
        unsigned image_height = height;
        image_data_8 reduced_image(image_width,image_height);
        reduce_4(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable);
        save_as_png(file,palette,reduced_image,width,height,4,compression,strategy,alphaTable,use_miniz);
    }
}

template <typename T1, typename T2, typename T3>
void save_as_png8(T1 & file,
                  T2 const& image,
                  T3 const & tree,
                  std::vector<mapnik::rgb> const& palette,
                  std::vector<unsigned> const& alphaTable,
                  int compression = Z_DEFAULT_COMPRESSION,
                  int strategy = Z_DEFAULT_STRATEGY,
                  bool use_miniz = false)
{
    unsigned width = image.width();
    unsigned height = image.height();

    if (palette.size() > 16 )
    {
        // >16 && <=256 colors -> write 8-bit color depth
        image_data_8 reduced_image(width, height);
        for (unsigned y = 0; y < height; ++y)
        {
            mapnik::image_data_32::pixel_type const * row = image.getRow(y);
            mapnik::image_data_8::pixel_type  * row_out = reduced_image.getRow(y);
            for (unsigned x = 0; x < width; ++x)
            {
                row_out[x] = tree.quantize(row[x]);
            }
        }
        save_as_png(file, palette, reduced_image, width, height, 8, compression, strategy, alphaTable, use_miniz);
    }
    else if (palette.size() == 1)
    {
        // 1 color image ->  write 1-bit color depth PNG
        unsigned image_width  = ((width + 15) >> 3) & ~1U; // 1-bit image, round up to 16-bit boundary
        unsigned image_height = height;
        image_data_8 reduced_image(image_width, image_height);
        reduced_image.set(0);
        save_as_png(file, palette, reduced_image, width, height, 1, compression, strategy, alphaTable, use_miniz);
    }
    else
    {
        // <=16 colors -> write 4-bit color depth PNG
        unsigned image_width  = ((width + 7) >> 1) & ~3U; // 4-bit image, round up to 32-bit boundary
        unsigned image_height = height;
        image_data_8 reduced_image(image_width, image_height);
        for (unsigned y = 0; y < height; ++y)
        {
            mapnik::image_data_32::pixel_type const * row = image.getRow(y);
            mapnik::image_data_8::pixel_type  * row_out = reduced_image.getRow(y);
            byte index = 0;
            for (unsigned x = 0; x < width; ++x)
            {

                index = tree.quantize(row[x]);
                if (x%2 == 0)
                {
                    index = index<<4;
                }
                row_out[x>>1] |= index;
            }
        }
        save_as_png(file, palette, reduced_image, width, height, 4, compression, strategy, alphaTable, use_miniz);
    }
}

template <typename T1,typename T2>
void save_as_png8_hex(T1 & file,
                      T2 const& image,
                      int colors = 256,
                      int compression = Z_DEFAULT_COMPRESSION,
                      int strategy = Z_DEFAULT_STRATEGY,
                      int trans_mode = -1,
                      double gamma = 2.0,
                      bool use_miniz = false)
{
    unsigned width = image.width();
    unsigned height = image.height();

    // structure for color quantization
    hextree<mapnik::rgba> tree(colors);
    if (trans_mode >= 0)
    {
        tree.setTransMode(trans_mode);
    }
    if (gamma > 0)
    {
        tree.setGamma(gamma);
    }

    for (unsigned y = 0; y < height; ++y)
    {
        typename T2::pixel_type const * row = image.getRow(y);
        for (unsigned x = 0; x < width; ++x)
        {
            unsigned val = row[x];
            tree.insert(mapnik::rgba(U2RED(val), U2GREEN(val), U2BLUE(val), U2ALPHA(val)));
        }
    }

    //transparency values per palette index
    std::vector<mapnik::rgba> pal;
    tree.create_palette(pal);
    assert(int(pal.size()) <= colors);
    std::vector<mapnik::rgb> palette;
    std::vector<unsigned> alphaTable;
    for(unsigned i=0; i<pal.size(); i++)
    {
        palette.push_back(rgb(pal[i].r, pal[i].g, pal[i].b));
        alphaTable.push_back(pal[i].a);
    }

    save_as_png8<T1, T2, hextree<mapnik::rgba> >(file, image, tree, palette, alphaTable, compression, strategy, use_miniz);
}

template <typename T1, typename T2>
void save_as_png8_pal(T1 & file,
                      T2 const& image,
                      rgba_palette const& pal,
                      int compression = Z_DEFAULT_COMPRESSION,
                      int strategy = Z_DEFAULT_STRATEGY,
                      bool use_miniz = false)
{
    save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette(), pal.alphaTable(), compression, strategy, use_miniz);
}

}

#endif // MAPNIK_PNG_IO_HPP

max_stars_repo_name: Wujingli/OpenWebGlobeDataProcessing

max_issues_repo_name: Wujingli/OpenWebGlobeDataProcessing

max_forks_repo_name: Wujingli/OpenWebGlobeDataProcessing


text:
#pragma once

#include <cstdint>
#include <Eigen/Dense>

/** @class RobotEstimator
 *  This class implements a Kalman Filter in order to estimate a robot's current state.
 *  The estimated state is then used in motion control to assign wheel velocities accordingly
 *
 *  Explanations:
 *  - https://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/
 *  - https://en.wikipedia.org/wiki/Kalman_filter
 *  - https://www.mathworks.com/videos/series/understanding-kalman-filters.html
 */
class RobotEstimator {
private:
    /**
     * Number of tracked states (number of states in state vector, x_hat)
     *
     * 3 Total:
     * - X and Y: linear velocities of robot body (m/s)
     * - W: angular velocity of robot body around z axis (rad/s)
     */
    static constexpr int numStates = 3;

    /**
     * Number of applied inputs (number of control inputs in control vector, u)
     *
     * 4 total:
     * - Motor duty cycle for each motor (% max), controls average applied voltage
     */
    static constexpr int numInputs = 4;

    /**
     * Number of tracked measurable outputs (number of outputs in output vector, y)
     *
     * 5 total:
     * - 4 wheel motor encoders (rad/s)
     * - Gyro angular velocity (rad/s)
     */
    static constexpr int numOutputs = 5;

public:
    /**
     * @param dt_us Expected period of the controller in us
     */
    RobotEstimator(uint32_t dt_us);

    /**
     * Using the previous state and the next input
     * We can guess where we are this time step
     *
     * @param u Last motor command
     */
    void predict(Eigen::Matrix<float, numInputs, 1> u);

    /**
     * Using the next measurements, we can move our prediction
     * closer to the true target
     *
     * @param z Encoders 1-4 then gyro
     */
    void update(Eigen::Matrix<float, numOutputs, 1> z);

    /**
     * @param state Matrix that the current guess will be saved into
     */
    void getState(Eigen::Matrix<float, numStates, 1>& state);

private:

    static constexpr float processNoise = 0.05;  /**< State noise from unmodeled influences (model errors/omissions) */
    static constexpr float encoderNoise = 0.04;  /**< Measurement noise in the encoder */
    static constexpr float gyroNoise = 0.005;    /**< Measurement noise in the gyro */
    static constexpr float initCovariance = 0.1; /**< The initial covariance value in each entry of `P` */

    /**
     * State Transition Matrix/Prediction Matrix
     *
     * Predict our next state based on our current state using dynamics
     */
    Eigen::Matrix<float, numStates,  numStates>  F;

    /**
     * Control Input Matrix
     *
     * Corrects our next state prediction by mapping control input (known influences, `u`) to our next state
     */
    Eigen::Matrix<float, numStates,  numInputs>  B;

    /**
     * Observation Matrix
     *
     * Predicts the measurements from our sensors (`z`) from our current state (`x_hat`).
     */
    Eigen::Matrix<float, numOutputs, numStates>  H;

    /**
     * Covariance Matrix for Process Noise
     *
     * A matrix whose entries are the estimated covariances between any two state variables.
     * Entries represent uncertainty in our state vector (`x_hat`) due to unmodeled influences.
     */
    Eigen::Matrix<float, numStates,  numStates>  Q;

    /**
     * Covariance Matrix for Observation Noise
     *
     * A matrix whose entries are the estimated covariances between any two state variables.
     * Entries represent uncertainty in our measurements (`z`) due to random noise
     */
    Eigen::Matrix<float, numOutputs, numOutputs> R;

    /**
     * Covariance Estimate Matrix
     *
     * A matrix whose entries are the estimated covariances between any two state variables.
     * Entries represent our overall uncertainty in our state vector (`x_hat`).
     */
    Eigen::Matrix<float, numStates,  numStates>  P;

    /**
     * Identity Matrix
     *
     * A square matrix with only 1s on the diagonals
     */
    Eigen::Matrix<float, numStates, numStates> I;

    /**
     * Current State Vector Estimate
     *
     * What the robot estimator believes our current state to be
     */
    Eigen::Matrix<float, numStates, 1> x_hat;
};

max_stars_repo_name: RRRekkitRalph/robocup-firmware

max_issues_repo_name: RRRekkitRalph/robocup-firmware

max_forks_repo_name: RRRekkitRalph/robocup-firmware