<commit_before>/*
    behaviorconfig.cpp  -  Kopete Look Feel Config

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.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.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "behaviorconfig.h"
#include "behaviorconfig_general.h"
#include "behaviorconfig_chat.h"

#include <qcheckbox.h>
#include <qlayout.h>
#include <qhbuttongroup.h>
#include <qspinbox.h>

#include <kdebug.h>
#include <klocale.h>
#include <knotifydialog.h>
#include <kpushbutton.h>
#include <kgenericfactory.h>
#include <ktrader.h>
#include <kconfig.h>

#include "kopeteprefs.h"
#include "kopeteaway.h"
#include "kopeteawayconfigui.h"

#include <qtabwidget.h>

typedef KGenericFactory<BehaviorConfig, QWidget> KopeteBehaviorConfigFactory;
K_EXPORT_COMPONENT_FACTORY( kcm_kopete_behaviorconfig, KopeteBehaviorConfigFactory( "kcm_kopete_behaviorconfig" ) )

BehaviorConfig::BehaviorConfig(QWidget *parent, const char * /* name */, const QStringList &args) :
		KCModule( KopeteBehaviorConfigFactory::instance(), parent, args )
{
	(new QVBoxLayout(this))->setAutoAdd(true);
	mBehaviorTabCtl = new QTabWidget(this, "mBehaviorTabCtl");

	// "General" TAB ============================================================
	mPrfsGeneral = new BehaviorConfig_General(mBehaviorTabCtl);
	connect(mPrfsGeneral->configSound, SIGNAL(clicked()),
		this, SLOT(slotConfigSound()));
	connect(mPrfsGeneral->mShowTrayChk, SIGNAL(toggled(bool)),
		this, SLOT(slotShowTrayChanged(bool)));
	mBehaviorTabCtl->addTab(mPrfsGeneral, i18n("&General"));

	// "Away" TAB ===============================================================
	mAwayConfigUI = new KopeteAwayConfigUI(mBehaviorTabCtl);
	mBehaviorTabCtl->addTab(mAwayConfigUI, i18n("&Away Settings"));

	// "Chat" TAB ===============================================================
	mPrfsChat = new BehaviorConfig_Chat(mBehaviorTabCtl);
	mBehaviorTabCtl->addTab(mPrfsChat, i18n("&Chat"));

	load();
	//connect a whole bunch of signals and slots so the thing works
	//TODO: There's gotta be a better way to do this --Matt  | I hope so too --Will

	connect(mPrfsGeneral->mStartDockedChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mUseQueueChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mBalloonNotifyChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mTrayflashNotifyChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mSoundIfAwayChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mTreeContactList, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mSortByGroup, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));

	//"Chat" TAB signals
	connect( mPrfsChat->cb_RaiseMsgWindowChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mPrfsChat->cb_ShowEventsChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mPrfsChat->highlightEnabled, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mPrfsChat->chatWindowGroup, SIGNAL(clicked(int)),
		this, SLOT(slotValueChanged(int)));
	connect( mPrfsChat->interfaceGroup, SIGNAL(clicked(int)),
		this, SLOT(slotValueChanged(int)));
	connect( mPrfsChat->mChatViewBufferSize, SIGNAL(valueChanged(int)),
		this, SLOT(slotValueChanged(int)));

	//"Away" TAB signals
	connect( mAwayConfigUI->mAutoAwayTimeout, SIGNAL(valueChanged(int)),
		this, SLOT(slotValueChanged(int)));
	connect( mAwayConfigUI->mGoAvailable, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mAwayConfigUI->mUseAutoAway, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mAwayConfigUI->mNotifyAway, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mAwayConfigUI, SIGNAL(awayMessagesChanged(bool)),
		this, SLOT(slotSettingsChanged(bool)));
}

void BehaviorConfig::save()
{
//	kdDebug(14000) << k_funcinfo << "called." << endl;

	KopetePrefs *p = KopetePrefs::prefs();

	// "General" TAB ============================================================
	p->setShowTray(mPrfsGeneral->mShowTrayChk->isChecked());
	p->setStartDocked(mPrfsGeneral->mStartDockedChk->isChecked());
	p->setUseQueue(mPrfsGeneral->mUseQueueChk->isChecked());
	p->setTrayflashNotify(mPrfsGeneral->mTrayflashNotifyChk->isChecked());
	p->setBalloonNotify(mPrfsGeneral->mBalloonNotifyChk->isChecked());
	p->setSoundIfAway(mPrfsGeneral->mSoundIfAwayChk->isChecked());
	p->setTreeView(mPrfsGeneral->mTreeContactList->isChecked());
	p->setSortByGroup(mPrfsGeneral->mSortByGroup->isChecked());

	// "Away" TAB ===============================================================
	p->setNotifyAway( mAwayConfigUI->mNotifyAway->isChecked());

	KConfig *config = KGlobal::config();
	config->setGroup("AutoAway");
	config->writeEntry("Timeout", mAwayConfigUI->mAutoAwayTimeout->value() * 60);
	config->writeEntry("GoAvailable", mAwayConfigUI->mGoAvailable->isChecked());
	config->writeEntry("UseAutoAway", mAwayConfigUI->mUseAutoAway->isChecked() );
	config->sync();

	// "Chat" TAB ===============================================================
	p->setRaiseMsgWindow(mPrfsChat->cb_RaiseMsgWindowChk->isChecked());
	p->setShowEvents(mPrfsChat->cb_ShowEventsChk->isChecked());
	p->setHighlightEnabled(mPrfsChat->highlightEnabled->isChecked());
	p->setChatWindowPolicy(mPrfsChat->chatWindowGroup->id(
			mPrfsChat->chatWindowGroup->selected()));
	p->setInterfacePreference(mPrfsChat->interfaceGroup->id(
			mPrfsChat->interfaceGroup->selected()) );
	p->setChatViewBufferSize(mPrfsChat->mChatViewBufferSize->value());

	p->save();
	setChanged(false);
}

void BehaviorConfig::load()
{
//	kdDebug(14000) << k_funcinfo << "called" << endl;
	KopetePrefs *p = KopetePrefs::prefs();

	// "General" TAB ============================================================
	mPrfsGeneral->mShowTrayChk->setChecked( p->showTray() );
	mPrfsGeneral->mStartDockedChk->setChecked( p->startDocked() );
	mPrfsGeneral->mUseQueueChk->setChecked( p->useQueue() );
	mPrfsGeneral->mTrayflashNotifyChk->setChecked ( p->trayflashNotify() );
	mPrfsGeneral->mBalloonNotifyChk->setChecked ( p->balloonNotify() );
	mPrfsGeneral->mSoundIfAwayChk->setChecked( p->soundIfAway() );
	slotShowTrayChanged( mPrfsGeneral->mShowTrayChk->isChecked() );
	mPrfsGeneral->mTreeContactList->setChecked( p->treeView() );
	mPrfsGeneral->mSortByGroup->setChecked( p->sortByGroup() );

	// "Away" TAB ===============================================================
	KConfig *config = KGlobal::config();
	config->setGroup("AutoAway");
	mAwayConfigUI->mAutoAwayTimeout->setValue(config->readNumEntry("Timeout", 600)/60);
	mAwayConfigUI->mGoAvailable->setChecked(config->readBoolEntry("GoAvailable", true));
	mAwayConfigUI->mUseAutoAway->setChecked(config->readBoolEntry("UseAutoAway", true));
	mAwayConfigUI->mNotifyAway->setChecked( p->notifyAway() );

	mAwayConfigUI->updateView();

	// "Chat" TAB ===============================================================
	mPrfsChat->cb_RaiseMsgWindowChk->setChecked(p->raiseMsgWindow());
	mPrfsChat->cb_ShowEventsChk->setChecked(p->showEvents());
	mPrfsChat->highlightEnabled->setChecked(p->highlightEnabled());
	mPrfsChat->chatWindowGroup->setButton(p->chatWindowPolicy());
	mPrfsChat->interfaceGroup->setButton(p->interfacePreference());
	mPrfsChat->mChatViewBufferSize->setValue(p->chatViewBufferSize());

	//TODO: make the whole thing working corretly insteads of this ugly hack...
	setChanged(false);
	setChanged(true);
}

void BehaviorConfig::slotConfigSound()
{
	KNotifyDialog::configure( this );
	setChanged(true);
}

void BehaviorConfig::slotShowTrayChanged(bool check)
{
	mPrfsGeneral->mStartDockedChk->setEnabled(check);
	mPrfsGeneral->mTrayflashNotifyChk->setEnabled(check);
	mPrfsGeneral->mBalloonNotifyChk->setEnabled(check);
	setChanged(true);
}

void BehaviorConfig::slotSettingsChanged(bool)
{
	setChanged(true);
}

void BehaviorConfig::slotValueChanged(int)
{
	setChanged( true );
}
#include "behaviorconfig.moc"
// vim: set noet ts=4 sts=4 sw=4:
<commit_msg>s/setChanged/emit changed/<commit_after>/*
    behaviorconfig.cpp  -  Kopete Look Feel Config

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.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.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "behaviorconfig.h"
#include "behaviorconfig_general.h"
#include "behaviorconfig_chat.h"

#include <qcheckbox.h>
#include <qlayout.h>
#include <qhbuttongroup.h>
#include <qspinbox.h>

#include <kdebug.h>
#include <klocale.h>
#include <knotifydialog.h>
#include <kpushbutton.h>
#include <kgenericfactory.h>
#include <ktrader.h>
#include <kconfig.h>

#include "kopeteprefs.h"
#include "kopeteaway.h"
#include "kopeteawayconfigui.h"

#include <qtabwidget.h>

typedef KGenericFactory<BehaviorConfig, QWidget> KopeteBehaviorConfigFactory;
K_EXPORT_COMPONENT_FACTORY( kcm_kopete_behaviorconfig, KopeteBehaviorConfigFactory( "kcm_kopete_behaviorconfig" ) )

BehaviorConfig::BehaviorConfig(QWidget *parent, const char * /* name */, const QStringList &args) :
		KCModule( KopeteBehaviorConfigFactory::instance(), parent, args )
{
	(new QVBoxLayout(this))->setAutoAdd(true);
	mBehaviorTabCtl = new QTabWidget(this, "mBehaviorTabCtl");

	// "General" TAB ============================================================
	mPrfsGeneral = new BehaviorConfig_General(mBehaviorTabCtl);
	connect(mPrfsGeneral->configSound, SIGNAL(clicked()),
		this, SLOT(slotConfigSound()));
	connect(mPrfsGeneral->mShowTrayChk, SIGNAL(toggled(bool)),
		this, SLOT(slotShowTrayChanged(bool)));
	mBehaviorTabCtl->addTab(mPrfsGeneral, i18n("&General"));

	// "Away" TAB ===============================================================
	mAwayConfigUI = new KopeteAwayConfigUI(mBehaviorTabCtl);
	mBehaviorTabCtl->addTab(mAwayConfigUI, i18n("&Away Settings"));

	// "Chat" TAB ===============================================================
	mPrfsChat = new BehaviorConfig_Chat(mBehaviorTabCtl);
	mBehaviorTabCtl->addTab(mPrfsChat, i18n("&Chat"));

	load();
	//connect a whole bunch of signals and slots so the thing works
	//TODO: There's gotta be a better way to do this --Matt  | I hope so too --Will

	connect(mPrfsGeneral->mStartDockedChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mUseQueueChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mBalloonNotifyChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mTrayflashNotifyChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mSoundIfAwayChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mTreeContactList, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect(mPrfsGeneral->mSortByGroup, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));

	//"Chat" TAB signals
	connect( mPrfsChat->cb_RaiseMsgWindowChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mPrfsChat->cb_ShowEventsChk, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mPrfsChat->highlightEnabled, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mPrfsChat->chatWindowGroup, SIGNAL(clicked(int)),
		this, SLOT(slotValueChanged(int)));
	connect( mPrfsChat->interfaceGroup, SIGNAL(clicked(int)),
		this, SLOT(slotValueChanged(int)));
	connect( mPrfsChat->mChatViewBufferSize, SIGNAL(valueChanged(int)),
		this, SLOT(slotValueChanged(int)));

	//"Away" TAB signals
	connect( mAwayConfigUI->mAutoAwayTimeout, SIGNAL(valueChanged(int)),
		this, SLOT(slotValueChanged(int)));
	connect( mAwayConfigUI->mGoAvailable, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mAwayConfigUI->mUseAutoAway, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mAwayConfigUI->mNotifyAway, SIGNAL(toggled(bool)),
		this, SLOT(slotSettingsChanged(bool)));
	connect( mAwayConfigUI, SIGNAL(awayMessagesChanged(bool)),
		this, SLOT(slotSettingsChanged(bool)));
}

