<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sourcelistener.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:32:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "sourcelistener.hxx"

DragSourceListener::DragSourceListener()
{
}
DragSourceListener::~DragSourceListener()
{
}

void SAL_CALL DragSourceListener::disposing( const EventObject& Source )
        throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragDropEnd( const DragSourceDropEvent& dsde )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragEnter( const DragSourceDragEvent& dsde )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragExit( const DragSourceEvent& dse )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragOver( const DragSourceDragEvent& dsde )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dropActionChanged( const DragSourceDragEvent& dsde )
    throw(RuntimeException)
{
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.2.40); FILE MERGED 2006/09/01 17:25:41 kaib 1.2.40.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sourcelistener.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 17:04:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dtrans.hxx"

#include "sourcelistener.hxx"

DragSourceListener::DragSourceListener()
{
}
DragSourceListener::~DragSourceListener()
{
}

void SAL_CALL DragSourceListener::disposing( const EventObject& Source )
        throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragDropEnd( const DragSourceDropEvent& dsde )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragEnter( const DragSourceDragEvent& dsde )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragExit( const DragSourceEvent& dse )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dragOver( const DragSourceDragEvent& dsde )
    throw(RuntimeException)
{
}

void SAL_CALL DragSourceListener::dropActionChanged( const DragSourceDragEvent& dsde )
    throw(RuntimeException)
{
}

<|endoftext|>


<commit_before>#include "StableHeaders.h"

#include "OgreUIView.h"
#include "Profiler.h"

#ifndef Q_WS_WIN
#include <QX11Info>
#endif

#include <QCoreApplication>
#include <QApplication>
#include <QDebug>
#include <QMouseEvent>
#include <QPicture>
#include <QGraphicsSceneEvent.h>

#include <OgreHardwarePixelBuffer.h>
#include <OgreTexture.h>
#include <OgreMaterial.h>
#include <OgreTextAreaOverlayElement.h>
#include <OgreFontManager.h>
#include <OgrePanelOverlayElement.h>
#include <OgreTextureUnitState.h>

namespace QtUI
{

OgreUIView::OgreUIView()
:overlay_(0),
container_(0),
mouseDown(false)
{
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}

OgreUIView::~OgreUIView()
{
}

void OgreUIView::SetViewCanvasSize(int width, int height)
{
    this->move(0, 0);
    this->resize(width, height);

    CreateOgreResources(width, height);
}

void OgreUIView::ResizeOgreTexture(int width, int height)
{
    texture_->freeInternalResources();
    texture_->setWidth(width);
    texture_->setHeight(height);
    texture_->createInternalResources();
}

void OgreUIView::CreateOgreResources(int width, int height)
{
    // If we've already created the resources, just resize the texture to a new size.
    if (texture_.get())
    {
        if (width == texture_->getWidth() && height == texture_->getHeight())
            return;
        ResizeOgreTexture(width, height);
        assert(overlay_);
        assert(container_);
        assert(material_.get());
        return;
    }

    overlay_ = Ogre::OverlayManager::getSingleton().create("OgreUIViewOverlay");

    container_ = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton()
                                     .createOverlayElement("Panel", "OgreUIViewContainer"));

    // Make the overlay cover 100% of the render window. Note that the UI surface will be
    // rendered pixel perfect without stretching only if the GraphicsView surface dimension
    // matches the render window size.
    container_->setPosition(0,0);
    container_->setDimensions(1.0,1.0);

    // Add container in default overlay
    overlay_->add2D(container_);

    ///\todo Tell Ogre not to generate a mipmap chain. This texture only needs to have only one
    /// mip level.
    const char surfaceName[] = "OgreUIViewSurface";
    texture_ = Ogre::TextureManager::getSingleton().createManual(surfaceName,
						        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
						        Ogre::TEX_TYPE_2D, width, height, 0,
						        Ogre::PF_A8R8G8B8, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    const char surfaceMaterial[] = "OgreUIViewMaterial";
    material_ = Ogre::MaterialManager::getSingleton().create(surfaceMaterial,
						        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    Ogre::TextureUnitState *state = material_->getTechnique(0)->getPass(0)->createTextureUnitState();
    material_->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
    state->setTextureName(surfaceName);

    container_->setMaterialName(surfaceMaterial);
    container_->show();
    container_->setEnabled(true);
    container_->setColour(Ogre::ColourValue(1,1,1,1));

    overlay_->show();
}

void OgreUIView::SetParentWindowSize(int windowWidth, int windowHeight)
{
    // Compute the appropriate Ogre overlay scale so that the resulting composition will be pixel perfect.
    float relWidth = (float)texture_->getWidth()/windowWidth;
    float relHeight = (float)texture_->getHeight()/windowHeight;

    ///\todo Offer a method for the user to place the canvas as well as resizing it.
    /// For now we do a fixed positioning on the bottom right.
    container_->setPosition(1.f - relWidth, 1.f - relHeight);
    container_->setDimensions(relWidth, relHeight);
}

void OgreUIView::drawBackground(QPainter *painter, const QRectF &rect)
{
    QBrush black(Qt::transparent);
    painter->fillRect(rect, black);
}

void OgreUIView::RenderSceneToOgreSurface()
{
    PROFILE(RenderSceneToOgre);
    // We draw the GraphicsView area to an offscreen QPixmap and blit that onto the Ogre GPU surface.
    QPixmap pixmap(this->size());
    {
        PROFILE(FillEmpty);
        pixmap.fill(Qt::transparent);
    }
    assert(pixmap.hasAlphaChannel());
    QImage img = pixmap.toImage();
//  assert(texture_->getWidth() == img.rect().width());
//  assert(texture_->getHeight() == img.rect().height());
    QPainter painter(&img);
    QRectF destRect(0, 0, pixmap.width(), pixmap.height());
    QRect sourceRect(0, 0, pixmap.width(), pixmap.height());
    {
        PROFILE(RenderUI);
        this->render(&painter, destRect, sourceRect);
    }
    assert(img.hasAlphaChannel());

    ///\todo Can optimize an extra blit away if we paint directly onto the GPU surface.
    Ogre::Box dimensions(0,0, img.rect().width(), img.rect().height());
    Ogre::PixelBox pixel_box(dimensions, Ogre::PF_A8R8G8B8, (void*)img.bits());
    {
        PROFILE(UIToOgreBlit);
        texture_->getBuffer()->blitFromMemory(pixel_box);
    }
}

void OgreUIView::InjectMouseMove(int x, int y)
{
    // Translate the mouse position from QGraphicsView coordinate frame onto
    // the QGraphicsScene coordinate frame.
    QPointF pos = this->mapToScene(x, y);
    QPoint mousePos((int)pos.x(), (int)pos.y());

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
    if (mouseDown)
    {
        mouseEvent.setButtonDownScenePos(Qt::LeftButton, QPoint(mousePressX, mousePressY));
        mouseEvent.setButtonDownScreenPos(Qt::LeftButton, QPoint(mousePressX, mousePressY));
    }
    else
    {
        mouseEvent.setButtonDownScenePos(Qt::NoButton, mousePos);
        mouseEvent.setButtonDownScreenPos(Qt::NoButton, mousePos);
    }
    mouseEvent.setScenePos(mousePos);
    mouseEvent.setScreenPos(mousePos);
    mouseEvent.setLastScenePos(mousePos);
    mouseEvent.setLastScreenPos(mousePos);
    mouseEvent.setButtons(mouseDown ? Qt::LeftButton : Qt::NoButton);
    mouseEvent.setButton(mouseDown ? Qt::LeftButton : Qt::NoButton);
    mouseEvent.setModifiers(0);
    mouseEvent.setAccepted(false);
    QApplication::sendEvent(this->scene(), &mouseEvent);
}

void OgreUIView::InjectMousePress(int x, int y)
{
    // Translate the mouse position from QGraphicsView coordinate frame onto
    // the QGraphicsScene coordinate frame.
    QPointF pos = this->mapToScene(x, y);
    QPoint mousePos((int)pos.x(), (int)pos.y());

    mouseDown = true;
    mousePressX = mousePos.x();
    mousePressY = mousePos.y();

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
    mouseEvent.setButtonDownScenePos(Qt::LeftButton, mousePos);
    mouseEvent.setButtonDownScreenPos(Qt::LeftButton, mousePos);
    mouseEvent.setScenePos(mousePos);
    mouseEvent.setScreenPos(mousePos);
    mouseEvent.setLastScenePos(mousePos);
    mouseEvent.setLastScreenPos(mousePos);
    mouseEvent.setButtons(Qt::LeftButton);
    mouseEvent.setButton(Qt::LeftButton);
    mouseEvent.setModifiers(0);
    mouseEvent.setAccepted(false);
    QApplication::sendEvent(this->scene(), &mouseEvent);
}

void OgreUIView::InjectMouseRelease(int x, int y)
{
    // Translate the mouse position from QGraphicsView coordinate frame onto
    // the QGraphicsScene coordinate frame.
    QPointF pos = this->mapToScene(x, y);
    QPoint mousePos((int)pos.x(), (int)pos.y());

    mouseDown = false;

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
    mouseEvent.setButtonDownScenePos(Qt::NoButton, mousePos);
    mouseEvent.setButtonDownScreenPos(Qt::NoButton, mousePos);
    mouseEvent.setScenePos(mousePos);
    mouseEvent.setScreenPos(mousePos);
    mouseEvent.setLastScenePos(mousePos);
    mouseEvent.setLastScreenPos(mousePos);
    mouseEvent.setButtons(Qt::NoButton);
    mouseEvent.setButton(Qt::LeftButton);
    mouseEvent.setModifiers(0);
    mouseEvent.setAccepted(false);
    QApplication::sendEvent(this->scene(), &mouseEvent);
}

}
<commit_msg>[Fix] Fixed a GCC compile problem. <commit_after>#include "StableHeaders.h"

#include "OgreUIView.h"
#include "Profiler.h"

#ifndef Q_WS_WIN
#include <QX11Info>
#endif

#include <QCoreApplication>
#include <QApplication>
#include <QDebug>
#include <QMouseEvent>
#include <QPicture>
#include <QGraphicsSceneEvent>

#include <OgreHardwarePixelBuffer.h>
#include <OgreTexture.h>
#include <OgreMaterial.h>
#include <OgreTextAreaOverlayElement.h>
#include <OgreFontManager.h>
#include <OgrePanelOverlayElement.h>
#include <OgreTextureUnitState.h>

namespace QtUI
{

OgreUIView::OgreUIView()
:overlay_(0),
container_(0),
mouseDown(false)
{
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}

OgreUIView::~OgreUIView()
{
}

void OgreUIView::SetViewCanvasSize(int width, int height)
{
    this->move(0, 0);
    this->resize(width, height);

    CreateOgreResources(width, height);
}

void OgreUIView::ResizeOgreTexture(int width, int height)
{
    texture_->freeInternalResources();
    texture_->setWidth(width);
    texture_->setHeight(height);
    texture_->createInternalResources();
}

void OgreUIView::CreateOgreResources(int width, int height)
{
    // If we've already created the resources, just resize the texture to a new size.
    if (texture_.get())
    {
        if (width == texture_->getWidth() && height == texture_->getHeight())
            return;
        ResizeOgreTexture(width, height);
        assert(overlay_);
        assert(container_);
        assert(material_.get());
        return;
    }

    overlay_ = Ogre::OverlayManager::getSingleton().create("OgreUIViewOverlay");

    container_ = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton()
                                     .createOverlayElement("Panel", "OgreUIViewContainer"));

