<commit_before>#include "Chemharp.hpp"
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/numpy.hpp>

namespace py = boost::python;
namespace np = boost::numpy;
using namespace harp;

void translate_Error(Error const& e) {
    auto err = std::string("Chemharp error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

void translate_FileError(FileError const& e) {
    auto err = std::string("Chemharp file error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

void translate_MemoryError(MemoryError const& e) {
    auto err = std::string("Chemharp memory error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

void translate_FormatError(FormatError const& e) {
    auto err = std::string("Chemharp format error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

// ResultConverterGenerator used to transform Array3D to numpy ndarray.
struct Array3D_convertor {
    template <class T> struct apply {
        struct type {
            // Convert Array3D to ndarray.
            PyObject* operator()(const Array3D& A) const {
                py::tuple shape = py::make_tuple(A.size(), 3);
                np::dtype dtype = np::dtype::get_builtin<float>();
                np::ndarray res = np::empty(shape, dtype);

                auto c_arr = reinterpret_cast<float (*)[3]>(res.get_data());
                for (size_t i=0; i<A.size(); i++)
                    for (size_t j=0; j<3; j++)
                        c_arr[i][j] = A[i][j];

                return py::incref(res.ptr());
            }

            // Used for documentation.
            const PyTypeObject* get_pytype() const { return 0; }
        };
    };
};

struct std_vector_convertor {
    template <class T> struct apply {
        struct type {
            // Convert any std::vector to python list.
            template <class S>
            PyObject* operator()(const std::vector<S>& A) const {
                py::list res;
                for (auto val : A)
                    res.append(val);
                return py::incref(res.ptr());
            }

            // Used for documentation.
            const PyTypeObject* get_pytype() const { return 0; }
        };
    };
};

void init_module(){
    // Removing this line will result in bad stuff appening, like segfaults and
    // your grand mother being kidnaped by aliens. So don't do this!
    np::initialize();
}

BOOST_PYTHON_MODULE(chemharp){
    init_module();

    /* Exception management ***************************************************/
    py::register_exception_translator<Error>(&translate_Error);
    py::register_exception_translator<FileError>(&translate_FileError);
    py::register_exception_translator<MemoryError>(&translate_MemoryError);
    py::register_exception_translator<FormatError>(&translate_FormatError);

    /* Trajectory class *******************************************************/
    py::class_<Trajectory, boost::noncopyable>("Trajectory",
            py::init<std::string, py::optional<std::string, std::string>>())
        .def("read_next_step", &Trajectory::read_next_step,
                                    py::return_internal_reference<1,
                                        py::with_custodian_and_ward_postcall<0, 1> >())
        .def("read_at_step", &Trajectory::read_at_step,
                                    py::return_internal_reference<1,
                                        py::with_custodian_and_ward_postcall<0, 1> >())
        .def("write_step", &Trajectory::write_step)
    ;

    /* Frame class ************************************************************/
    py::class_<Frame>("Frame")
        .def("positions",
            static_cast<const Array3D& (Frame::*)(void) const>(&Frame::positions),
            py::return_value_policy<Array3D_convertor>())
        .def("velocities",
            static_cast<const Array3D& (Frame::*)(void) const>(&Frame::velocities),
            py::return_value_policy<Array3D_convertor>())
        .add_property("has_velocities", &Frame::has_velocities)
        .def("__len__", &Frame::natoms)
        .add_property("natoms", &Frame::natoms)
        .add_property("topology",
            py::make_function(
                static_cast<const Topology& (Frame::*)(void) const>(&Frame::topology),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Frame::*)(const Topology&)>(&Frame::topology))
        .add_property("cell",
            py::make_function(
                static_cast<const UnitCell& (Frame::*)(void) const>(&Frame::cell),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Frame::*)(const UnitCell&)>(&Frame::cell))
        .add_property("step",
            static_cast<size_t (Frame::*)(void) const>(&Frame::step),
            static_cast<void (Frame::*)(size_t)>(&Frame::step))
    ;

    /* Atom class *************************************************************/
    py::scope atom_scope = py::class_<Atom>("Atom", py::init<std::string>())
        .add_property("name",
            py::make_function(
                static_cast<const std::string& (Atom::*)(void) const>(&Atom::name),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(const std::string&)>(&Atom::name))
        .add_property("mass",
            py::make_function(
                static_cast<const float& (Atom::*)(void) const>(&Atom::mass),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(float)>(&Atom::mass))
        .add_property("charge",
            py::make_function(
                static_cast<const float& (Atom::*)(void) const>(&Atom::charge),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(float)>(&Atom::charge))
        .add_property("type",
            py::make_function(
                static_cast<const Atom::AtomType& (Atom::*)(void) const>(&Atom::type),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(Atom::AtomType)>(&Atom::type))
    ;

    /* AtomType enum **********************************************************/
    py::enum_<Atom::AtomType>("AtomType")
        .value("ELEMENT", Atom::ELEMENT)
        .value("CORSE_GRAIN", Atom::CORSE_GRAIN)
        .value("DUMMY", Atom::DUMMY)
        .value("UNDEFINED", Atom::UNDEFINED)
    ;

    /* Topology class *********************************************************/
    py::class_<Topology>("Topology")
        .def("append", &Topology::append)
        .def("add_bond", &Topology::add_bond)
        .def("__len__", &Topology::natoms)
        .add_property("natoms", &Topology::natoms)
        .add_property("natom_types", &Topology::natom_types)
        .def("clear", &Topology::clear)
        .def("resize", &Topology::resize)
/*      TODO:
        operator[]
        void guess_bonds();
        vector<bond> bonds(void);
        vector<angle> angles(void);
        vector<dihedral> dihedrals(void);
        isbond,
        isangle,
        isdihedral,
        constuctor
*/
    ;

    /* UnitCell class *********************************************************/
    py::class_<UnitCell>("UnitCell", py::init<>())
        .def(py::init<double>())
        .def(py::init<double, double, double>())
        .def(py::init<double, double, double, double, double, double>())
        .def(py::init<UnitCell::CellType>())
        .def(py::init<UnitCell::CellType, double>())
        .def(py::init<UnitCell::CellType, double, double, double>())
        // TODO Matrix3D matricial() const;
        .add_property("type",
            py::make_function(
                static_cast<const UnitCell::CellType& (UnitCell::*)(void) const>(&UnitCell::type),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (UnitCell::*)(UnitCell::CellType)>(&UnitCell::type))
        .add_property("a",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::a),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::a))
        .add_property("b",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::b),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::b))
        .add_property("c",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::c),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::c))
        .add_property("alpha",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::alpha),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::alpha))
        .add_property("beta",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::beta),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::beta))
        .add_property("gamma",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::gamma),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::gamma))
        .add_property("periodic_x",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::periodic_x),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::periodic_x))
        .add_property("periodic_y",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::periodic_y),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::periodic_y))
        .add_property("periodic_z",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::periodic_z),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::periodic_z))
        .add_property("full_periodic",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::full_periodic),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::full_periodic))
    ;

    /* CellType enum **********************************************************/
    py::enum_<UnitCell::CellType>("CellType")
        .value("ORTHOROMBIC", UnitCell::ORTHOROMBIC)
        .value("TRICLINIC", UnitCell::TRICLINIC)
        .value("INFINITE", UnitCell::INFINITE)
    ;

    // TODO: Logger class

}
<commit_msg>Add all missing functions to the Python Binding<commit_after>#include "Chemharp.hpp"
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/numpy.hpp>

namespace py = boost::python;
namespace np = boost::numpy;
using namespace harp;
using std::string;