void BehaviorConfig::save()
{
//	kdDebug(14000) << k_funcinfo << "called." << endl;

	KopetePrefs *p = KopetePrefs::prefs();

	// "General" TAB ============================================================
	p->setShowTray(mPrfsGeneral->mShowTrayChk->isChecked());
	p->setStartDocked(mPrfsGeneral->mStartDockedChk->isChecked());
	p->setUseQueue(mPrfsGeneral->mUseQueueChk->isChecked());
	p->setTrayflashNotify(mPrfsGeneral->mTrayflashNotifyChk->isChecked());
	p->setBalloonNotify(mPrfsGeneral->mBalloonNotifyChk->isChecked());
	p->setSoundIfAway(mPrfsGeneral->mSoundIfAwayChk->isChecked());
	p->setTreeView(mPrfsGeneral->mTreeContactList->isChecked());
	p->setSortByGroup(mPrfsGeneral->mSortByGroup->isChecked());

	// "Away" TAB ===============================================================
	p->setNotifyAway( mAwayConfigUI->mNotifyAway->isChecked());

	KConfig *config = KGlobal::config();
	config->setGroup("AutoAway");
	config->writeEntry("Timeout", mAwayConfigUI->mAutoAwayTimeout->value() * 60);
	config->writeEntry("GoAvailable", mAwayConfigUI->mGoAvailable->isChecked());
	config->writeEntry("UseAutoAway", mAwayConfigUI->mUseAutoAway->isChecked() );
	config->sync();

	// "Chat" TAB ===============================================================
	p->setRaiseMsgWindow(mPrfsChat->cb_RaiseMsgWindowChk->isChecked());
	p->setShowEvents(mPrfsChat->cb_ShowEventsChk->isChecked());
	p->setHighlightEnabled(mPrfsChat->highlightEnabled->isChecked());
	p->setChatWindowPolicy(mPrfsChat->chatWindowGroup->id(
			mPrfsChat->chatWindowGroup->selected()));
	p->setInterfacePreference(mPrfsChat->interfaceGroup->id(
			mPrfsChat->interfaceGroup->selected()) );
	p->setChatViewBufferSize(mPrfsChat->mChatViewBufferSize->value());

	p->save();
	emit changed(false);
}

void BehaviorConfig::load()
{
//	kdDebug(14000) << k_funcinfo << "called" << endl;
	KopetePrefs *p = KopetePrefs::prefs();

	// "General" TAB ============================================================
	mPrfsGeneral->mShowTrayChk->setChecked( p->showTray() );
	mPrfsGeneral->mStartDockedChk->setChecked( p->startDocked() );
	mPrfsGeneral->mUseQueueChk->setChecked( p->useQueue() );
	mPrfsGeneral->mTrayflashNotifyChk->setChecked ( p->trayflashNotify() );
	mPrfsGeneral->mBalloonNotifyChk->setChecked ( p->balloonNotify() );
	mPrfsGeneral->mSoundIfAwayChk->setChecked( p->soundIfAway() );
	slotShowTrayChanged( mPrfsGeneral->mShowTrayChk->isChecked() );
	mPrfsGeneral->mTreeContactList->setChecked( p->treeView() );
	mPrfsGeneral->mSortByGroup->setChecked( p->sortByGroup() );

	// "Away" TAB ===============================================================
	KConfig *config = KGlobal::config();
	config->setGroup("AutoAway");
	mAwayConfigUI->mAutoAwayTimeout->setValue(config->readNumEntry("Timeout", 600)/60);
	mAwayConfigUI->mGoAvailable->setChecked(config->readBoolEntry("GoAvailable", true));
	mAwayConfigUI->mUseAutoAway->setChecked(config->readBoolEntry("UseAutoAway", true));
	mAwayConfigUI->mNotifyAway->setChecked( p->notifyAway() );

	mAwayConfigUI->updateView();

	// "Chat" TAB ===============================================================
	mPrfsChat->cb_RaiseMsgWindowChk->setChecked(p->raiseMsgWindow());
	mPrfsChat->cb_ShowEventsChk->setChecked(p->showEvents());
	mPrfsChat->highlightEnabled->setChecked(p->highlightEnabled());
	mPrfsChat->chatWindowGroup->setButton(p->chatWindowPolicy());
	mPrfsChat->interfaceGroup->setButton(p->interfacePreference());
	mPrfsChat->mChatViewBufferSize->setValue(p->chatViewBufferSize());

	//TODO: make the whole thing working corretly insteads of this ugly hack...
	// emit changed(false);
	// emit changed(true);
}

void BehaviorConfig::slotConfigSound()
{
	KNotifyDialog::configure( this );
	emit changed(true);
}

void BehaviorConfig::slotShowTrayChanged(bool check)
{
	mPrfsGeneral->mStartDockedChk->setEnabled(check);
	mPrfsGeneral->mTrayflashNotifyChk->setEnabled(check);
	mPrfsGeneral->mBalloonNotifyChk->setEnabled(check);
	emit changed(true);
}

void BehaviorConfig::slotSettingsChanged(bool)
{
	emit changed(true);
}

void BehaviorConfig::slotValueChanged(int)
{
	emit changed( true );
}
#include "behaviorconfig.moc"
// vim: set noet ts=4 sts=4 sw=4:
<|endoftext|>


<commit_before>//
// Copyright Antoine Leblanc 2010 - 2013
// Distributed under the MIT license.
//
// http://nauths.fr
// http://github.com/nicuveo
// mailto://antoine.jp.leblanc@gmail.com
//

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Includes

#include <string>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <nauths/mml/mml.hh>
#include "img/io/tga.hh"

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Local code

namespace
{

  // types

  typedef mml::shapes<int>::Shape Shape;
  typedef mml::shapes<int>::Point Point;
  typedef mml::shapes<int>::Vector Vector;
  typedef mml::shapes<int>::Line Line;
  typedef mml::shapes<int>::Rect Rect;
  typedef mml::Tessellation<int> Tessellation;
  typedef tools::Bitmap Bitmap;
  typedef tools::Color Color;
  typedef tools::Bitmap::size_type size_type;

  // constants

  const int IMW      = 1600;
  const int IMH      = 1200;
  const int REF_SIZE =  600;

  const int FACT     =   2;
  const int   AA     =   0;

  const Shape REF    = Shape::square(FACT * IMW / 2, FACT * IMH / 2, FACT * REF_SIZE);

  // scale
  //   scales a bitmap, blending colours

  Bitmap scale(Bitmap const& in)
  {
    assert(in.width()  % FACT == 0);
    assert(in.height() % FACT == 0);
    assert(in.width()  == FACT * IMW);
    assert(in.height() == FACT * IMH);

    Bitmap res(IMW, IMH);
    const int r_min = -AA;
    const int r_max = FACT + AA;
    const float k = 1.f / std::pow(FACT + 2 * AA, 2);

    for (size_type y = 0; y < size_type(IMH); y += 1)
      for (size_type x = 0; x < size_type(IMW); x += 1)
      {
        float c[3] = { 0, 0, 0 };

        for (int dy = r_min; dy < r_max; ++dy)
          for (int dx = r_min; dx < r_max; ++dx)
          {
            size_type rx = std::max<size_type>(std::min<size_type>(FACT * x + dx, in.width()  - 1), 0);
            size_type ry = std::max<size_type>(std::min<size_type>(FACT * y + dy, in.height() - 1), 0);
            const Color& color = in.at(rx, ry);

            c[0] += color.rf() * k;
            c[1] += color.gf() * k;
            c[2] += color.bf() * k;
          }

        res(x, y) = Color::rgbf(c[0], c[1], c[2]);

        // Color color = Color::rgbf(c[0], c[1], c[2]);
        // std::cout << "res["
        //           << std::dec << std::setfill(' ') << std::setw(4) << x
        //           << ", "
        //           << std::dec << std::setfill(' ') << std::setw(4) << y
        //           << "]: <- #"
        //           << std::hex << std::setfill('0') << std::setw(2) << int(color.r())
        //           << std::hex << std::setfill('0') << std::setw(2) << int(color.g())
        //           << std::hex << std::setfill('0') << std::setw(2) << int(color.b())
        //           << std::endl;
      }

    return res;
  }

  // add
  //   add two rgb colors

  Color add(const Color& c1, const Color& c2)
  {
    return Color::rgb(
      std::min(int(c1.r()) + int(c2.r()), 255),
      std::min(int(c1.g()) + int(c2.g()), 255),
      std::min(int(c1.b()) + int(c2.b()), 255));
  }

  // mul
  //   multiplies a rgb color by a scalar k

  Color mul(const Color& c, float k)
  {
    return Color::rgbf(mml::clamp(c.rf() * k, 0.f, 1.f),
                       mml::clamp(c.gf() * k, 0.f, 1.f),
                       mml::clamp(c.bf() * k, 0.f, 1.f));
  }

  // next color
  //  picks a color according to a key

  template <typename Key>
  Color next_color(Key k)
  {
    static Color colors[] = { Color::red,
                              Color::green,
                              Color::blue,
                              Color::yellow,
                              Color::cyan,
                              Color::magenta,
                              Color::cyan,
                              Color::yellow,
                              Color::blue,
                              Color::green };

    static int size = sizeof(colors) / sizeof(Color);
    static int current = 0;
    static std::map<Key, int> color_indices;

    static bool first = true;

    if (first)
    {
      first = false;
      std::cout << size << ", " << sizeof(colors) << ", " << sizeof(Color) << std::endl;
    }

    typename std::map<Key, int>::const_iterator it = color_indices.find(k);

    if (it != color_indices.end())
      return colors[it->second];

    const Color& c = colors[current % size];
    std::cout << current << ": ("
              << std::right << std::setw(3) << int(c.r())
              << ", "
              << std::right << std::setw(3) << int(c.g())
              << ", "
              << std::right << std::setw(3) << int(c.b())
              << ")" <<std::endl;

    color_indices[k] = current % size;
    return colors[current++ % size];
  }

  // draw_shape
  //   draws a shape on the bitmap

  void draw_shape(Bitmap& b, const Shape& s, const Color& c, bool override = false)
  {
    const Rect bb = s.bounding_rect();
    const size_type xmin = std::max<size_type>(bb.x_min(), 0);
    const size_type ymin = std::max<size_type>(bb.y_min(), 0);
    const size_type xmax = std::min<size_type>(bb.x_max(), b.width()  - 1);
    const size_type ymax = std::min<size_type>(bb.y_max(), b.height() - 1);

    for (size_type y = ymin; y <= ymax; ++y)
      for (size_type x = xmin; x <= xmax; ++x)
        if (mml::contains(s, Point(x, y)))
        {
          if (override)
            b(x, y) = c;
          else
            b(x, y) = add(b(x, y), c);
        }
  }

  // draw_point
  //   draws a point on the bitmap

  void draw_point(Bitmap& b, const Point& p, const Color& c, int k = 1, bool override = false)
  {
    const int d = k * FACT;

    draw_shape(b, Shape::rect(p - Point(d, d), p + Point(d, d)), c, override);
  }

  // draw_line
  //   draws a line on the bitmap