    // Make the overlay cover 100% of the render window. Note that the UI surface will be
    // rendered pixel perfect without stretching only if the GraphicsView surface dimension
    // matches the render window size.
    container_->setPosition(0,0);
    container_->setDimensions(1.0,1.0);

    // Add container in default overlay
    overlay_->add2D(container_);

    ///\todo Tell Ogre not to generate a mipmap chain. This texture only needs to have only one
    /// mip level.
    const char surfaceName[] = "OgreUIViewSurface";
    texture_ = Ogre::TextureManager::getSingleton().createManual(surfaceName,
						        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
						        Ogre::TEX_TYPE_2D, width, height, 0,
						        Ogre::PF_A8R8G8B8, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    const char surfaceMaterial[] = "OgreUIViewMaterial";
    material_ = Ogre::MaterialManager::getSingleton().create(surfaceMaterial,
						        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    Ogre::TextureUnitState *state = material_->getTechnique(0)->getPass(0)->createTextureUnitState();
    material_->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
    state->setTextureName(surfaceName);

    container_->setMaterialName(surfaceMaterial);
    container_->show();
    container_->setEnabled(true);
    container_->setColour(Ogre::ColourValue(1,1,1,1));

    overlay_->show();
}

void OgreUIView::SetParentWindowSize(int windowWidth, int windowHeight)
{
    // Compute the appropriate Ogre overlay scale so that the resulting composition will be pixel perfect.
    float relWidth = (float)texture_->getWidth()/windowWidth;
    float relHeight = (float)texture_->getHeight()/windowHeight;

    ///\todo Offer a method for the user to place the canvas as well as resizing it.
    /// For now we do a fixed positioning on the bottom right.
    container_->setPosition(1.f - relWidth, 1.f - relHeight);
    container_->setDimensions(relWidth, relHeight);
}

void OgreUIView::drawBackground(QPainter *painter, const QRectF &rect)
{
    QBrush black(Qt::transparent);
    painter->fillRect(rect, black);
}

void OgreUIView::RenderSceneToOgreSurface()
{
    PROFILE(RenderSceneToOgre);
    // We draw the GraphicsView area to an offscreen QPixmap and blit that onto the Ogre GPU surface.
    QPixmap pixmap(this->size());
    {
        PROFILE(FillEmpty);
        pixmap.fill(Qt::transparent);
    }
    assert(pixmap.hasAlphaChannel());
    QImage img = pixmap.toImage();
//  assert(texture_->getWidth() == img.rect().width());
//  assert(texture_->getHeight() == img.rect().height());
    QPainter painter(&img);
    QRectF destRect(0, 0, pixmap.width(), pixmap.height());
    QRect sourceRect(0, 0, pixmap.width(), pixmap.height());
    {
        PROFILE(RenderUI);
        this->render(&painter, destRect, sourceRect);
    }
    assert(img.hasAlphaChannel());

    ///\todo Can optimize an extra blit away if we paint directly onto the GPU surface.
    Ogre::Box dimensions(0,0, img.rect().width(), img.rect().height());
    Ogre::PixelBox pixel_box(dimensions, Ogre::PF_A8R8G8B8, (void*)img.bits());
    {
        PROFILE(UIToOgreBlit);
        texture_->getBuffer()->blitFromMemory(pixel_box);
    }
}

void OgreUIView::InjectMouseMove(int x, int y)
{
    // Translate the mouse position from QGraphicsView coordinate frame onto
    // the QGraphicsScene coordinate frame.
    QPointF pos = this->mapToScene(x, y);
    QPoint mousePos((int)pos.x(), (int)pos.y());

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
    if (mouseDown)
    {
        mouseEvent.setButtonDownScenePos(Qt::LeftButton, QPoint(mousePressX, mousePressY));
        mouseEvent.setButtonDownScreenPos(Qt::LeftButton, QPoint(mousePressX, mousePressY));
    }
    else
    {
        mouseEvent.setButtonDownScenePos(Qt::NoButton, mousePos);
        mouseEvent.setButtonDownScreenPos(Qt::NoButton, mousePos);
    }
    mouseEvent.setScenePos(mousePos);
    mouseEvent.setScreenPos(mousePos);
    mouseEvent.setLastScenePos(mousePos);
    mouseEvent.setLastScreenPos(mousePos);
    mouseEvent.setButtons(mouseDown ? Qt::LeftButton : Qt::NoButton);
    mouseEvent.setButton(mouseDown ? Qt::LeftButton : Qt::NoButton);
    mouseEvent.setModifiers(0);
    mouseEvent.setAccepted(false);
    QApplication::sendEvent(this->scene(), &mouseEvent);
}

void OgreUIView::InjectMousePress(int x, int y)
{
    // Translate the mouse position from QGraphicsView coordinate frame onto
    // the QGraphicsScene coordinate frame.
    QPointF pos = this->mapToScene(x, y);
    QPoint mousePos((int)pos.x(), (int)pos.y());

    mouseDown = true;
    mousePressX = mousePos.x();
    mousePressY = mousePos.y();

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
    mouseEvent.setButtonDownScenePos(Qt::LeftButton, mousePos);
    mouseEvent.setButtonDownScreenPos(Qt::LeftButton, mousePos);
    mouseEvent.setScenePos(mousePos);
    mouseEvent.setScreenPos(mousePos);
    mouseEvent.setLastScenePos(mousePos);
    mouseEvent.setLastScreenPos(mousePos);
    mouseEvent.setButtons(Qt::LeftButton);
    mouseEvent.setButton(Qt::LeftButton);
    mouseEvent.setModifiers(0);
    mouseEvent.setAccepted(false);
    QApplication::sendEvent(this->scene(), &mouseEvent);
}

void OgreUIView::InjectMouseRelease(int x, int y)
{
    // Translate the mouse position from QGraphicsView coordinate frame onto
    // the QGraphicsScene coordinate frame.
    QPointF pos = this->mapToScene(x, y);
    QPoint mousePos((int)pos.x(), (int)pos.y());

    mouseDown = false;

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
    mouseEvent.setButtonDownScenePos(Qt::NoButton, mousePos);
    mouseEvent.setButtonDownScreenPos(Qt::NoButton, mousePos);
    mouseEvent.setScenePos(mousePos);
    mouseEvent.setScreenPos(mousePos);
    mouseEvent.setLastScenePos(mousePos);
    mouseEvent.setLastScreenPos(mousePos);
    mouseEvent.setButtons(Qt::NoButton);
    mouseEvent.setButton(Qt::LeftButton);
    mouseEvent.setModifiers(0);
    mouseEvent.setAccepted(false);
    QApplication::sendEvent(this->scene(), &mouseEvent);
}

}
<|endoftext|>


<commit_before>#ifndef _FALCON_LAMBDA_LOOPS_HPP
#define _FALCON_LAMBDA_LOOPS_HPP

#include <utility>
#include <falcon/lambda/lambda.hpp>

namespace falcon {
namespace lambda {

template<typename _Init, typename _Functor, typename _End, typename _State>
struct forloop
{
	_Init init;
	_Functor condition;
	_End  endf;
	_State f;

	template<typename... _Args>
	inline void operator()(_Args&&... args)
	{
		for (auto v = init(std::forward<_Args>(args)...); condition(v, std::forward<_Args>(args)...); endf(v, std::forward<_Args>(args)...))
			f(v, std::forward<_Args>(args)...);
	}
};

template<typename _Functor, typename _State>
struct whileloop
{
	_Functor condition;
	_State f;

	template<typename... _Args>
	inline void operator()(_Args&&... args)
	{
		while (condition(std::forward<_Args>(args)...))
			f(std::forward<_Args>(args)...);
	}
};

template<typename _Functor, typename _State>
struct do_whileloop
{
	_Functor condition;
	_State f;

	template<typename... _Args>
	inline void operator()(_Args&&... args)
	{
		do {
			f(std::forward<_Args>(args)...);
		} while (condition(std::forward<_Args>(args)...));
	}
};

template<typename _Init, typename _Functor, typename _End, typename _State>
inline ___lambda<operators::binder, forloop<_Init, _Functor, _End, _State> > for_loop(_Init init, _Functor condition, _End endf, _State f)
{
	return {{init, condition, endf, f}};
}

template<typename _Functor, typename _State>
inline ___lambda<operators::binder, whileloop<_Functor, _State> > while_loop(_Functor condition, _State f)
{
	return {{condition, f}};
}

template<typename _Functor, typename _State>
inline ___lambda<operators::binder, do_whileloop<_Functor, _State> > do_while_loop(_Functor condition, _State f)
{
	return {{condition, f}};
}

}
}

#endif
<commit_msg>fix bug in for_loop, while_loop and do_while_lop<commit_after>#ifndef _FALCON_LAMBDA_LOOPS_HPP
#define _FALCON_LAMBDA_LOOPS_HPP

#include <utility>
#include <falcon/lambda/lambda.hpp>

namespace falcon {
namespace lambda {

template<typename _Init, typename _Functor, typename _End, typename _State>
struct forloop
{
	_Init init;
	_Functor condition;
	_End  endf;
	_State f;

	template<typename... _Args>
	inline void operator()(_Args&&... args)
	{
		for (auto v = init(std::forward<_Args>(args)...); condition(v, std::forward<_Args>(args)...); endf(v, std::forward<_Args>(args)...))
			f(v, std::forward<_Args>(args)...);
	}
};

template<typename _Functor, typename _State>
struct whileloop
{
	_Functor condition;
	_State f;

	template<typename... _Args>
	inline void operator()(_Args&&... args)
	{
		while (condition(std::forward<_Args>(args)...))
			f(std::forward<_Args>(args)...);
	}
};

template<typename _Functor, typename _State>
struct do_whileloop
{
	_Functor condition;
	_State f;