void translate_Error(Error const& e) {
    auto err = string("Chemharp error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

void translate_FileError(FileError const& e) {
    auto err = string("Chemharp file error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

void translate_MemoryError(MemoryError const& e) {
    auto err = string("Chemharp memory error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

void translate_FormatError(FormatError const& e) {
    auto err = string("Chemharp format error: ") + e.what();
    PyErr_SetString(PyExc_UserWarning, err.c_str());
}

// ResultConverterGenerator used to transform Array3D to numpy ndarray.
struct Array3D_convertor {
    template <class T> struct apply {
        struct type {
            // Convert Array3D to ndarray.
            PyObject* operator()(const Array3D& A) const {
                py::tuple shape = py::make_tuple(A.size(), 3);
                np::dtype dtype = np::dtype::get_builtin<float>();
                np::ndarray res = np::empty(shape, dtype);

                auto c_arr = reinterpret_cast<float (*)[3]>(res.get_data());
                for (size_t i=0; i<A.size(); i++)
                    for (size_t j=0; j<3; j++)
                        c_arr[i][j] = A[i][j];

                return py::incref(res.ptr());
            }

            // Used for documentation.
            const PyTypeObject* get_pytype() const { return 0; }
        };
    };
};

// ResultConverterGenerator used to transform Matrix3D to numpy ndarray.
struct Matrix3D_convertor {
    template <class T> struct apply {
        struct type {
            // Convert Matrix3D to ndarray.
            PyObject* operator()(const Matrix3D& A) const {
                py::tuple shape = py::make_tuple(3, 3);
                np::dtype dtype = np::dtype::get_builtin<double>();
                np::ndarray res = np::empty(shape, dtype);

                auto c_arr = reinterpret_cast<double (*)[3]>(res.get_data());
                for (size_t i=0; i<3; i++)
                    for (size_t j=0; j<3; j++)
                        c_arr[i][j] = A[i][j];

                return py::incref(res.ptr());
            }

            // Used for documentation.
            const PyTypeObject* get_pytype() const { return 0; }
        };
    };
};

struct std_vector_convertor {
    template <class T> struct apply {
        struct type {
            // Convert any std::vector to python list.
            template <class S>
            PyObject* operator()(const std::vector<S>& A) const {
                py::list res;
                for (auto val : A)
                    res.append(val);
                return py::incref(res.ptr());
            }

            // Used for documentation.
            const PyTypeObject* get_pytype() const { return 0; }
        };
    };
};

void topology_setitem(Topology& top, size_t index, const Atom& atom) {
    top[index] = atom;
}

void init_module(){
    // Removing this line will result in bad stuff appening, like segfaults and
    // your grand mother being kidnaped by aliens. So don't do this!
    np::initialize();
}

BOOST_PYTHON_MODULE(chemharp){
    init_module();

    /* Exception management ***************************************************/
    py::register_exception_translator<Error>(&translate_Error);
    py::register_exception_translator<FileError>(&translate_FileError);
    py::register_exception_translator<MemoryError>(&translate_MemoryError);
    py::register_exception_translator<FormatError>(&translate_FormatError);

    /* Trajectory class *******************************************************/
    py::class_<Trajectory, boost::noncopyable>("Trajectory",
            py::init<string, py::optional<string, string>>())
        .def("read_next_step", &Trajectory::read_next_step)
        .def("read_at_step", &Trajectory::read_at_step)
        .def("write_step", &Trajectory::write_step)
        .def("done", &Trajectory::done)
        .def("close", &Trajectory::close)
        .def("nsteps", &Trajectory::nsteps)
        .def("topology",
            static_cast<void (Trajectory::*)(const Topology&)>(&Trajectory::topology))
        .def("topology",
            static_cast<void (Trajectory::*)(const string&)>(&Trajectory::topology))
    ;

    /* Frame class ************************************************************/
    py::class_<Frame>("Frame")
        .def("positions",
            static_cast<const Array3D& (Frame::*)(void) const>(&Frame::positions),
            py::return_value_policy<Array3D_convertor>())
        .def("velocities",
            static_cast<const Array3D& (Frame::*)(void) const>(&Frame::velocities),
            py::return_value_policy<Array3D_convertor>())
        .add_property("has_velocities", &Frame::has_velocities)
        .def("__len__", &Frame::natoms)
        .add_property("natoms", &Frame::natoms)
        .add_property("topology",
            py::make_function(
                static_cast<const Topology& (Frame::*)(void) const>(&Frame::topology),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Frame::*)(const Topology&)>(&Frame::topology))
        .add_property("cell",
            py::make_function(
                static_cast<const UnitCell& (Frame::*)(void) const>(&Frame::cell),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Frame::*)(const UnitCell&)>(&Frame::cell))
        .add_property("step",
            static_cast<size_t (Frame::*)(void) const>(&Frame::step),
            static_cast<void (Frame::*)(size_t)>(&Frame::step))
    ;

    /* Atom class *************************************************************/
    py::scope atom_scope = py::class_<Atom>("Atom", py::init<string>())
        .add_property("name",
            py::make_function(
                static_cast<const string& (Atom::*)(void) const>(&Atom::name),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(const string&)>(&Atom::name))
        .add_property("mass",
            py::make_function(
                static_cast<const float& (Atom::*)(void) const>(&Atom::mass),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(float)>(&Atom::mass))
        .add_property("charge",
            py::make_function(
                static_cast<const float& (Atom::*)(void) const>(&Atom::charge),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(float)>(&Atom::charge))
        .add_property("type",
            py::make_function(
                static_cast<const Atom::AtomType& (Atom::*)(void) const>(&Atom::type),
                py::return_value_policy<py::copy_const_reference>()),
            static_cast<void (Atom::*)(Atom::AtomType)>(&Atom::type))
        .def("full_name", &Atom::full_name)
        .def("vdw_radius", &Atom::vdw_radius)
        .def("covalent_radius", &Atom::covalent_radius)
        .def("atomic_number", &Atom::atomic_number)
    ;

    /* AtomType enum **********************************************************/
    py::enum_<Atom::AtomType>("AtomType")
        .value("ELEMENT", Atom::ELEMENT)
        .value("CORSE_GRAIN", Atom::CORSE_GRAIN)
        .value("DUMMY", Atom::DUMMY)
        .value("UNDEFINED", Atom::UNDEFINED)
    ;

    /* Topology class *********************************************************/
    py::class_<Topology>("Topology")
        .def("append", &Topology::append)
        .def("remove", &Topology::remove)
        .def("add_bond", &Topology::add_bond)
        .def("remove_bond", &Topology::remove_bond)

        .def("__len__", &Topology::natoms)
        .add_property("natoms", &Topology::natoms)
        .add_property("natom_types", &Topology::natom_types)

        .def("clear", &Topology::clear)
        .def("resize", &Topology::resize)

        .def("isbond", &Topology::isbond)
        .def("isangle", &Topology::isangle)
        .def("isdihedral", &Topology::isdihedral)

        .def("guess_bonds", &Topology::guess_bonds)

        .def( "__getitem__",
                static_cast<const Atom& (Topology::*)(size_t) const>(&Topology::operator[]),
                py::return_internal_reference<>())
        .def( "__setitem__", &topology_setitem)

        /* TODO:
        vector<bond> bonds(void);
        vector<angle> angles(void);
        vector<dihedral> dihedrals(void);
        */
    ;

    py::def("dummy_topology", dummy_topology);

    /* UnitCell class *********************************************************/
    py::class_<UnitCell>("UnitCell", py::init<>())
        .def(py::init<double>())
        .def(py::init<double, double, double>())
        .def(py::init<double, double, double, double, double, double>())
        .def(py::init<UnitCell::CellType>())
        .def(py::init<UnitCell::CellType, double>())
        .def(py::init<UnitCell::CellType, double, double, double>())
        .def("matricial", &UnitCell::matricial, py::return_value_policy<Matrix3D_convertor>())
        .add_property("type",
            static_cast<UnitCell::CellType (UnitCell::*)(void) const>(&UnitCell::type),
            static_cast<void (UnitCell::*)(UnitCell::CellType)>(&UnitCell::type))
        .add_property("a",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::a),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::a))
        .add_property("b",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::b),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::b))
        .add_property("c",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::c),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::c))
        .add_property("alpha",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::alpha),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::alpha))
        .add_property("beta",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::beta),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::beta))
        .add_property("gamma",
            static_cast<double (UnitCell::*)(void) const>(&UnitCell::gamma),
            static_cast<void (UnitCell::*)(double)>(&UnitCell::gamma))
        .add_property("periodic_x",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::periodic_x),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::periodic_x))
        .add_property("periodic_y",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::periodic_y),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::periodic_y))
        .add_property("periodic_z",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::periodic_z),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::periodic_z))
        .add_property("full_periodic",
            static_cast<bool (UnitCell::*)(void) const>(&UnitCell::full_periodic),
            static_cast<void (UnitCell::*)(bool)>(&UnitCell::full_periodic))
    ;

    /* CellType enum **********************************************************/
    py::enum_<UnitCell::CellType>("CellType")
        .value("ORTHOROMBIC", UnitCell::ORTHOROMBIC)
        .value("TRICLINIC", UnitCell::TRICLINIC)
        .value("INFINITE", UnitCell::INFINITE)
    ;

    /* LogLevel enum **********************************************************/
    py::enum_<Logger::LogLevel>("LogLevel")
        .value("NONE", Logger::NONE)
        .value("ERROR", Logger::ERROR)
        .value("WARNING", Logger::WARNING)
        .value("INFO", Logger::INFO)
        .value("DEBUG", Logger::DEBUG)
    ;

    /* Logger class ***********************************************************/
    py::class_<Logger, boost::noncopyable>("Logger", py::no_init)
        .add_property("level",
            static_cast<Logger::LogLevel (*)(void)>(&Logger::level),
            static_cast<void (*)(Logger::LogLevel)>(&Logger::level))
        .def("log_to_file", &Logger::log_to_file)
            .staticmethod("log_to_file")
        .def("log_to_stdout", &Logger::log_to_stdout)
            .staticmethod("log_to_stdout")
    ;
}
<|endoftext|>


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

 Module:       FGFDMExec.cpp
 Author:       Jon S. Berndt
 Date started: 11/17/98
 Purpose:      Schedules and runs the model routines.
 Called by:    The GUI.

 ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------

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

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