  void draw_line(Bitmap& b, const Line& l, const Color& c, int k = 0, bool override = false)
  {
    Vector v = l.delta();
    int steps = l.length();
    for (int i = 0; i <= steps; ++i)
      draw_point(b, l[0] + (float(i) / steps) * v, c, k, override);
  }

  // out
  //   outputs file name

  std::string out(int t, int a, int x, int m)
  {
    std::ostringstream oss;

    oss << "out/t_"
        << std::dec << std::setw(2) << std::setfill('0') << t
        << "_"
        << std::dec << std::setw(3) << std::setfill('0') << a
        << "_"
        << std::dec << std::setw(3) << std::setfill('0') << x
        << "_"
        << m
        << ".tga";

    return oss.str();
  }

  // populate
  //   populates teh bitmap

  Bitmap populate(mml::TilingType type, int a, int x, int m)
  {
    Shape draw(REF/*.circle().polygonize(1024 * FACT)*/);
    Bitmap res(IMW * FACT, IMH * FACT, Color::black);
    std::set<double> dbs;

    Tessellation tess(type, REF, FACT * x, (a * (2 * mml::pi()) / 360.));
    std::map<unsigned, Point> links_ref;

    for (Tessellation::iterator it = tess.begin(true, true); it != tess.end(); ++it)
    {
      Point center = it->center();
      links_ref[it.index()] = center;
      Color c;

      switch ((it.index() / (tess.pattern().size())) % 6)
      {
        case  0: c = Color::rgb(  0,   0, 200); break;
        case  1: c = Color::rgb(  0, 200,   0); break;
        case  2: c = Color::rgb(  0, 200, 200); break;
        case  3: c = Color::rgb(200,   0,   0); break;
        case  4: c = Color::rgb(200,   0, 200); break;
        case  5: c = Color::rgb(200, 200,   0); break;
      }

      int i = (it.index() % tess.pattern().size()) + 1;
      c = mul(c, 0.2 + 0.8 * (i / float(tess.pattern().size())));

      switch (m)
      {
        case 0:
        case 4:
        {
          draw_shape(res, *it, c);
          break;
        }

        case 1:
        case 3:
        case 5:
        {
          mml_foreach (const Line& l, it->polygon().lines())
            draw_line(res, l, Color::white, 1);
          break;
        }

        default:
          break;
      }

      mml_foreach (const Tessellation::Link& nid, it.links())
      {
        if (links_ref.find(nid.first) != links_ref.end())
        {
          Line l(center, links_ref[nid.first]);

          switch (m)
          {
            case 0:
            {
              draw_line(res, l, Color::white);
              break;
            }

            case 1:
            {
              draw_line(res, l, next_color(nid.second + type), 1);
              break;
            }

            case 5:
            {
              draw_line(res, l, next_color(l.delta().length()), 1);
              break;
            }

            case 2:
            {
              double d = l.length();
              double k = std::abs(d - nid.second) / d;
              float coeff = mml::clamp<float>(k, 0, 1.f);

              if (k >= 0.01 and dbs.find(k) == dbs.end())
              {
                std::cout << "  " << int(k * 10000 + 0.5) / 100. << "%" << std::endl;
                dbs.insert(k);
              }

              draw_line(res, l, Color::grayf(coeff), 2, true);
              break;
            }

            default:
              break;
          }
        }
      }
    }

    switch (m)
    {
      case 3:
      case 4:
        break;

      default:
        // mml_foreach (const Point& p, draw.polygon().points_data())
        //   draw_point(res, p, Color::white);
        // draw_point(res, REF.center(), Color::white);
        break;
    }

    return res;
  }

}

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Implementation

static const  mml::TilingType tts[] =
{
  mml::tiling::TRIANGULAR,
  mml::tiling::SQUARE,
  mml::tiling::HEXAGONAL,

  mml::tiling::SNUB_HEXAGONAL,
  mml::tiling::REFLECTED_SNUB_HEXAGONAL,
  mml::tiling::TRI_HEXAGONAL,
  mml::tiling::ELONGATED_TRIANGULAR,
  mml::tiling::SNUB_SQUARE,
  mml::tiling::RHOMBITRIHEXAGONAL,
  mml::tiling::TRUNCATED_SQUARE,
  mml::tiling::TRUNCATED_HEXAGONAL,
  mml::tiling::TRUNCATED_TRIHEXAGONAL
};

void render(unsigned t, int a, int x, int m)
{
  Bitmap res = populate(tts[t], a, x, m);
  std::string ofn = out(t, a, x, m);
  std::ofstream res_file(ofn.c_str());
  if (not res_file.is_open())
    std::exit(1);

  res_file << tools::tga(scale(res));
  res_file.close();

  std::cout << ">>> " << ofn << std::endl;
}

int main()
{
  // for (unsigned t = 0; t < (sizeof (tts) / sizeof (mml::TilingType)); ++t)
  //   for (int a = 0; a < 360; a += 120)
  //     for (int x = 25; x <= 400; x *= 2)
  //       for (int m = 0; m <= 2; ++m)
  //         render(t, a, x, m);

//  render(11, 0, 120, 2);
  render(11, 0, 500, 1);
}
<commit_msg>Prettier output.<commit_after>//
// Copyright Antoine Leblanc 2010 - 2013
// Distributed under the MIT license.
//
// http://nauths.fr
// http://github.com/nicuveo
// mailto://antoine.jp.leblanc@gmail.com
//

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Includes

#include <string>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <nauths/mml/mml.hh>
#include "img/io/tga.hh"

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Local code

namespace
{

  // types

  typedef mml::shapes<int>::Shape Shape;
  typedef mml::shapes<int>::Point Point;
  typedef mml::shapes<int>::Vector Vector;
  typedef mml::shapes<int>::Line Line;
  typedef mml::shapes<int>::Rect Rect;
  typedef mml::Tessellation<int> Tessellation;
  typedef tools::Bitmap Bitmap;
  typedef tools::Color Color;
  typedef tools::Bitmap::size_type size_type;

  // constants

  const int IMW      = 1600;
  const int IMH      = 1200;
  const int REF_SIZE =  503;

  const int FACT     =   2;
  const int   AA     =   0;

  const Shape REF    = Shape::circle(FACT * IMW / 2, FACT * IMH / 2, FACT * REF_SIZE);

  // scale
  //   scales a bitmap, blending colours

  Bitmap scale(Bitmap const& in)
  {
    assert(in.width()  % FACT == 0);
    assert(in.height() % FACT == 0);
    assert(in.width()  == FACT * IMW);
    assert(in.height() == FACT * IMH);

    Bitmap res(IMW, IMH);
    const int r_min = -AA;
    const int r_max = FACT + AA;
    const float k = 1.f / std::pow(FACT + 2 * AA, 2);

    for (size_type y = 0; y < size_type(IMH); y += 1)
      for (size_type x = 0; x < size_type(IMW); x += 1)
      {
        float c[3] = { 0, 0, 0 };

        for (int dy = r_min; dy < r_max; ++dy)
          for (int dx = r_min; dx < r_max; ++dx)
          {
            size_type rx = std::max<size_type>(std::min<size_type>(FACT * x + dx, in.width()  - 1), 0);
            size_type ry = std::max<size_type>(std::min<size_type>(FACT * y + dy, in.height() - 1), 0);
            const Color& color = in.at(rx, ry);

            c[0] += color.rf() * k;
            c[1] += color.gf() * k;
            c[2] += color.bf() * k;
          }

        res(x, y) = Color::rgbf(c[0], c[1], c[2]);

        // Color color = Color::rgbf(c[0], c[1], c[2]);
        // std::cout << "res["
        //           << std::dec << std::setfill(' ') << std::setw(4) << x
        //           << ", "
        //           << std::dec << std::setfill(' ') << std::setw(4) << y
        //           << "]: <- #"
        //           << std::hex << std::setfill('0') << std::setw(2) << int(color.r())
        //           << std::hex << std::setfill('0') << std::setw(2) << int(color.g())
        //           << std::hex << std::setfill('0') << std::setw(2) << int(color.b())
        //           << std::endl;
      }

    return res;
  }

  // add
  //   add two rgb colors

  Color add(const Color& c1, const Color& c2)
  {
    return Color::rgb(
      std::min(int(c1.r()) + int(c2.r()), 255),
      std::min(int(c1.g()) + int(c2.g()), 255),
      std::min(int(c1.b()) + int(c2.b()), 255));
  }

  // mul
  //   multiplies a rgb color by a scalar k

  Color mul(const Color& c, float k)
  {
    return Color::rgbf(mml::clamp(c.rf() * k, 0.f, 1.f),
                       mml::clamp(c.gf() * k, 0.f, 1.f),
                       mml::clamp(c.bf() * k, 0.f, 1.f));
  }

  // next color
  //  picks a color according to a key

  template <typename Key>
  Color next_color(Key k)
  {
    static Color colors[] = { Color::red,
                              Color::green,
                              Color::blue,
                              Color::yellow,
                              Color::cyan,
                              Color::magenta,
                              Color::cyan,
                              Color::yellow,
                              Color::blue,
                              Color::green };

    static int size = sizeof(colors) / sizeof(Color);
    static int current = 0;
    static std::map<Key, int> color_indices;

    static bool first = true;

    if (first)
    {
      first = false;
      std::cout << size << ", " << sizeof(colors) << ", " << sizeof(Color) << std::endl;
    }

    typename std::map<Key, int>::const_iterator it = color_indices.find(k);

    if (it != color_indices.end())
      return colors[it->second];

    const Color& c = colors[current % size];
    std::cout << current << ": ("
              << std::right << std::setw(3) << int(c.r())
              << ", "
              << std::right << std::setw(3) << int(c.g())
              << ", "
              << std::right << std::setw(3) << int(c.b())
              << ")" <<std::endl;

    color_indices[k] = current % size;
    return colors[current++ % size];
  }

  // draw_shape
  //   draws a shape on the bitmap

  void draw_shape(Bitmap& b, const Shape& s, const Color& c, bool override = false)
  {
    const Rect bb = s.bounding_rect();
    const size_type xmin = std::max<size_type>(bb.x_min(), 0);
    const size_type ymin = std::max<size_type>(bb.y_min(), 0);
    const size_type xmax = std::min<size_type>(bb.x_max(), b.width()  - 1);
    const size_type ymax = std::min<size_type>(bb.y_max(), b.height() - 1);

    for (size_type y = ymin; y <= ymax; ++y)
      for (size_type x = xmin; x <= xmax; ++x)
        if (mml::contains(s, Point(x, y)))
        {
          if (override)
            b(x, y) = c;
          else
            b(x, y) = add(b(x, y), c);
        }
  }

  // draw_point
  //   draws a point on the bitmap

  void draw_point(Bitmap& b, const Point& p, const Color& c, int k = 1, bool override = false)
  {
    const int d = k * FACT;

    draw_shape(b, Shape::rect(p - Point(d, d), p + Point(d, d)), c, override);
  }

  // draw_line
  //   draws a line on the bitmap

  void draw_line(Bitmap& b, const Line& l, const Color& c, int k = 0, bool override = false)
  {
    Vector v = l.delta();
    int steps = l.length();
    for (int i = 0; i <= steps; ++i)
      draw_point(b, l[0] + (float(i) / steps) * v, c, k, override);
  }

  // out
  //   outputs file name

  std::string out(int t, int a, int x, int m)
  {
    std::ostringstream oss;

    oss << "out/t_"
        << std::dec << std::setw(2) << std::setfill('0') << t
        << "_"
        << std::dec << std::setw(3) << std::setfill('0') << a
        << "_"
        << std::dec << std::setw(3) << std::setfill('0') << x
        << "_"
        << m
        << ".tga";

    return oss.str();
  }

  // populate
  //   populates teh bitmap