	template<typename... _Args>
	inline void operator()(_Args&&... args)
	{
		do {
			f(std::forward<_Args>(args)...);
		} while (condition(std::forward<_Args>(args)...));
	}
};

template<typename _Init, typename _Functor, typename _End, typename _State>
inline ___lambda<operators::binder, forloop<_Init, _Functor, _End, _State>, void> for_loop(_Init init, _Functor condition, _End endf, _State f)
{
	return {{init, condition, endf, f}};
}

template<typename _Functor, typename _State>
inline ___lambda<operators::binder, whileloop<_Functor, _State>, void> while_loop(_Functor condition, _State f)
{
	return {{condition, f}};
}

template<typename _Functor, typename _State>
inline ___lambda<operators::binder, do_whileloop<_Functor, _State>, void> do_while_loop(_Functor condition, _State f)
{
	return {{condition, f}};
}

}
}

#endif
<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@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.

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

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

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "resourceview.h"

#include <klistview.h>
#include <klocale.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kmessagebox.h>
#include <kresources/resource.h>
#include <kresources/configdialog.h>
#include <kinputdialog.h>
#include <libkcal/calendarresources.h>

#include <qhbox.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpushbutton.h>

using namespace KCal;

ResourceViewFactory::ResourceViewFactory( KCal::CalendarResources *calendar,
                                          CalendarView *view )
{
  mCalendar = calendar;
  mView = view;
}

CalendarViewExtension *ResourceViewFactory::create( QWidget *parent )
{
  ResourceView *view = new ResourceView( mCalendar->resourceManager(), parent );

  QObject::connect( view, SIGNAL( resourcesChanged() ),
                    mView, SLOT( updateView() ) );
  QObject::connect( view, SIGNAL( signalErrorMessage( const QString & ) ),
                    mView, SLOT( showErrorMessage( const QString & ) ) );

  QObject::connect( mCalendar,
                    SIGNAL( signalResourceAdded( ResourceCalendar * ) ),
                    view, SLOT( addResourceItem( ResourceCalendar * ) ) );
  QObject::connect( mCalendar,
                    SIGNAL( signalResourceModified( ResourceCalendar * ) ),
                    view, SLOT( updateResourceItem( ResourceCalendar * ) ) );

  return view;
}

ResourceItem::ResourceItem( ResourceCalendar *resource, ResourceView *view,
                            KListView *parent )
  : QCheckListItem( parent, resource->resourceName(), CheckBox ),
    mResource( resource ), mView( view ), mBlockStateChange( false ),
    mIsSubresource( false )
{
  setGuiState();

  const QStringList subresources = mResource->subresources();
  if ( !subresources.isEmpty() ) {
    setOpen( true );
    setExpandable( true );
    // This resource has subresources
    QStringList::ConstIterator it;
    for ( it=subresources.begin(); it!=subresources.end(); ++it ) {
      ( void )new ResourceItem( mResource, *it, mView, this );
    }
  }
}

ResourceItem::ResourceItem( KCal::ResourceCalendar *resource,
                            const QString& sub, ResourceView *view,
                            ResourceItem* parent )
  : QCheckListItem( parent, sub, CheckBox ), mResource( resource ),
    mView( view ), mBlockStateChange( false ), mIsSubresource( true )
{
  setGuiState();
}

void ResourceItem::setGuiState()
{
  mBlockStateChange = true;
  if ( mIsSubresource )
    setOn( mResource->subresourceActive( text( 0 ) ) );
  else
    setOn( mResource->isActive() );
  mBlockStateChange = false;
}

void ResourceItem::stateChange( bool active )
{
  if ( mBlockStateChange ) return;

  if ( !mIsSubresource ) {
    // Handle a full resource
    bool toActivate = active;
    if ( active ) {
      bool success = mResource->open();
      if ( success ) {
        success = mResource->load();
      }
      if ( !success ) {
        QString msg = mResource->errorMessage();
        if ( !msg.isEmpty() ) mView->emitErrorMessage( msg );
        toActivate = false;
      }
    } else {
      mResource->save();
      mResource->close();
    }
    mResource->setActive( toActivate );

    setOpen( toActivate && childCount() > 0 );

    setGuiState();
  } else
    // Handle a subresource
    mResource->setSubresourceActive( text( 0 ), active );

  mView->emitResourcesChanged();
}

void ResourceItem::update()
{
  setGuiState();
}

ResourceView::ResourceView( KCal::CalendarResourceManager *manager,
                            QWidget *parent, const char *name )
  : CalendarViewExtension( parent, name ),
    mManager( manager )
{
  QBoxLayout *topLayout = new QVBoxLayout( this );

  mListView = new KListView( this );
  mListView->addColumn( i18n("Calendar") );
  mListView->setResizeMode( QListView::LastColumn );
  topLayout->addWidget( mListView );

  QHBox *buttonBox = new QHBox( this );
  topLayout->addWidget( buttonBox );

  mAddButton = new QPushButton( i18n("Add..."), buttonBox, "add" );
  mDeleteButton = new QPushButton( i18n("Remove"), buttonBox, "del" );
  mEditButton = new QPushButton( i18n("Edit..."), buttonBox, "edit" );
  mDeleteButton->setDisabled( true );
  mEditButton->setDisabled( true );

  connect( mListView, SIGNAL( clicked( QListViewItem * ) ),
           SLOT( currentChanged( QListViewItem * ) ) );
  connect( mAddButton, SIGNAL( clicked() ), SLOT( addResource() ) );
  connect( mDeleteButton, SIGNAL( clicked() ), SLOT( removeResource() ) );
  connect( mEditButton, SIGNAL( clicked() ), SLOT( editResource() ) );
  connect( mListView, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), SLOT( editResource() ) );

  updateView();
}

ResourceView::~ResourceView()
{
}

void ResourceView::updateView()
{
  mListView->clear();

  KCal::CalendarResourceManager::Iterator it;
  for( it = mManager->begin(); it != mManager->end(); ++it ) {
    addResourceItem( *it );
  }
}

void ResourceView::emitResourcesChanged()
{
  emit resourcesChanged();
}

void ResourceView::addResource()
{
  QStringList types = mManager->resourceTypeNames();
  QStringList descs = mManager->resourceTypeDescriptions();
  bool ok = false;
  QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
      i18n( "Please select type of the new resource:" ), descs, 0, false, &ok,
            this );
  if ( !ok )
    return;

  QString type = types[ descs.findIndex( desc ) ];

  // Create new resource
  ResourceCalendar *resource = mManager->createResource( type );
  if( !resource ) {
    KMessageBox::error( this, i18n("<qt>Unable to create resource of type %1.</qt>")
                              .arg( type ) );
    return;
  }

  resource->setResourceName( i18n("%1 resource").arg( type ) );

  KRES::ConfigDialog dlg( this, QString("calendar"), resource,
                          "KRES::ConfigDialog" );

  if ( dlg.exec() ) {
    if ( resource->isActive() ) {
      resource->open();
      resource->load();
    }

    mManager->add( resource );
    addResourceItem( resource );
  } else {
    delete resource;
    resource = 0;
  }
}

void ResourceView::addResourceItem( ResourceCalendar *resource )
{
  new ResourceItem( resource, this, mListView );
  connect( resource, SIGNAL( signalSubresourceAdded( ResourceCalendar *,
                                                     const QString &,
                                                     const QString & ) ),
           this, SLOT( slotSubresourceAdded( ResourceCalendar *,
                                             const QString &,
                                             const QString & ) ) );
  connect( resource, SIGNAL( signalSubresourceRemoved( ResourceCalendar *,
                                                       const QString &,
                                                       const QString & ) ),
           this, SLOT( slotSubresourceRemoved( ResourceCalendar *,
                                               const QString &,
                                               const QString & ) ) );
  emitResourcesChanged();
}

// Add a new entry
void ResourceView::slotSubresourceAdded( ResourceCalendar *calendar,
                                         const QString &/*type*/,
                                         const QString &resource )
{
  QListViewItem* i = mListView->findItem( calendar->resourceName(), 0 );
  if ( !i )
    // Not found
    return;

  ResourceItem* item = static_cast<ResourceItem*>( i );
  ( void )new ResourceItem( calendar, resource, this, item );
}

// Remove an entry
void ResourceView::slotSubresourceRemoved( ResourceCalendar */*calendar*/,
                                           const QString &/*type*/,
                                           const QString &resource )
{
  delete mListView->findItem( resource, 0 );
}

void ResourceView::updateResourceItem( ResourceCalendar *resource )
{
  ResourceItem *item = findItem( resource );
  if ( item ) {
    item->update();
  }
}

void ResourceView::removeResource()
{
  QListViewItem *item = mListView->currentItem();
  ResourceItem *rItem = static_cast<ResourceItem *>( item );

  if ( !rItem )
    return;

  int km = KMessageBox::warningContinueCancel( this,
        i18n("<qt>Do you really want to delete the resource %1?</qt>")
        .arg( rItem->resource()->resourceName() ),"",KGuiItem(i18n("&Delete"),"editdelete") );
  if ( km == KMessageBox::Cancel ) return;

// Don't be so restricitve
#if 0
  if ( rItem->resource() == mManager->standardResource() ) {
    KMessageBox::sorry( this,
                        i18n( "You cannot remove your standard resource." ) );
    return;
  }
#endif

  mManager->remove( rItem->resource() );

  mListView->takeItem( item );
  delete item;
  emitResourcesChanged();
}

void ResourceView::editResource()
{
  QListViewItem *item = mListView->currentItem();
  ResourceItem *rItem = static_cast<ResourceItem *>( item );
  if ( !rItem )
    return;

  ResourceCalendar *resource = rItem->resource();

  KRES::ConfigDialog dlg( this, QString("calendar"), resource,
                          "KRES::ConfigDialog" );

  if ( dlg.exec() ) {
    rItem->setText( 0, resource->resourceName() );

    mManager->change( resource );
  }
}

void ResourceView::currentChanged( QListViewItem *item)
{
  bool selected = true;
  if ( !item ) selected = false;
  mDeleteButton->setEnabled( selected );
  mEditButton->setEnabled( selected );
}

void ResourceView::emitErrorMessage( const QString &msg )
{
  emit signalErrorMessage( msg );
}

ResourceItem *ResourceView::findItem( ResourceCalendar *r )
{
  QListViewItem *item;
  ResourceItem *i = 0;
  for( item = mListView->firstChild(); item; item = item->nextSibling() ) {
    i = static_cast<ResourceItem *>( item );
    if ( i->resource() == r ) break;
  }
  return i;
}

#include "resourceview.moc"
<commit_msg>Use consistent naming.<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@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.

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

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

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "resourceview.h"

#include <klistview.h>
#include <klocale.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kmessagebox.h>
#include <kresources/resource.h>
#include <kresources/configdialog.h>
#include <kinputdialog.h>
#include <libkcal/calendarresources.h>

#include <qhbox.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpushbutton.h>

using namespace KCal;

ResourceViewFactory::ResourceViewFactory( KCal::CalendarResources *calendar,
                                          CalendarView *view )
{
  mCalendar = calendar;
  mView = view;
}

CalendarViewExtension *ResourceViewFactory::create( QWidget *parent )
{
  ResourceView *view = new ResourceView( mCalendar->resourceManager(), parent );

  QObject::connect( view, SIGNAL( resourcesChanged() ),
                    mView, SLOT( updateView() ) );
  QObject::connect( view, SIGNAL( signalErrorMessage( const QString & ) ),
                    mView, SLOT( showErrorMessage( const QString & ) ) );

  QObject::connect( mCalendar,
                    SIGNAL( signalResourceAdded( ResourceCalendar * ) ),
                    view, SLOT( addResourceItem( ResourceCalendar * ) ) );
  QObject::connect( mCalendar,
                    SIGNAL( signalResourceModified( ResourceCalendar * ) ),
                    view, SLOT( updateResourceItem( ResourceCalendar * ) ) );

  return view;
}