This class wraps up the simulation scheduling routines.

HISTORY
--------------------------------------------------------------------------------
11/17/98   JSB   Created

********************************************************************************
INCLUDES
*******************************************************************************/

#ifdef FGFS
#  include <simgear/compiler.h>
#  ifdef FG_HAVE_STD_INCLUDES
#    include <iostream>
#    include <ctime>
#  else
#    include <iostream.h>
#    include <time.h>
#  endif
#else
#  include <iostream>
#  include <ctime>
#endif

#include "FGFDMExec.h"
#include "FGState.h"
#include "FGAtmosphere.h"
#include "FGFCS.h"
#include "FGAircraft.h"
#include "FGTranslation.h"
#include "FGRotation.h"
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"

/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/

// Constructor

FGFDMExec::FGFDMExec(void)
{
  FirstModel  = 0;
  Error       = 0;
  State       = 0;
  Atmosphere  = 0;
  FCS         = 0;
  Aircraft    = 0;
  Translation = 0;
  Rotation    = 0;
  Position    = 0;
  Auxiliary   = 0;
  Output      = 0;

  // Instantiate this FDM Executive's Models

  Atmosphere  = new FGAtmosphere(this);
  FCS         = new FGFCS(this);
  Aircraft    = new FGAircraft(this);
  Translation = new FGTranslation(this);
  Rotation    = new FGRotation(this);
  Position    = new FGPosition(this);
  Auxiliary   = new FGAuxiliary(this);
  Output      = new FGOutput(this);

  State       = new FGState(this);

  // Initialize models so they can communicate with each other

  if (!Atmosphere->InitModel()) {cerr << "Atmosphere model init failed"; Error+=1;}
  if (!FCS->InitModel())        {cerr << "FCS model init failed"; Error+=2;}
  if (!Aircraft->InitModel())   {cerr << "Aircraft model init failed"; Error+=4;}
  if (!Translation->InitModel()){cerr << "Translation model init failed"; Error+=8;}
  if (!Rotation->InitModel())   {cerr << "Rotation model init failed"; Error+=16;}
  if (!Position->InitModel())   {cerr << "Position model init failed"; Error+=32;}
  if (!Auxiliary->InitModel())  {cerr << "Auxiliary model init failed"; Error+=64;}
  if (!Output->InitModel())     {cerr << "Output model init failed"; Error+=128;}

  // Schedule a model. The second arg (the integer) is the pass number. For
  // instance, the atmosphere model gets executed every fifth pass it is called
  // by the executive. Everything else here gets executed each pass.

  Schedule(Atmosphere,  1);
  Schedule(FCS,         1);
  Schedule(Aircraft,    1);
  Schedule(Rotation,    1);
  Schedule(Translation, 1);
  Schedule(Position,    1);
  Schedule(Auxiliary,   1);
  Schedule(Output,     1);

  terminate = false;
  frozen = false;
}

FGFDMExec::~FGFDMExec(void){

  cout << "~FGFDMExec" << endl;
  if ( Atmosphere != NULL )  delete Atmosphere;
  cout << "Atmosphere" << endl;
  if ( FCS != NULL )         delete FCS;
  cout << "FCS" << endl;
  if ( Aircraft != NULL )    delete Aircraft;
  cout << "Aircraft" << endl;
  if ( Translation != NULL ) delete Translation;
  cout << "Translation" << endl;
  if ( Rotation != NULL )    delete Rotation;
  cout << "Rotation" << endl;
  if ( Position != NULL )    delete Position;
  cout << "Position" << endl;
  if ( Auxiliary != NULL )   delete Auxiliary;
  cout << "Auxiliary" << endl;
  if ( Output != NULL )      delete Output;
  cout << "Output" << endl;
  if ( State != NULL )       delete State;
  cout << "State" << endl;

}

int FGFDMExec::Schedule(FGModel* model, int rate)
{
  FGModel* model_iterator;

  model_iterator = FirstModel;

  if (model_iterator == 0L) {                  // this is the first model

    FirstModel = model;
    FirstModel->NextModel = 0L;
    FirstModel->SetRate(rate);

  } else {                                     // subsequent model

    while (model_iterator->NextModel != 0L) {
      model_iterator = model_iterator->NextModel;
    }
    model_iterator->NextModel = model;
    model_iterator->NextModel->SetRate(rate);

  }
  return 0;
}

bool FGFDMExec::Run(void)
{
  FGModel* model_iterator;

  if (frozen) return true;

  model_iterator = FirstModel;
  if (model_iterator == 0L) return false;

  while (!model_iterator->Run())
  {
    model_iterator = model_iterator->NextModel;
    if (model_iterator == 0L) break;
  }

  State->IncrTime();

  return true;
}

bool FGFDMExec::RunIC(FGInitialCondition *fgic)
{
  State->Suspend();
  State->Initialize(fgic);
  Run();
  State->Resume();
  return true;
}

bool FGFDMExec::LoadModel(string APath, string EPath, string model)
{
	AircraftPath = APath;
	EnginePath = EPath;
  return Aircraft->LoadAircraft(AircraftPath, EnginePath, model);
}

bool FGFDMExec::RunScript(string script)
{
}
<commit_msg>AKP removed some output<commit_after>/*******************************************************************************

 Module:       FGFDMExec.cpp
 Author:       Jon S. Berndt
 Date started: 11/17/98
 Purpose:      Schedules and runs the model routines.
 Called by:    The GUI.

 ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------

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

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

This class wraps up the simulation scheduling routines.

HISTORY
--------------------------------------------------------------------------------
11/17/98   JSB   Created

********************************************************************************
INCLUDES
*******************************************************************************/

#ifdef FGFS
#  include <simgear/compiler.h>
#  ifdef FG_HAVE_STD_INCLUDES
#    include <iostream>
#    include <ctime>
#  else
#    include <iostream.h>
#    include <time.h>
#  endif
#else
#  include <iostream>
#  include <ctime>
#endif

#include "FGFDMExec.h"
#include "FGState.h"
#include "FGAtmosphere.h"
#include "FGFCS.h"
#include "FGAircraft.h"
#include "FGTranslation.h"
#include "FGRotation.h"
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"

/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/

// Constructor

FGFDMExec::FGFDMExec(void)
{
  FirstModel  = 0;
  Error       = 0;
  State       = 0;
  Atmosphere  = 0;
  FCS         = 0;
  Aircraft    = 0;
  Translation = 0;
  Rotation    = 0;
  Position    = 0;
  Auxiliary   = 0;
  Output      = 0;

  // Instantiate this FDM Executive's Models

  Atmosphere  = new FGAtmosphere(this);
  FCS         = new FGFCS(this);
  Aircraft    = new FGAircraft(this);
  Translation = new FGTranslation(this);
  Rotation    = new FGRotation(this);
  Position    = new FGPosition(this);
  Auxiliary   = new FGAuxiliary(this);
  Output      = new FGOutput(this);

  State       = new FGState(this);

  // Initialize models so they can communicate with each other

  if (!Atmosphere->InitModel()) {cerr << "Atmosphere model init failed"; Error+=1;}
  if (!FCS->InitModel())        {cerr << "FCS model init failed"; Error+=2;}
  if (!Aircraft->InitModel())   {cerr << "Aircraft model init failed"; Error+=4;}
  if (!Translation->InitModel()){cerr << "Translation model init failed"; Error+=8;}
  if (!Rotation->InitModel())   {cerr << "Rotation model init failed"; Error+=16;}
  if (!Position->InitModel())   {cerr << "Position model init failed"; Error+=32;}
  if (!Auxiliary->InitModel())  {cerr << "Auxiliary model init failed"; Error+=64;}
  if (!Output->InitModel())     {cerr << "Output model init failed"; Error+=128;}

  // Schedule a model. The second arg (the integer) is the pass number. For
  // instance, the atmosphere model gets executed every fifth pass it is called
  // by the executive. Everything else here gets executed each pass.

  Schedule(Atmosphere,  1);
  Schedule(FCS,         1);
  Schedule(Aircraft,    1);
  Schedule(Rotation,    1);
  Schedule(Translation, 1);
  Schedule(Position,    1);
  Schedule(Auxiliary,   1);
  Schedule(Output,     1);

  terminate = false;
  frozen = false;
}