  Bitmap populate(mml::TilingType type, int a, int x, int m)
  {
    Shape draw(REF);
    Bitmap res(IMW * FACT, IMH * FACT, Color::black);
    std::set<double> dbs;

    Tessellation tess(type, REF, FACT * x, (a * (2 * mml::pi()) / 360.));
    std::map<unsigned, Point> links_ref;

    for (Tessellation::iterator it = tess.begin(true, true); it != tess.end(); ++it)
    {
      Point center = it->center();
      links_ref[it.index()] = center;
      Color c;

      switch ((it.index() / (tess.pattern().size())) % 6)
      {
        case  0: c = Color::rgb(  0,   0, 200); break;
        case  1: c = Color::rgb(  0, 200,   0); break;
        case  2: c = Color::rgb(  0, 200, 200); break;
        case  3: c = Color::rgb(200,   0,   0); break;
        case  4: c = Color::rgb(200,   0, 200); break;
        case  5: c = Color::rgb(200, 200,   0); break;
      }

      int i = (it.index() % tess.pattern().size()) + 1;
      c = mul(c, 0.4 + 0.6 * (i / float(tess.pattern().size())));

      switch (m)
      {
        case 0:
        case 4:
        {
          draw_shape(res, *it, c);
          break;
        }

        case 1:
        case 3:
        case 5:
        {
          mml_foreach (const Line& l, it->polygon().lines())
            draw_line(res, l, Color::white, 1);
          break;
        }

        default:
          break;
      }

      mml_foreach (const Tessellation::Link& nid, it.links())
      {
        if (links_ref.find(nid.first) != links_ref.end())
        {
          Line l(center, links_ref[nid.first]);

          switch (m)
          {
            // case 0:
            // {
            //   draw_line(res, l, Color::white);
            //   break;
            // }

            case 1:
            {
              draw_line(res, l, next_color(nid.second + type), 1);
              break;
            }

            case 5:
            {
              draw_line(res, l, next_color(l.delta().length()), 1);
              break;
            }

            case 2:
            {
              double d = l.length();
              double k = std::abs(d - nid.second) / d;
              float coeff = mml::clamp<float>(k, 0, 1.f);

              if (k >= 0.01 and dbs.find(k) == dbs.end())
              {
                std::cout << "  " << int(k * 10000 + 0.5) / 100. << "%" << std::endl;
                dbs.insert(k);
              }

              draw_line(res, l, Color::grayf(coeff), 2, true);
              break;
            }

            default:
              break;
          }
        }
      }
    }

    switch (m)
    {
      case 3:
      case 4:
        break;

      default:
        // mml_foreach (const Point& p, draw.polygon().points_data())
        //   draw_point(res, p, Color::white);
        // draw_point(res, REF.center(), Color::white);
        break;
    }

    return res;
  }

}

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Implementation

static const  mml::TilingType tts[] =
{
  mml::tiling::TRIANGULAR,
  mml::tiling::SQUARE,
  mml::tiling::HEXAGONAL,

  mml::tiling::SNUB_HEXAGONAL,
  mml::tiling::REFLECTED_SNUB_HEXAGONAL,
  mml::tiling::TRI_HEXAGONAL,
  mml::tiling::ELONGATED_TRIANGULAR,
  mml::tiling::SNUB_SQUARE,
  mml::tiling::RHOMBITRIHEXAGONAL,
  mml::tiling::TRUNCATED_SQUARE,
  mml::tiling::TRUNCATED_HEXAGONAL,
  mml::tiling::TRUNCATED_TRIHEXAGONAL
};

void render(unsigned t, int a, int x, int m)
{
  Bitmap res = populate(tts[t], a, x, m);
  std::string ofn = out(t, a, x, m);
  std::ofstream res_file(ofn.c_str());
  if (not res_file.is_open())
    std::exit(1);

  res_file << tools::tga(scale(res));
  res_file.close();

  std::cout << ">>> " << ofn << std::endl;
}

int main()
{
  for (unsigned t = 0; t < (sizeof (tts) / sizeof (mml::TilingType)); ++t)
    for (int x = 50; x <= 400; x *= 2)
    {
      render(t, 0, x, 0);
      render(t, 0, x, 1);
    }
}
<|endoftext|>


<commit_before>// Copyright WRLD Ltd (2018-), All Rights Reserved

#include "SearchServices.h"
#include "SearchQuery.h"
#include "AutocompleteSuggestionsMessage.h"
#include "AutocompleteSuggestionsCancelledMessage.h"
#include "ISearchResultsRepository.h"

#include <algorithm>

namespace ExampleApp
{
    namespace SearchMenu
    {
		namespace View
		{
			SearchServices::SearchServices(ISearchProvider& searchProvider,
										   ISearchResultsRepository& searchResultsRepository,
										   ISearchResultsRepository& suggestionsRepository,
                                           ExampleApp::SearchMenu::View::ISearchWidgetView& searchWidgetView,
										   ExampleAppMessaging::TMessageBus& messageBus)
			: m_searchProvider(searchProvider)
			, m_searchResultsRepository(searchResultsRepository)
			, m_suggestionsRepository(suggestionsRepository)
			, m_messageBus(messageBus)
			, m_onSearchCallback(this, &SearchServices::OnSearch)
			, m_onSearchWithContextCallback(this, &SearchServices::OnSearchWithContext)
            , m_onAutocompleteSuggestionsCallback(this, &SearchServices::OnAutocompleteSuggestions)
			, m_onCancelCallback(this, &SearchServices::OnCancel)
			, m_responseReceivedHandler(this, &SearchServices::OnSearchQueryResponseReceivedMessage)
			, m_autocompleteSuggestionsResponseReceivedHandler(this, &SearchServices::OnAutocompleteSuggestionsResponseReceivedMessage)
			, m_onCancelSuggestions(this, &SearchServices::OnCancelSuggestions)
            , m_searchWidgetView(searchWidgetView)
            , m_onSearchbarChangedCallback(this, &SearchServices::OnSearchbarTextChanged)
            , m_rerunLastTagSearch(false)
            , m_lastSearchContext(false, false, "", false)

			{
				m_searchProvider.InsertSearchPerformedCallback(m_onSearchCallback);
				m_searchProvider.InsertSearchWithContextCallback(m_onSearchWithContextCallback);
				m_searchProvider.InsertSearchCancelledCallback(m_onCancelCallback);
				m_searchProvider.InsertSuggestionsCancelledCallback(m_onCancelSuggestions);
				m_searchProvider.InsertAutocompleteSuggestionsCallback(m_onAutocompleteSuggestionsCallback);
                m_searchWidgetView.InsertSearchbarTextChangedCallback(m_onSearchbarChangedCallback);

                m_messageBus.SubscribeUi(m_responseReceivedHandler);
				m_messageBus.SubscribeUi(m_autocompleteSuggestionsResponseReceivedHandler);
            }

			SearchServices::~SearchServices()
			{
				m_messageBus.UnsubscribeUi(m_autocompleteSuggestionsResponseReceivedHandler);
				m_messageBus.UnsubscribeUi(m_responseReceivedHandler);

                m_searchWidgetView.RemoveSearchbarTextChangedCallback(m_onSearchbarChangedCallback);
				m_searchProvider.RemoveAutocompleteSuggestionsCallback(m_onAutocompleteSuggestionsCallback);
				m_searchProvider.RemoveSuggestionsCancelledCallback(m_onCancelSuggestions);
				m_searchProvider.RemoveSearchCancelledCallback(m_onCancelCallback);
				m_searchProvider.RemoveSearchWithContextCallback(m_onSearchWithContextCallback);
				m_searchProvider.RemoveSearchPerformedCallback(m_onSearchCallback);
			}

            void SearchServices::OnSearchbarTextChanged(const std::string& newText)
            {
                m_rerunLastTagSearch = false;
            }

			void SearchServices::OnAutocompleteSuggestions(const std::string& searchQuery)
            {
				 m_messageBus.Publish(AutocompleteSuggestionsMessage(searchQuery));
			}

            void SearchServices::OnSearch(const std::string& searchQuery)
            {
                if(m_rerunLastTagSearch)
                {
                    OnSearchWithContext(searchQuery, m_lastSearchContext);
                }
                else
                {
                    m_messageBus.Publish(SearchMenuPerformedSearchMessage(searchQuery, false, false));
                }
            }

			void SearchServices::OnSearchWithContext(const std::string& searchQuery, const QueryContext& context)
			{
                m_lastSearchContext = context;

				std::string effectiveQuery = context.IsTag() ? context.TagText() : searchQuery;

                m_rerunLastTagSearch = context.IsTag();

				m_messageBus.Publish(SearchMenuSearchWithContextMessage(effectiveQuery, context));
			}

			void SearchServices::OnCancel()
			{
				m_messageBus.Publish(SearchResultSection::SearchResultViewClearedMessage());
			}

			void SearchServices::OnCancelSuggestions()
			{
				m_messageBus.Publish(AutocompleteSuggestionsCancelledMessage());
			}

			void SearchServices::OnSearchQueryResponseReceivedMessage(const Search::SearchQueryResponseReceivedMessage& message)
            {
				m_searchResultsRepository.SetResults(message.GetResults());
				m_searchProvider.OnSearchResponseReceived(message.DidSucceed(), m_searchResultsRepository.GetResults());
			}

			void SearchServices::OnAutocompleteSuggestionsResponseReceivedMessage(const Search::AutocompleteSuggestionsReceivedMessage& message)
			{
				m_suggestionsRepository.SetResults(message.GetResults());
				m_searchProvider.OnAutocompleteSuggestionsResponseReceived(message.DidSucceed(), m_suggestionsRepository.GetResults());
			}
		}
	}
}
<commit_msg>Fix for MPLY-10381 Before re-running a text search as a tag search, check that the last tag search text is the same. Buddy: Jordan<commit_after>// Copyright WRLD Ltd (2018-), All Rights Reserved

#include "SearchServices.h"
#include "SearchQuery.h"
#include "AutocompleteSuggestionsMessage.h"
#include "AutocompleteSuggestionsCancelledMessage.h"
#include "ISearchResultsRepository.h"

#include <algorithm>

namespace ExampleApp
{
    namespace SearchMenu
    {
		namespace View
		{
			SearchServices::SearchServices(ISearchProvider& searchProvider,
										   ISearchResultsRepository& searchResultsRepository,
										   ISearchResultsRepository& suggestionsRepository,
                                           ExampleApp::SearchMenu::View::ISearchWidgetView& searchWidgetView,
										   ExampleAppMessaging::TMessageBus& messageBus)
			: m_searchProvider(searchProvider)
			, m_searchResultsRepository(searchResultsRepository)
			, m_suggestionsRepository(suggestionsRepository)
			, m_messageBus(messageBus)
			, m_onSearchCallback(this, &SearchServices::OnSearch)
			, m_onSearchWithContextCallback(this, &SearchServices::OnSearchWithContext)
            , m_onAutocompleteSuggestionsCallback(this, &SearchServices::OnAutocompleteSuggestions)
			, m_onCancelCallback(this, &SearchServices::OnCancel)
			, m_responseReceivedHandler(this, &SearchServices::OnSearchQueryResponseReceivedMessage)
			, m_autocompleteSuggestionsResponseReceivedHandler(this, &SearchServices::OnAutocompleteSuggestionsResponseReceivedMessage)
			, m_onCancelSuggestions(this, &SearchServices::OnCancelSuggestions)
            , m_searchWidgetView(searchWidgetView)
            , m_onSearchbarChangedCallback(this, &SearchServices::OnSearchbarTextChanged)
            , m_rerunLastTagSearch(false)
            , m_lastSearchContext(false, false, "", false)

			{
				m_searchProvider.InsertSearchPerformedCallback(m_onSearchCallback);
				m_searchProvider.InsertSearchWithContextCallback(m_onSearchWithContextCallback);
				m_searchProvider.InsertSearchCancelledCallback(m_onCancelCallback);
				m_searchProvider.InsertSuggestionsCancelledCallback(m_onCancelSuggestions);
				m_searchProvider.InsertAutocompleteSuggestionsCallback(m_onAutocompleteSuggestionsCallback);
                m_searchWidgetView.InsertSearchbarTextChangedCallback(m_onSearchbarChangedCallback);

                m_messageBus.SubscribeUi(m_responseReceivedHandler);
				m_messageBus.SubscribeUi(m_autocompleteSuggestionsResponseReceivedHandler);
            }