ResourceItem::ResourceItem( ResourceCalendar *resource, ResourceView *view,
                            KListView *parent )
  : QCheckListItem( parent, resource->resourceName(), CheckBox ),
    mResource( resource ), mView( view ), mBlockStateChange( false ),
    mIsSubresource( false )
{
  setGuiState();

  const QStringList subresources = mResource->subresources();
  if ( !subresources.isEmpty() ) {
    setOpen( true );
    setExpandable( true );
    // This resource has subresources
    QStringList::ConstIterator it;
    for ( it=subresources.begin(); it!=subresources.end(); ++it ) {
      ( void )new ResourceItem( mResource, *it, mView, this );
    }
  }
}

ResourceItem::ResourceItem( KCal::ResourceCalendar *resource,
                            const QString& sub, ResourceView *view,
                            ResourceItem* parent )
  : QCheckListItem( parent, sub, CheckBox ), mResource( resource ),
    mView( view ), mBlockStateChange( false ), mIsSubresource( true )
{
  setGuiState();
}

void ResourceItem::setGuiState()
{
  mBlockStateChange = true;
  if ( mIsSubresource )
    setOn( mResource->subresourceActive( text( 0 ) ) );
  else
    setOn( mResource->isActive() );
  mBlockStateChange = false;
}

void ResourceItem::stateChange( bool active )
{
  if ( mBlockStateChange ) return;

  if ( !mIsSubresource ) {
    // Handle a full resource
    bool toActivate = active;
    if ( active ) {
      bool success = mResource->open();
      if ( success ) {
        success = mResource->load();
      }
      if ( !success ) {
        QString msg = mResource->errorMessage();
        if ( !msg.isEmpty() ) mView->emitErrorMessage( msg );
        toActivate = false;
      }
    } else {
      mResource->save();
      mResource->close();
    }
    mResource->setActive( toActivate );

    setOpen( toActivate && childCount() > 0 );

    setGuiState();
  } else
    // Handle a subresource
    mResource->setSubresourceActive( text( 0 ), active );

  mView->emitResourcesChanged();
}

void ResourceItem::update()
{
  setGuiState();
}

ResourceView::ResourceView( KCal::CalendarResourceManager *manager,
                            QWidget *parent, const char *name )
  : CalendarViewExtension( parent, name ),
    mManager( manager )
{
  QBoxLayout *topLayout = new QVBoxLayout( this );

  mListView = new KListView( this );
  mListView->addColumn( i18n("Calendar") );
  mListView->setResizeMode( QListView::LastColumn );
  topLayout->addWidget( mListView );

  QHBox *buttonBox = new QHBox( this );
  topLayout->addWidget( buttonBox );

  mAddButton = new QPushButton( i18n("Add..."), buttonBox, "add" );
  mDeleteButton = new QPushButton( i18n("Remove"), buttonBox, "del" );
  mEditButton = new QPushButton( i18n("Edit..."), buttonBox, "edit" );
  mDeleteButton->setDisabled( true );
  mEditButton->setDisabled( true );

  connect( mListView, SIGNAL( clicked( QListViewItem * ) ),
           SLOT( currentChanged( QListViewItem * ) ) );
  connect( mAddButton, SIGNAL( clicked() ), SLOT( addResource() ) );
  connect( mDeleteButton, SIGNAL( clicked() ), SLOT( removeResource() ) );
  connect( mEditButton, SIGNAL( clicked() ), SLOT( editResource() ) );
  connect( mListView, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), SLOT( editResource() ) );

  updateView();
}

ResourceView::~ResourceView()
{
}

void ResourceView::updateView()
{
  mListView->clear();

  KCal::CalendarResourceManager::Iterator it;
  for( it = mManager->begin(); it != mManager->end(); ++it ) {
    addResourceItem( *it );
  }
}

void ResourceView::emitResourcesChanged()
{
  emit resourcesChanged();
}

void ResourceView::addResource()
{
  QStringList types = mManager->resourceTypeNames();
  QStringList descs = mManager->resourceTypeDescriptions();
  bool ok = false;
  QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
      i18n( "Please select type of the new resource:" ), descs, 0, false, &ok,
            this );
  if ( !ok )
    return;

  QString type = types[ descs.findIndex( desc ) ];

  // Create new resource
  ResourceCalendar *resource = mManager->createResource( type );
  if( !resource ) {
    KMessageBox::error( this, i18n("<qt>Unable to create resource of type %1.</qt>")
                              .arg( type ) );
    return;
  }

  resource->setResourceName( i18n("%1 resource").arg( type ) );

  KRES::ConfigDialog dlg( this, QString("calendar"), resource,
                          "KRES::ConfigDialog" );

  if ( dlg.exec() ) {
    if ( resource->isActive() ) {
      resource->open();
      resource->load();
    }

    mManager->add( resource );
    addResourceItem( resource );
  } else {
    delete resource;
    resource = 0;
  }
}

void ResourceView::addResourceItem( ResourceCalendar *resource )
{
  new ResourceItem( resource, this, mListView );
  connect( resource, SIGNAL( signalSubresourceAdded( ResourceCalendar *,
                                                     const QString &,
                                                     const QString & ) ),
           this, SLOT( slotSubresourceAdded( ResourceCalendar *,
                                             const QString &,
                                             const QString & ) ) );
  connect( resource, SIGNAL( signalSubresourceRemoved( ResourceCalendar *,
                                                       const QString &,
                                                       const QString & ) ),
           this, SLOT( slotSubresourceRemoved( ResourceCalendar *,
                                               const QString &,
                                               const QString & ) ) );
  emitResourcesChanged();
}

// Add a new entry
void ResourceView::slotSubresourceAdded( ResourceCalendar *calendar,
                                         const QString &/*type*/,
                                         const QString &resource )
{
  QListViewItem* i = mListView->findItem( calendar->resourceName(), 0 );
  if ( !i )
    // Not found
    return;

  ResourceItem* item = static_cast<ResourceItem*>( i );
  ( void )new ResourceItem( calendar, resource, this, item );
}

// Remove an entry
void ResourceView::slotSubresourceRemoved( ResourceCalendar */*calendar*/,
                                           const QString &/*type*/,
                                           const QString &resource )
{
  delete mListView->findItem( resource, 0 );
}

void ResourceView::updateResourceItem( ResourceCalendar *resource )
{
  ResourceItem *item = findItem( resource );
  if ( item ) {
    item->update();
  }
}

void ResourceView::removeResource()
{
  QListViewItem *item = mListView->currentItem();
  ResourceItem *rItem = static_cast<ResourceItem *>( item );

  if ( !rItem )
    return;

  int km = KMessageBox::warningContinueCancel( this,
        i18n("<qt>Do you really want to remove the resource %1?</qt>")
        .arg( rItem->resource()->resourceName() ),"",KGuiItem(i18n("&Remove"),"editdelete") );
  if ( km == KMessageBox::Cancel ) return;

// Don't be so restricitve
#if 0
  if ( rItem->resource() == mManager->standardResource() ) {
    KMessageBox::sorry( this,
                        i18n( "You cannot remove your standard resource." ) );
    return;
  }
#endif

  mManager->remove( rItem->resource() );

  mListView->takeItem( item );
  delete item;
  emitResourcesChanged();
}

void ResourceView::editResource()
{
  QListViewItem *item = mListView->currentItem();
  ResourceItem *rItem = static_cast<ResourceItem *>( item );
  if ( !rItem )
    return;

  ResourceCalendar *resource = rItem->resource();

  KRES::ConfigDialog dlg( this, QString("calendar"), resource,
                          "KRES::ConfigDialog" );

  if ( dlg.exec() ) {
    rItem->setText( 0, resource->resourceName() );

    mManager->change( resource );
  }
}

void ResourceView::currentChanged( QListViewItem *item)
{
  bool selected = true;
  if ( !item ) selected = false;
  mDeleteButton->setEnabled( selected );
  mEditButton->setEnabled( selected );
}

void ResourceView::emitErrorMessage( const QString &msg )
{
  emit signalErrorMessage( msg );
}

ResourceItem *ResourceView::findItem( ResourceCalendar *r )
{
  QListViewItem *item;
  ResourceItem *i = 0;
  for( item = mListView->firstChild(); item; item = item->nextSibling() ) {
    i = static_cast<ResourceItem *>( item );
    if ( i->resource() == r ) break;
  }
  return i;
}

#include "resourceview.moc"
<|endoftext|>


<commit_before>// This file is part of the dune-pymor project:
//   https://github.com/pymor/dune-pymor
// Copyright holders: Stephan Rave, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_PYMOR_DISCRETIZATIONS_INTERFACES_HH
#define DUNE_PYMOR_DISCRETIZATIONS_INTERFACES_HH

#include <vector>
#include <string>

#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/common/crtp.hh>

#include <dune/pymor/parameters/base.hh>
#include <dune/pymor/operators/interfaces.hh>
#include <dune/pymor/functionals/interfaces.hh>
#include <dune/pymor/la/container/affine.hh>

namespace Dune {
namespace Pymor {
namespace Tags {

class StationaryDiscretizationInterface {};

class StationaryMultiscaleDiscretiztionInterface {};

} // namespace Tags

template< class Traits >
class StationaryDiscretizationInterface
  : public Parametric
  , public Stuff::CRTPInterface< StationaryDiscretizationInterface< Traits >, Traits >
  , public Tags::StationaryDiscretizationInterface
{
public:
  typedef typename Traits::derived_type   derived_type;
  typedef typename Traits::OperatorType   OperatorType;
  typedef typename Traits::FunctionalType FunctionalType;
  typedef typename Traits::ProductType    ProductType;
  typedef typename Traits::VectorType     VectorType;

  typedef Pymor::LA::AffinelyDecomposedContainer< VectorType > AffinelyDecomposedVectorType;

  StationaryDiscretizationInterface(const ParameterType tt = ParameterType())
    : Parametric(tt)
  {}

  StationaryDiscretizationInterface(const Parametric& other)
    : Parametric(other)
  {}

  OperatorType get_operator() const
  {
    CHECK_CRTP(this->as_imp(*this).get_operator());
    return this->as_imp(*this).get_operator();
  }

  OperatorType* get_operator_and_return_ptr() const
  {
    return new OperatorType(get_operator());
  }

  FunctionalType get_rhs() const
  {
    CHECK_CRTP(this->as_imp(*this).get_rhs());
    return this->as_imp(*this).get_rhs();
  }

  FunctionalType* get_rhs_and_return_ptr() const
  {
    return new FunctionalType(get_rhs());
  }

  std::vector< std::string > available_products() const
  {
    CHECK_CRTP(this->as_imp(*this).available_products());
    return this->as_imp(*this).available_products();
  }

  ProductType get_product(const std::string id) const
  {
    CHECK_CRTP(this->as_imp(*this).get_product(id));
    return this->as_imp(*this).get_product(id);
  }

  ProductType* get_product_and_return_ptr(const std::string id) const
  {
    return new ProductType(get_product(id));
  }

  std::vector< std::string > available_vectors() const
  {
    CHECK_CRTP(this->as_imp(*this).available_vectors());
    return this->as_imp(*this).available_vectors();
  }

  AffinelyDecomposedVectorType get_vector(const std::string id) const
  {
    CHECK_CRTP(this->as_imp(*this).get_vector(id));
    return this->as_imp(*this).get_vector(id);
  }

  VectorType* get_vector_and_return_ptr(const std::string id) const
  {
    return new VectorType(get_vector(id));
  }

  VectorType create_vector() const
  {
    CHECK_CRTP(this->as_imp(*this).create_vector());
    return this->as_imp(*this).create_vector();
  }

  VectorType* create_vector_and_return_ptr() const
  {
    return new VectorType(create_vector());
  }

//  std::vector< std::string > solver_options() const
//  {
//    CHECK_CRTP(this->as_imp(*this).solver_options());
//    return this->as_imp(*this).solver_options();
//  }

//  std::string solver_options(const std::string context) const
//  {
//    CHECK_CRTP(this->as_imp(*this).solver_options(context));
//    return this->as_imp(*this).solver_options(context);
//  }

  void solve(VectorType& vector, const Parameter mu = Parameter()) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).solve(vector, mu));
  }

  VectorType solve(const Parameter mu = Parameter()) const
  {
    VectorType ret = create_vector();
    solve(ret, mu);
    return ret;
  }

  VectorType* solve_and_return_ptr(const Parameter mu = Parameter()) const
  {
    return new VectorType(solve(mu));
  }

  void visualize(const VectorType& vector, const std::string filename, const std::string name) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).visualize(vector, filename, name));
  }
}; // class StationaryDiscretizationInterface

} // namespace Pymor
} // namespace Dune