FGFDMExec::~FGFDMExec(void){

  if ( Atmosphere != NULL )  delete Atmosphere;
  if ( FCS != NULL )         delete FCS;
  if ( Aircraft != NULL )    delete Aircraft;
  if ( Translation != NULL ) delete Translation;
  if ( Rotation != NULL )    delete Rotation;
  if ( Position != NULL )    delete Position;
  if ( Auxiliary != NULL )   delete Auxiliary;
  if ( Output != NULL )      delete Output;
  if ( State != NULL )       delete State;

}

int FGFDMExec::Schedule(FGModel* model, int rate)
{
  FGModel* model_iterator;

  model_iterator = FirstModel;

  if (model_iterator == 0L) {                  // this is the first model

    FirstModel = model;
    FirstModel->NextModel = 0L;
    FirstModel->SetRate(rate);

  } else {                                     // subsequent model

    while (model_iterator->NextModel != 0L) {
      model_iterator = model_iterator->NextModel;
    }
    model_iterator->NextModel = model;
    model_iterator->NextModel->SetRate(rate);

  }
  return 0;
}

bool FGFDMExec::Run(void)
{
  FGModel* model_iterator;

  if (frozen) return true;

  model_iterator = FirstModel;
  if (model_iterator == 0L) return false;

  while (!model_iterator->Run())
  {
    model_iterator = model_iterator->NextModel;
    if (model_iterator == 0L) break;
  }

  State->IncrTime();

  return true;
}

bool FGFDMExec::RunIC(FGInitialCondition *fgic)
{
  State->Suspend();
  State->Initialize(fgic);
  Run();
  State->Resume();
  return true;
}

bool FGFDMExec::LoadModel(string APath, string EPath, string model)
{
	AircraftPath = APath;
	EnginePath = EPath;
  return Aircraft->LoadAircraft(AircraftPath, EnginePath, model);
}

bool FGFDMExec::RunScript(string script)
{
}
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------*/
/*                                                                            */
/*   Copyright (c) 2015 data-fetish                                           */
/*   All rights reserved.                                                     */
/*                                                                            */
/*   Team: Knowledge-mining                                                   */
/*                                                                            */
/*   Authors:  Akash Raj K N                                                  */
/*             Gopichand Paturi                                               */
/*             Anjali Thakur                                                  */
/*                                                                            */
/*----------------------------------------------------------------------------*/

/*
  FP-Growth - Generation of frequent itemsets
  FP_GROWTH.cpp
*/

#include <bits/stdc++.h>
#include "FP_TREE_GEN.c"

using namespace std;

FILE *fitem;
FILE *fitem1, *fitem2, *fitem3, *fitem4, *fitem5, *fitem6,
     *fitem7, *fitem8, *fitem9, *fitem10;
stack< vector<long long> > s;
vector<long long> candidateItemSet;
long long totalSupport = 0;

void checkPrinter()
{

  cout<<"im high as the moon== "<<minSupportCount<<endl;

}

void initializeStack()
{
  //initialize the stack with single items frequent sets
  for(int i=0; i<numFreqItems; ++i)
  {
    vector<long long> temp;
    temp.push_back(freqList[i].id);
    s.push(temp);
  }

}

void generateSubProblems()
{
  int len = candidateItemSet.size();
  long long lastOne = candidateItemSet[len-1];

  vector<long long> candidateExtend, tempvec;

  candidateExtend = candidateItemSet;
  candidateExtend.push_back(-1);

  for(int i=0; i<numFreqItems; ++i)
  {
    if(lastOne==freqList[i].id)
    {
      break;
    }

    candidateExtend[len] = freqList[i].id;

    s.push(candidateExtend);
    /*tempvec = s.top();

    for(int j=0; j<tempvec.size();++j)
    {
      cout<<tempvec[j]<<" ";
    }
    cout<<endl;*/
  }
}

long long findIndex(long long p)
{
  //linear search the freqList for the current item id
  long long idx = -1;

  for(int i=0; i<numFreqItems; ++i)
  {
    if(freqList[i].id == p)
    {
      idx = i;
      break;
    }
  }

  return idx;
}

int isCandidateFrequent()
{
  if(candidateItemSet.size()==1)
  {
    totalSupport = freqList[findIndex(candidateItemSet[0])].support;

    return 1;
  }

  long long currentSupport = 0;
  long long freqIdx, tempIdx;
  int setFound;

  totalSupport = 0;

  struct treeNode *currentPtr, *horizontalPtr;

  //find the index of the frequent item in the freqList table, uses linear search
  //can be optimized with binary search
  for(int i=0; i<numFreqItems; ++i)
  {
    if(freqList[i].id==candidateItemSet[0])
    {
      freqIdx = i;
      break;
    }
  }

  horizontalPtr = freqList[freqIdx].ptr;

  //go to all paths which end with freqList[i].id
  while(horizontalPtr!=NULL)
  {
    currentPtr = horizontalPtr;
    tempIdx = 0; //to iterate the candidateItemSet
    setFound = 1; //default, the candidateItemSet is present in the current path
    currentSupport = currentPtr->count;

    //search if the entire itemSet is in the path
    while(currentPtr!=head)
    {
      if(currentPtr->id != candidateItemSet[tempIdx]) //current id in the path is not equal to the candidate[idx]
      {
        if(findIndex(currentPtr->id) < findIndex(candidateItemSet[tempIdx]))
        {
          setFound = 0;
          break;
        }
      }
      else
      {
        if(tempIdx == candidateItemSet.size()-1) //if the entire itemSet is found, then exit
        {
          break;
        }

        tempIdx++;
      }

      currentPtr = currentPtr->parent;
    } //end of while

    if(setFound)
    {
      totalSupport += currentSupport;
    }

    horizontalPtr = horizontalPtr->horizontal; //go to the next horizontal pointer
  }
/*
  for(int i=0; i<candidateItemSet.size(); ++i)
  {
    printf("%lld  ", candidateItemSet[i]);
  }
  printf("\n");

  cout<<"support="<<totalSupport<<endl;
*/

  return totalSupport>minSupportCount?1:0;
}

void fileInitializer()
{
  fitem1 = fopen("frequent1ItemSet.txt", "w");
  fitem2 = fopen("frequent2ItemSet.txt", "w");
  fitem3 = fopen("frequent3ItemSet.txt", "w");
  fitem4 = fopen("frequent4ItemSet.txt", "w");
  fitem5 = fopen("frequent5ItemSet.txt", "w");
  fitem6 = fopen("frequent6ItemSet.txt", "w");
  fitem7 = fopen("frequent7ItemSet.txt", "w");
  fitem8 = fopen("frequent8ItemSet.txt", "w");
  fitem9 = fopen("frequent9ItemSet.txt", "w");
  fitem10 = fopen("frequent10ItemSet.txt", "w");
}

void tree_growth()
{

  fitem = fopen("frequentItemSet.txt","w");

  fileInitializer();

  initializeStack();

  while(!s.empty())
  {
    candidateItemSet = s.top(); //take top of stack
    s.pop();

    if(isCandidateFrequent())
    {
      //write to file the current frequent ItemSet
      for(int i=0; i<candidateItemSet.size(); ++i)
      {
        fprintf(fitem, "%lld ", candidateItemSet[i]);
      }

      // write to files
      switch(candidateItemSet.size())
      {
        case 1: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem1, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem1, "%lld ", totalSupport);
                fprintf(fitem1, "\n");
                break;

        case 2: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem2, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem2, "%lld ", totalSupport);
                fprintf(fitem2, "\n");
                break;

        case 3: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem3, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem3, "%lld ", totalSupport);
                fprintf(fitem3, "\n");
                break;

        case 4: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem4, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem4, "%lld ", totalSupport);
                fprintf(fitem4, "\n");
                break;

        case 5: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem5, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem5, "%lld ", totalSupport);
                fprintf(fitem5, "\n");
                break;

        case 6: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem6, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem6, "%lld ", totalSupport);
                fprintf(fitem6, "\n");
                break;

        case 7: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem7, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem7, "%lld ", totalSupport);
                fprintf(fitem7, "\n");
                break;

        case 8: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem8, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem8, "%lld ", totalSupport);
                fprintf(fitem8, "\n");
                break;

        case 9: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem9, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem9, "%lld ", totalSupport);
                fprintf(fitem9, "\n");
                break;

        case 10:for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem10, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem10, "%lld ", totalSupport);
                fprintf(fitem10, "\n");
                break;

        default: cout<<"frequent "<<candidateItemSet.size()<<" itemsets are not considered"<<endl;
      }

      fprintf(fitem, "%lld ", totalSupport);
      fprintf(fitem, "\n");

      generateSubProblems();
    }

  }

  fclose(fitem);
  fcloseall();
}