			SearchServices::~SearchServices()
			{
				m_messageBus.UnsubscribeUi(m_autocompleteSuggestionsResponseReceivedHandler);
				m_messageBus.UnsubscribeUi(m_responseReceivedHandler);

                m_searchWidgetView.RemoveSearchbarTextChangedCallback(m_onSearchbarChangedCallback);
				m_searchProvider.RemoveAutocompleteSuggestionsCallback(m_onAutocompleteSuggestionsCallback);
				m_searchProvider.RemoveSuggestionsCancelledCallback(m_onCancelSuggestions);
				m_searchProvider.RemoveSearchCancelledCallback(m_onCancelCallback);
				m_searchProvider.RemoveSearchWithContextCallback(m_onSearchWithContextCallback);
				m_searchProvider.RemoveSearchPerformedCallback(m_onSearchCallback);
			}

            void SearchServices::OnSearchbarTextChanged(const std::string& newText)
            {
                m_rerunLastTagSearch = false;
            }

			void SearchServices::OnAutocompleteSuggestions(const std::string& searchQuery)
            {
				 m_messageBus.Publish(AutocompleteSuggestionsMessage(searchQuery));
			}

            void SearchServices::OnSearch(const std::string& searchQuery)
            {
                if(m_rerunLastTagSearch)
                {
                    OnSearchWithContext(searchQuery, m_lastSearchContext);
                }
                else
                {
                    m_messageBus.Publish(SearchMenuPerformedSearchMessage(searchQuery, false, false));
                }
            }

			void SearchServices::OnSearchWithContext(const std::string& searchQuery, const QueryContext& context)
			{
                bool samePreviousSearchText = context.TagText() == m_lastSearchContext.TagText();
                m_lastSearchContext = context;

				std::string effectiveQuery = context.IsTag() ? context.TagText() : searchQuery;

                m_rerunLastTagSearch = context.IsTag() && samePreviousSearchText;

				m_messageBus.Publish(SearchMenuSearchWithContextMessage(effectiveQuery, context));
			}

			void SearchServices::OnCancel()
			{
				m_messageBus.Publish(SearchResultSection::SearchResultViewClearedMessage());
			}

			void SearchServices::OnCancelSuggestions()
			{
				m_messageBus.Publish(AutocompleteSuggestionsCancelledMessage());
			}

			void SearchServices::OnSearchQueryResponseReceivedMessage(const Search::SearchQueryResponseReceivedMessage& message)
            {
				m_searchResultsRepository.SetResults(message.GetResults());
				m_searchProvider.OnSearchResponseReceived(message.DidSucceed(), m_searchResultsRepository.GetResults());
			}

			void SearchServices::OnAutocompleteSuggestionsResponseReceivedMessage(const Search::AutocompleteSuggestionsReceivedMessage& message)
			{
				m_suggestionsRepository.SetResults(message.GetResults());
				m_searchProvider.OnAutocompleteSuggestionsResponseReceived(message.DidSucceed(), m_suggestionsRepository.GetResults());
			}
		}
	}
}
<|endoftext|>


<commit_before>#include "vision_methods.hpp"
//#include <oepncv2/features2d.hpp>
#include <opencv2/opencv.hpp>

vision_methods::vision_methods () {
}

vision_methods::~vision_methods () {
}

cv::Mat vision_methods::preprocessing (const cv::Mat& image_in) {
    cv::Mat image_out;
    cvtColor (image_in, image_out, CV_BGR2GRAY);
    cv::GaussianBlur (image_out, image_out, cv::Size (_ksize_x, _ksize_y), _sigma_x, _sigma_y);
    return image_out;
}

cv::Mat vision_methods::segmentation (const cv::Mat& image_in) {
    cv::Mat image_out, image_thres;

    double otsus_threshold =
    cv::threshold (image_in, image_thres, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    double CannyThresh = 0;

    cv::Canny (image_in, image_out, CannyThresh, otsus_threshold);

    return image_out;
}

cv::Mat vision_methods::extraction (const cv::Mat& image_in,
std::map<unsigned int, cv::KeyPoint>& markers) {
    std::vector<cv::KeyPoint> key_points;
    cv::Mat image_out;
    // blob detection creation
    cv::SimpleBlobDetector::Params blob_detector_params;
    blob_detector_params.filterByArea        = true;
    blob_detector_params.maxArea             = 10000.0;
    blob_detector_params.minArea             = 10.0;
    blob_detector_params.minDistBetweenBlobs = 5.0; // 50?
    cv::SimpleBlobDetector blob_detector (blob_detector_params);

    blob_detector.detect (image_in, key_points);

    int i = 0;
    for (cv::KeyPoint point : key_points) {
        markers[i] = point;
        ++i;
    }

    cv::drawKeypoints (image_in, key_points, image_out);
    return image_out;
}
<commit_msg>change detection to use findcontours<commit_after>#include "vision_methods.hpp"
//#include <oepncv2/features2d.hpp>
#include <opencv2/opencv.hpp>

vision_methods::vision_methods () {
}

vision_methods::~vision_methods () {
}

cv::Mat vision_methods::preprocessing (const cv::Mat& image_in) {
    cv::Mat image_out;
    cvtColor (image_in, image_out, CV_BGR2GRAY);
    cv::GaussianBlur (image_out, image_out, cv::Size (_ksize_x, _ksize_y), _sigma_x, _sigma_y);
    return image_out;
}

cv::Mat vision_methods::segmentation (const cv::Mat& image_in) {
    cv::Mat image_out, image_thres;

    double otsus_threshold =
    cv::threshold (image_in, image_thres, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    double CannyThresh = 0;

    cv::Canny (image_in, image_out, CannyThresh, otsus_threshold);

    return image_out;
}

cv::Mat vision_methods::extraction (const cv::Mat& image_in,
std::map<unsigned int, cv::KeyPoint>& markers) {
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
    cv::RNG rng;
    cv::Mat* image_out;

    cv::findContours (image_in, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

    cv::Mat drawing = cv::Mat::zeros (image_in.size (), CV_8UC3);
    for (unsigned int i = 0; i < contours.size (); i++) {
        cv::Scalar color =
        cv::Scalar (rng.uniform (0, 255), rng.uniform (0, 255), rng.uniform (0, 255));
        cv::drawContours (drawing, contours, i, color, 2, 8, hierarchy, 0);
    }

    return drawing;
}

/*    // blob detection creation
    cv::SimpleBlobDetector::Params blob_detector_params;
    blob_detector_params.filterByArea        = true;
    blob_detector_params.maxArea             = 10000.0;
    blob_detector_params.minArea             = 10.0;
    blob_detector_params.minDistBetweenBlobs = 5.0; // 50?
    cv::SimpleBlobDetector blob_detector (blob_detector_params);

    blob_detector.detect (image_in, key_points);

    int i = 0;
    for (cv::KeyPoint point : key_points) {
        markers[i] = point;
        ++i;
    }

    cv::drawKeypoints (image_in, key_points, image_out);
*/
<|endoftext|>


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

/*
VULKAN_SAMPLE_SHORT_DESCRIPTION
Draw Cube
*/

#include <util_init.hpp>
#include <assert.h>
#include <string.h>
#include <cstdlib>
#include "cube_data.h"

static const char *vertShaderText =
        "#version 140\n"
        "#extension GL_ARB_separate_shader_objects : enable\n"
        "#extension GL_ARB_shading_language_420pack : enable\n"
        "layout (std140, binding = 0) uniform bufferVals {\n"
        "    mat4 mvp;\n"
        "} myBufferVals;\n"
        "layout (location = 0) in vec4 pos;\n"
        "layout (location = 1) in vec4 inColor;\n"
        "layout (location = 0) out vec4 outColor;\n"
        "void main() {\n"
        "   outColor = inColor;\n"
        "   gl_Position = myBufferVals.mvp * pos;\n"
        "   gl_Position.y = -gl_Position.y;\n"
        "   gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;\n"
        "}\n";

static const char *fragShaderText=
    "#version 140\n"
    "#extension GL_ARB_separate_shader_objects : enable\n"
    "#extension GL_ARB_shading_language_420pack : enable\n"
    "layout (location = 0) in vec4 color;\n"
    "layout (location = 0) out vec4 outColor;\n"
    "void main() {\n"
    "   outColor = color;\n"
    "}\n";

int main(int argc, char **argv)
{
    VkResult U_ASSERT_ONLY res;
    struct sample_info info = {};
    char sample_title[] = "Draw Cube";

    init_global_layer_properties(info);
    info.instance_extension_names.push_back(VK_WSI_SWAPCHAIN_EXTENSION_NAME);
    info.device_extension_names.push_back(VK_WSI_DEVICE_SWAPCHAIN_EXTENSION_NAME);
    init_instance(info, sample_title);
    init_enumerate_device(info);
    init_device(info);
    info.width = info.height = 500;
    init_connection(info);
    init_window(info);
    init_wsi(info);
    init_and_begin_command_buffer(info);
    init_device_queue(info);
    init_swap_chain(info);
    init_depth_buffer(info);
    init_uniform_buffer(info);
    init_renderpass(info);
    init_framebuffers(info);
    init_vertex_buffer(info, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data),
                               sizeof(g_vb_solid_face_colors_Data[0]), false);
    init_descriptor_and_pipeline_layouts(info, false);
    init_descriptor_set(info, false);
    init_shaders(info, vertShaderText, fragShaderText);
    init_pipeline(info);
    init_dynamic_state(info);

    /* VULKAN_KEY_START */

    VkClearValue clear_values[2];
    clear_values[0].color.f32[0] = 0.2f;
    clear_values[0].color.f32[1] = 0.2f;
    clear_values[0].color.f32[2] = 0.2f;
    clear_values[0].color.f32[3] = 0.2f;
    clear_values[1].ds.depth     = 1.0f;
    clear_values[1].ds.stencil   = 0;

    VkRenderPassBeginInfo rp_begin;
    rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    rp_begin.pNext = NULL;
    rp_begin.renderPass = info.render_pass;
    rp_begin.framebuffer = info.framebuffers[info.current_buffer];
    rp_begin.renderArea.offset.x = 0;
    rp_begin.renderArea.offset.y = 0;
    rp_begin.renderArea.extent.width = info.width;
    rp_begin.renderArea.extent.height = info.height;
    rp_begin.attachmentCount = 2;
    rp_begin.pAttachmentClearValues = clear_values;

    vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_RENDER_PASS_CONTENTS_INLINE);

    vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
                                  info.pipeline);
    vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout,
            0, 1, &info.desc_set, 0, NULL);

    const VkDeviceSize offsets[1] = {0};
    vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets);

    vkCmdBindDynamicViewportState(info.cmd, info.dyn_viewport);
    vkCmdBindDynamicRasterState(info.cmd,  info.dyn_raster);
    vkCmdBindDynamicColorBlendState(info.cmd, info.dyn_blend);
    vkCmdBindDynamicDepthStencilState(info.cmd, info.dyn_depth);

    vkCmdDraw(info.cmd, 0, 12 * 3, 0, 1);
    vkCmdEndRenderPass(info.cmd);

    end_and_submit_command_buffer(info);

    /* Now present the image in the window */

    VkPresentInfoWSI present;
    present.sType = VK_STRUCTURE_TYPE_QUEUE_PRESENT_INFO_WSI;
    present.pNext = NULL;
    present.swapChainCount = 1;
    present.swapChains = &info.swap_chain;
    present.imageIndices = &info.current_buffer;

    res = info.fpQueuePresentWSI(info.queue, &present);
    // TODO: Deal with the VK_SUBOPTIMAL_WSI and VK_ERROR_OUT_OF_DATE_WSI
    // return codes
    assert(!res);

    res = vkQueueWaitIdle(info.queue);
    assert(res == VK_SUCCESS);

    wait_seconds(1);
    /* VULKAN_KEY_END */

    vkDestroyDynamicViewportState(info.device, info.dyn_viewport);
    vkDestroyDynamicRasterState(info.device, info.dyn_raster);
    vkDestroyDynamicColorBlendState(info.device, info.dyn_blend);
    vkDestroyDynamicDepthStencilState(info.device, info.dyn_depth);
    vkDestroyPipeline(info.device, info.pipeline);
    vkDestroyPipelineCache(info.device, info.pipelineCache);
    vkFreeMemory(info.device, info.uniform_data.mem);
    vkDestroyBufferView(info.device, info.uniform_data.view);
    vkDestroyBuffer(info.device, info.uniform_data.buf);
    vkDestroyDescriptorSetLayout(info.device, info.desc_layout);
    vkDestroyPipelineLayout(info.device, info.pipeline_layout);
    vkFreeDescriptorSets(info.device, info.desc_pool, 1, &info.desc_set);
    vkDestroyDescriptorPool(info.device, info.desc_pool);
    vkDestroyShader(info.device,info.shaderStages[0].shader);
    vkDestroyShader(info.device,info.shaderStages[1].shader);
    vkDestroyShaderModule(info.device, info.vert_shader_module);
    vkDestroyShaderModule(info.device, info.frag_shader_module);
    vkDestroyCommandBuffer(info.device, info.cmd);
    vkDestroyCommandPool(info.device, info.cmd_pool);
    vkFreeMemory(info.device, info.depth.mem);
    vkDestroyAttachmentView(info.device, info.depth.view);
    vkDestroyImage(info.device, info.depth.image);
    vkFreeMemory(info.device, info.vertex_buffer.mem);
    vkDestroyBufferView(info.device, info.vertex_buffer.view);
    vkDestroyBuffer(info.device, info.vertex_buffer.buf);
    for (int i = 0; i < info.swapChainImageCount; i++) {
        vkDestroyAttachmentView(info.device, info.buffers[i].view);
    }
    info.fpDestroySwapChainWSI(info.device, info.swap_chain);
    for (int i = 0; i < SAMPLE_BUFFER_COUNT; i++) {
        vkDestroyFramebuffer(info.device, info.framebuffers[i]);
    }
    vkDestroyRenderPass(info.device, info.render_pass);
    vkDestroyDevice(info.device);
    vkDestroyInstance(info.inst);
    destroy_window(info);
}
<commit_msg>Fix indent on shader in drawcube<commit_after>/*
 * Vulkan Samples Kit
 *
 * Copyright (C) 2015 LunarG, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/*
VULKAN_SAMPLE_SHORT_DESCRIPTION
Draw Cube
*/