#endif // DUNE_PYMOR_DISCRETIZATIONS_INTERFACES_HH
<commit_msg>[discretizations.interfaces] fixed get_vector_and_return_ptr()<commit_after>// This file is part of the dune-pymor project:
//   https://github.com/pymor/dune-pymor
// Copyright holders: Stephan Rave, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_PYMOR_DISCRETIZATIONS_INTERFACES_HH
#define DUNE_PYMOR_DISCRETIZATIONS_INTERFACES_HH

#include <vector>
#include <string>

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/common/crtp.hh>

#include <dune/pymor/parameters/base.hh>
#include <dune/pymor/operators/interfaces.hh>
#include <dune/pymor/functionals/interfaces.hh>
#include <dune/pymor/la/container/affine.hh>

namespace Dune {
namespace Pymor {
namespace Tags {

class StationaryDiscretizationInterface {};

class StationaryMultiscaleDiscretiztionInterface {};

} // namespace Tags

template< class Traits >
class StationaryDiscretizationInterface
  : public Parametric
  , public Stuff::CRTPInterface< StationaryDiscretizationInterface< Traits >, Traits >
  , public Tags::StationaryDiscretizationInterface
{
public:
  typedef typename Traits::derived_type   derived_type;
  typedef typename Traits::OperatorType   OperatorType;
  typedef typename Traits::FunctionalType FunctionalType;
  typedef typename Traits::ProductType    ProductType;
  typedef typename Traits::VectorType     VectorType;

  typedef Pymor::LA::AffinelyDecomposedContainer< VectorType > AffinelyDecomposedVectorType;

  StationaryDiscretizationInterface(const ParameterType tt = ParameterType())
    : Parametric(tt)
  {}

  StationaryDiscretizationInterface(const Parametric& other)
    : Parametric(other)
  {}

  OperatorType get_operator() const
  {
    CHECK_CRTP(this->as_imp(*this).get_operator());
    return this->as_imp(*this).get_operator();
  }

  OperatorType* get_operator_and_return_ptr() const
  {
    return new OperatorType(get_operator());
  }

  FunctionalType get_rhs() const
  {
    CHECK_CRTP(this->as_imp(*this).get_rhs());
    return this->as_imp(*this).get_rhs();
  }

  FunctionalType* get_rhs_and_return_ptr() const
  {
    return new FunctionalType(get_rhs());
  }

  std::vector< std::string > available_products() const
  {
    CHECK_CRTP(this->as_imp(*this).available_products());
    return this->as_imp(*this).available_products();
  }

  ProductType get_product(const std::string id) const
  {
    CHECK_CRTP(this->as_imp(*this).get_product(id));
    return this->as_imp(*this).get_product(id);
  }

  ProductType* get_product_and_return_ptr(const std::string id) const
  {
    return new ProductType(get_product(id));
  }

  std::vector< std::string > available_vectors() const
  {
    CHECK_CRTP(this->as_imp(*this).available_vectors());
    return this->as_imp(*this).available_vectors();
  }

  AffinelyDecomposedVectorType get_vector(const std::string id) const
  {
    CHECK_CRTP(this->as_imp(*this).get_vector(id));
    return this->as_imp(*this).get_vector(id);
  }

  VectorType* get_vector_and_return_ptr(const std::string id) const
  {
    auto vec = get_vector(id);
    if (vec.parametric())
      DUNE_THROW_COLORFULLY(NotImplemented, "Not implemented yet for parametric vectors!");
    return new VectorType(*(vec.affine_part()));
  }

  VectorType create_vector() const
  {
    CHECK_CRTP(this->as_imp(*this).create_vector());
    return this->as_imp(*this).create_vector();
  }

  VectorType* create_vector_and_return_ptr() const
  {
    return new VectorType(create_vector());
  }

//  std::vector< std::string > solver_options() const
//  {
//    CHECK_CRTP(this->as_imp(*this).solver_options());
//    return this->as_imp(*this).solver_options();
//  }

//  std::string solver_options(const std::string context) const
//  {
//    CHECK_CRTP(this->as_imp(*this).solver_options(context));
//    return this->as_imp(*this).solver_options(context);
//  }

  void solve(VectorType& vector, const Parameter mu = Parameter()) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).solve(vector, mu));
  }

  VectorType solve(const Parameter mu = Parameter()) const
  {
    VectorType ret = create_vector();
    solve(ret, mu);
    return ret;
  }

  VectorType* solve_and_return_ptr(const Parameter mu = Parameter()) const
  {
    return new VectorType(solve(mu));
  }

  void visualize(const VectorType& vector, const std::string filename, const std::string name) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).visualize(vector, filename, name));
  }
}; // class StationaryDiscretizationInterface

} // namespace Pymor
} // namespace Dune

#endif // DUNE_PYMOR_DISCRETIZATIONS_INTERFACES_HH
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    SBVRGeogen.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    September 2008
*/

#include <algorithm>
#include <functional>
#include <limits>
#include "SBVRGeogen.h"

#include <Basics/MathTools.h>

static bool EpsilonEqual(float a, float b);
static bool CheckOrdering(const FLOATVECTOR3& a, const FLOATVECTOR3& b,
                          const FLOATVECTOR3& c);
static void SortPoints(std::vector<POS3TEX3_VERTEX> &fArray);

SBVRGeogen::SBVRGeogen(void) :
  m_fSamplingModifier(1.0f),
  m_fMinZ(0),
  m_vAspect(1,1,1),
  m_vSize(1,1,1),
  m_vTexCoordMin(0,0,0),
  m_vTexCoordMax(1,1,1),
  m_iMinLayers(100),
  m_vGlobalAspect(1,1,1),
  m_vGlobalSize(1,1,1),
  m_vLODSize(1,1,1)
{
  m_pfBBOXStaticVertex[0] = FLOATVECTOR3(-0.5, 0.5,-0.5);
  m_pfBBOXStaticVertex[1] = FLOATVECTOR3( 0.5, 0.5,-0.5);
  m_pfBBOXStaticVertex[2] = FLOATVECTOR3( 0.5, 0.5, 0.5);
  m_pfBBOXStaticVertex[3] = FLOATVECTOR3(-0.5, 0.5, 0.5);
  m_pfBBOXStaticVertex[4] = FLOATVECTOR3(-0.5,-0.5,-0.5);
  m_pfBBOXStaticVertex[5] = FLOATVECTOR3( 0.5,-0.5,-0.5);
  m_pfBBOXStaticVertex[6] = FLOATVECTOR3( 0.5,-0.5, 0.5);
  m_pfBBOXStaticVertex[7] = FLOATVECTOR3(-0.5,-0.5, 0.5);

  m_pfBBOXVertex[0] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[1] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[2] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[3] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[4] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[5] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[6] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[7] = FLOATVECTOR3(0,0,0);
}

SBVRGeogen::~SBVRGeogen(void)
{
}

void SBVRGeogen::SetTransformation(const FLOATMATRIX4& matTransform, bool bForceUpdate) {
  if (bForceUpdate || m_matTransform != matTransform)  {
    m_matTransform = matTransform;
    InitBBOX();
    ComputeGeometry();
  }
}

// Finds the point with the minimum position in Z.
struct vertex_min_z : public std::binary_function<POS3TEX3_VERTEX,
                                                  POS3TEX3_VERTEX,
                                                  bool> {
  bool operator()(const POS3TEX3_VERTEX &a, const POS3TEX3_VERTEX &b) const {
    return (a.m_vPos.z < b.m_vPos.z);
  }
};

void SBVRGeogen::InitBBOX() {

  FLOATVECTOR3 vVertexScale(m_vAspect);

  m_pfBBOXVertex[0] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[0]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMax.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[1] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[1]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMax.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[2] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[2]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMax.y,m_vTexCoordMax.z));
  m_pfBBOXVertex[3] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[3]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMax.y,m_vTexCoordMax.z));
  m_pfBBOXVertex[4] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[4]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMin.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[5] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[5]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMin.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[6] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[6]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMin.y,m_vTexCoordMax.z));
  m_pfBBOXVertex[7] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[7]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMin.y,m_vTexCoordMax.z));

  // find the minimum z value
  m_fMinZ = (*std::min_element(m_pfBBOXVertex, m_pfBBOXVertex+8,
                               vertex_min_z())).m_vPos.z;
}

static bool ComputeIntersection(float z,
                                const POS3TEX3_VERTEX &plA,
                                const POS3TEX3_VERTEX &plB,
                                std::vector<POS3TEX3_VERTEX>& vHits)
{
  /*
     returns NO INTERSECTION if the line of the 2 points a,b is
     1. in front of the intersection plane
     2. behind the intersection plane
     3. parallel to the intersection plane (both points have "pretty much" the same z)
  */
  if ((z > plA.m_vPos.z && z > plB.m_vPos.z) ||
      (z < plA.m_vPos.z && z < plB.m_vPos.z) ||
      (EpsilonEqual(plA.m_vPos.z, plB.m_vPos.z))) {
    return false;
  }

  float fAlpha = (z - plA.m_vPos.z) /
                 (plA.m_vPos.z - plB.m_vPos.z);

  POS3TEX3_VERTEX vHit;

  vHit.m_vPos.x = plA.m_vPos.x + (plA.m_vPos.x - plB.m_vPos.x) * fAlpha;
  vHit.m_vPos.y = plA.m_vPos.y + (plA.m_vPos.y - plB.m_vPos.y) * fAlpha;
  vHit.m_vPos.z = z;

  vHit.m_vTex = plA.m_vTex + (plA.m_vTex - plB.m_vTex) * fAlpha;

  vHits.push_back(vHit);

  return true;
}