<commit_msg>fixed linker errors<commit_after>/*----------------------------------------------------------------------------*/
/*                                                                            */
/*   Copyright (c) 2015 data-fetish                                           */
/*   All rights reserved.                                                     */
/*                                                                            */
/*   Team: Knowledge-mining                                                   */
/*                                                                            */
/*   Authors:  Akash Raj K N                                                  */
/*             Gopichand Paturi                                               */
/*             Anjali Thakur                                                  */
/*                                                                            */
/*----------------------------------------------------------------------------*/

/*
  FP-Growth - Generation of frequent itemsets
  FP_GROWTH.cpp
*/

#include <bits/stdc++.h>
#include "FP_TREE_GEN.c"

using namespace std;

FILE *fitem;
FILE *fitem1, *fitem2, *fitem3, *fitem4, *fitem5, *fitem6,
     *fitem7, *fitem8, *fitem9, *fitem10;
stack< vector<long long> > s;
vector<long long> candidateItemSet;
long long totalSupport = 0;

extern "C" void checkPrinter()
{

  cout<<"im high as the moon== "<<minSupportCount<<endl;

}

extern "C" void initializeStack()
{
  //initialize the stack with single items frequent sets
  for(int i=0; i<numFreqItems; ++i)
  {
    vector<long long> temp;
    temp.push_back(freqList[i].id);
    s.push(temp);
  }

}

extern "C" void generateSubProblems()
{
  int len = candidateItemSet.size();
  long long lastOne = candidateItemSet[len-1];

  vector<long long> candidateExtend, tempvec;

  candidateExtend = candidateItemSet;
  candidateExtend.push_back(-1);

  for(int i=0; i<numFreqItems; ++i)
  {
    if(lastOne==freqList[i].id)
    {
      break;
    }

    candidateExtend[len] = freqList[i].id;

    s.push(candidateExtend);
    /*tempvec = s.top();

    for(int j=0; j<tempvec.size();++j)
    {
      cout<<tempvec[j]<<" ";
    }
    cout<<endl;*/
  }
}

extern "C" long long findIndex(long long p)
{
  //linear search the freqList for the current item id
  long long idx = -1;

  for(int i=0; i<numFreqItems; ++i)
  {
    if(freqList[i].id == p)
    {
      idx = i;
      break;
    }
  }

  return idx;
}

extern "C" int isCandidateFrequent()
{
  if(candidateItemSet.size()==1)
  {
    totalSupport = freqList[findIndex(candidateItemSet[0])].support;

    return 1;
  }

  long long currentSupport = 0;
  long long freqIdx, tempIdx;
  int setFound;

  totalSupport = 0;

  struct treeNode *currentPtr, *horizontalPtr;

  //find the index of the frequent item in the freqList table, uses linear search
  //can be optimized with binary search
  for(int i=0; i<numFreqItems; ++i)
  {
    if(freqList[i].id==candidateItemSet[0])
    {
      freqIdx = i;
      break;
    }
  }

  horizontalPtr = freqList[freqIdx].ptr;

  //go to all paths which end with freqList[i].id
  while(horizontalPtr!=NULL)
  {
    currentPtr = horizontalPtr;
    tempIdx = 0; //to iterate the candidateItemSet
    setFound = 1; //default, the candidateItemSet is present in the current path
    currentSupport = currentPtr->count;

    //search if the entire itemSet is in the path
    while(currentPtr!=head)
    {
      if(currentPtr->id != candidateItemSet[tempIdx]) //current id in the path is not equal to the candidate[idx]
      {
        if(findIndex(currentPtr->id) < findIndex(candidateItemSet[tempIdx]))
        {
          setFound = 0;
          break;
        }
      }
      else
      {
        if(tempIdx == candidateItemSet.size()-1) //if the entire itemSet is found, then exit
        {
          break;
        }

        tempIdx++;
      }

      currentPtr = currentPtr->parent;
    } //end of while

    if(setFound)
    {
      totalSupport += currentSupport;
    }

    horizontalPtr = horizontalPtr->horizontal; //go to the next horizontal pointer
  }
/*
  for(int i=0; i<candidateItemSet.size(); ++i)
  {
    printf("%lld  ", candidateItemSet[i]);
  }
  printf("\n");

  cout<<"support="<<totalSupport<<endl;
*/

  return totalSupport>minSupportCount?1:0;
}

extern "C" void fileInitializer()
{
  fitem1 = fopen("frequent1ItemSet.txt", "w");
  fitem2 = fopen("frequent2ItemSet.txt", "w");
  fitem3 = fopen("frequent3ItemSet.txt", "w");
  fitem4 = fopen("frequent4ItemSet.txt", "w");
  fitem5 = fopen("frequent5ItemSet.txt", "w");
  fitem6 = fopen("frequent6ItemSet.txt", "w");
  fitem7 = fopen("frequent7ItemSet.txt", "w");
  fitem8 = fopen("frequent8ItemSet.txt", "w");
  fitem9 = fopen("frequent9ItemSet.txt", "w");
  fitem10 = fopen("frequent10ItemSet.txt", "w");
}

extern "C" void tree_growth()
{

  fitem = fopen("frequentItemSet.txt","w");

  fileInitializer();

  initializeStack();

  while(!s.empty())
  {
    candidateItemSet = s.top(); //take top of stack
    s.pop();

    if(isCandidateFrequent())
    {
      //write to file the current frequent ItemSet
      for(int i=0; i<candidateItemSet.size(); ++i)
      {
        fprintf(fitem, "%lld ", candidateItemSet[i]);
      }

      // write to files
      switch(candidateItemSet.size())
      {
        case 1: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem1, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem1, "%lld ", totalSupport);
                fprintf(fitem1, "\n");
                break;

        case 2: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem2, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem2, "%lld ", totalSupport);
                fprintf(fitem2, "\n");
                break;

        case 3: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem3, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem3, "%lld ", totalSupport);
                fprintf(fitem3, "\n");
                break;

        case 4: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem4, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem4, "%lld ", totalSupport);
                fprintf(fitem4, "\n");
                break;

        case 5: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem5, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem5, "%lld ", totalSupport);
                fprintf(fitem5, "\n");
                break;

        case 6: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem6, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem6, "%lld ", totalSupport);
                fprintf(fitem6, "\n");
                break;

        case 7: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem7, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem7, "%lld ", totalSupport);
                fprintf(fitem7, "\n");
                break;

        case 8: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem8, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem8, "%lld ", totalSupport);
                fprintf(fitem8, "\n");
                break;

        case 9: for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem9, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem9, "%lld ", totalSupport);
                fprintf(fitem9, "\n");
                break;

        case 10:for(int i=0; i<candidateItemSet.size(); ++i)
                {
                  fprintf(fitem10, "%lld ", candidateItemSet[i]);
                }
                fprintf(fitem10, "%lld ", totalSupport);
                fprintf(fitem10, "\n");
                break;

        default: cout<<"frequent "<<candidateItemSet.size()<<" itemsets are not considered"<<endl;
      }

      fprintf(fitem, "%lld ", totalSupport);
      fprintf(fitem, "\n");

      generateSubProblems();
    }

  }

  fclose(fitem);
  fcloseall();
}

<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/core/graph/adjacency.h"

#include <opencv2/core/core.hpp>

#include "elm/core/exception.h"

#ifdef __WITH_PCL

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/Vertices.h>

#endif // __WITH_PCL

#include "elm/core/pcl/triangle_utils.h"

using namespace std;
using namespace cv;
using namespace elm;

extern template class cv::Mat_<float>;
extern template class pcl::PointCloud<pcl::PointXYZ >;

#ifdef __WITH_PCL

using namespace pcl;