#include <util_init.hpp>
#include <assert.h>
#include <string.h>
#include <cstdlib>
#include "cube_data.h"

static const char *vertShaderText =
    "#version 140\n"
    "#extension GL_ARB_separate_shader_objects : enable\n"
    "#extension GL_ARB_shading_language_420pack : enable\n"
    "layout (std140, binding = 0) uniform bufferVals {\n"
    "    mat4 mvp;\n"
    "} myBufferVals;\n"
    "layout (location = 0) in vec4 pos;\n"
    "layout (location = 1) in vec4 inColor;\n"
    "layout (location = 0) out vec4 outColor;\n"
    "void main() {\n"
    "   outColor = inColor;\n"
    "   gl_Position = myBufferVals.mvp * pos;\n"
    "   gl_Position.y = -gl_Position.y;\n"
    "   gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;\n"
    "}\n";

static const char *fragShaderText=
    "#version 140\n"
    "#extension GL_ARB_separate_shader_objects : enable\n"
    "#extension GL_ARB_shading_language_420pack : enable\n"
    "layout (location = 0) in vec4 color;\n"
    "layout (location = 0) out vec4 outColor;\n"
    "void main() {\n"
    "   outColor = color;\n"
    "}\n";

int main(int argc, char **argv)
{
    VkResult U_ASSERT_ONLY res;
    struct sample_info info = {};
    char sample_title[] = "Draw Cube";

    init_global_layer_properties(info);
    info.instance_extension_names.push_back(VK_WSI_SWAPCHAIN_EXTENSION_NAME);
    info.device_extension_names.push_back(VK_WSI_DEVICE_SWAPCHAIN_EXTENSION_NAME);
    init_instance(info, sample_title);
    init_enumerate_device(info);
    init_device(info);
    info.width = info.height = 500;
    init_connection(info);
    init_window(info);
    init_wsi(info);
    init_and_begin_command_buffer(info);
    init_device_queue(info);
    init_swap_chain(info);
    init_depth_buffer(info);
    init_uniform_buffer(info);
    init_renderpass(info);
    init_framebuffers(info);
    init_vertex_buffer(info, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data),
                               sizeof(g_vb_solid_face_colors_Data[0]), false);
    init_descriptor_and_pipeline_layouts(info, false);
    init_descriptor_set(info, false);
    init_shaders(info, vertShaderText, fragShaderText);
    init_pipeline(info);
    init_dynamic_state(info);

    /* VULKAN_KEY_START */

    VkClearValue clear_values[2];
    clear_values[0].color.f32[0] = 0.2f;
    clear_values[0].color.f32[1] = 0.2f;
    clear_values[0].color.f32[2] = 0.2f;
    clear_values[0].color.f32[3] = 0.2f;
    clear_values[1].ds.depth     = 1.0f;
    clear_values[1].ds.stencil   = 0;

    VkRenderPassBeginInfo rp_begin;
    rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    rp_begin.pNext = NULL;
    rp_begin.renderPass = info.render_pass;
    rp_begin.framebuffer = info.framebuffers[info.current_buffer];
    rp_begin.renderArea.offset.x = 0;
    rp_begin.renderArea.offset.y = 0;
    rp_begin.renderArea.extent.width = info.width;
    rp_begin.renderArea.extent.height = info.height;
    rp_begin.attachmentCount = 2;
    rp_begin.pAttachmentClearValues = clear_values;

    vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_RENDER_PASS_CONTENTS_INLINE);

    vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
                                  info.pipeline);
    vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout,
            0, 1, &info.desc_set, 0, NULL);

    const VkDeviceSize offsets[1] = {0};
    vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets);

    vkCmdBindDynamicViewportState(info.cmd, info.dyn_viewport);
    vkCmdBindDynamicRasterState(info.cmd,  info.dyn_raster);
    vkCmdBindDynamicColorBlendState(info.cmd, info.dyn_blend);
    vkCmdBindDynamicDepthStencilState(info.cmd, info.dyn_depth);

    vkCmdDraw(info.cmd, 0, 12 * 3, 0, 1);
    vkCmdEndRenderPass(info.cmd);

    end_and_submit_command_buffer(info);

    /* Now present the image in the window */

    VkPresentInfoWSI present;
    present.sType = VK_STRUCTURE_TYPE_QUEUE_PRESENT_INFO_WSI;
    present.pNext = NULL;
    present.swapChainCount = 1;
    present.swapChains = &info.swap_chain;
    present.imageIndices = &info.current_buffer;

    res = info.fpQueuePresentWSI(info.queue, &present);
    // TODO: Deal with the VK_SUBOPTIMAL_WSI and VK_ERROR_OUT_OF_DATE_WSI
    // return codes
    assert(!res);

    res = vkQueueWaitIdle(info.queue);
    assert(res == VK_SUCCESS);

    wait_seconds(1);
    /* VULKAN_KEY_END */

    vkDestroyDynamicViewportState(info.device, info.dyn_viewport);
    vkDestroyDynamicRasterState(info.device, info.dyn_raster);
    vkDestroyDynamicColorBlendState(info.device, info.dyn_blend);
    vkDestroyDynamicDepthStencilState(info.device, info.dyn_depth);
    vkDestroyPipeline(info.device, info.pipeline);
    vkDestroyPipelineCache(info.device, info.pipelineCache);
    vkFreeMemory(info.device, info.uniform_data.mem);
    vkDestroyBufferView(info.device, info.uniform_data.view);
    vkDestroyBuffer(info.device, info.uniform_data.buf);
    vkDestroyDescriptorSetLayout(info.device, info.desc_layout);
    vkDestroyPipelineLayout(info.device, info.pipeline_layout);
    vkFreeDescriptorSets(info.device, info.desc_pool, 1, &info.desc_set);
    vkDestroyDescriptorPool(info.device, info.desc_pool);
    vkDestroyShader(info.device,info.shaderStages[0].shader);
    vkDestroyShader(info.device,info.shaderStages[1].shader);
    vkDestroyShaderModule(info.device, info.vert_shader_module);
    vkDestroyShaderModule(info.device, info.frag_shader_module);
    vkDestroyCommandBuffer(info.device, info.cmd);
    vkDestroyCommandPool(info.device, info.cmd_pool);
    vkFreeMemory(info.device, info.depth.mem);
    vkDestroyAttachmentView(info.device, info.depth.view);
    vkDestroyImage(info.device, info.depth.image);
    vkFreeMemory(info.device, info.vertex_buffer.mem);
    vkDestroyBufferView(info.device, info.vertex_buffer.view);
    vkDestroyBuffer(info.device, info.vertex_buffer.buf);
    for (int i = 0; i < info.swapChainImageCount; i++) {
        vkDestroyAttachmentView(info.device, info.buffers[i].view);
    }
    info.fpDestroySwapChainWSI(info.device, info.swap_chain);
    for (int i = 0; i < SAMPLE_BUFFER_COUNT; i++) {
        vkDestroyFramebuffer(info.device, info.framebuffers[i]);
    }
    vkDestroyRenderPass(info.device, info.render_pass);
    vkDestroyDevice(info.device);
    vkDestroyInstance(info.inst);
    destroy_window(info);
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2011 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

/// \file ipfind.cc
///
/// Finds the interest points in an image and outputs them an Binary
/// (default) or ASCII format.  The ASCII format is compatible with
/// the popular Lowe-SIFT toolchain.
///
#include <vw/Core.h>
#include <vw/InterestPoint.h>
#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/Math/BBox.h>

using namespace vw;
using namespace vw::ip;

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

#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;

template <class ImageT, class ValueT>
void draw_line( ImageViewBase<ImageT>& image,
                ValueT const& value,
                Vector2i const& start,
                Vector2i const& end ) {

  BBox2i bound = bounding_box(image.impl());
  if ( !bound.contains( start ) ||
       !bound.contains( end ) )
    return;
  Vector2i delta = end - start;
  for ( float r=0; r<1.0; r+=1/norm_2(delta) ) {
    int i = (int)(0.5 + start.x() + r*float(delta.x()) );
    int j = (int)(0.5 + start.y() + r*float(delta.y()) );
    image.impl()(i,j) = value;
  }
}