// Functor to identify the point with the lowest `y' coordinate.
struct vertex_min : public std::binary_function<POS3TEX3_VERTEX,
                                                POS3TEX3_VERTEX,
                                                bool> {
  bool operator()(const POS3TEX3_VERTEX &a, const POS3TEX3_VERTEX &b) const {
    return (a.m_vPos.y < b.m_vPos.y);
  }
};

// Sorts a vector
static void SortByGradient(std::vector<POS3TEX3_VERTEX>& fArray)
{
  // move bottom element to front of array
  if(fArray.empty()) { return; }
  std::swap(fArray[0],
            *std::min_element(fArray.begin(), fArray.end(), vertex_min()));
  if(fArray.size() > 2) {
    // sort points according to gradient
    SortPoints(fArray);
  }
}

void SBVRGeogen::Triangulate(std::vector<POS3TEX3_VERTEX> &fArray) {
  SortByGradient(fArray);

  // convert to triangles
  for (UINT32 i=0; i<(fArray.size()-2) ; i++) {
    m_vSliceTriangles.push_back(fArray[0]);
    m_vSliceTriangles.push_back(fArray[i+1]);
    m_vSliceTriangles.push_back(fArray[i+2]);
  }
}

bool SBVRGeogen::ComputeLayerGeometry(float fDepth) {
  std::vector<POS3TEX3_VERTEX> vLayerPoints;
  vLayerPoints.reserve(12);

  ComputeIntersection(fDepth, m_pfBBOXVertex[0], m_pfBBOXVertex[1],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[1], m_pfBBOXVertex[2],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[2], m_pfBBOXVertex[3],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[3], m_pfBBOXVertex[0],
                      vLayerPoints);

  ComputeIntersection(fDepth, m_pfBBOXVertex[4], m_pfBBOXVertex[5],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[5], m_pfBBOXVertex[6],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[6], m_pfBBOXVertex[7],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[7], m_pfBBOXVertex[4],
                      vLayerPoints);

  ComputeIntersection(fDepth, m_pfBBOXVertex[4], m_pfBBOXVertex[0],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[5], m_pfBBOXVertex[1],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[6], m_pfBBOXVertex[2],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[7], m_pfBBOXVertex[3],
                      vLayerPoints);

  if (vLayerPoints.size() <= 2) {
    return false;
  }

  Triangulate(vLayerPoints);
  return true;
}

float SBVRGeogen::GetLayerDistance() {
  return (0.5f * 1.0f/m_fSamplingModifier * (m_vAspect/FLOATVECTOR3(m_vSize))).minVal(); //float(m_vAspect.minVal())/float(std::max(m_vSize.maxVal(),m_iMinLayers));
}

float SBVRGeogen::GetOpacityCorrection() {
  return 1.0f/m_fSamplingModifier * (FLOATVECTOR3(m_vGlobalSize)/FLOATVECTOR3(m_vLODSize)).maxVal();//  GetLayerDistance()*m_vSize.maxVal();
}

void SBVRGeogen::ComputeGeometry() {
  m_vSliceTriangles.clear();

  float fDepth = m_fMinZ;
  float fLayerDistance = GetLayerDistance();

  while (ComputeLayerGeometry(fDepth)) fDepth += fLayerDistance;
}

void SBVRGeogen::SetVolumeData(const FLOATVECTOR3& vAspect, const UINTVECTOR3& vSize) {
  m_vGlobalAspect = vAspect;
  m_vGlobalSize = vSize;
}

void SBVRGeogen::SetLODData(const UINTVECTOR3& vSize) {
  m_vLODSize = vSize;
}

void SBVRGeogen::SetBrickData(const FLOATVECTOR3& vAspect,
                              const UINTVECTOR3& vSize,
                              const FLOATVECTOR3& vTexCoordMin,
                              const FLOATVECTOR3& vTexCoordMax) {
  m_vAspect       = vAspect;
  m_vSize         = vSize;
  m_vTexCoordMin  = vTexCoordMin;
  m_vTexCoordMax  = vTexCoordMax;
  InitBBOX();
}

static bool EpsilonEqual(float a, float b) {
  return fabs(a-b) <= std::numeric_limits<float>::epsilon();
}

// Checks the ordering of two points relative to another.
static bool CheckOrdering(const FLOATVECTOR3& a,
                          const FLOATVECTOR3& b,
                          const FLOATVECTOR3& c) {
  float g1 = (a.y-c.y)/(a.x-c.x),
        g2 = (b.y-c.y)/(b.x-c.x);

  if (EpsilonEqual(a.x,c.x))
    return (g2 < 0) || (EpsilonEqual(g2,0) && b.x < c.x);
  if (EpsilonEqual(b.x,c.x))
    return (g1 > 0) || (EpsilonEqual(g1,0) && a.x > c.x);

  if (a.x < c.x)
    if (b.x < c.x) return g1 < g2; else return false;
  else
    if (b.x < c.x) return true; else return g1 < g2;
}

/// @todo: should be replaced with std::sort.
static void SortPoints(std::vector<POS3TEX3_VERTEX> &fArray) {
  // for small arrays, this bubble sort actually beats qsort.
  for (UINT32 i= 1;i<fArray.size();++i)
    for (UINT32 j = 1;j<fArray.size()-i;++j)
      if (!CheckOrdering(fArray[j].m_vPos,fArray[j+1].m_vPos,fArray[0].m_vPos))
        std::swap(fArray[j], fArray[j+1]);
}
<commit_msg>Add `intersection(line segment, plane)' function.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/**
  \file    SBVRGeogen.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    September 2008
*/

#include <algorithm>
#include <functional>
#include <limits>
#include "SBVRGeogen.h"

#include <Basics/MathTools.h>

static bool EpsilonEqual(float a, float b);
static bool CheckOrdering(const FLOATVECTOR3& a, const FLOATVECTOR3& b,
                          const FLOATVECTOR3& c);
static void SortPoints(std::vector<POS3TEX3_VERTEX> &fArray);

SBVRGeogen::SBVRGeogen(void) :
  m_fSamplingModifier(1.0f),
  m_fMinZ(0),
  m_vAspect(1,1,1),
  m_vSize(1,1,1),
  m_vTexCoordMin(0,0,0),
  m_vTexCoordMax(1,1,1),
  m_iMinLayers(100),
  m_vGlobalAspect(1,1,1),
  m_vGlobalSize(1,1,1),
  m_vLODSize(1,1,1)
{
  m_pfBBOXStaticVertex[0] = FLOATVECTOR3(-0.5, 0.5,-0.5);
  m_pfBBOXStaticVertex[1] = FLOATVECTOR3( 0.5, 0.5,-0.5);
  m_pfBBOXStaticVertex[2] = FLOATVECTOR3( 0.5, 0.5, 0.5);
  m_pfBBOXStaticVertex[3] = FLOATVECTOR3(-0.5, 0.5, 0.5);
  m_pfBBOXStaticVertex[4] = FLOATVECTOR3(-0.5,-0.5,-0.5);
  m_pfBBOXStaticVertex[5] = FLOATVECTOR3( 0.5,-0.5,-0.5);
  m_pfBBOXStaticVertex[6] = FLOATVECTOR3( 0.5,-0.5, 0.5);
  m_pfBBOXStaticVertex[7] = FLOATVECTOR3(-0.5,-0.5, 0.5);

  m_pfBBOXVertex[0] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[1] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[2] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[3] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[4] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[5] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[6] = FLOATVECTOR3(0,0,0);
  m_pfBBOXVertex[7] = FLOATVECTOR3(0,0,0);
}

SBVRGeogen::~SBVRGeogen(void)
{
}

void SBVRGeogen::SetTransformation(const FLOATMATRIX4& matTransform, bool bForceUpdate) {
  if (bForceUpdate || m_matTransform != matTransform)  {
    m_matTransform = matTransform;
    InitBBOX();
    ComputeGeometry();
  }
}

// Finds the point with the minimum position in Z.
struct vertex_min_z : public std::binary_function<POS3TEX3_VERTEX,
                                                  POS3TEX3_VERTEX,
                                                  bool> {
  bool operator()(const POS3TEX3_VERTEX &a, const POS3TEX3_VERTEX &b) const {
    return (a.m_vPos.z < b.m_vPos.z);
  }
};

void SBVRGeogen::InitBBOX() {

  FLOATVECTOR3 vVertexScale(m_vAspect);

  m_pfBBOXVertex[0] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[0]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMax.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[1] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[1]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMax.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[2] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[2]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMax.y,m_vTexCoordMax.z));
  m_pfBBOXVertex[3] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[3]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMax.y,m_vTexCoordMax.z));
  m_pfBBOXVertex[4] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[4]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMin.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[5] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[5]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMin.y,m_vTexCoordMin.z));
  m_pfBBOXVertex[6] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[6]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMax.x,m_vTexCoordMin.y,m_vTexCoordMax.z));
  m_pfBBOXVertex[7] = POS3TEX3_VERTEX(FLOATVECTOR4(m_pfBBOXStaticVertex[7]*vVertexScale,1.0f) * m_matTransform, FLOATVECTOR3(m_vTexCoordMin.x,m_vTexCoordMin.y,m_vTexCoordMax.z));

  // find the minimum z value
  m_fMinZ = (*std::min_element(m_pfBBOXVertex, m_pfBBOXVertex+8,
                               vertex_min_z())).m_vPos.z;
}

static bool ComputeIntersection(float z,
                                const POS3TEX3_VERTEX &plA,
                                const POS3TEX3_VERTEX &plB,
                                std::vector<POS3TEX3_VERTEX>& vHits)
{
  /*
     returns NO INTERSECTION if the line of the 2 points a,b is
     1. in front of the intersection plane
     2. behind the intersection plane
     3. parallel to the intersection plane (both points have "pretty much" the same z)
  */
  if ((z > plA.m_vPos.z && z > plB.m_vPos.z) ||
      (z < plA.m_vPos.z && z < plB.m_vPos.z) ||
      (EpsilonEqual(plA.m_vPos.z, plB.m_vPos.z))) {
    return false;
  }

  float fAlpha = (z - plA.m_vPos.z) /
                 (plA.m_vPos.z - plB.m_vPos.z);

  POS3TEX3_VERTEX vHit;

  vHit.m_vPos.x = plA.m_vPos.x + (plA.m_vPos.x - plB.m_vPos.x) * fAlpha;
  vHit.m_vPos.y = plA.m_vPos.y + (plA.m_vPos.y - plB.m_vPos.y) * fAlpha;
  vHit.m_vPos.z = z;

  vHit.m_vTex = plA.m_vTex + (plA.m_vTex - plB.m_vTex) * fAlpha;

  vHits.push_back(vHit);

  return true;
}

// Calculates the intersection point of a line segment lb->la which crosses the
// plane with normal `n'.
static bool intersection(const POS3TEX3_VERTEX &la,
                         const POS3TEX3_VERTEX &lb,
                         const FLOATVECTOR3 &n,
                         POS3TEX3_VERTEX &hit)
{
  const FLOATVECTOR3 &va = la.m_vPos;
  const FLOATVECTOR3 &vb = lb.m_vPos;
  const float denom = n ^ (va - vb);
  if(EpsilonEqual(denom, 0)) {
    return false;
  }
  const float D = 0;
  const float t = ((n ^ va) + D) / denom;

  hit.m_vPos = va + (t*(vb - va));
  hit.m_vTex = la.m_vTex + t*(lb.m_vTex - la.m_vTex);

  return true;
}