void elm::TriangulatedCloudToAdjacency(const CloudXYZPtr &cld, const Triangles &t, Mat1f &dst)
{
    uint32_t nb_vertices_uint = static_cast<uint32_t>(cld->size());
    int nb_vertices = static_cast<int>(nb_vertices_uint);

    if(dst.rows < nb_vertices || dst.cols < nb_vertices) {

        dst = Mat1f::zeros(nb_vertices, nb_vertices);
    }

    for(Triangles::const_iterator itr=t.begin(); itr!=t.end(); ++itr) {

        const Vertices V = *itr;

        if(V.vertices.size() < size_t(3)) {

            ELM_THROW_BAD_DIMS("triangle with less than 3 vertices.");
        }

        //foreach vertex
        uint32_t v0 = V.vertices[0];
        uint32_t v1 = V.vertices[1];
        uint32_t v2 = V.vertices[2];

        if(v0 >= nb_vertices_uint || v1 >= nb_vertices_uint || v2 >= nb_vertices_uint) {

            ELM_THROW_KEY_ERROR("Triangle vertex outside point cloud.");
        }

        Mat1f e_triangle = TriangleEdges(cld->points.at(v0),
                                         cld->points.at(v1),
                                         cld->points.at(v2));

        dst(v0, v1) = dst(v1, v0) = e_triangle(0);
        dst(v0, v2) = dst(v2, v0) = e_triangle(1);
        dst(v1, v2) = dst(v2, v1) = e_triangle(2);
    }
}

void elm::TriangulatedCloudToAdjacency(const CloudXYZPtr &cld, const Triangles &t, SparseMat1f &dst)
{
    uint32_t nb_vertices_uint = static_cast<uint32_t>(cld->size());
    int nb_vertices = static_cast<int>(nb_vertices_uint);

    if((dst.size() == 0) || (nb_vertices < dst.size()[0]) || (nb_vertices < dst.size()[1])) {

        const int DIMS = 2;
        const int _sizes[DIMS] = {nb_vertices, nb_vertices};
        if(nb_vertices > 0) {

            dst = SparseMat1f(DIMS, _sizes);
        }
    }

    for(Triangles::const_iterator itr=t.begin(); itr!=t.end(); ++itr) {

        const Vertices V = *itr;

        if(V.vertices.size() < size_t(3)) {

            ELM_THROW_BAD_DIMS("triangle with less than 3 vertices.");
        }

        //foreach vertex
        uint32_t v0 = V.vertices[0];
        uint32_t v1 = V.vertices[1];
        uint32_t v2 = V.vertices[2];

        if(v0 >= nb_vertices_uint || v1 >= nb_vertices_uint || v2 >= nb_vertices_uint) {

            ELM_THROW_KEY_ERROR("Triangle vertex outside point cloud.");
        }

        Mat1f e_triangle = TriangleEdges(cld->points.at(v0),
                                         cld->points.at(v1),
                                         cld->points.at(v2));

        // force symmetry
        dst.ref(v0, v1) = e_triangle(0);
        dst.ref(v1, v0) = e_triangle(0);

        dst.ref(v0, v2) = e_triangle(1);
        dst.ref(v2, v0) = e_triangle(1);

        dst.ref(v1, v2) = e_triangle(2);
        dst.ref(v2, v1) = e_triangle(2);
    }
}

#endif // __WITH_PCL
<commit_msg>only specify point cloud extern template when pcl support is enabled<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/core/graph/adjacency.h"

#include <opencv2/core/core.hpp>

#include "elm/core/exception.h"

#ifdef __WITH_PCL

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/Vertices.h>

#endif // __WITH_PCL

#include "elm/core/pcl/triangle_utils.h"

using namespace std;
using namespace cv;
using namespace elm;

extern template class cv::Mat_<float>;

#ifdef __WITH_PCL

extern template class pcl::PointCloud<pcl::PointXYZ >;

using namespace pcl;

void elm::TriangulatedCloudToAdjacency(const CloudXYZPtr &cld, const Triangles &t, Mat1f &dst)
{
    uint32_t nb_vertices_uint = static_cast<uint32_t>(cld->size());
    int nb_vertices = static_cast<int>(nb_vertices_uint);

    if(dst.rows < nb_vertices || dst.cols < nb_vertices) {

        dst = Mat1f::zeros(nb_vertices, nb_vertices);
    }

    for(Triangles::const_iterator itr=t.begin(); itr!=t.end(); ++itr) {

        const Vertices V = *itr;

        if(V.vertices.size() < size_t(3)) {

            ELM_THROW_BAD_DIMS("triangle with less than 3 vertices.");
        }

        //foreach vertex
        uint32_t v0 = V.vertices[0];
        uint32_t v1 = V.vertices[1];
        uint32_t v2 = V.vertices[2];

        if(v0 >= nb_vertices_uint || v1 >= nb_vertices_uint || v2 >= nb_vertices_uint) {

            ELM_THROW_KEY_ERROR("Triangle vertex outside point cloud.");
        }

        Mat1f e_triangle = TriangleEdges(cld->points.at(v0),
                                         cld->points.at(v1),
                                         cld->points.at(v2));

        dst(v0, v1) = dst(v1, v0) = e_triangle(0);
        dst(v0, v2) = dst(v2, v0) = e_triangle(1);
        dst(v1, v2) = dst(v2, v1) = e_triangle(2);
    }
}

void elm::TriangulatedCloudToAdjacency(const CloudXYZPtr &cld, const Triangles &t, SparseMat1f &dst)
{
    uint32_t nb_vertices_uint = static_cast<uint32_t>(cld->size());
    int nb_vertices = static_cast<int>(nb_vertices_uint);

    if((dst.size() == 0) || (nb_vertices < dst.size()[0]) || (nb_vertices < dst.size()[1])) {

        const int DIMS = 2;
        const int _sizes[DIMS] = {nb_vertices, nb_vertices};
        if(nb_vertices > 0) {

            dst = SparseMat1f(DIMS, _sizes);
        }
    }

    for(Triangles::const_iterator itr=t.begin(); itr!=t.end(); ++itr) {

        const Vertices V = *itr;

        if(V.vertices.size() < size_t(3)) {

            ELM_THROW_BAD_DIMS("triangle with less than 3 vertices.");
        }

        //foreach vertex
        uint32_t v0 = V.vertices[0];
        uint32_t v1 = V.vertices[1];
        uint32_t v2 = V.vertices[2];

        if(v0 >= nb_vertices_uint || v1 >= nb_vertices_uint || v2 >= nb_vertices_uint) {

            ELM_THROW_KEY_ERROR("Triangle vertex outside point cloud.");
        }

        Mat1f e_triangle = TriangleEdges(cld->points.at(v0),
                                         cld->points.at(v1),
                                         cld->points.at(v2));

        // force symmetry
        dst.ref(v0, v1) = e_triangle(0);
        dst.ref(v1, v0) = e_triangle(0);

        dst.ref(v0, v2) = e_triangle(1);
        dst.ref(v2, v0) = e_triangle(1);

        dst.ref(v1, v2) = e_triangle(2);
        dst.ref(v2, v1) = e_triangle(2);
    }
}

#endif // __WITH_PCL
<|endoftext|>


<commit_before>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

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

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
// removed for now; it didn't generalize well
/*
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
  imshow("canny mask", gray.mul(canny));
*/

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
  imshow("dark mask", gray.mul(kindofdark));

  Mat mask = flow.mul(kindofdark);
// close the mask
/*
  Mat smallMask;
  resize(mask, smallMask, Size(150,150));
  int t1 = tracker1+1-(tracker1%2);
  if (t1>50) t1=51;
  if (t1<3) t1=3;
  int t2 = tracker2+1-(tracker2%2);
  if (t2>50) t2=51;
  if (t2<3) t2=3;
  Mat erodeKernel = ellipticKernel(t1,t2);
  erode(smallMask, smallMask, erodeKernel);
  Mat dilateKernel = ellipticKernel(t1,t2);
  dilate(smallMask, smallMask, dilateKernel);
  resize(smallMask, smallMask, Size(width, height));
  bitwise_and(smallMask,mask,mask);
*/
  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
// erode it first since we really want to be sure it's bg

  Mat erodeKernel = ellipticKernel(21);
  erode(mask, mask, erodeKernel);
  Mat mask_;
  subtract(1,mask,mask_);
  Mat mask3, mask3_;
  channel[0] = mask;
  channel[1] = mask;
  channel[2] = mask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

  Moments lol = moments(mask, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);

  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  Mat classifyThis;
  blur(gray, classifyThis, Size(10,10));
