<commit_before>// STCDB class

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <stdlib.h>

#include "STCDB.h"

#include "Env.h"
#include "CycException.h"

using namespace std;

STCDB* STCDB::instance_ = 0;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDB* STCDB::Instance() {
  // If we haven't created a STCDB yet, create it.
  // Return it either way
  if (0 == instance_) {
    instance_ = new STCDB();
  }
  return instance_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDB::STCDB() :
  file_path_(Env::getInstallPath() + "/share/stc_data.sqlite") {
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDB::~STCDB() {
  delete instance_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double STCDB::stc(mat_t mat, Iso tope, int the_time){
  return table(mat)->stc(tope, the_time);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDataTablePtr STCDB::table(mat_t mat) {
  STCDataTablePtr to_ret;
  if(initialized(mat_name(mat)) ){
    to_ret = (*tables_.find(mat_name(mat))).second;
  } else {
    to_ret = initializeFromSQL(mat);
    tables_.insert(make_pair(mat_name(mat),to_ret));
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool STCDB::initialized(string mat){
  map<string,STCDataTablePtr>::iterator it;
  it=tables_.find(mat);
  return it!=tables_.end()? true : false;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string STCDB::mat_name(mat_t mat){
  std::string mat_name =
    "a"+boost::lexical_cast<string>(mat.alpha_th)+
    "k"+boost::lexical_cast<string>(mat.k_th)+
    "s"+boost::lexical_cast<string>(mat.spacing)+
    "r"+boost::lexical_cast<string>(mat.r_calc);
  return mat_name;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDataTablePtr STCDB::initializeFromSQL(mat_t mat){
  SqliteDb* db = new SqliteDb(file_path_);
  vector<stc_t> arr = stc_array(db, mat);
  STCDataTablePtr to_ret = STCDataTablePtr(new STCDataTable(mat_name(mat), vec,
        iso_index(db, mat), time_index(db, mat)));
  delete db;
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string STCDB::whereClause(mat_t mat){
  string where_clause = "WHERE alpha_th="+
    boost::lexical_cast<string>( mat.alpha_th ) +
    " AND k_th="    + boost::lexical_cast<string>( mat.k_th ) +
    " AND spacing=" + boost::lexical_cast<string>( mat.spacing ) +
    " AND r_calc="  + boost::lexical_cast<string>( mat.r_calc );
  return where_clause;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
map<Iso, int> STCDB::iso_index(SqliteDb* db, mat_t mat){

  std::vector<StrList> inums = db->query("SELECT iso FROM STCData " +
      whereClause(mat));

  map<Iso, int> iso_index;
  for (int i = 0; i < inums.size(); i++){
    // // obtain the database row and declare the appropriate members
    string iStr = inums.at(i).at(0);
    Iso tope = atoi( iStr.c_str() );
    // log it accordingly
    iso_index.insert(make_pair(tope, i));
  }
  return iso_index;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
map<Iso, int> STCDB::time_index(SqliteDb* db, mat_t mat){

  std::vector<StrList> inums = db->query("SELECT time FROM STCData " +
      whereClause(mat));

  map<int, int> time_index;
  for (int t = 0; t < tnums.size(); t++){
    // // obtain the database row and declare the appropriate members
    strtng tStr = tnums.at(t).at(0);
    int the_time = atoi( tStr.c_str() );
    // log it accordingly
    time_index.insert(make_pair(the_time, t));
  }
  return time_index;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vector<stc_t> STCDB::n_timesteps(SqliteDb* db, mat_t mat){
  std::vector<StrList> tnums = db->query("SELECT DISTINCT time FROM STCData " +
      whereClause(mat));
  int n_timesteps = tnums.size();
  return n_timesteps;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vector<stc_t> STCDB::n_isos(SqliteDb* db, mat_t mat){
  std::vector<StrList> inums = db->query("SELECT DISTINCT iso FROM STCData " +
      whereClause(mat));
  int n_isos = inums.size();
  return n_isos;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vector<stc_t> STCDB::stc_vec(SqliteDb* db, mat_t mat){
  std::vector<StrList> inums = db->query("SELECT iso FROM STCData " +
      whereClause(mat));
  std::vector<StrList> snums = db->query("SELECT stc FROM STCData " +
      whereClause(mat));
  std::vector<StrList> tnums = db->query("SELECT time FROM STCData " +
      whereClause(mat));

  boost::multi_array<double, 2> stc_array(boost::extents(n_isos(db, mat),
        n_timesteps(db, mat)));

  vector<stc_t> stc_vec;
  for (int i = 0; i < inums.size(); i++){
    // // obtain the database row and declare the appropriate members
    string iStr = inums.at(i).at(0);
    string sStr = snums.at(i).at(0);
    string tStr = tnums.at(i).at(0);
    Iso tope = atoi( iStr.c_str() );
    int the_time = atoi( tStr.c_str() );
    double stc = atof( sStr.c_str() );
    // determine array indcies and add stc to the stc array
    stc_array[iso_index(db, mat)[iso]][time_index(db, mat)[the_time]] = stc;
  }
  return stc_array;
}

<commit_msg>deprecates stc_vec<commit_after>// STCDB class

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <stdlib.h>

#include "STCDB.h"

#include "Env.h"
#include "CycException.h"

using namespace std;

STCDB* STCDB::instance_ = 0;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDB* STCDB::Instance() {
  // If we haven't created a STCDB yet, create it.
  // Return it either way
  if (0 == instance_) {
    instance_ = new STCDB();
  }
  return instance_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDB::STCDB() :
  file_path_(Env::getInstallPath() + "/share/stc_data.sqlite") {
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDB::~STCDB() {
  delete instance_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double STCDB::stc(mat_t mat, Iso tope, int the_time){
  return table(mat)->stc(tope, the_time);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDataTablePtr STCDB::table(mat_t mat) {
  STCDataTablePtr to_ret;
  if(initialized(mat_name(mat)) ){
    to_ret = (*tables_.find(mat_name(mat))).second;
  } else {
    to_ret = initializeFromSQL(mat);
    tables_.insert(make_pair(mat_name(mat),to_ret));
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool STCDB::initialized(string mat){
  map<string,STCDataTablePtr>::iterator it;
  it=tables_.find(mat);
  return it!=tables_.end()? true : false;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string STCDB::mat_name(mat_t mat){
  std::string mat_name =
    "a"+boost::lexical_cast<string>(mat.alpha_th)+
    "k"+boost::lexical_cast<string>(mat.k_th)+
    "s"+boost::lexical_cast<string>(mat.spacing)+
    "r"+boost::lexical_cast<string>(mat.r_calc);
  return mat_name;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STCDataTablePtr STCDB::initializeFromSQL(mat_t mat){
  SqliteDb* db = new SqliteDb(file_path_);
  vector<stc_t> arr = stc_array(db, mat);
  STCDataTablePtr to_ret = STCDataTablePtr(new STCDataTable(mat_name(mat), vec,
        iso_index(db, mat), time_index(db, mat)));
  delete db;
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string STCDB::whereClause(mat_t mat){
  string where_clause = "WHERE alpha_th="+
    boost::lexical_cast<string>( mat.alpha_th ) +
    " AND k_th="    + boost::lexical_cast<string>( mat.k_th ) +
    " AND spacing=" + boost::lexical_cast<string>( mat.spacing ) +
    " AND r_calc="  + boost::lexical_cast<string>( mat.r_calc );
  return where_clause;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
map<Iso, int> STCDB::iso_index(SqliteDb* db, mat_t mat){

  std::vector<StrList> inums = db->query("SELECT iso FROM STCData " +
      whereClause(mat));

  map<Iso, int> iso_index;
  for (int i = 0; i < inums.size(); i++){
    // // obtain the database row and declare the appropriate members
    string iStr = inums.at(i).at(0);
    Iso tope = atoi( iStr.c_str() );
    // log it accordingly
    iso_index.insert(make_pair(tope, i));
  }
  return iso_index;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
map<Iso, int> STCDB::time_index(SqliteDb* db, mat_t mat){

  std::vector<StrList> inums = db->query("SELECT time FROM STCData " +
      whereClause(mat));

  map<int, int> time_index;
  for (int t = 0; t < tnums.size(); t++){
    // // obtain the database row and declare the appropriate members
    strtng tStr = tnums.at(t).at(0);
    int the_time = atoi( tStr.c_str() );
    // log it accordingly
    time_index.insert(make_pair(the_time, t));
  }
  return time_index;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vector<stc_t> STCDB::n_timesteps(SqliteDb* db, mat_t mat){
  std::vector<StrList> tnums = db->query("SELECT DISTINCT time FROM STCData " +
      whereClause(mat));
  int n_timesteps = tnums.size();
  return n_timesteps;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vector<stc_t> STCDB::n_isos(SqliteDb* db, mat_t mat){
  std::vector<StrList> inums = db->query("SELECT DISTINCT iso FROM STCData " +
      whereClause(mat));
  int n_isos = inums.size();
  return n_isos;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
boost::multi_array<double, 2> STCDB::stc_array(SqliteDb* db, mat_t mat){
  std::vector<StrList> inums = db->query("SELECT iso FROM STCData " +
      whereClause(mat));
  std::vector<StrList> snums = db->query("SELECT stc FROM STCData " +
      whereClause(mat));
  std::vector<StrList> tnums = db->query("SELECT time FROM STCData " +
      whereClause(mat));

  boost::multi_array<double, 2> stc_array(boost::extents(n_isos(db, mat),
        n_timesteps(db, mat)));

  vector<stc_t> stc_vec;
  for (int i = 0; i < inums.size(); i++){
    // // obtain the database row and declare the appropriate members
    string iStr = inums.at(i).at(0);
    string sStr = snums.at(i).at(0);
    string tStr = tnums.at(i).at(0);
    Iso tope = atoi( iStr.c_str() );
    int the_time = atoi( tStr.c_str() );
    double stc = atof( sStr.c_str() );
    // determine array indcies and add stc to the stc array
    stc_array[iso_index(db, mat)[iso]][time_index(db, mat)[the_time]] = stc;
  }
  return stc_array;
}

<|endoftext|>


<commit_before>#include "interpreter.hpp"

Interpreter::Interpreter(std::ostream& logStream)
    : m_logger{logStream}
{
}

int Interpreter::interpret(const ast::StatementList& statements)
{
    for(auto& statement : statements)
    {
        // TODO: make eval return an error code along
        // with a Value?
        statement.eval(*this);
    }

	return 0;
}
<commit_msg>Case sensitivity matters<commit_after>#include "Interpreter.hpp"

Interpreter::Interpreter(std::ostream& logStream)
    : m_logger{logStream}
{
}

int Interpreter::interpret(const ast::StatementList& statements)
{
    for(auto& statement : statements)
    {
        // TODO: make eval return an error code along
        // with a Value?
        statement.eval(*this);
    }

	return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: browserview.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: fs $ $Date: 2002-11-06 09:19:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _EXTENSIONS_PROPCTRLR_BROWSERVIEW_HXX_
#include "browserview.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_
#include "propertyeditor.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPHELPID_HRC_
#include "prophelpid.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_
#include "propcontroller.hxx"
#endif
#include <memory>

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;

    //========================================================================
    //= class OPropertyBrowserView
    //========================================================================
    DBG_NAME(OPropertyBrowserView)
    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, WinBits nBits)
                  :Window(_pParent, nBits | WB_3DLOOK)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, const ResId& rId)
                  :Window(_pParent, rId)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetPosSizePixel(Point(0,0), aSize);
        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    IMPL_LINK(OPropertyBrowserView, OnPageActivation, void*, EMPTYARG)
    {
        m_nActivePage = m_pPropBox->GetCurPage();
        if (m_aPageActivationHandler.IsSet())
            m_aPageActivationHandler.Call(NULL);
        return 0L;
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::~OPropertyBrowserView()
    {
        if(m_pPropBox)
        {
            sal_uInt16 nTmpPage = m_pPropBox->GetCurPage();
            if (nTmpPage)
                m_nActivePage = nTmpPage;
            ::std::auto_ptr<Window> aTemp(m_pPropBox);
            m_pPropBox = NULL;
        }
        if (m_pActiveController)
            m_pActiveController->release();
        m_pActiveController = NULL;

        m_xORB = NULL;

        DBG_DTOR(OPropertyBrowserView, NULL);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::activatePage(sal_uInt16 _nPage)
    {
        m_nActivePage = _nPage;
        getPropertyBox()->SetPage(m_nActivePage);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::setActiveController(OPropertyBrowserController* _pController)
    {
        if (_pController != m_pActiveController)
        {
            if (m_pActiveController) m_pActiveController->release();
            m_pActiveController = _pController;
            if (m_pActiveController) m_pActiveController->acquire();
        }
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::GetFocus()
    {
        if (m_pPropBox)
            m_pPropBox->GrabFocus();
        else
            Window::GetFocus();
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::Resize()
    {
        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetSizePixel(aSize);
    }

    // #95343# ---------------------------------------------------------------
    ::com::sun::star::awt::Size OPropertyBrowserView::getMinimumSize()
    {
        Size aSize = GetOutputSizePixel();
        if( m_pPropBox )
            aSize.setWidth( m_pPropBox->getMinimumWidth() );
        return ::com::sun::star::awt::Size( aSize.Width(), aSize.Height() );
    }

//............................................................................
} // namespace pcr
//............................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.5  2002/08/06 08:13:10  oj
 *  #102058# use auto_ptr in dtor
 *
 *  Revision 1.4  2001/05/30 13:44:49  fs
 *  #86838# forward the GetFocus event to the property box
 *
 *  Revision 1.3  2001/02/19 14:08:31  fs
 *  #84041# infrastructure for activating pages from outside
 *
 *  Revision 1.2  2001/01/18 14:45:10  rt
 *  #65293# semicolon removed
 *
 *  Revision 1.1  2001/01/12 11:26:10  fs
 *  initial checkin - outsourced the form property browser
 *
 *
 *  Revision 1.0 08.01.01 11:05:54  fs
 ************************************************************************/

<commit_msg>#95343# minimum size defaulted (not actual size)<commit_after>/*************************************************************************
 *
 *  $RCSfile: browserview.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: fs $ $Date: 2002-11-12 12:06:47 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _EXTENSIONS_PROPCTRLR_BROWSERVIEW_HXX_
#include "browserview.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_
#include "propertyeditor.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPHELPID_HRC_
#include "prophelpid.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_
#include "propcontroller.hxx"
#endif
#include <memory>

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;

    //========================================================================
    //= class OPropertyBrowserView
    //========================================================================
    DBG_NAME(OPropertyBrowserView)
    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, WinBits nBits)
                  :Window(_pParent, nBits | WB_3DLOOK)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, const ResId& rId)
                  :Window(_pParent, rId)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetPosSizePixel(Point(0,0), aSize);
        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    IMPL_LINK(OPropertyBrowserView, OnPageActivation, void*, EMPTYARG)
    {
        m_nActivePage = m_pPropBox->GetCurPage();
        if (m_aPageActivationHandler.IsSet())
            m_aPageActivationHandler.Call(NULL);
        return 0L;
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::~OPropertyBrowserView()
    {
        if(m_pPropBox)
        {
            sal_uInt16 nTmpPage = m_pPropBox->GetCurPage();
            if (nTmpPage)
                m_nActivePage = nTmpPage;
            ::std::auto_ptr<Window> aTemp(m_pPropBox);
            m_pPropBox = NULL;
        }
        if (m_pActiveController)
            m_pActiveController->release();
        m_pActiveController = NULL;

        m_xORB = NULL;

        DBG_DTOR(OPropertyBrowserView, NULL);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::activatePage(sal_uInt16 _nPage)
    {
        m_nActivePage = _nPage;
        getPropertyBox()->SetPage(m_nActivePage);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::setActiveController(OPropertyBrowserController* _pController)
    {
        if (_pController != m_pActiveController)
        {
            if (m_pActiveController) m_pActiveController->release();
            m_pActiveController = _pController;
            if (m_pActiveController) m_pActiveController->acquire();
        }
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::GetFocus()
    {
        if (m_pPropBox)
            m_pPropBox->GrabFocus();
        else
            Window::GetFocus();
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::Resize()
    {
        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetSizePixel(aSize);
    }

    // #95343# ---------------------------------------------------------------
    ::com::sun::star::awt::Size OPropertyBrowserView::getMinimumSize()
    {
        Size aSize = GetOutputSizePixel();
        aSize.setHeight( 250 );
        if( m_pPropBox )
            aSize.setWidth( m_pPropBox->getMinimumWidth() );
        return ::com::sun::star::awt::Size( aSize.Width(), aSize.Height() );
    }

//............................................................................
} // namespace pcr
//............................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.6  2002/11/06 09:19:27  fs
 *  #95343# (on behalf of SleepyBear@openoffice.org) changes for calculating layout
 *
 *  Revision 1.5  2002/08/06 08:13:10  oj
 *  #102058# use auto_ptr in dtor
 *
 *  Revision 1.4  2001/05/30 13:44:49  fs
 *  #86838# forward the GetFocus event to the property box
 *
 *  Revision 1.3  2001/02/19 14:08:31  fs
 *  #84041# infrastructure for activating pages from outside
 *
 *  Revision 1.2  2001/01/18 14:45:10  rt
 *  #65293# semicolon removed
 *
 *  Revision 1.1  2001/01/12 11:26:10  fs
 *  initial checkin - outsourced the form property browser
 *
 *
 *  Revision 1.0 08.01.01 11:05:54  fs
 ************************************************************************/

<|endoftext|>


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

#ifndef PCL_FEATURES_IMPL_FPFH_H_
#define PCL_FEATURES_IMPL_FPFH_H_

#include "pcl/features/fpfh.h"

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> bool
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computePairFeatures (
      const pcl::PointCloud<PointInT> &cloud, const pcl::PointCloud<PointNT> &normals,
      int p_idx, int q_idx, float &f1, float &f2, float &f3, float &f4)
{
  // Compute the Cartesian difference between the two points
  Eigen::Vector4f delta = cloud.points[q_idx].getVector4fMap () - cloud.points[p_idx].getVector4fMap ();
  delta[3] = 0;

  // Compute the Euclidean norm = || p_idx - q_idx ||
  float distance_sqr = delta.squaredNorm ();

  if (distance_sqr == 0)
  {
    PCL_DEBUG ("Euclidean distance between points %d and %d is 0!\n", p_idx, q_idx);
    f1 = f2 = f3 = f4 = 0;
    return (false);
  }

  // Estimate f4 = || delta ||
  f4 = sqrt (distance_sqr);

  // Create a Darboux frame coordinate system u-v-w
  // u = n1; v = (p_idx - q_idx) x u / || (p_idx - q_idx) x u ||; w = u x v
  pcl::Vector4fMapConst u = normals.points[p_idx].getNormalVector4fMap ();

  // Estimate f3 = u * delta / || delta ||
  // delta[3] = 0 (line 59)
  f3 = u.dot (delta) / f4;

  // v = delta * u
  Eigen::Vector4f v = Eigen::Vector4f::Zero ();
  v = delta.cross3 (u);

  distance_sqr = v.squaredNorm ();
  if (distance_sqr == 0)
  {
    PCL_DEBUG ("Norm of Delta x U is 0 for point %d and %d!\n", p_idx, q_idx);
    f1 = f2 = f3 = f4 = 0;
    return (false);
  }

  // Copy the q_idx normal
  Eigen::Vector4f nq (normals.points[q_idx].normal_x,
                      normals.points[q_idx].normal_y,
                      normals.points[q_idx].normal_z,
                      0);

  // Normalize the vector
  v /= sqrt (distance_sqr);

  // Compute delta (w) = u x v
  delta = u.cross3 (v);

  // Compute f2 = v * n2;
  // v[3] = 0 (line 82)
  f2 = v.dot (nq);

  // Compute f1 = arctan (w * n2, u * n2) i.e. angle of n2 in the x=u, y=w coordinate system
  // delta[3] = 0 (line 59), nq[3] = 0 (line 97)
  f1 = atan2f (delta.dot (nq), u.dot (nq));       // @todo: optimize this

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT>
void pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::
computePointSPFHSignature (const pcl::PointCloud<PointInT> &cloud, const pcl::PointCloud<PointNT> &normals,
                           int p_idx, const std::vector<int> &indices,
                           Eigen::MatrixXf &hist_f1, Eigen::MatrixXf &hist_f2, Eigen::MatrixXf &hist_f3)
{
  Eigen::Vector4f pfh_tuple;
  // Get the number of bins from the histograms size
  int nr_bins_f1 = hist_f1.cols ();
  int nr_bins_f2 = hist_f2.cols ();
  int nr_bins_f3 = hist_f3.cols ();

  // Factorization constant
  float hist_incr = 100.0 / (float)(indices.size () - 1);

  // Iterate over all the points in the neighborhood
  for (size_t idx = 0; idx < indices.size (); ++idx)
  {
    // Avoid unnecessary returns
    if (p_idx == indices[idx])
      continue;

    // Compute the pair P to NNi
    if (!computePairFeatures (cloud, normals, p_idx, indices[idx], pfh_tuple[0], pfh_tuple[1], pfh_tuple[2], pfh_tuple[3]))
      continue;

    // Normalize the f1, f2, f3 features and push them in the histogram
    int h_index = floor (nr_bins_f1 * ((pfh_tuple[0] + M_PI) * d_pi_));
    if (h_index < 0)           h_index = 0;
    if (h_index >= nr_bins_f1) h_index = nr_bins_f1 - 1;
    hist_f1 (p_idx, h_index) += hist_incr;

    h_index = floor (nr_bins_f2 * ((pfh_tuple[1] + 1.0) * 0.5));
    if (h_index < 0)           h_index = 0;
    if (h_index >= nr_bins_f2) h_index = nr_bins_f2 - 1;
    hist_f2 (p_idx, h_index) += hist_incr;

    h_index = floor (nr_bins_f3 * ((pfh_tuple[2] + 1.0) * 0.5));
    if (h_index < 0)           h_index = 0;
    if (h_index >= nr_bins_f3) h_index = nr_bins_f3 - 1;
    hist_f3 (p_idx, h_index) += hist_incr;
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::weightPointSPFHSignature (
      const Eigen::MatrixXf &hist_f1, const Eigen::MatrixXf &hist_f2, const Eigen::MatrixXf &hist_f3,
      const std::vector<int> &indices, const std::vector<float> &dists, Eigen::VectorXf &fpfh_histogram)
{
  assert (indices.size () == dists.size ());
  double sum_f1 = 0.0, sum_f2 = 0.0, sum_f3 = 0.0;
  float weight = 0.0, val_f1, val_f2, val_f3;

  // Get the number of bins from the histograms size
  int nr_bins_f1 = hist_f1.cols ();
  int nr_bins_f2 = hist_f2.cols ();
  int nr_bins_f3 = hist_f3.cols ();
  int nr_bins_f12 = nr_bins_f1 + nr_bins_f2;

  // Use the entire patch
  for (size_t idx = 0, data_size = indices.size (); idx < data_size; ++idx)
  {
    // Minus the query point itself
    if (dists[idx] == 0)
      continue;

    // Standard weighting function used
    weight = 1.0 / dists[idx];

    // Weight the SPFH of the query point with the SPFH of its neighbors
    for (int f1_i = 0; f1_i < nr_bins_f1; ++f1_i)
    {
      val_f1 = hist_f1 (indices[idx], f1_i) * weight;
      sum_f1 += val_f1;
      fpfh_histogram[f1_i] += val_f1;
    }

    for (int f2_i = 0; f2_i < nr_bins_f2; ++f2_i)
    {
      val_f2 = hist_f2 (indices[idx], f2_i) * weight;
      sum_f2 += val_f2;
      fpfh_histogram[f2_i + nr_bins_f1] += val_f2;
    }

    for (int f3_i = 0; f3_i < nr_bins_f3; ++f3_i)
    {
      val_f3 = hist_f3 (indices[idx], f3_i) * weight;
      sum_f3 += val_f3;
      fpfh_histogram[f3_i + nr_bins_f12] += val_f3;
    }
  }

  if (sum_f1 != 0)
    sum_f1 = 100.0 / sum_f1;           // histogram values sum up to 100
  if (sum_f2 != 0)
    sum_f2 = 100.0 / sum_f2;           // histogram values sum up to 100
  if (sum_f3 != 0)
    sum_f3 = 100.0 / sum_f3;           // histogram values sum up to 100

  // Adjust final FPFH values
  for (int f1_i = 0; f1_i < nr_bins_f1; ++f1_i)
    fpfh_histogram[f1_i] *= sum_f1;
  for (int f2_i = 0; f2_i < nr_bins_f2; ++f2_i)
    fpfh_histogram[f2_i + nr_bins_f1] *= sum_f2;
  for (int f3_i = 0; f3_i < nr_bins_f3; ++f3_i)
    fpfh_histogram[f3_i + nr_bins_f12] *= sum_f3;
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeFeature (PointCloudOut &output)
{
  // Allocate enough space to hold the NN search results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  std::set<int> spfh_indices;
  std::vector<int> spfh_hist_lookup (surface_->points.size ());

  // Build a list of (unique) indices for which we will need to compute SPFH signatures
  // (We need an SPFH signature for every point that is a neighbor of any point in input_[indices_])
  if (surface_ != input_ ||
      indices_->size () != surface_->points.size ())
  {
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      int p_idx = (*indices_)[idx];
      this->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists);

      spfh_indices.insert (nn_indices.begin (), nn_indices.end ());
    }
  }
  else
  {
    // Special case: When a feature must be computed at every point, there is no need for a neighborhood search
    for (size_t idx = 0; idx < indices_->size (); ++idx)
      spfh_indices.insert (idx);
  }

  // Initialize the arrays that will store the SPFH signatures
  size_t data_size = spfh_indices.size ();
  hist_f1_.setZero (data_size, nr_bins_f1_);
  hist_f2_.setZero (data_size, nr_bins_f2_);
  hist_f3_.setZero (data_size, nr_bins_f3_);

  // Compute SPFH signatures for every point that needs them
  std::set<int>::iterator spfh_indices_itr = spfh_indices.begin ();
  for (size_t i = 0; i < spfh_indices.size (); ++i)
  {
    // Get the next point index
    int p_idx = *spfh_indices_itr;
    ++spfh_indices_itr;

    // Find the neighborhood around p_idx
    this->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists);

    // Estimate the SPFH signature around p_idx
    computePointSPFHSignature (*surface_, *normals_, i, nn_indices, hist_f1_, hist_f2_, hist_f3_);

    // Populate a lookup table for converting a point index to its corresponding row in the spfh_hist_* matrices
    spfh_hist_lookup[p_idx] = i;
  }

  // Intialize the array that will store the FPFH signature
  int nr_bins = nr_bins_f1_ + nr_bins_f2_ + nr_bins_f3_;
  fpfh_histogram_.setZero (nr_bins);

  // Iterate over the entire index vector
  for (size_t idx = 0; idx < indices_->size (); ++idx)
  {
    // Find the indices of point idx's neighbors...
    this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists);

    // ... and remap the nn_indices values so that they represent row indices in the spfh_hist_* matrices
    // instead of indices into surface_->points
    for (size_t i = 0; i < nn_indices.size (); ++i)
      nn_indices[i] = spfh_hist_lookup[nn_indices[i]];

    // Compute the FPFH signature (i.e. compute a weighted combination of local SPFH signatures) ...
    weightPointSPFHSignature (hist_f1_, hist_f2_, hist_f3_, nn_indices, nn_dists, fpfh_histogram_);

    // ...and copy it into the output cloud
    for (int d = 0; d < fpfh_histogram_.size (); ++d)
      output.points[idx].histogram[d] = fpfh_histogram_[d];

    fpfh_histogram_.setZero ();
  }

}

#define PCL_INSTANTIATE_FPFHEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::FPFHEstimation<T,NT,OutT>;

#endif    // PCL_FEATURES_IMPL_FPFH_H_

<commit_msg>FPFHEstimation now uses the pcl::computePairFeatures () method instead of its own private copy of it<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2009, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FEATURES_IMPL_FPFH_H_
#define PCL_FEATURES_IMPL_FPFH_H_

#include "pcl/features/fpfh.h"
#include <pcl/features/pfh.h>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> bool
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computePairFeatures (
      const pcl::PointCloud<PointInT> &cloud, const pcl::PointCloud<PointNT> &normals,
      int p_idx, int q_idx, float &f1, float &f2, float &f3, float &f4)
{
  pcl::computePairFeatures (cloud.points[p_idx].getVector4fMap (), normals.points[p_idx].getNormalVector4fMap (),
                             cloud.points[q_idx].getVector4fMap (), normals.points[q_idx].getNormalVector4fMap (),
                             f1, f2, f3, f4);
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT>
void pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::
computePointSPFHSignature (const pcl::PointCloud<PointInT> &cloud, const pcl::PointCloud<PointNT> &normals,
                           int p_idx, const std::vector<int> &indices,
                           Eigen::MatrixXf &hist_f1, Eigen::MatrixXf &hist_f2, Eigen::MatrixXf &hist_f3)
{
  Eigen::Vector4f pfh_tuple;
  // Get the number of bins from the histograms size
  int nr_bins_f1 = hist_f1.cols ();
  int nr_bins_f2 = hist_f2.cols ();
  int nr_bins_f3 = hist_f3.cols ();

  // Factorization constant
  float hist_incr = 100.0 / (float)(indices.size () - 1);

  // Iterate over all the points in the neighborhood
  for (size_t idx = 0; idx < indices.size (); ++idx)
  {
    // Avoid unnecessary returns
    if (p_idx == indices[idx])
      continue;

    // Compute the pair P to NNi
    if (!computePairFeatures (cloud, normals, p_idx, indices[idx], pfh_tuple[0], pfh_tuple[1], pfh_tuple[2], pfh_tuple[3]))
      continue;

    // Normalize the f1, f2, f3 features and push them in the histogram
    int h_index = floor (nr_bins_f1 * ((pfh_tuple[0] + M_PI) * d_pi_));
    if (h_index < 0)           h_index = 0;
    if (h_index >= nr_bins_f1) h_index = nr_bins_f1 - 1;
    hist_f1 (p_idx, h_index) += hist_incr;

    h_index = floor (nr_bins_f2 * ((pfh_tuple[1] + 1.0) * 0.5));
    if (h_index < 0)           h_index = 0;
    if (h_index >= nr_bins_f2) h_index = nr_bins_f2 - 1;
    hist_f2 (p_idx, h_index) += hist_incr;

    h_index = floor (nr_bins_f3 * ((pfh_tuple[2] + 1.0) * 0.5));
    if (h_index < 0)           h_index = 0;
    if (h_index >= nr_bins_f3) h_index = nr_bins_f3 - 1;
    hist_f3 (p_idx, h_index) += hist_incr;
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::weightPointSPFHSignature (
      const Eigen::MatrixXf &hist_f1, const Eigen::MatrixXf &hist_f2, const Eigen::MatrixXf &hist_f3,
      const std::vector<int> &indices, const std::vector<float> &dists, Eigen::VectorXf &fpfh_histogram)
{
  assert (indices.size () == dists.size ());
  double sum_f1 = 0.0, sum_f2 = 0.0, sum_f3 = 0.0;
  float weight = 0.0, val_f1, val_f2, val_f3;

  // Get the number of bins from the histograms size
  int nr_bins_f1 = hist_f1.cols ();
  int nr_bins_f2 = hist_f2.cols ();
  int nr_bins_f3 = hist_f3.cols ();
  int nr_bins_f12 = nr_bins_f1 + nr_bins_f2;

  // Use the entire patch
  for (size_t idx = 0, data_size = indices.size (); idx < data_size; ++idx)
  {
    // Minus the query point itself
    if (dists[idx] == 0)
      continue;

    // Standard weighting function used
    weight = 1.0 / dists[idx];

    // Weight the SPFH of the query point with the SPFH of its neighbors
    for (int f1_i = 0; f1_i < nr_bins_f1; ++f1_i)
    {
      val_f1 = hist_f1 (indices[idx], f1_i) * weight;
      sum_f1 += val_f1;
      fpfh_histogram[f1_i] += val_f1;
    }

    for (int f2_i = 0; f2_i < nr_bins_f2; ++f2_i)
    {
      val_f2 = hist_f2 (indices[idx], f2_i) * weight;
      sum_f2 += val_f2;
      fpfh_histogram[f2_i + nr_bins_f1] += val_f2;
    }

    for (int f3_i = 0; f3_i < nr_bins_f3; ++f3_i)
    {
      val_f3 = hist_f3 (indices[idx], f3_i) * weight;
      sum_f3 += val_f3;
      fpfh_histogram[f3_i + nr_bins_f12] += val_f3;
    }
  }

  if (sum_f1 != 0)
    sum_f1 = 100.0 / sum_f1;           // histogram values sum up to 100
  if (sum_f2 != 0)
    sum_f2 = 100.0 / sum_f2;           // histogram values sum up to 100
  if (sum_f3 != 0)
    sum_f3 = 100.0 / sum_f3;           // histogram values sum up to 100

  // Adjust final FPFH values
  for (int f1_i = 0; f1_i < nr_bins_f1; ++f1_i)
    fpfh_histogram[f1_i] *= sum_f1;
  for (int f2_i = 0; f2_i < nr_bins_f2; ++f2_i)
    fpfh_histogram[f2_i + nr_bins_f1] *= sum_f2;
  for (int f3_i = 0; f3_i < nr_bins_f3; ++f3_i)
    fpfh_histogram[f3_i + nr_bins_f12] *= sum_f3;
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeFeature (PointCloudOut &output)
{
  // Allocate enough space to hold the NN search results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  std::set<int> spfh_indices;
  std::vector<int> spfh_hist_lookup (surface_->points.size ());

  // Build a list of (unique) indices for which we will need to compute SPFH signatures
  // (We need an SPFH signature for every point that is a neighbor of any point in input_[indices_])
  if (surface_ != input_ ||
      indices_->size () != surface_->points.size ())
  {
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      int p_idx = (*indices_)[idx];
      this->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists);

      spfh_indices.insert (nn_indices.begin (), nn_indices.end ());
    }
  }
  else
  {
    // Special case: When a feature must be computed at every point, there is no need for a neighborhood search
    for (size_t idx = 0; idx < indices_->size (); ++idx)
      spfh_indices.insert (idx);
  }

  // Initialize the arrays that will store the SPFH signatures
  size_t data_size = spfh_indices.size ();
  hist_f1_.setZero (data_size, nr_bins_f1_);
  hist_f2_.setZero (data_size, nr_bins_f2_);
  hist_f3_.setZero (data_size, nr_bins_f3_);

  // Compute SPFH signatures for every point that needs them
  std::set<int>::iterator spfh_indices_itr = spfh_indices.begin ();
  for (size_t i = 0; i < spfh_indices.size (); ++i)
  {
    // Get the next point index
    int p_idx = *spfh_indices_itr;
    ++spfh_indices_itr;

    // Find the neighborhood around p_idx
    this->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists);

    // Estimate the SPFH signature around p_idx
    computePointSPFHSignature (*surface_, *normals_, i, nn_indices, hist_f1_, hist_f2_, hist_f3_);

    // Populate a lookup table for converting a point index to its corresponding row in the spfh_hist_* matrices
    spfh_hist_lookup[p_idx] = i;
  }

  // Intialize the array that will store the FPFH signature
  int nr_bins = nr_bins_f1_ + nr_bins_f2_ + nr_bins_f3_;
  fpfh_histogram_.setZero (nr_bins);

  // Iterate over the entire index vector
  for (size_t idx = 0; idx < indices_->size (); ++idx)
  {
    // Find the indices of point idx's neighbors...
    this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists);

    // ... and remap the nn_indices values so that they represent row indices in the spfh_hist_* matrices
    // instead of indices into surface_->points
    for (size_t i = 0; i < nn_indices.size (); ++i)
      nn_indices[i] = spfh_hist_lookup[nn_indices[i]];

    // Compute the FPFH signature (i.e. compute a weighted combination of local SPFH signatures) ...
    weightPointSPFHSignature (hist_f1_, hist_f2_, hist_f3_, nn_indices, nn_dists, fpfh_histogram_);

    // ...and copy it into the output cloud
    for (int d = 0; d < fpfh_histogram_.size (); ++d)
      output.points[idx].histogram[d] = fpfh_histogram_[d];

    fpfh_histogram_.setZero ();
  }

}

#define PCL_INSTANTIATE_FPFHEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::FPFHEstimation<T,NT,OutT>;

#endif    // PCL_FEATURES_IMPL_FPFH_H_

<|endoftext|>


<commit_before>// MOVE.C -- implementation of MOVE class

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ugens.h>
#include <mixerr.h>
#include <rt.h>
#include <rtdefs.h>

#include "MOVE.h"
#include "common.h"

#undef debug

#ifdef SIG_DEBUG
#define DBG(stmt) { stmt; }
#else
#define DBG(stmt)
#endif

extern "C" int get_path_params(float *rhos, float *thetas, int *cartesian, double *mdiff);

extern double SINARRAY[1025], COSARRAY[1025], ATANARRAY[1025];

static const double radpt = 162.99746617261;   /* converts rads to 1024-element array ptr */
static const double radpt2 = 325.9493234522;

inline double SIN(double x) { return SINARRAY[(int)(wrap(x) * radpt + 0.5)]; }
inline double COS(double x) { return COSARRAY[(int)(wrap(x) * radpt + 0.5)]; }
inline double ATAN(double x) { return ATANARRAY[(int)((x) * radpt2) + 512]; }

static const double LocationUnset = -999999.999999;

/* ------------------------------------------------------------ makeMOVE --- */
Instrument *makeMOVE()
{
   MOVE *inst;

   inst = new MOVE();
   inst->set_bus_config("MOVE");

   return inst;
}

/* ------------------------------------------------------------ rtprofile --- */
void rtprofile()
{
   RT_INTRO("MOVE", makeMOVE);
}

// Move methods

MOVE::MOVE()
{
    R_old = -100000.0;
    T_old = 0.0;
    setup_trigfuns();
    rholoc = new float[ARRAYSIZE];
    thetaloc = new float[ARRAYSIZE];
    for (int n = 0; n < 2; n++)
        for (int o = 0; o < 13; o++)
	    oldOutlocs[n][o] = LocationUnset;	// to force update
}

MOVE::~MOVE()
{
    delete [] thetaloc;
    delete [] rholoc;
}

int MOVE::localInit(float *p, int n_args)
{
    if (n_args < 6)
        die(name(), "Wrong number of args.");
    m_dist = p[4];
    m_rvbamp = p[5];
    m_inchan = n_args > 6 ? (int)p[6] : AVERAGE_CHANS;

    // copy global params into instrument

    if (get_path_params(&rholoc[0], &thetaloc[0], &cartflag, &mindiff) < 0)
        return -1;

	// treat mindiff as update rate in seconds
	if (mindiff > 0.0)
	    setBufferSize((int) SR * mindiff);

    // tables for positional lookup

    tableset(m_dur, ARRAYSIZE, tabr);
    tableset(m_dur, ARRAYSIZE, tabt);

    return 0;
}

int MOVE::finishInit(double rvb_time, double *ringdur)
{
    *ringdur = rvb_time;	// default
    return 0;
}

void MOVE::get_tap(int currentSamp, int chan, int path, int len)
{
   Vector *vec = &m_vectors[chan][path];
   double outloc = vec->outloc;
   const double oldOutloc = oldOutlocs[chan][path];
   double delta;
   if (oldOutloc == LocationUnset)
       delta = 0.0;
   else
       delta = outloc - oldOutloc;
   oldOutlocs[chan][path] = outloc;

   double incr = 1.0 + delta / len;

   const int tap = currentSamp % m_tapsize;
   register double otap = (double) tap - outloc;
   if (otap < 0.0) otap += m_tapsize;
   double otapPlusOne = otap + 1.0;
   if (otapPlusOne >= (double) m_tapsize) otapPlusOne -= m_tapsize;

   double closestToEnd = max(otap, otapPlusOne);

   // run till one of output taps wrap, or len reached

   int len1 = min(len, m_tapsize - (int) closestToEnd);

   register double *tapdel = m_tapDelay;
   register double *Sig = vec->Sig;
   int out = 0;

   while (out < len)
   {
       const int clen = len1;
       for (int i = 0; i < clen; ++i) {
	   int outtap = (int) otap;
	   double frac = otap - (double)outtap;
	   Sig[out++] = tapdel[outtap] + frac * (tapdel[outtap + 1] - tapdel[outtap]);
	   otap += incr;
       }

       if (otap >= (double) m_tapsize) otap -= m_tapsize;
       otapPlusOne = otap + 1.0;
       if (otapPlusOne >= (double) m_tapsize) otapPlusOne -= m_tapsize;
       closestToEnd = max(otap, otapPlusOne);

       len1 = min(len - out, m_tapsize - (int) closestToEnd);
   }
}

// This gets called every internal buffer's worth of samples.
// The angle filters are only reset once every N degrees, where N is variable.

int MOVE::updatePosition(int currentSamp)
{
    double R = tablei(currentSamp, rholoc, tabr);
    double T = tablei(currentSamp, thetaloc, tabt);
    int maxtap = tapcount;
    int resetFlag = 0;	// no reset during update
    if (R != R_old || T != T_old) {
#ifdef debug
        printf("updatePosition: R: %f  T: %f\n", R, T);
#endif
	if (roomtrig(R , T, m_dist, cartflag)) {
            return (-1);
	}
        // set taps, return max samp
        maxtap = tap_set(m_binaural);
	airfil_set(resetFlag);
	if (m_binaural)
	   earfil_set(resetFlag);
	else
	   mike_set();
	R_old = R;
	T_old = T;
    }
    return maxtap;	// return new maximum delay in samples
}
<commit_msg>Rewrote update rate calculation code<commit_after>// MOVE.C -- implementation of MOVE class

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ugens.h>
#include <mixerr.h>
#include <rt.h>
#include <rtdefs.h>

#include "MOVE.h"
#include "common.h"

#undef debug

#ifdef SIG_DEBUG
#define DBG(stmt) { stmt; }
#else
#define DBG(stmt)
#endif

extern "C" int get_path_params(float *rhos, float *thetas, int *cartesian, double *mdiff);

extern double SINARRAY[1025], COSARRAY[1025], ATANARRAY[1025];

static const double radpt = 162.99746617261;   /* converts rads to 1024-element array ptr */
static const double radpt2 = 325.9493234522;

inline double SIN(double x) { return SINARRAY[(int)(wrap(x) * radpt + 0.5)]; }
inline double COS(double x) { return COSARRAY[(int)(wrap(x) * radpt + 0.5)]; }
inline double ATAN(double x) { return ATANARRAY[(int)((x) * radpt2) + 512]; }

static const double LocationUnset = -999999.999999;

/* ------------------------------------------------------------ makeMOVE --- */
Instrument *makeMOVE()
{
   MOVE *inst;

   inst = new MOVE();
   inst->set_bus_config("MOVE");

   return inst;
}

/* ------------------------------------------------------------ rtprofile --- */
void rtprofile()
{
   RT_INTRO("MOVE", makeMOVE);
}

// Move methods

MOVE::MOVE()
{
    R_old = -100000.0;
    T_old = 0.0;
    m_updateCount = 0;
    m_updateSamps = BUFLEN;
    setup_trigfuns();
    rholoc = new float[ARRAYSIZE];
    thetaloc = new float[ARRAYSIZE];
    for (int n = 0; n < 2; n++)
        for (int o = 0; o < 13; o++)
	    oldOutlocs[n][o] = LocationUnset;	// to force update
}

MOVE::~MOVE()
{
    delete [] thetaloc;
    delete [] rholoc;
}

int MOVE::localInit(float *p, int n_args)
{
    if (n_args < 6)
        die(name(), "Wrong number of args.");
    m_dist = p[4];
    m_rvbamp = p[5];
    m_inchan = n_args > 6 ? (int)p[6] : AVERAGE_CHANS;

    // copy global params into instrument

    if (get_path_params(&rholoc[0], &thetaloc[0], &cartflag, &mindiff) < 0)
        return -1;

	// treat mindiff as update rate in seconds
	if (mindiff > 0.0) {
		m_updateSamps = (int) (SR * mindiff + 0.5);
		if (m_updateSamps <= BUFLEN)
		{
	        setBufferSize(m_updateSamps);
#ifdef debug
			printf("buffer size reset to %d samples\n", getBufferSize());
#endif
		}
		// if update rate is larger than BUFLEN samples, set buffer size
		// to be some integer fraction of the desired update count, then
		// reset update count to be multiple of this.
		else {
		    int divisor = 2;
			int newBufferLen;
			while ((newBufferLen = m_updateSamps / divisor) > BUFLEN)
			    divisor++;
			setBufferSize(newBufferLen);
			m_updateSamps = newBufferLen * divisor;
#ifdef debug
			printf("buffer size reset to %d samples\n", getBufferSize());
#endif
		}
#ifdef debug
	    printf("updating every %d samps\n", m_updateSamps);
#endif
	}

    // tables for positional lookup

    tableset(m_dur, ARRAYSIZE, tabr);
    tableset(m_dur, ARRAYSIZE, tabt);

    return 0;
}

int MOVE::finishInit(double rvb_time, double *ringdur)
{
    *ringdur = rvb_time;	// default
    return 0;
}

void MOVE::get_tap(int currentSamp, int chan, int path, int len)
{
   Vector *vec = &m_vectors[chan][path];
   double outloc = vec->outloc;
   const double oldOutloc = oldOutlocs[chan][path];
   double delta;
   if (oldOutloc == LocationUnset)
       delta = 0.0;
   else
       delta = outloc - oldOutloc;
   oldOutlocs[chan][path] = outloc;

   double incr = 1.0 + delta / len;

   const int tap = currentSamp % m_tapsize;
   register double otap = (double) tap - outloc;
   if (otap < 0.0) otap += m_tapsize;
   double otapPlusOne = otap + 1.0;
   if (otapPlusOne >= (double) m_tapsize) otapPlusOne -= m_tapsize;

   double closestToEnd = max(otap, otapPlusOne);

   // run till one of output taps wrap, or len reached

   int len1 = min(len, m_tapsize - (int) closestToEnd);

   register double *tapdel = m_tapDelay;
   register double *Sig = vec->Sig;
   int out = 0;

   while (out < len)
   {
       const int clen = len1;
       for (int i = 0; i < clen; ++i) {
	   int outtap = (int) otap;
	   double frac = otap - (double)outtap;
	   Sig[out++] = tapdel[outtap] + frac * (tapdel[outtap + 1] - tapdel[outtap]);
	   otap += incr;
       }

       if (otap >= (double) m_tapsize) otap -= m_tapsize;
       otapPlusOne = otap + 1.0;
       if (otapPlusOne >= (double) m_tapsize) otapPlusOne -= m_tapsize;
       closestToEnd = max(otap, otapPlusOne);

       len1 = min(len - out, m_tapsize - (int) closestToEnd);
   }
}

// This gets called every internal buffer's worth of samples.  The actual
// update of source angles and delays only happens if we are due for an update
// (based on the update count) and there has been a change of position

int MOVE::updatePosition(int currentSamp)
{
    double R = tablei(currentSamp, rholoc, tabr);
    double T = tablei(currentSamp, thetaloc, tabt);
    int maxtap = tapcount;
	m_updateCount -= getBufferSize();
    if (m_updateCount <= 0 && (R != R_old || T != T_old)) {
#ifdef debug
        printf("updatePosition[%d]:\t\tR: %f  T: %f\n", currentSamp, R, T);
#endif
		if (roomtrig(R , T, m_dist, cartflag)) {
            return (-1);
		}
        // set taps, return max samp
        maxtap = tap_set(m_binaural);
 	    int resetFlag = 0;	// no reset during update
		airfil_set(resetFlag);
		if (m_binaural)
		   earfil_set(resetFlag);
		else
		   mike_set();
		R_old = R;
		T_old = T;
		m_updateCount = m_updateSamps;	// reset counter
    }
    return maxtap;	// return new maximum delay in samples
}
<|endoftext|>


<commit_before>#include "grok/context.h"

#include "object/jsstring.h"
#include "object/function.h"
#include <memory>
#include <functional>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace grok {

/// ctx ::= main global context
std::unique_ptr<Context> ContextStatic::ctx;

Context *ContextStatic::GetContext()
{
    return ctx.get();
}

void ContextStatic::Init()
{
    ctx = std::make_unique<Context>(std::cout);
    ctx->SetVMContext(new grok::vm::VMContext());
    grok::obj::JSString::Init();
    grok::obj::Function::Init();
}

void ContextStatic::Teardown()
{
    ctx->RunIO();
}

void InitializeContext()
{
    ContextStatic::Init();
    auto O = ContextStatic::GetContext()->GetOptions();
    O->AddOption("help,h", "view help message");
    O->AddOption("interactive,i", "run interactive mode (default if no "
            "other option specified)");
    O->AddOption("instructions", "print the instructions generated");
    O->AddOption("debug-execution", "print the instruction being executed");
    O->AddOption("debug-ast,a", "print AST");
    O->AddOption("dry-run", "don't run the VM");
    O->AddOption("top,t", "print the value present in stack after execution");
    O->AddOption("file,f", "interprete files",
        BPO::value<std::vector<std::string>>()->composing());
    O->AddOption("profile", "show profiling information while executing");
    O->AddPositionalOption("file", -1);
    GetContext()->SetIOServiceObject();
}

Context* GetContext()
{
    return ContextStatic::GetContext();
}

void Context::ParseCommandLineOptions(int argc, char **argv)
{
    options.ParseOptions(argc, argv);

    if (options.HasOption("help")) {
        options.PrintHelpAndExit();
    }
    interactive_ = true;

    debug_instruction_ = options.HasOption("instructions");
    debug_execution_ = options.HasOption("debug-execution");

    ast_ = options.HasOption("debug-ast");
    file_ = options.HasOption("file");
    profile_ = options.HasOption("profile");

    if (file_) {
        files_ = options.GetOptionAs<std::vector<std::string>>("file");
        interactive_ = options.HasOption("interactive");
    }
    dry_run_ = options.HasOption("dry-run");
    last_in_stack_ = options.HasOption("top");
}

void ParseCommandLineOptions(int argc, char **argv)
{
    auto ctx = GetContext();
    ctx->ParseCommandLineOptions(argc, argv);
}

void Context::RunIO()
{
    io_.run();
}

void Context::RunPoller()
{
    // while (true) {
    //     boost::asio::deadline_timer timer(io_,
    //             boost::posix_time::microseconds(100));
    //     timer.wait();
    //     io_.poll();
    // }
}

void Context::SetIOServiceObject()
{
}

}
<commit_msg>Added Array::Init call<commit_after>#include "grok/context.h"

#include "object/jsstring.h"
#include "object/function.h"
#include "object/array.h"
#include <memory>
#include <functional>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace grok {

/// ctx ::= main global context
std::unique_ptr<Context> ContextStatic::ctx;

Context *ContextStatic::GetContext()
{
    return ctx.get();
}

void ContextStatic::Init()
{
    ctx = std::make_unique<Context>(std::cout);
    ctx->SetVMContext(new grok::vm::VMContext());
    grok::obj::JSString::Init();
    grok::obj::Function::Init();
    grok::obj::JSArray::Init();
}

void ContextStatic::Teardown()
{
    ctx->RunIO();
}

void InitializeContext()
{
    ContextStatic::Init();
    auto O = ContextStatic::GetContext()->GetOptions();
    O->AddOption("help,h", "view help message");
    O->AddOption("interactive,i", "run interactive mode (default if no "
            "other option specified)");
    O->AddOption("instructions", "print the instructions generated");
    O->AddOption("debug-execution", "print the instruction being executed");
    O->AddOption("debug-ast,a", "print AST");
    O->AddOption("dry-run", "don't run the VM");
    O->AddOption("top,t", "print the value present in stack after execution");
    O->AddOption("file,f", "interprete files",
        BPO::value<std::vector<std::string>>()->composing());
    O->AddOption("profile", "show profiling information while executing");
    O->AddPositionalOption("file", -1);
    GetContext()->SetIOServiceObject();
}

Context* GetContext()
{
    return ContextStatic::GetContext();
}

void Context::ParseCommandLineOptions(int argc, char **argv)
{
    options.ParseOptions(argc, argv);

    if (options.HasOption("help")) {
        options.PrintHelpAndExit();
    }
    interactive_ = true;

    debug_instruction_ = options.HasOption("instructions");
    debug_execution_ = options.HasOption("debug-execution");

    ast_ = options.HasOption("debug-ast");
    file_ = options.HasOption("file");
    profile_ = options.HasOption("profile");

    if (file_) {
        files_ = options.GetOptionAs<std::vector<std::string>>("file");
        interactive_ = options.HasOption("interactive");
    }
    dry_run_ = options.HasOption("dry-run");
    last_in_stack_ = options.HasOption("top");
}

void ParseCommandLineOptions(int argc, char **argv)
{
    auto ctx = GetContext();
    ctx->ParseCommandLineOptions(argc, argv);
}

void Context::RunIO()
{
    io_.run();
}

void Context::RunPoller()
{
    // while (true) {
    //     boost::asio::deadline_timer timer(io_,
    //             boost::posix_time::microseconds(100));
    //     timer.wait();
    //     io_.poll();
    // }
}

void Context::SetIOServiceObject()
{
}

}
<|endoftext|>


<commit_before>#include "highlighters.hh"
#include "assert.hh"
#include "window.hh"
#include "color_registry.hh"
#include "highlighter_group.hh"
#include "string.hh"
#include "utf8.hh"

namespace Kakoune
{

using namespace std::placeholders;

typedef boost::regex_iterator<BufferIterator> RegexIterator;

template<typename T>
void highlight_range(DisplayBuffer& display_buffer,
                     BufferIterator begin, BufferIterator end,
                     bool skip_replaced, T func)
{
    if (begin == end or end <= display_buffer.range().first
                     or begin >= display_buffer.range().second)
        return;

    for (auto& line : display_buffer.lines())
    {
        if (line.buffer_line() >= begin.line() and line.buffer_line() <= end.line())
        {
            for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
            {
                bool is_replaced = atom_it->content.type() == AtomContent::ReplacedBufferRange;

                if (not atom_it->content.has_buffer_range() or
                    (skip_replaced and is_replaced))
                    continue;

                if (end <= atom_it->content.begin() or begin >= atom_it->content.end())
                    continue;

                if (not is_replaced and begin > atom_it->content.begin())
                    atom_it = ++line.split(atom_it, begin);

                if (not is_replaced and end < atom_it->content.end())
                {
                    atom_it = line.split(atom_it, end);
                    func(*atom_it);
                    ++atom_it;
                }
                else
                    func(*atom_it);
            }
        }
    }
}

typedef std::unordered_map<size_t, const ColorPair*> ColorSpec;

class RegexColorizer
{
public:
    RegexColorizer(Regex regex, ColorSpec colors)
        : m_regex(std::move(regex)), m_colors(std::move(colors)),
          m_cache_timestamp(0)
    {
    }

    void operator()(DisplayBuffer& display_buffer)
    {
        update_cache_ifn(display_buffer.range());
        for (auto& match : m_cache_matches)
        {
            for (size_t n = 0; n < match.size(); ++n)
            {
                auto col_it = m_colors.find(n);
                if (col_it == m_colors.end())
                    continue;

                highlight_range(display_buffer, match[n].first, match[n].second, true,
                                [&](DisplayAtom& atom) {
                                    atom.fg_color = col_it->second->first;
                                    atom.bg_color = col_it->second->second;
                                });
            }
        }
    }

private:
    BufferRange m_cache_range;
    size_t      m_cache_timestamp;
    std::vector<boost::match_results<BufferIterator>> m_cache_matches;

    Regex     m_regex;
    ColorSpec m_colors;

    void update_cache_ifn(const BufferRange& range)
    {
        const Buffer& buf = range.first.buffer();
        if (m_cache_range.first.is_valid() and
            &m_cache_range.first.buffer() == &buf and
            buf.timestamp() == m_cache_timestamp and
            range.first >= m_cache_range.first and
            range.second <= m_cache_range.second)
           return;

        m_cache_matches.clear();
        m_cache_range.first  = buf.iterator_at_line_begin(range.first.line() - 10);
        m_cache_range.second = buf.iterator_at_line_end(range.second.line() + 10);
        m_cache_timestamp = buf.timestamp();

        RegexIterator re_it(m_cache_range.first, m_cache_range.second, m_regex);
        RegexIterator re_end;
        for (; re_it != re_end; ++re_it)
            m_cache_matches.push_back(*re_it);
    }
};

HighlighterAndId colorize_regex_factory(Window& window,
                                        const HighlighterParameters params)
{
    if (params.size() < 2)
        throw runtime_error("wrong parameter count");

    try
    {
        static Regex color_spec_ex(R"((\d+):(\w+(,\w+)?))");
        ColorSpec colors;
        for (auto it = params.begin() + 1;  it != params.end(); ++it)
        {
            boost::match_results<String::iterator> res;
            if (not boost::regex_match(it->begin(), it->end(), res, color_spec_ex))
                throw runtime_error("wrong colorspec: '" + *it +
                                     "' expected <capture>:<fgcolor>[,<bgcolor>]");

            int capture = str_to_int(String(res[1].first, res[1].second));
            const ColorPair*& color = colors[capture];
            color = &ColorRegistry::instance()[String(res[2].first, res[2].second)];
        }

        String id = "colre'" + params[0] + "'";

        Regex ex(params[0].begin(), params[0].end(),
                 boost::regex::perl | boost::regex::optimize);

        return HighlighterAndId(id, RegexColorizer(std::move(ex),
                                                   std::move(colors)));
    }
    catch (boost::regex_error& err)
    {
        throw runtime_error(String("regex error: ") + err.what());
    }
}

void expand_tabulations(Window& window, DisplayBuffer& display_buffer)
{
    const int tabstop = window.options()["tabstop"].as_int();
    for (auto& line : display_buffer.lines())
    {
        for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
        {
            if (atom_it->content.type() != AtomContent::BufferRange)
                continue;

            auto begin = atom_it->content.begin();
            auto end = atom_it->content.end();
            for (BufferIterator it = begin; it != end; ++it)
            {
                if (*it == '\t')
                {
                    if (it != begin)
                        atom_it = ++line.split(atom_it, it);
                    if (it+1 != end)
                        atom_it = line.split(atom_it, it+1);

                    int column = 0;
                    for (auto line_it = it.buffer().iterator_at_line_begin(it);
                         line_it != it; ++line_it)
                    {
                        assert(*line_it != '\n');
                        if (*line_it == '\t')
                            column += tabstop - (column % tabstop);
                        else
                           ++column;
                    }

                    int count = tabstop - (column % tabstop);
                    String padding;
                    for (int i = 0; i < count; ++i)
                        padding += ' ';
                    atom_it->content.replace(padding);
                    break;
                }
            }
        }
    }
}

void show_line_numbers(Window& window, DisplayBuffer& display_buffer)
{
    LineCount last_line = window.buffer().line_count();
    int digit_count = 0;
    for (LineCount c = last_line; c > 0; c /= 10)
        ++digit_count;

    char format[] = "%?d ";
    format[1] = '0' + digit_count;

    for (auto& line : display_buffer.lines())
    {
        char buffer[10];
        snprintf(buffer, 10, format, (int)line.buffer_line() + 1);
        DisplayAtom atom = DisplayAtom(AtomContent(buffer));
        atom.fg_color = Color::Black;
        atom.bg_color = Color::White;
        line.insert(line.begin(), std::move(atom));
    }
}

void highlight_selections(Window& window, DisplayBuffer& display_buffer)
{
    for (auto& sel : window.selections())
    {
        highlight_range(display_buffer, sel.begin(), sel.end(), false,
                        [](DisplayAtom& atom) { atom.attribute |= Attributes::Underline; });

        const BufferIterator& last = sel.last();
        highlight_range(display_buffer, last, utf8::next(last), false,
                        [](DisplayAtom& atom) { atom.attribute |= Attributes::Reverse; });
    }
}

template<void (*highlighter_func)(DisplayBuffer&)>
class SimpleHighlighterFactory
{
public:
    SimpleHighlighterFactory(const String& id) : m_id(id) {}

    HighlighterAndId operator()(Window& window,
                                const HighlighterParameters& params) const
    {
        return HighlighterAndId(m_id, HighlighterFunc(highlighter_func));
    }
private:
    String m_id;
};

template<void (*highlighter_func)(Window&, DisplayBuffer&)>
class WindowHighlighterFactory
{
public:
    WindowHighlighterFactory(const String& id) : m_id(id) {}

    HighlighterAndId operator()(Window& window,
                                const HighlighterParameters& params) const
    {
        return HighlighterAndId(m_id, std::bind(highlighter_func, std::ref(window), _1));
    }
private:
    String m_id;
};

HighlighterAndId highlighter_group_factory(Window& window,
                                           const HighlighterParameters& params)
{
    if (params.size() != 1)
        throw runtime_error("wrong parameter count");

    return HighlighterAndId(params[0], HighlighterGroup());
}

void register_highlighters()
{
    HighlighterRegistry& registry = HighlighterRegistry::instance();

    registry.register_func("highlight_selections", WindowHighlighterFactory<highlight_selections>("highlight_selections"));
    registry.register_func("expand_tabs", WindowHighlighterFactory<expand_tabulations>("expand_tabs"));
    registry.register_func("number_lines", WindowHighlighterFactory<show_line_numbers>("number_lines"));
    registry.register_func("regex", colorize_regex_factory);
    registry.register_func("group", highlighter_group_factory);
}

}
<commit_msg>minor refactoring in highlight_range<commit_after>#include "highlighters.hh"
#include "assert.hh"
#include "window.hh"
#include "color_registry.hh"
#include "highlighter_group.hh"
#include "string.hh"
#include "utf8.hh"

namespace Kakoune
{

using namespace std::placeholders;

typedef boost::regex_iterator<BufferIterator> RegexIterator;

template<typename T>
void highlight_range(DisplayBuffer& display_buffer,
                     BufferIterator begin, BufferIterator end,
                     bool skip_replaced, T func)
{
    if (begin == end or end <= display_buffer.range().first
                     or begin >= display_buffer.range().second)
        return;

    for (auto& line : display_buffer.lines())
    {
        if (line.buffer_line() < begin.line() or  end.line() < line.buffer_line())
            continue;

        for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
        {
            bool is_replaced = atom_it->content.type() == AtomContent::ReplacedBufferRange;

            if (not atom_it->content.has_buffer_range() or
                (skip_replaced and is_replaced))
                continue;

            if (end <= atom_it->content.begin() or begin >= atom_it->content.end())
                continue;

            if (not is_replaced and begin > atom_it->content.begin())
                atom_it = ++line.split(atom_it, begin);

            if (not is_replaced and end < atom_it->content.end())
            {
                atom_it = line.split(atom_it, end);
                func(*atom_it);
                ++atom_it;
            }
            else
                func(*atom_it);
        }
    }
}

typedef std::unordered_map<size_t, const ColorPair*> ColorSpec;

class RegexColorizer
{
public:
    RegexColorizer(Regex regex, ColorSpec colors)
        : m_regex(std::move(regex)), m_colors(std::move(colors)),
          m_cache_timestamp(0)
    {
    }

    void operator()(DisplayBuffer& display_buffer)
    {
        update_cache_ifn(display_buffer.range());
        for (auto& match : m_cache_matches)
        {
            for (size_t n = 0; n < match.size(); ++n)
            {
                auto col_it = m_colors.find(n);
                if (col_it == m_colors.end())
                    continue;

                highlight_range(display_buffer, match[n].first, match[n].second, true,
                                [&](DisplayAtom& atom) {
                                    atom.fg_color = col_it->second->first;
                                    atom.bg_color = col_it->second->second;
                                });
            }
        }
    }

private:
    BufferRange m_cache_range;
    size_t      m_cache_timestamp;
    std::vector<boost::match_results<BufferIterator>> m_cache_matches;

    Regex     m_regex;
    ColorSpec m_colors;

    void update_cache_ifn(const BufferRange& range)
    {
        const Buffer& buf = range.first.buffer();
        if (m_cache_range.first.is_valid() and
            &m_cache_range.first.buffer() == &buf and
            buf.timestamp() == m_cache_timestamp and
            range.first >= m_cache_range.first and
            range.second <= m_cache_range.second)
           return;

        m_cache_matches.clear();
        m_cache_range.first  = buf.iterator_at_line_begin(range.first.line() - 10);
        m_cache_range.second = buf.iterator_at_line_end(range.second.line() + 10);
        m_cache_timestamp = buf.timestamp();

        RegexIterator re_it(m_cache_range.first, m_cache_range.second, m_regex);
        RegexIterator re_end;
        for (; re_it != re_end; ++re_it)
            m_cache_matches.push_back(*re_it);
    }
};

HighlighterAndId colorize_regex_factory(Window& window,
                                        const HighlighterParameters params)
{
    if (params.size() < 2)
        throw runtime_error("wrong parameter count");

    try
    {
        static Regex color_spec_ex(R"((\d+):(\w+(,\w+)?))");
        ColorSpec colors;
        for (auto it = params.begin() + 1;  it != params.end(); ++it)
        {
            boost::match_results<String::iterator> res;
            if (not boost::regex_match(it->begin(), it->end(), res, color_spec_ex))
                throw runtime_error("wrong colorspec: '" + *it +
                                     "' expected <capture>:<fgcolor>[,<bgcolor>]");

            int capture = str_to_int(String(res[1].first, res[1].second));
            const ColorPair*& color = colors[capture];
            color = &ColorRegistry::instance()[String(res[2].first, res[2].second)];
        }

        String id = "colre'" + params[0] + "'";

        Regex ex(params[0].begin(), params[0].end(),
                 boost::regex::perl | boost::regex::optimize);

        return HighlighterAndId(id, RegexColorizer(std::move(ex),
                                                   std::move(colors)));
    }
    catch (boost::regex_error& err)
    {
        throw runtime_error(String("regex error: ") + err.what());
    }
}

void expand_tabulations(Window& window, DisplayBuffer& display_buffer)
{
    const int tabstop = window.options()["tabstop"].as_int();
    for (auto& line : display_buffer.lines())
    {
        for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
        {
            if (atom_it->content.type() != AtomContent::BufferRange)
                continue;

            auto begin = atom_it->content.begin();
            auto end = atom_it->content.end();
            for (BufferIterator it = begin; it != end; ++it)
            {
                if (*it == '\t')
                {
                    if (it != begin)
                        atom_it = ++line.split(atom_it, it);
                    if (it+1 != end)
                        atom_it = line.split(atom_it, it+1);

                    int column = 0;
                    for (auto line_it = it.buffer().iterator_at_line_begin(it);
                         line_it != it; ++line_it)
                    {
                        assert(*line_it != '\n');
                        if (*line_it == '\t')
                            column += tabstop - (column % tabstop);
                        else
                           ++column;
                    }

                    int count = tabstop - (column % tabstop);
                    String padding;
                    for (int i = 0; i < count; ++i)
                        padding += ' ';
                    atom_it->content.replace(padding);
                    break;
                }
            }
        }
    }
}

void show_line_numbers(Window& window, DisplayBuffer& display_buffer)
{
    LineCount last_line = window.buffer().line_count();
    int digit_count = 0;
    for (LineCount c = last_line; c > 0; c /= 10)
        ++digit_count;

    char format[] = "%?d ";
    format[1] = '0' + digit_count;

    for (auto& line : display_buffer.lines())
    {
        char buffer[10];
        snprintf(buffer, 10, format, (int)line.buffer_line() + 1);
        DisplayAtom atom = DisplayAtom(AtomContent(buffer));
        atom.fg_color = Color::Black;
        atom.bg_color = Color::White;
        line.insert(line.begin(), std::move(atom));
    }
}

void highlight_selections(Window& window, DisplayBuffer& display_buffer)
{
    for (auto& sel : window.selections())
    {
        highlight_range(display_buffer, sel.begin(), sel.end(), false,
                        [](DisplayAtom& atom) { atom.attribute |= Attributes::Underline; });

        const BufferIterator& last = sel.last();
        highlight_range(display_buffer, last, utf8::next(last), false,
                        [](DisplayAtom& atom) { atom.attribute |= Attributes::Reverse; });
    }
}

template<void (*highlighter_func)(DisplayBuffer&)>
class SimpleHighlighterFactory
{
public:
    SimpleHighlighterFactory(const String& id) : m_id(id) {}

    HighlighterAndId operator()(Window& window,
                                const HighlighterParameters& params) const
    {
        return HighlighterAndId(m_id, HighlighterFunc(highlighter_func));
    }
private:
    String m_id;
};

template<void (*highlighter_func)(Window&, DisplayBuffer&)>
class WindowHighlighterFactory
{
public:
    WindowHighlighterFactory(const String& id) : m_id(id) {}

    HighlighterAndId operator()(Window& window,
                                const HighlighterParameters& params) const
    {
        return HighlighterAndId(m_id, std::bind(highlighter_func, std::ref(window), _1));
    }
private:
    String m_id;
};

HighlighterAndId highlighter_group_factory(Window& window,
                                           const HighlighterParameters& params)
{
    if (params.size() != 1)
        throw runtime_error("wrong parameter count");

    return HighlighterAndId(params[0], HighlighterGroup());
}

void register_highlighters()
{
    HighlighterRegistry& registry = HighlighterRegistry::instance();

    registry.register_func("highlight_selections", WindowHighlighterFactory<highlight_selections>("highlight_selections"));
    registry.register_func("expand_tabs", WindowHighlighterFactory<expand_tabulations>("expand_tabs"));
    registry.register_func("number_lines", WindowHighlighterFactory<show_line_numbers>("number_lines"));
    registry.register_func("regex", colorize_regex_factory);
    registry.register_func("group", highlighter_group_factory);
}

}
<|endoftext|>