// Functor to identify the point with the lowest `y' coordinate.
struct vertex_min : public std::binary_function<POS3TEX3_VERTEX,
                                                POS3TEX3_VERTEX,
                                                bool> {
  bool operator()(const POS3TEX3_VERTEX &a, const POS3TEX3_VERTEX &b) const {
    return (a.m_vPos.y < b.m_vPos.y);
  }
};

// Sorts a vector
static void SortByGradient(std::vector<POS3TEX3_VERTEX>& fArray)
{
  // move bottom element to front of array
  if(fArray.empty()) { return; }
  std::swap(fArray[0],
            *std::min_element(fArray.begin(), fArray.end(), vertex_min()));
  if(fArray.size() > 2) {
    // sort points according to gradient
    SortPoints(fArray);
  }
}

void SBVRGeogen::Triangulate(std::vector<POS3TEX3_VERTEX> &fArray) {
  SortByGradient(fArray);

  // convert to triangles
  for (UINT32 i=0; i<(fArray.size()-2) ; i++) {
    m_vSliceTriangles.push_back(fArray[0]);
    m_vSliceTriangles.push_back(fArray[i+1]);
    m_vSliceTriangles.push_back(fArray[i+2]);
  }
}

bool SBVRGeogen::ComputeLayerGeometry(float fDepth) {
  std::vector<POS3TEX3_VERTEX> vLayerPoints;
  vLayerPoints.reserve(12);

  ComputeIntersection(fDepth, m_pfBBOXVertex[0], m_pfBBOXVertex[1],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[1], m_pfBBOXVertex[2],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[2], m_pfBBOXVertex[3],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[3], m_pfBBOXVertex[0],
                      vLayerPoints);

  ComputeIntersection(fDepth, m_pfBBOXVertex[4], m_pfBBOXVertex[5],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[5], m_pfBBOXVertex[6],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[6], m_pfBBOXVertex[7],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[7], m_pfBBOXVertex[4],
                      vLayerPoints);

  ComputeIntersection(fDepth, m_pfBBOXVertex[4], m_pfBBOXVertex[0],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[5], m_pfBBOXVertex[1],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[6], m_pfBBOXVertex[2],
                      vLayerPoints);
  ComputeIntersection(fDepth, m_pfBBOXVertex[7], m_pfBBOXVertex[3],
                      vLayerPoints);

  if (vLayerPoints.size() <= 2) {
    return false;
  }

  Triangulate(vLayerPoints);
  return true;
}

float SBVRGeogen::GetLayerDistance() {
  return (0.5f * 1.0f/m_fSamplingModifier * (m_vAspect/FLOATVECTOR3(m_vSize))).minVal(); //float(m_vAspect.minVal())/float(std::max(m_vSize.maxVal(),m_iMinLayers));
}

float SBVRGeogen::GetOpacityCorrection() {
  return 1.0f/m_fSamplingModifier * (FLOATVECTOR3(m_vGlobalSize)/FLOATVECTOR3(m_vLODSize)).maxVal();//  GetLayerDistance()*m_vSize.maxVal();
}

void SBVRGeogen::ComputeGeometry() {
  m_vSliceTriangles.clear();

  float fDepth = m_fMinZ;
  float fLayerDistance = GetLayerDistance();

  while (ComputeLayerGeometry(fDepth)) fDepth += fLayerDistance;
}

void SBVRGeogen::SetVolumeData(const FLOATVECTOR3& vAspect, const UINTVECTOR3& vSize) {
  m_vGlobalAspect = vAspect;
  m_vGlobalSize = vSize;
}

void SBVRGeogen::SetLODData(const UINTVECTOR3& vSize) {
  m_vLODSize = vSize;
}

void SBVRGeogen::SetBrickData(const FLOATVECTOR3& vAspect,
                              const UINTVECTOR3& vSize,
                              const FLOATVECTOR3& vTexCoordMin,
                              const FLOATVECTOR3& vTexCoordMax) {
  m_vAspect       = vAspect;
  m_vSize         = vSize;
  m_vTexCoordMin  = vTexCoordMin;
  m_vTexCoordMax  = vTexCoordMax;
  InitBBOX();
}

static bool EpsilonEqual(float a, float b) {
  return fabs(a-b) <= std::numeric_limits<float>::epsilon();
}

// Checks the ordering of two points relative to another.
static bool CheckOrdering(const FLOATVECTOR3& a,
                          const FLOATVECTOR3& b,
                          const FLOATVECTOR3& c) {
  float g1 = (a.y-c.y)/(a.x-c.x),
        g2 = (b.y-c.y)/(b.x-c.x);

  if (EpsilonEqual(a.x,c.x))
    return (g2 < 0) || (EpsilonEqual(g2,0) && b.x < c.x);
  if (EpsilonEqual(b.x,c.x))
    return (g1 > 0) || (EpsilonEqual(g1,0) && a.x > c.x);

  if (a.x < c.x)
    if (b.x < c.x) return g1 < g2; else return false;
  else
    if (b.x < c.x) return true; else return g1 < g2;
}

/// @todo: should be replaced with std::sort.
static void SortPoints(std::vector<POS3TEX3_VERTEX> &fArray) {
  // for small arrays, this bubble sort actually beats qsort.
  for (UINT32 i= 1;i<fArray.size();++i)
    for (UINT32 j = 1;j<fArray.size()-i;++j)
      if (!CheckOrdering(fArray[j].m_vPos,fArray[j+1].m_vPos,fArray[0].m_vPos))
        std::swap(fArray[j], fArray[j+1]);
}
<|endoftext|>


<commit_before>#include "ukf-spark-library/ukf-spark-library.h"

// Simple example. Solves heating problem.

#define n  3 //number of state variables (temperature, insulation, and thermal mass)
#define pts  10 // for example, keep # of pts small, in reality this will probably be used on live data, and pts won't be stored
int m = 1; // number of measurement variables (temp))
float To = 4; // outside temp
float Ua = 4; // Insulation value
float Mt = 700; // thermal mass value
float u = 75; // heater percent on)
float max_time = 60; //simulation time (minutes)
float t[pts]; // time points
float r = 0.1; // std dev of measurement
float Q[] = {40, 0, 0,
  0, 40, 0,
  0, 0, 40}; //covariance of process
float R[] = {r * r}; //covariance of measurement
float x[] = {15, 2, 200}; // current/inital state (starting ata point off of real values to display convergence))
float P[] = {50, 0, 0,
  0, 50, 0,
  0, 0, 50}; // current/initial state covariance

float xV[n*pts];
float sV[n*pts];
float zV[1 * pts];

float T[pts];

UkfLib ukf;

void stateFuc(float *in, float *out)
{
  float dt = (max_time / (float) (pts - 1));
  out[0] = in[0] + (dt * (u + in[1]*(To - in[0]))) / in[2];
  out[1] = in[1];
  out[2] = in[2];
}

void measFunc(float *in, float *out)
{
  out[0] = in[0];
}

void setup()
{
  Serial.begin(9600);
  while (!Serial.available()) Spark.process();
  float delta_t = (max_time / (float) (pts - 1)); // delta_t time
  T[0] = 15; //Starting Temperature
  // Calculate actual temperatures
  for (int i = 1; i < pts; i++) {
    T[i] = T[i - 1] + delta_t * (u - Ua * (T[i - 1] - To)) / Mt;
  }
  for (int i = 0; i < pts; i++) {
    Serial.print(T[i]);
  }
  Serial.println();

  for (int k = 0; k < pts; k++) {
    float z[] = {T[k]}; // assume measurement temp is actual temp (no measurment error)
    ukf.ukf(stateFunc, x, P, measFunc, z, Q, R, n, m);
    for (int i = 0; i < n; i++) {
      xV[i * pts + k] = x[i];
    }
  }
  ukf.printArray(xV, 3, pts, "xv");

}

void loop()
{

}

<commit_msg>... seriously...<commit_after>#include "ukf-spark-library/ukf-spark-library.h"

// Simple example. Solves heating problem.

#define n  3 //number of state variables (temperature, insulation, and thermal mass)
#define pts  10 // for example, keep # of pts small, in reality this will probably be used on live data, and pts won't be stored
int m = 1; // number of measurement variables (temp))
float To = 4; // outside temp
float Ua = 4; // Insulation value
float Mt = 700; // thermal mass value
float u = 75; // heater percent on)
float max_time = 60; //simulation time (minutes)
float t[pts]; // time points
float r = 0.1; // std dev of measurement
float Q[] = {40, 0, 0,
  0, 40, 0,
  0, 0, 40}; //covariance of process
float R[] = {r * r}; //covariance of measurement
float x[] = {15, 2, 200}; // current/inital state (starting ata point off of real values to display convergence))
float P[] = {50, 0, 0,
  0, 50, 0,
  0, 0, 50}; // current/initial state covariance

float xV[n*pts];
float sV[n*pts];
float zV[1 * pts];

float T[pts];

UkfLib ukf;

void stateFunc(float *in, float *out)
{
  float dt = (max_time / (float) (pts - 1));
  out[0] = in[0] + (dt * (u + in[1]*(To - in[0]))) / in[2];
  out[1] = in[1];
  out[2] = in[2];
}

void measFunc(float *in, float *out)
{
  out[0] = in[0];
}

void setup()
{
  Serial.begin(9600);
  while (!Serial.available()) Spark.process();
  float delta_t = (max_time / (float) (pts - 1)); // delta_t time
  T[0] = 15; //Starting Temperature
  // Calculate actual temperatures
  for (int i = 1; i < pts; i++) {
    T[i] = T[i - 1] + delta_t * (u - Ua * (T[i - 1] - To)) / Mt;
  }
  for (int i = 0; i < pts; i++) {
    Serial.print(T[i]);
  }
  Serial.println();

  for (int k = 0; k < pts; k++) {
    float z[] = {T[k]}; // assume measurement temp is actual temp (no measurment error)
    ukf.ukf(stateFunc, x, P, measFunc, z, Q, R, n, m);
    for (int i = 0; i < n; i++) {
      xV[i * pts + k] = x[i];
    }
  }
  ukf.printArray(xV, 3, pts, "xv");

}

void loop()
{

}

<|endoftext|>


<commit_before>//=============================================================================
//
// akaze_features.cpp
// Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2)
// Institutions: Toshiba Research Europe Ltd (1)
//               TrueVision Solutions (2)
// Date: 07/10/2014
// Email: pablofdezalc@gmail.com
//
// AKAZE Features Copyright 2014, Pablo F. Alcantarilla, Jesus Nuevo
// All Rights Reserved
// See LICENSE for the license information
//=============================================================================