//  bilateralFilter(gray, classifyThis, 15, 10, 1);
  equalizeHist(classifyThis, classifyThis);
  classifyThis = classifyThis.mul(mask);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, 5, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Point center( mouths[i].x + mouths[i].width*0.5, mouths[i].y + mouths[i].height*0.5 );
   ellipse( image, center, Size( mouths[i].width*0.5, mouths[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
  }
  imshow("MOUTH", image);

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

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

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
// removed for now; it didn't generalize well
/*
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
  imshow("canny mask", gray.mul(canny));
*/

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
  imshow("dark mask", gray.mul(kindofdark));

  Mat mask = flow.mul(kindofdark);
// close the mask
/*
  Mat smallMask;
  resize(mask, smallMask, Size(150,150));
  int t1 = tracker1+1-(tracker1%2);
  if (t1>50) t1=51;
  if (t1<3) t1=3;
  int t2 = tracker2+1-(tracker2%2);
  if (t2>50) t2=51;
  if (t2<3) t2=3;
  Mat erodeKernel = ellipticKernel(t1,t2);
  erode(smallMask, smallMask, erodeKernel);
  Mat dilateKernel = ellipticKernel(t1,t2);
  dilate(smallMask, smallMask, dilateKernel);
  resize(smallMask, smallMask, Size(width, height));
  bitwise_and(smallMask,mask,mask);
*/
  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
// erode it first since we really want to be sure it's bg

  Mat erodeKernel = ellipticKernel(21);
  erode(mask, mask, erodeKernel);
  Mat mask_;
  subtract(1,mask,mask_);
  Mat mask3, mask3_;
  channel[0] = mask;
  channel[1] = mask;
  channel[2] = mask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

  Moments lol = moments(mask, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);

/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  Mat classifyThis;
  blur(gray, classifyThis, Size(10,10));
//  bilateralFilter(gray, classifyThis, 15, 10, 1);
  equalizeHist(classifyThis, classifyThis);
  classifyThis = classifyThis.mul(mask);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, 5, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Point center( mouths[i].x + mouths[i].width*0.5, mouths[i].y + mouths[i].height*0.5 );
   ellipse( image, center, Size( mouths[i].width*0.5, mouths[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
  }
  imshow("MOUTH", image);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>


<commit_before>f#include "webcam.hpp"

using namespace cv;
using namespace std;

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

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
  imshow("webcam", image);

// thresholds on dark regions

  Mat black, blurred;
  split(image, channel);
  black = (channel[0] + channel[1] + channel[2])/3.0;
//  equalizeHist(black, black);
//  blur(black, blurred, Size(width/9,height/18));
//  threshold(blurred, blurred, 220, 255, THRESH_BINARY);
//  imshow("lol", blurred);
//  waitKey(1);
  merge(channel, 3, black);
  blur(black, blurred, Size(width/4.5,height/9));
  split(blurred, channel);
  black = (channel[0] + channel[1] + channel[2])/3.0;
  equalizeHist(black, black);
  bitwise_not(black,black);

  threshold(black, black, 220, 255, THRESH_BINARY);
  imshow("black", black);

/*
  split(image, channel);
  channel[0] = channel[0].mul(black);
  channel[1] = channel[1].mul(black);
  channel[2] = channel[2].mul(black);
  merge(channel, 3, image);
*/
//  imshow("yox", image);

//do some weird morphological closing thing
//  Mat channel[3];

/*
  Mat canny;
  Canny(image, canny, 0, 50);
  imshow("canny", canny);
*/

/*
  Mat fill = image.clone();
  Point seed(rand()%width, rand()%height);
  floodFill(fill, seed, Scalar(200,0,0), 0, Scalar(0,0,0), Scalar(25,25,25));
  imshow("fill", fill);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

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

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
  imshow("webcam", image);

// thresholds on dark regions

  Mat black, blurred;
  split(image, channel);
  black = (channel[0] + channel[1] + channel[2])/3.0;
//  equalizeHist(black, black);
//  blur(black, blurred, Size(width/9,height/18));
//  threshold(blurred, blurred, 220, 255, THRESH_BINARY);
//  imshow("lol", blurred);
//  waitKey(1);
  merge(channel, 3, black);
  blur(black, blurred, Size(width/4.5,height/9));
  split(blurred, channel);
  black = (channel[0] + channel[1] + channel[2])/3.0;
  equalizeHist(black, black);
  bitwise_not(black,black);

  threshold(black, black, 220, 255, THRESH_BINARY);
  imshow("black", black);

/*
  split(image, channel);
  channel[0] = channel[0].mul(black);
  channel[1] = channel[1].mul(black);
  channel[2] = channel[2].mul(black);
  merge(channel, 3, image);
*/
//  imshow("yox", image);

//do some weird morphological closing thing
//  Mat channel[3];

/*
  Mat canny;
  Canny(image, canny, 0, 50);
  imshow("canny", canny);
*/

/*
  Mat fill = image.clone();
  Point seed(rand()%width, rand()%height);
  floodFill(fill, seed, Scalar(200,0,0), 0, Scalar(0,0,0), Scalar(25,25,25));
  imshow("fill", fill);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>


<commit_before>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

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

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
// removed for now; it didn't generalize well
/*
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
  imshow("canny mask", gray.mul(canny));
*/

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
//  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
//  imshow("dark mask", gray.mul(kindofdark));

// this mask gets rid of anything far away from red stuff
// lips have a lot of red
  Mat notlips;
  Mat channels[3];
  split(image, channels);
  channels[2].convertTo(notlips, CV_32FC1);
  divide(notlips, gray, notlips, 1, CV_32FC1);
  //equalistHist is horrible for a red background
  //equalizeHist(notlips, notlips);
  threshold(notlips, notlips, tracker2/30.0, 1, THRESH_BINARY);
  imshow("lip mask", notlips*255);
  int tx = tracker1+1-(tracker1%2);
  if (tx<3) tx=3;
  if (tx>90) tx=91;
  morphFast(notlips, 100, tx, 0, 1);
  morphFast(notlips, 100, tx, 0, 0);
  imshow("lips2", notlips*255);
  waitKey(1);

  Mat mask = flow.mul(kindofdark);
// open the mask
  Mat smallMask0, smallMask1;
  resize(mask, smallMask0, Size(width/5,height/5));
  Mat erodeKernel = ellipticKernel(69,79);
  erode(smallMask0, smallMask1, erodeKernel);
  Mat dilateKernel = ellipticKernel(69,79);
  dilate(smallMask1, smallMask1, dilateKernel);
  bitwise_and(smallMask0, smallMask1, smallMask1);
  resize(smallMask1, mask, Size(width, height));
//  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
// erode it first since we really want to be sure it's bg

//  Mat erodeKernel = ellipticKernel(21);
  Mat erodedMask;
  erode(mask, erodedMask, erodeKernel);
  Mat mask_;
  subtract(1,erodedMask,mask_);
  Mat mask3, mask3_;
  channel[0] = erodedMask;
  channel[1] = erodedMask;
  channel[2] = erodedMask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

/*
  Moments lol = moments(gray, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);
*/
/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  int scale = tracker1+1;
  Mat classifyThis = image.clone();
  equalizeHist(gray, gray);//ew; watch out not to use this later
  resize(gray.mul(mask), classifyThis, Size(width/scale,height/scale));
//  bilateralFilter(gray, classifyThis, 15, 10, 1);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, tracker2, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Rect scaled(mouths[i].x*scale, mouths[i].y*scale, mouths[i].width*scale,mouths[i].height*scale);
   rectangle(image, scaled, Scalar(255,0,0));
  }
  imshow("MOUTH", image);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

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

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
// removed for now; it didn't generalize well
/*
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
  imshow("canny mask", gray.mul(canny));
*/

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
//  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
//  imshow("dark mask", gray.mul(kindofdark));

// this mask gets rid of anything far away from red stuff
// lips have a lot of red
  Mat notlips;
  Mat channels[3];
  split(image, channels);
  channels[2].convertTo(notlips, CV_32FC1);
  divide(notlips, gray, notlips, 1, CV_32FC1);
  //equalistHist is horrible for a red background
  //equalizeHist(notlips, notlips);
  threshold(notlips, notlips, tracker3/30.0, 1, THRESH_BINARY);
  imshow("lip mask", notlips*255);
  int tx = tracker1+1-(tracker1%2);
  if (tx<3) tx=1;
  if (tx>90) tx=91;
  morphFast(notlips, 100, tx, 0, 0);
  ty = tracker2+1-(tracker2%2);
  if (tx<3) tx=1;
  if (tx>90) tx=91;
  morphFast(notlips, 100, ty, 0, 1);
  imshow("lips2", notlips*255);
  waitKey(1);

  Mat mask = flow.mul(kindofdark);
// open the mask
  Mat smallMask0, smallMask1;
  resize(mask, smallMask0, Size(width/5,height/5));
  Mat erodeKernel = ellipticKernel(69,79);
  erode(smallMask0, smallMask1, erodeKernel);
  Mat dilateKernel = ellipticKernel(69,79);
  dilate(smallMask1, smallMask1, dilateKernel);
  bitwise_and(smallMask0, smallMask1, smallMask1);
  resize(smallMask1, mask, Size(width, height));
//  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
// erode it first since we really want to be sure it's bg

//  Mat erodeKernel = ellipticKernel(21);
  Mat erodedMask;
  erode(mask, erodedMask, erodeKernel);
  Mat mask_;
  subtract(1,erodedMask,mask_);
  Mat mask3, mask3_;
  channel[0] = erodedMask;
  channel[1] = erodedMask;
  channel[2] = erodedMask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

/*
  Moments lol = moments(gray, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);
*/
/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  int scale = tracker1+1;
  Mat classifyThis = image.clone();
  equalizeHist(gray, gray);//ew; watch out not to use this later
  resize(gray.mul(mask), classifyThis, Size(width/scale,height/scale));
//  bilateralFilter(gray, classifyThis, 15, 10, 1);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, tracker2, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Rect scaled(mouths[i].x*scale, mouths[i].y*scale, mouths[i].width*scale,mouths[i].height*scale);
   rectangle(image, scaled, Scalar(255,0,0));
  }
  imshow("MOUTH", image);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * Copyright © 2011 VideoLAN
 * $Id$
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "timetooltip.hpp"

#include <QApplication>
#include <QPainter>
#include <QPainterPath>
#include <QBitmap>
#include <QFontMetrics>

#define TIP_HEIGHT 5

TimeTooltip::TimeTooltip( QWidget *parent ) :
    QWidget( parent )
{
    setWindowFlags( Qt::Window                  |
                    Qt::WindowStaysOnTopHint    |
                    Qt::FramelessWindowHint     |
                    Qt::X11BypassWindowManagerHint );

    // Tell Qt that it doesn't need to erase the background before
    // a paintEvent occurs. This should save some CPU cycles.
    setAttribute( Qt::WA_OpaquePaintEvent );

#ifdef Q_WS_WIN
    /*
    - This attribute is required on Windows to avoid focus stealing of other windows.
    - When set on Linux the TimeTooltip appears behind the FSController in fullscreen.
    */
    setAttribute( Qt::WA_ShowWithoutActivating );
#endif

    // Inherit from the system default font size -5
    mFont = QFont( "Verdana", qMax( qApp->font().pointSize() - 5, 7 ) );
    mPreviousMetricsWidth = 0;

    // Set default text
    setText( "00:00:00", "" );
}

void TimeTooltip::buildPath()
{
    QFontMetrics metrics( mFont );

    // Get the bounding box required to print the text and add some padding
    QRect textbox = metrics.boundingRect( mDisplayedText ).adjusted( -2, -2, 2, 2 );

    if ( mPreviousMetricsWidth == textbox.width() )
        return; //same width == same path
    else
        mPreviousMetricsWidth = textbox.width();

    mBox = QRect( 0, 0, textbox.width(), textbox.height() );

    // Resize the widget to fit our needs
    resize( mBox.width() + 1, mBox.height() + TIP_HEIGHT + 1 );

    // Prepare the painter path for future use so
    // we only have to generate the text at runtime.

    // Draw the text box
    mPainterPath = QPainterPath();
    mPainterPath.addRect( mBox );

    // Draw the tip
    int center = mBox.width() / 2;
    QPolygon polygon;
    polygon << QPoint( center - 3,   mBox.height() )
            << QPoint( center,       mBox.height() + TIP_HEIGHT )
            << QPoint( center + 3,   mBox.height() );

    mPainterPath.addPolygon( polygon );

    // Store the simplified version of the path
    mPainterPath = mPainterPath.simplified();

    // Create the mask used to erase the background
    // Note: this is a binary bitmap (black & white)
    mMask = QBitmap( size() );
    QPainter painter( &mMask );
    painter.fillRect( mMask.rect(), Qt::white );
    painter.setPen( QColor( 0, 0, 0 ) );
    painter.setBrush( QColor( 0, 0, 0 ) );
    painter.drawPath( mPainterPath );
    painter.end();

    setMask( mMask );
}

void TimeTooltip::setText( const QString& time, const QString& text )
{
    mDisplayedText = time;
    if ( !mText.isEmpty() ) mDisplayedText.append( " - " + text );

    if ( time.length() != mTime.length() || mText != text )
        buildPath();

    mTime = time;
    mText = text;
    update();
}

void TimeTooltip::paintEvent( QPaintEvent * )
{
    QPainter p( this );
    p.setRenderHints( QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing );

    p.setPen( Qt::black );
    p.setBrush( qApp->palette().base() );
    p.drawPath( mPainterPath );

    p.setFont( mFont );
    p.setPen( QPen( qApp->palette().text(), 1 ) );
    p.drawText( mBox, Qt::AlignCenter, mDisplayedText );
}

#undef TIP_HEIGHT
<commit_msg>Qt4: Test the correct text.<commit_after>/*****************************************************************************
 * Copyright © 2011 VideoLAN
 * $Id$
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "timetooltip.hpp"

#include <QApplication>
#include <QPainter>
#include <QPainterPath>
#include <QBitmap>
#include <QFontMetrics>

#define TIP_HEIGHT 5

TimeTooltip::TimeTooltip( QWidget *parent ) :
    QWidget( parent )
{
    setWindowFlags( Qt::Window                  |
                    Qt::WindowStaysOnTopHint    |
                    Qt::FramelessWindowHint     |
                    Qt::X11BypassWindowManagerHint );

    // Tell Qt that it doesn't need to erase the background before
    // a paintEvent occurs. This should save some CPU cycles.
    setAttribute( Qt::WA_OpaquePaintEvent );

#ifdef Q_WS_WIN
    /*
    - This attribute is required on Windows to avoid focus stealing of other windows.
    - When set on Linux the TimeTooltip appears behind the FSController in fullscreen.
    */
    setAttribute( Qt::WA_ShowWithoutActivating );
#endif

    // Inherit from the system default font size -5
    mFont = QFont( "Verdana", qMax( qApp->font().pointSize() - 5, 7 ) );
    mPreviousMetricsWidth = 0;

    // Set default text
    setText( "00:00:00", "" );
}

void TimeTooltip::buildPath()
{
    QFontMetrics metrics( mFont );

    // Get the bounding box required to print the text and add some padding
    QRect textbox = metrics.boundingRect( mDisplayedText ).adjusted( -2, -2, 2, 2 );

    if ( mPreviousMetricsWidth == textbox.width() )
        return; //same width == same path
    else
        mPreviousMetricsWidth = textbox.width();

    mBox = QRect( 0, 0, textbox.width(), textbox.height() );

    // Resize the widget to fit our needs
    resize( mBox.width() + 1, mBox.height() + TIP_HEIGHT + 1 );

    // Prepare the painter path for future use so
    // we only have to generate the text at runtime.

    // Draw the text box
    mPainterPath = QPainterPath();
    mPainterPath.addRect( mBox );

    // Draw the tip
    int center = mBox.width() / 2;
    QPolygon polygon;
    polygon << QPoint( center - 3,   mBox.height() )
            << QPoint( center,       mBox.height() + TIP_HEIGHT )
            << QPoint( center + 3,   mBox.height() );

    mPainterPath.addPolygon( polygon );

    // Store the simplified version of the path
    mPainterPath = mPainterPath.simplified();

    // Create the mask used to erase the background
    // Note: this is a binary bitmap (black & white)
    mMask = QBitmap( size() );
    QPainter painter( &mMask );
    painter.fillRect( mMask.rect(), Qt::white );
    painter.setPen( QColor( 0, 0, 0 ) );
    painter.setBrush( QColor( 0, 0, 0 ) );
    painter.drawPath( mPainterPath );
    painter.end();

    setMask( mMask );
}

void TimeTooltip::setText( const QString& time, const QString& text )
{
    mDisplayedText = time;
    if ( !text.isEmpty() )
        mDisplayedText.append( " - " ).append( text );

    if ( time.length() != mTime.length() || mText != text )
        buildPath();

    mTime = time;
    mText = text;
    update();
}

void TimeTooltip::paintEvent( QPaintEvent * )
{
    QPainter p( this );
    p.setRenderHints( QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing );

    p.setPen( Qt::black );
    p.setBrush( qApp->palette().base() );
    p.drawPath( mPainterPath );

    p.setFont( mFont );
    p.setPen( QPen( qApp->palette().text(), 1 ) );
    p.drawText( mBox, Qt::AlignCenter, mDisplayedText );
}

#undef TIP_HEIGHT
<|endoftext|>