static void write_debug_image( std::string out_file_name,
                               std::string input_file_name,
                               InterestPointList const& ip ) {
  vw_out() << "Writing debug image: " << out_file_name << "\n";
  DiskImageView<PixelGray<uint8> > image( input_file_name );

  vw_out(InfoMessage,"interest_point") << "\t > Gathering statistics:\n";
  float min = 1e30, max = -1e30;
  for ( InterestPointList::const_iterator point = ip.begin();
        point != ip.end(); ++point ) {
    if ( point->interest > max )
      max = point->interest;
    if ( point->interest < min )
      min = point->interest;
  }
  float diff = max - min;

  vw_out(InfoMessage,"interest_point") << "\t > Drawing raster:\n";
  ImageView<PixelRGB<uint8> > oimage;
  oimage = pixel_cast<PixelRGB<uint8> >(image*0.5);
  for ( InterestPointList::const_iterator point = ip.begin();
        point != ip.end(); ++point ) {
    float norm_i = (point->interest - min)/diff;
    PixelRGB<uint8> color(0,0,0);
    if ( norm_i < .5 ) {
      // Form of red
      color.r() = 255;
      color.g() = (uint8)(2*norm_i*255);
    } else {
      // Form of green
      color.g() = 255;
      color.r() = 255 - (uint8)(2*(norm_i-.5)*255);
    }

    // Marking point w/ Dot
    oimage(point->ix,point->iy) = color;

    // Circling point
    for (float a = 0; a < 6; a+=.392 ) {
      float a_d = a + .392;
      Vector2i start( int(2*point->scale*cos(a)+point->x),
                      int(2*point->scale*sin(a)+point->y) );
      Vector2i end( int(2*point->scale*cos(a_d)+point->x),
                    int(2*point->scale*sin(a_d)+point->y) );
      draw_line( oimage, color, start, end );
    }
  }

  DiskImageResource *rsrc = DiskImageResource::create(out_file_name,
                                                      oimage.format() );
  vw_out(InfoMessage,"interest_point") << "\t > Writing out image:\n";
  block_write_image( *rsrc, oimage,
                     TerminalProgressCallback( "tools.ipfind","\t : ") );

}

int main(int argc, char** argv) {
  std::vector<std::string> input_file_names;
  std::string interest_operator, descriptor_generator;
  float ip_gain;
  uint32 max_points;
  int tile_size, num_threads;
  ImageView<double> integral;

  const float IDEAL_LOG_THRESHOLD = .03;
  const float IDEAL_OBALOG_THRESHOLD = .07;
  const float IDEAL_HARRIS_THRESHOLD = 1.2e-5;

  po::options_description general_options("Options");
  general_options.add_options()
    ("help,h", "Display this help message")
    ("num-threads", po::value(&num_threads)->default_value(0), "Set the number of threads for interest point detection.  Setting the num_threads to zero causes ipfind to use the visionworkbench default number of threads.")
    ("tile-size,t", po::value(&tile_size), "Specify the tile size for processing interest points. (Useful when working with large images). VW usually picks 1024 px.")
    ("lowe,l", "Save the interest points in an ASCII data format that is compatible with the Lowe-SIFT toolchain.")
    ("debug-image,d", "Write out debug images.")

    // Interest point detector options
    ("interest-operator", po::value(&interest_operator)->default_value("OBALoG"), "Choose an interest point metric from [LoG, Harris, OBALoG]")
    ("gain,g", po::value(&ip_gain)->default_value(1.0), "Increasing this number will increase the gain at which interest points are detected.")
    ("max-points", po::value(&max_points)->default_value(0), "Set the maximum number of interest points you want returned.  The most \"interesting\" points are selected.")
    ("single-scale", "Turn off scale-invariant interest point detection.  This option only searches for interest points in the first octave of the scale space.")

    // Descriptor generator options
    ("descriptor-generator", po::value(&descriptor_generator)->default_value("sgrad"), "Choose a descriptor generator from [patch,pca,sgrad,sgrad2]");

  po::options_description hidden_options("");
  hidden_options.add_options()
    ("input-files", po::value(&input_file_names));

  po::options_description options("Allowed Options");
  options.add(general_options).add(hidden_options);

  po::positional_options_description p;
  p.add("input-files", -1);

  std::ostringstream usage;
  usage << "Usage: " << argv[0] << " [options] <filenames>..." << std::endl << std::endl;
  usage << general_options << std::endl;

  po::variables_map vm;
  try {
    po::store( po::command_line_parser( argc, argv ).options(options).positional(p).run(), vm );
    po::notify( vm );
  } catch (const po::error& e) {
    std::cout << "An error occured while parsing command line arguments.\n";
    std::cout << "\t" << e.what() << "\n\n";
    std::cout << usage.str();
    return 1;
  }

  if( vm.count("help") ) {
    vw_out() << usage.str();
    return 1;
  }

  if( input_file_names.size() < 1 ) {
    vw_out() << "Error: Must specify at least one input file!" << std::endl << std::endl;
    vw_out() << usage.str();
    return 1;
  }

  if ( vm.count("num-threads"))
    vw_settings().set_default_num_threads(num_threads);
  if ( vm.count("tile-size"))
    vw_settings().set_default_tile_size(tile_size);

  // Checking strings
  boost::to_lower( interest_operator );
  boost::to_lower( descriptor_generator );
  // Determine if interest_operator is legitimate
  if ( !( interest_operator == "harris" ||
          interest_operator == "log" ||
          interest_operator == "obalog" ) ) {
    vw_out() << "Unknown interest operator: " << interest_operator
              << ". Options are : [ Harris, LoG, OBALoG ]\n";
    exit(0);
  }
  // Determine if descriptor_generator is legitimate
  if ( !( descriptor_generator == "patch" ||
          descriptor_generator == "pca"   ||
          descriptor_generator == "sgrad" ||
          descriptor_generator == "sgrad2" ) ) {
    vw_out() << "Unkown descriptor generator: " << descriptor_generator
              << ". Options are : [ Patch, PCA, SGrad, SGrad2 ]\n";
    exit(0);
  }

  // Iterate over the input files and find interest points in each.
  for (size_t i = 0; i < input_file_names.size(); ++i) {

    vw_out() << "Finding interest points in \"" << input_file_names[i] << "\".\n";
    std::string file_prefix = fs::path(input_file_names[i]).replace_extension().string();
    DiskImageResource *image_rsrc = DiskImageResource::open( input_file_names[i] );
    DiskImageView<PixelGray<float> > image(image_rsrc);

    // Potentially mask image on a no data value
    if ( image_rsrc->has_nodata_read() )
      vw_out(DebugMessage,"interest_point") << "Image has a nodata value: "
                                            << image_rsrc->nodata_read() << "\n";

    // The max points sent to IP Detector class is applied to each
    // tile of an image. In order to curb memory use we'll set the max
    // size for each tile smaller (proportional to the number of
    // tiles).
    int number_tiles = (image.cols()/vw_settings().default_tile_size()+1) *
      (image.rows()/vw_settings().default_tile_size()+1);
    uint32 tile_max_points = uint32(float(max_points)/float(number_tiles))*2; // A little over shoot
                                                                     // incase the tile is empty
    if ( max_points == 0 ) tile_max_points = 0; // No culling
    else if ( tile_max_points < 50 ) tile_max_points = 50;

    // Detecting Interest Points
    InterestPointList ip;
    if ( interest_operator == "harris" ) {
      // Harris threshold is inversely proportional to gain.
      HarrisInterestOperator interest_operator(IDEAL_HARRIS_THRESHOLD/ip_gain);
      if (!vm.count("single-scale")) {
        ScaledInterestPointDetector<HarrisInterestOperator> detector(interest_operator,
                                                                     tile_max_points);
        ip = detect_interest_points(image, detector);
      } else {
        InterestPointDetector<HarrisInterestOperator> detector(interest_operator,
                                                               tile_max_points);
        ip = detect_interest_points(image, detector);
      }
    } else if ( interest_operator == "log") {
      // Use a scale-space Laplacian of Gaussian feature detector. The
      // associated threshold is abs(interest) > interest_threshold.
      // LoG threshold is inversely proportional to gain..
      LogInterestOperator interest_operator(IDEAL_LOG_THRESHOLD/ip_gain);
      if (!vm.count("single-scale")) {
        ScaledInterestPointDetector<LogInterestOperator> detector(interest_operator,
                                                                  tile_max_points);
        ip = detect_interest_points(image, detector);
      } else {
        InterestPointDetector<LogInterestOperator> detector(interest_operator,
                                                            tile_max_points);
        ip = detect_interest_points(image, detector);
      }
    } else if ( interest_operator == "obalog") {
      // OBALoG threshold is inversely proportional to gain ..
      OBALoGInterestOperator interest_operator(IDEAL_OBALOG_THRESHOLD/ip_gain);
      IntegralInterestPointDetector<OBALoGInterestOperator> detector( interest_operator,
                                                                      tile_max_points );
      ip = detect_interest_points(image, detector);
    }

    // Removing Interest Points on nodata or within 1/px
    if ( image_rsrc->has_nodata_read() ) {
      float nodata_value = image_rsrc->nodata_read();
      ImageViewRef<PixelMask<PixelGray<float> > > image_mask = create_mask(image,nodata_value);
      BBox2i bound = bounding_box( image_mask );
      bound.contract(1);
      int before_size = ip.size();
      for ( InterestPointList::iterator point = ip.begin();
            point != ip.end(); ++point ) {

        // To Avoid out of index issues
        if ( !bound.contains( Vector2i(point->ix,
                                       point->iy ))) {
          point = ip.erase(point);
          point--;
          continue;
        }

        if ( !image_mask(point->ix,point->iy).valid() ||
             !image_mask(point->ix+1,point->iy+1).valid() ||
             !image_mask(point->ix+1,point->iy).valid() ||
             !image_mask(point->ix+1,point->iy-1).valid() ||
             !image_mask(point->ix,point->iy+1).valid() ||
             !image_mask(point->ix,point->iy-1).valid() ||
             !image_mask(point->ix-1,point->iy+1).valid() ||
             !image_mask(point->ix-1,point->iy).valid() ||
             !image_mask(point->ix-1,point->iy-1).valid() ) {
          point = ip.erase(point);
          point--;
          continue;
        }
      }
      vw_out(InfoMessage,"interest_point") << "Removed " << before_size-ip.size() << " points close to nodata.\n";
    }

    vw_out() << "\t Found " << ip.size() << " points.\n";

    // Additional Culling for the entire image
    ip.sort();
    if ( (max_points > 0) && (ip.size() > max_points) ) {
      ip.resize(max_points);
      vw_out() << "\t Culled to " << ip.size() << " points.\n";
    }

    // Generate descriptors for interest points.
    vw_out(InfoMessage) << "\tRunning " << descriptor_generator << " descriptor generator.\n";
    if (descriptor_generator == "patch") {
      PatchDescriptorGenerator descriptor;
      descriptor(image, ip);
    } else if (descriptor_generator == "pca") {
      PCASIFTDescriptorGenerator descriptor("pca_basis.exr", "pca_avg.exr");
      descriptor(image, ip);
    } else if (descriptor_generator == "sgrad") {
      SGradDescriptorGenerator descriptor;
      descriptor(image, ip);
    } else if (descriptor_generator == "sgrad2") {
      SGrad2DescriptorGenerator descriptor;
      descriptor(image, ip);
    }

    // If ASCII output was requested, write it out.  Otherwise stick
    // with binary output.
    if (vm.count("lowe"))
      write_lowe_ascii_ip_file(file_prefix + ".key", ip);
    else
      write_binary_ip_file(file_prefix + ".vwip", ip);

    // Write Debug image
    if (vm.count("debug-image")) {
      std::string output_file_name =
        file_prefix + "_debug.jpg";
      write_debug_image( output_file_name,
                         input_file_names[i],
                         ip );
    }
  }
}
<commit_msg>Prohibit ipfind from defaulting to zero threads<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2011 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

/// \file ipfind.cc
///
/// Finds the interest points in an image and outputs them an Binary
/// (default) or ASCII format.  The ASCII format is compatible with
/// the popular Lowe-SIFT toolchain.
///
#include <vw/Core.h>
#include <vw/InterestPoint.h>
#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/Math/BBox.h>

using namespace vw;
using namespace vw::ip;

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

#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;

template <class ImageT, class ValueT>
void draw_line( ImageViewBase<ImageT>& image,
                ValueT const& value,
                Vector2i const& start,
                Vector2i const& end ) {

  BBox2i bound = bounding_box(image.impl());
  if ( !bound.contains( start ) ||
       !bound.contains( end ) )
    return;
  Vector2i delta = end - start;
  for ( float r=0; r<1.0; r+=1/norm_2(delta) ) {
    int i = (int)(0.5 + start.x() + r*float(delta.x()) );
    int j = (int)(0.5 + start.y() + r*float(delta.y()) );
    image.impl()(i,j) = value;
  }
}