/**
 * @file akaze_features.cpp
 * @brief Main program for detecting and computing binary descriptors in an
 * accelerated nonlinear scale space
 * @date Oct 07, 2014
 * @author Pablo F. Alcantarilla, Jesus Nuevo
 */

#include "./lib/AKAZE.h"

// OpenCV
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;

/* ************************************************************************* */
/**
 * @brief This function parses the command line arguments for setting A-KAZE parameters
 * @param options Structure that contains A-KAZE settings
 * @param img_path Path for the input image
 * @param kpts_path Path for the file where the keypoints where be stored
 */
int parse_input_options(AKAZEOptions& options, std::string& img_path,
                        std::string& kpts_path, int argc, char *argv[]);

/* ************************************************************************* */
int main(int argc, char *argv[]) {

  // Variables
  AKAZEOptions options;
  string img_path, kpts_path;

  // Variable for computation times.
  double t1 = 0.0, t2 = 0.0, tdet = 0.0, tdesc = 0.0;

  // Parse the input command line options
  if (parse_input_options(options, img_path, kpts_path, argc, argv))
    return -1;

  if (options.verbosity) {
    cout << "Check AKAZE options:" << endl;
    cout << options << endl;
  }

  // Try to read the image and if necessary convert to grayscale.
  cv::Mat img = cv::imread(img_path.c_str(), 0);
  if (img.data == NULL) {
    cerr << "Error: cannot load image from file:" << endl << img_path << endl;
    return -1;
  }

  // Convert the image to float to extract features
  cv::Mat img_32;
  img.convertTo(img_32, CV_32F, 1.0/255.0, 0);

  // Don't forget to specify image dimensions in AKAZE's options
  options.img_width = img.cols;
  options.img_height = img.rows;

  // Extract features
  libAKAZE::AKAZE evolution(options);
  vector<cv::KeyPoint> kpts;

  t1 = cv::getTickCount();
  evolution.Create_Nonlinear_Scale_Space(img_32);
  evolution.Feature_Detection(kpts);
  t2 = cv::getTickCount();
  tdet = 1000.0*(t2-t1) / cv::getTickFrequency();

  // Compute descriptors.
  cv::Mat desc;
  t1 = cv::getTickCount();
  evolution.Compute_Descriptors(kpts, desc);
  t2 = cv::getTickCount();
  tdesc = 1000.0*(t2-t1) / cv::getTickFrequency();

  // Summarize the computation times.
  evolution.Show_Computation_Times();

  cout << "Number of points: " << kpts.size() << endl;
  cout << "Time Detector: " << tdet << " ms" << endl;
  cout << "Time Descriptor: " << tdesc << " ms" << endl;

  // Save keypoints in ASCII format
  if (!kpts_path.empty())
    save_keypoints(kpts_path, kpts, desc, true);

  // Check out the result visually
  cv::Mat img_rgb = cv::Mat(cv::Size(img.cols, img.rows), CV_8UC3);
  cvtColor(img,img_rgb, cv::COLOR_GRAY2BGR);
  draw_keypoints(img_rgb, kpts);
  cv::imshow(img_path, img_rgb);
  cv::waitKey(0);
}

/* ************************************************************************* */
int parse_input_options(AKAZEOptions& options, std::string& img_path,
                        std::string& kpts_path, int argc, char *argv[]) {

  // If there is only one argument return
  if (argc == 1) {
    show_input_options_help(0);
    return -1;
  }
  // Set the options from the command line
  else if (argc >= 2) {
    options = AKAZEOptions();
    kpts_path = "./keypoints.txt";

    if (!strcmp(argv[1],"--help")) {
      show_input_options_help(0);
      return -1;
    }

    img_path = argv[1];

    for (int i = 2; i < argc; i++) {
      if (!strcmp(argv[i],"--soffset")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.soffset = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--omax")) {
        i = i+1;
        if ( i >= argc ) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.omax = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--dthreshold")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.dthreshold = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--sderivatives")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.sderivatives = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--nsublevels")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else
          options.nsublevels = atoi(argv[i]);
      }
      else if (!strcmp(argv[i],"--diffusivity")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else
          options.diffusivity = DIFFUSIVITY_TYPE(atoi(argv[i]));
      }
      else if (!strcmp(argv[i],"--descriptor")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.descriptor = DESCRIPTOR_TYPE(atoi(argv[i]));

          if (options.descriptor < 0 || options.descriptor > MLDB) {
            options.descriptor = MLDB;
          }
        }
      }
      else if (!strcmp(argv[i],"--descriptor_channels")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.descriptor_channels = atoi(argv[i]);

          if (options.descriptor_channels <= 0 || options.descriptor_channels > 3) {
            options.descriptor_channels = 3;
          }
        }
      }
      else if (!strcmp(argv[i],"--descriptor_size")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.descriptor_size = atoi(argv[i]);

          if (options.descriptor_size < 0) {
            options.descriptor_size = 0;
          }
        }
      }
      else if (!strcmp(argv[i],"--save_scale_space")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.save_scale_space = (bool)atoi(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--verbose")) {
        options.verbosity = true;
      }
      else if (!strcmp(argv[i],"--output")) {
        options.save_keypoints = true;
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else
          kpts_path = argv[i];
      }
    }
  }

  return 0;
}
<commit_msg>Minor change in OpenCV visualization call<commit_after>//=============================================================================
//
// akaze_features.cpp
// Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2)
// Institutions: Toshiba Research Europe Ltd (1)
//               TrueVision Solutions (2)
// Date: 07/10/2014
// Email: pablofdezalc@gmail.com
//
// AKAZE Features Copyright 2014, Pablo F. Alcantarilla, Jesus Nuevo
// All Rights Reserved
// See LICENSE for the license information
//=============================================================================

/**
 * @file akaze_features.cpp
 * @brief Main program for detecting and computing binary descriptors in an
 * accelerated nonlinear scale space
 * @date Oct 07, 2014
 * @author Pablo F. Alcantarilla, Jesus Nuevo
 */

#include "./lib/AKAZE.h"

// OpenCV
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace std;

/* ************************************************************************* */
/**
 * @brief This function parses the command line arguments for setting A-KAZE parameters
 * @param options Structure that contains A-KAZE settings
 * @param img_path Path for the input image
 * @param kpts_path Path for the file where the keypoints where be stored
 */
int parse_input_options(AKAZEOptions& options, std::string& img_path,
                        std::string& kpts_path, int argc, char *argv[]);

/* ************************************************************************* */
int main(int argc, char *argv[]) {

  // Variables
  AKAZEOptions options;
  string img_path, kpts_path;

  // Variable for computation times.
  double t1 = 0.0, t2 = 0.0, tdet = 0.0, tdesc = 0.0;

  // Parse the input command line options
  if (parse_input_options(options, img_path, kpts_path, argc, argv))
    return -1;

  if (options.verbosity) {
    cout << "Check AKAZE options:" << endl;
    cout << options << endl;
  }

  // Try to read the image and if necessary convert to grayscale.
  cv::Mat img = cv::imread(img_path.c_str(), 0);
  if (img.data == NULL) {
    cerr << "Error: cannot load image from file:" << endl << img_path << endl;
    return -1;
  }

  // Convert the image to float to extract features
  cv::Mat img_32;
  img.convertTo(img_32, CV_32F, 1.0/255.0, 0);

  // Don't forget to specify image dimensions in AKAZE's options
  options.img_width = img.cols;
  options.img_height = img.rows;

  // Extract features
  libAKAZE::AKAZE evolution(options);
  vector<cv::KeyPoint> kpts;

  t1 = cv::getTickCount();
  evolution.Create_Nonlinear_Scale_Space(img_32);
  evolution.Feature_Detection(kpts);
  t2 = cv::getTickCount();
  tdet = 1000.0*(t2-t1) / cv::getTickFrequency();

  // Compute descriptors.
  cv::Mat desc;
  t1 = cv::getTickCount();
  evolution.Compute_Descriptors(kpts, desc);
  t2 = cv::getTickCount();
  tdesc = 1000.0*(t2-t1) / cv::getTickFrequency();

  // Summarize the computation times.
  evolution.Show_Computation_Times();

  cout << "Number of points: " << kpts.size() << endl;
  cout << "Time Detector: " << tdet << " ms" << endl;
  cout << "Time Descriptor: " << tdesc << " ms" << endl;

  // Save keypoints in ASCII format
  if (!kpts_path.empty())
    save_keypoints(kpts_path, kpts, desc, true);

  // Check out the result visually
  cv::Mat img_rgb = cv::Mat(cv::Size(img.cols, img.rows), CV_8UC3);
  cvtColor(img,img_rgb, cv::COLOR_GRAY2BGR);
  draw_keypoints(img_rgb, kpts);

  cv::namedWindow("A-KAZE", cv::WINDOW_AUTOSIZE);
  cv::imshow("A-KAZE", img_rgb);
  cv::waitKey(0);
}

/* ************************************************************************* */
int parse_input_options(AKAZEOptions& options, std::string& img_path,
                        std::string& kpts_path, int argc, char *argv[]) {

  // If there is only one argument return
  if (argc == 1) {
    show_input_options_help(0);
    return -1;
  }
  // Set the options from the command line
  else if (argc >= 2) {
    options = AKAZEOptions();
    kpts_path = "./keypoints.txt";

    if (!strcmp(argv[1],"--help")) {
      show_input_options_help(0);
      return -1;
    }

    img_path = argv[1];

    for (int i = 2; i < argc; i++) {
      if (!strcmp(argv[i],"--soffset")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.soffset = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--omax")) {
        i = i+1;
        if ( i >= argc ) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.omax = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--dthreshold")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.dthreshold = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--sderivatives")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.sderivatives = atof(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--nsublevels")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else
          options.nsublevels = atoi(argv[i]);
      }
      else if (!strcmp(argv[i],"--diffusivity")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else
          options.diffusivity = DIFFUSIVITY_TYPE(atoi(argv[i]));
      }
      else if (!strcmp(argv[i],"--descriptor")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.descriptor = DESCRIPTOR_TYPE(atoi(argv[i]));

          if (options.descriptor < 0 || options.descriptor > MLDB) {
            options.descriptor = MLDB;
          }
        }
      }
      else if (!strcmp(argv[i],"--descriptor_channels")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.descriptor_channels = atoi(argv[i]);

          if (options.descriptor_channels <= 0 || options.descriptor_channels > 3) {
            options.descriptor_channels = 3;
          }
        }
      }
      else if (!strcmp(argv[i],"--descriptor_size")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.descriptor_size = atoi(argv[i]);

          if (options.descriptor_size < 0) {
            options.descriptor_size = 0;
          }
        }
      }
      else if (!strcmp(argv[i],"--save_scale_space")) {
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else {
          options.save_scale_space = (bool)atoi(argv[i]);
        }
      }
      else if (!strcmp(argv[i],"--verbose")) {
        options.verbosity = true;
      }
      else if (!strcmp(argv[i],"--output")) {
        options.save_keypoints = true;
        i = i+1;
        if (i >= argc) {
          cerr << "Error introducing input options!!" << endl;
          return -1;
        }
        else
          kpts_path = argv[i];
      }
    }
  }

  return 0;
}
<|endoftext|>