static void write_debug_image( std::string out_file_name,
                               std::string input_file_name,
                               InterestPointList const& ip ) {
  vw_out() << "Writing debug image: " << out_file_name << "\n";
  DiskImageView<PixelGray<uint8> > image( input_file_name );

  vw_out(InfoMessage,"interest_point") << "\t > Gathering statistics:\n";
  float min = 1e30, max = -1e30;
  for ( InterestPointList::const_iterator point = ip.begin();
        point != ip.end(); ++point ) {
    if ( point->interest > max )
      max = point->interest;
    if ( point->interest < min )
      min = point->interest;
  }
  float diff = max - min;

  vw_out(InfoMessage,"interest_point") << "\t > Drawing raster:\n";
  ImageView<PixelRGB<uint8> > oimage;
  oimage = pixel_cast<PixelRGB<uint8> >(image*0.5);
  for ( InterestPointList::const_iterator point = ip.begin();
        point != ip.end(); ++point ) {
    float norm_i = (point->interest - min)/diff;
    PixelRGB<uint8> color(0,0,0);
    if ( norm_i < .5 ) {
      // Form of red
      color.r() = 255;
      color.g() = (uint8)(2*norm_i*255);
    } else {
      // Form of green
      color.g() = 255;
      color.r() = 255 - (uint8)(2*(norm_i-.5)*255);
    }

    // Marking point w/ Dot
    oimage(point->ix,point->iy) = color;

    // Circling point
    for (float a = 0; a < 6; a+=.392 ) {
      float a_d = a + .392;
      Vector2i start( int(2*point->scale*cos(a)+point->x),
                      int(2*point->scale*sin(a)+point->y) );
      Vector2i end( int(2*point->scale*cos(a_d)+point->x),
                    int(2*point->scale*sin(a_d)+point->y) );
      draw_line( oimage, color, start, end );
    }
  }

  DiskImageResource *rsrc = DiskImageResource::create(out_file_name,
                                                      oimage.format() );
  vw_out(InfoMessage,"interest_point") << "\t > Writing out image:\n";
  block_write_image( *rsrc, oimage,
                     TerminalProgressCallback( "tools.ipfind","\t : ") );

}

int main(int argc, char** argv) {
  std::vector<std::string> input_file_names;
  std::string interest_operator, descriptor_generator;
  float ip_gain;
  uint32 max_points;
  int tile_size, num_threads;
  ImageView<double> integral;

  const float IDEAL_LOG_THRESHOLD = .03;
  const float IDEAL_OBALOG_THRESHOLD = .07;
  const float IDEAL_HARRIS_THRESHOLD = 1.2e-5;

  po::options_description general_options("Options");
  general_options.add_options()
    ("help,h", "Display this help message")
    ("num-threads", po::value(&num_threads)->default_value(0), "Set the number of threads for interest point detection.  Setting the num_threads to zero causes ipfind to use the visionworkbench default number of threads.")
    ("tile-size,t", po::value(&tile_size), "Specify the tile size for processing interest points. (Useful when working with large images).")
    ("lowe,l", "Save the interest points in an ASCII data format that is compatible with the Lowe-SIFT toolchain.")
    ("debug-image,d", "Write out debug images.")

    // Interest point detector options
    ("interest-operator", po::value(&interest_operator)->default_value("OBALoG"), "Choose an interest point metric from [LoG, Harris, OBALoG]")
    ("gain,g", po::value(&ip_gain)->default_value(1.0), "Increasing this number will increase the gain at which interest points are detected.")
    ("max-points", po::value(&max_points)->default_value(0), "Set the maximum number of interest points you want returned.  The most \"interesting\" points are selected.")
    ("single-scale", "Turn off scale-invariant interest point detection.  This option only searches for interest points in the first octave of the scale space.")

    // Descriptor generator options
    ("descriptor-generator", po::value(&descriptor_generator)->default_value("sgrad"), "Choose a descriptor generator from [patch,pca,sgrad,sgrad2]");

  po::options_description hidden_options("");
  hidden_options.add_options()
    ("input-files", po::value(&input_file_names));

  po::options_description options("Allowed Options");
  options.add(general_options).add(hidden_options);

  po::positional_options_description p;
  p.add("input-files", -1);

  std::ostringstream usage;
  usage << "Usage: " << argv[0] << " [options] <filenames>..." << std::endl << std::endl;
  usage << general_options << std::endl;

  po::variables_map vm;
  try {
    po::store( po::command_line_parser( argc, argv ).options(options).positional(p).run(), vm );
    po::notify( vm );
  } catch (const po::error& e) {
    std::cout << "An error occured while parsing command line arguments.\n";
    std::cout << "\t" << e.what() << "\n\n";
    std::cout << usage.str();
    return 1;
  }

  if( vm.count("help") ) {
    vw_out() << usage.str();
    return 1;
  }

  if( input_file_names.size() < 1 ) {
    vw_out() << "Error: Must specify at least one input file!" << std::endl << std::endl;
    vw_out() << usage.str();
    return 1;
  }

  if ( num_threads > 0 )
    vw_settings().set_default_num_threads(num_threads);
  if ( vm.count("tile-size"))
    vw_settings().set_default_tile_size(tile_size);

  // Checking strings
  boost::to_lower( interest_operator );
  boost::to_lower( descriptor_generator );
  // Determine if interest_operator is legitimate
  if ( !( interest_operator == "harris" ||
          interest_operator == "log" ||
          interest_operator == "obalog" ) ) {
    vw_out() << "Unknown interest operator: " << interest_operator
              << ". Options are : [ Harris, LoG, OBALoG ]\n";
    exit(0);
  }
  // Determine if descriptor_generator is legitimate
  if ( !( descriptor_generator == "patch" ||
          descriptor_generator == "pca"   ||
          descriptor_generator == "sgrad" ||
          descriptor_generator == "sgrad2" ) ) {
    vw_out() << "Unkown descriptor generator: " << descriptor_generator
              << ". Options are : [ Patch, PCA, SGrad, SGrad2 ]\n";
    exit(0);
  }

  // Iterate over the input files and find interest points in each.
  for (size_t i = 0; i < input_file_names.size(); ++i) {

    vw_out() << "Finding interest points in \"" << input_file_names[i] << "\".\n";
    std::string file_prefix = fs::path(input_file_names[i]).replace_extension().string();
    DiskImageResource *image_rsrc = DiskImageResource::open( input_file_names[i] );
    DiskImageView<PixelGray<float> > image(image_rsrc);

    // Potentially mask image on a no data value
    if ( image_rsrc->has_nodata_read() )
      vw_out(DebugMessage,"interest_point") << "Image has a nodata value: "
                                            << image_rsrc->nodata_read() << "\n";

    // The max points sent to IP Detector class is applied to each
    // tile of an image. In order to curb memory use we'll set the max
    // size for each tile smaller (proportional to the number of
    // tiles).
    int number_tiles = (image.cols()/vw_settings().default_tile_size()+1) *
      (image.rows()/vw_settings().default_tile_size()+1);
    uint32 tile_max_points = uint32(float(max_points)/float(number_tiles))*2; // A little over shoot
                                                                     // incase the tile is empty
    if ( max_points == 0 ) tile_max_points = 0; // No culling
    else if ( tile_max_points < 50 ) tile_max_points = 50;

    // Detecting Interest Points
    InterestPointList ip;
    if ( interest_operator == "harris" ) {
      // Harris threshold is inversely proportional to gain.
      HarrisInterestOperator interest_operator(IDEAL_HARRIS_THRESHOLD/ip_gain);
      if (!vm.count("single-scale")) {
        ScaledInterestPointDetector<HarrisInterestOperator> detector(interest_operator,
                                                                     tile_max_points);
        ip = detect_interest_points(image, detector);
      } else {
        InterestPointDetector<HarrisInterestOperator> detector(interest_operator,
                                                               tile_max_points);
        ip = detect_interest_points(image, detector);
      }
    } else if ( interest_operator == "log") {
      // Use a scale-space Laplacian of Gaussian feature detector. The
      // associated threshold is abs(interest) > interest_threshold.
      // LoG threshold is inversely proportional to gain..
      LogInterestOperator interest_operator(IDEAL_LOG_THRESHOLD/ip_gain);
      if (!vm.count("single-scale")) {
        ScaledInterestPointDetector<LogInterestOperator> detector(interest_operator,
                                                                  tile_max_points);
        ip = detect_interest_points(image, detector);
      } else {
        InterestPointDetector<LogInterestOperator> detector(interest_operator,
                                                            tile_max_points);
        ip = detect_interest_points(image, detector);
      }
    } else if ( interest_operator == "obalog") {
      // OBALoG threshold is inversely proportional to gain ..
      OBALoGInterestOperator interest_operator(IDEAL_OBALOG_THRESHOLD/ip_gain);
      IntegralInterestPointDetector<OBALoGInterestOperator> detector( interest_operator,
                                                                      tile_max_points );
      ip = detect_interest_points(image, detector);
    }

    // Removing Interest Points on nodata or within 1/px
    if ( image_rsrc->has_nodata_read() ) {
      float nodata_value = image_rsrc->nodata_read();
      ImageViewRef<PixelMask<PixelGray<float> > > image_mask = create_mask(image,nodata_value);
      BBox2i bound = bounding_box( image_mask );
      bound.contract(1);
      int before_size = ip.size();
      for ( InterestPointList::iterator point = ip.begin();
            point != ip.end(); ++point ) {

        // To Avoid out of index issues
        if ( !bound.contains( Vector2i(point->ix,
                                       point->iy ))) {
          point = ip.erase(point);
          point--;
          continue;
        }

        if ( !image_mask(point->ix,point->iy).valid() ||
             !image_mask(point->ix+1,point->iy+1).valid() ||
             !image_mask(point->ix+1,point->iy).valid() ||
             !image_mask(point->ix+1,point->iy-1).valid() ||
             !image_mask(point->ix,point->iy+1).valid() ||
             !image_mask(point->ix,point->iy-1).valid() ||
             !image_mask(point->ix-1,point->iy+1).valid() ||
             !image_mask(point->ix-1,point->iy).valid() ||
             !image_mask(point->ix-1,point->iy-1).valid() ) {
          point = ip.erase(point);
          point--;
          continue;
        }
      }
      vw_out(InfoMessage,"interest_point") << "Removed " << before_size-ip.size() << " points close to nodata.\n";
    }

    vw_out() << "\t Found " << ip.size() << " points.\n";

    // Additional Culling for the entire image
    ip.sort();
    if ( (max_points > 0) && (ip.size() > max_points) ) {
      ip.resize(max_points);
      vw_out() << "\t Culled to " << ip.size() << " points.\n";
    }

    // Generate descriptors for interest points.
    vw_out(InfoMessage) << "\tRunning " << descriptor_generator << " descriptor generator.\n";
    if (descriptor_generator == "patch") {
      PatchDescriptorGenerator descriptor;
      descriptor(image, ip);
    } else if (descriptor_generator == "pca") {
      PCASIFTDescriptorGenerator descriptor("pca_basis.exr", "pca_avg.exr");
      descriptor(image, ip);
    } else if (descriptor_generator == "sgrad") {
      SGradDescriptorGenerator descriptor;
      descriptor(image, ip);
    } else if (descriptor_generator == "sgrad2") {
      SGrad2DescriptorGenerator descriptor;
      descriptor(image, ip);
    }

    // If ASCII output was requested, write it out.  Otherwise stick
    // with binary output.
    if (vm.count("lowe"))
      write_lowe_ascii_ip_file(file_prefix + ".key", ip);
    else
      write_binary_ip_file(file_prefix + ".vwip", ip);

    // Write Debug image
    if (vm.count("debug-image")) {
      std::string output_file_name =
        file_prefix + "_debug.jpg";
      write_debug_image( output_file_name,
                         input_file_names[i],
                         ip );
    }
  }
}
<|endoftext|>