<commit_before>/**
 * \file
 * \brief RoundRobinQuantum class header
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-08-05
 */

#ifndef INCLUDE_DISTORTOS_SCHEDULER_ROUNDROBINQUANTUM_HPP_
#define INCLUDE_DISTORTOS_SCHEDULER_ROUNDROBINQUANTUM_HPP_

#include <cstdint>

namespace distortos
{

namespace scheduler
{

/// RoundRobinQuantum class is a quantum of time for round-robin scheduling
class RoundRobinQuantum
{
public:

	/**
	 * \brief RoundRobinQuantum's constructor
	 *
	 * Initializes quantum value to 0.
	 */

	constexpr RoundRobinQuantum() :
			quantum_{}
	{}

	/**
	 * \brief Decrements round-robin's quantum.
	 *
	 * This function should be called from tick interrupt for the currently running thread. Underflow of quantum after
	 * this decrement is not possible.
	 *
	 * \note this function must be called with enabled interrupt masking
	 */

	void decrement();

	/**
	 * \brief Gets current value of round-robin's quantum.
	 *
	 * \return current value of round-robin's quantum of the thread
	 */

	uint8_t get() const { return quantum_; }

	/**
	 * \brief Resets value of round-robin's quantum.
	 *
	 * This function should be called from context switcher after selecting new task that will be run.
	 */

	void reset();

private:

	/// round-robin quantum
	uint8_t quantum_;
};

}	// namespace scheduler

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SCHEDULER_ROUNDROBINQUANTUM_HPP_
<commit_msg>RoundRobinQuantum: add convenience RoundRobinQuantum::isZero() function<commit_after>/**
 * \file
 * \brief RoundRobinQuantum class header
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-09-16
 */

#ifndef INCLUDE_DISTORTOS_SCHEDULER_ROUNDROBINQUANTUM_HPP_
#define INCLUDE_DISTORTOS_SCHEDULER_ROUNDROBINQUANTUM_HPP_

#include <cstdint>

namespace distortos
{

namespace scheduler
{

/// RoundRobinQuantum class is a quantum of time for round-robin scheduling
class RoundRobinQuantum
{
public:

	/**
	 * \brief RoundRobinQuantum's constructor
	 *
	 * Initializes quantum value to 0.
	 */

	constexpr RoundRobinQuantum() :
			quantum_{}
	{}

	/**
	 * \brief Decrements round-robin's quantum.
	 *
	 * This function should be called from tick interrupt for the currently running thread. Underflow of quantum after
	 * this decrement is not possible.
	 *
	 * \note this function must be called with enabled interrupt masking
	 */

	void decrement();

	/**
	 * \brief Gets current value of round-robin's quantum.
	 *
	 * \return current value of round-robin's quantum of the thread
	 */

	uint8_t get() const { return quantum_; }

	/**
	 * \brief Convenience function to test whether the quantum is already at 0.
	 *
	 * \return true if quantum is zero, false otherwise
	 */

	bool isZero() const
	{
		return quantum_ == 0;
	}

	/**
	 * \brief Resets value of round-robin's quantum.
	 *
	 * This function should be called from context switcher after selecting new task that will be run.
	 */

	void reset();

private:

	/// round-robin quantum
	uint8_t quantum_;
};

}	// namespace scheduler

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SCHEDULER_ROUNDROBINQUANTUM_HPP_
<|endoftext|>


<commit_before>///
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn  <tackat@kde.org>
// Copyright 2007      Inge Wallin   <ingwa@kde.org>
// Copyright 2007      Thomas Zander <zander@kde.org>
// Copyright 2010      Bastian Holst <bastianholst@gmx.de>
//

// Self
#include "NavigationWidget.h"

// Marble
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "MarbleRunnerManager.h"
#include "MarblePlacemarkModel.h"
#include "GeoDataDocument.h"
#include "GeoDataTreeModel.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"

// Qt
#include <QtCore/QTime>
#include <QtCore/QTimer>
#include <QtGui/QSortFilterProxyModel>

using namespace Marble;

#include "ui_NavigationWidget.h"

namespace Marble
{

class NavigationWidgetPrivate
{
 public:
    Ui::NavigationWidget    m_navigationUi;
    MarbleWidget           *m_widget;
    QSortFilterProxyModel  *m_sortproxy;
    QString                 m_searchTerm;
    MarbleRunnerManager    *m_runnerManager;
    QTimer                  m_deferSearch;
    GeoDataTreeModel        m_treeModel;
    GeoDataDocument        *m_document;

    NavigationWidgetPrivate()
        : m_document( new GeoDataDocument ) {
    m_document->setDocumentRole( SearchResultDocument );
    m_treeModel.setRootDocument( m_document );
    };

};

NavigationWidget::NavigationWidget( QWidget *parent, Qt::WindowFlags f )
    : QWidget( parent, f ),
      d( new NavigationWidgetPrivate() )
{
    d->m_searchTerm.clear();
    d->m_widget = 0;

    d->m_navigationUi.setupUi( this );

    d->m_sortproxy = new QSortFilterProxyModel( this );
    d->m_navigationUi.locationListView->setModel( d->m_sortproxy );
    d->m_deferSearch.setSingleShot( true );
    connect ( &d->m_deferSearch, SIGNAL( timeout() ),
              this, SLOT( search()) );

    connect( d->m_navigationUi.goHomeButton,     SIGNAL( clicked() ),
             this,                               SIGNAL( goHome() ) );
    connect( d->m_navigationUi.zoomSlider,       SIGNAL( valueChanged( int ) ),
             this,                               SIGNAL( zoomChanged( int ) ) );
    connect( d->m_navigationUi.zoomInButton,     SIGNAL( clicked() ),
             this,                               SIGNAL( zoomIn() ) );
    connect( d->m_navigationUi.zoomOutButton,    SIGNAL( clicked() ),
             this,                               SIGNAL( zoomOut() ) );

    connect( d->m_navigationUi.zoomSlider,       SIGNAL( valueChanged( int ) ),
             this,                               SLOT( updateButtons( int ) ) );

    connect( d->m_navigationUi.moveLeftButton,   SIGNAL( clicked() ),
             this,                               SIGNAL( moveLeft() ) );
    connect( d->m_navigationUi.moveRightButton,  SIGNAL( clicked() ),
             this,                               SIGNAL( moveRight() ) );
    connect( d->m_navigationUi.moveUpButton,     SIGNAL( clicked() ),
             this,                               SIGNAL( moveUp() ) );
    connect( d->m_navigationUi.moveDownButton,   SIGNAL( clicked() ),
             this,                               SIGNAL( moveDown() ) );

    connect( d->m_navigationUi.locationListView, SIGNAL( activated( const QModelIndex& ) ),
             this,                               SLOT( mapCenterOnSignal( const QModelIndex& ) ) );

    connect( d->m_navigationUi.searchLineEdit,   SIGNAL( textChanged( const QString& ) ),
             this,                               SLOT( searchLineChanged( const QString& ) ) );
    connect( d->m_navigationUi.searchLineEdit,   SIGNAL( returnPressed() ),
             this,                               SLOT( searchReturnPressed() ) );

    connect( d->m_navigationUi.zoomSlider,       SIGNAL( sliderPressed() ),
             this,                               SLOT( adjustForAnimation() ) );
    connect( d->m_navigationUi.zoomSlider,       SIGNAL( sliderReleased() ),
             this,                               SLOT( adjustForStill() ) );
}

NavigationWidget::~NavigationWidget()
{
    delete d;
}

void NavigationWidget::setMarbleWidget( MarbleWidget *widget )
{
    d->m_runnerManager = new MarbleRunnerManager( widget->model()->pluginManager(), this );
    connect( d->m_runnerManager, SIGNAL( searchResultChanged( QVector<GeoDataPlacemark*> ) ),
             this,               SLOT( setLocations( QVector<GeoDataPlacemark*> ) ) );

    d->m_widget = widget;
    d->m_runnerManager->setModel( widget->model() );
    d->m_widget->model()->treeModel()->addDocument( d->m_document );

    d->m_sortproxy->setSortLocaleAware( true );
    d->m_sortproxy->setDynamicSortFilter( true );

    // Make us aware of all the Placemarks in the MarbleModel so that
    // we can search them.
    d->m_sortproxy->setSourceModel( d->m_widget->model()->placemarkModel() );
    d->m_sortproxy->sort( 0 );

    // Connect necessary signals.
    connect( this, SIGNAL( goHome() ),         d->m_widget, SLOT( goHome() ) );
    connect( this, SIGNAL( zoomChanged(int) ), d->m_widget, SLOT( zoomView( int ) ) );
    connect( this, SIGNAL( zoomIn() ),         d->m_widget, SLOT( zoomIn() ) );
    connect( this, SIGNAL( zoomOut() ),        d->m_widget, SLOT( zoomOut() ) );

    connect( this, SIGNAL( moveLeft() ),  d->m_widget, SLOT( moveLeft() ) );
    connect( this, SIGNAL( moveRight() ), d->m_widget, SLOT( moveRight() ) );
    connect( this, SIGNAL( moveUp() ),    d->m_widget, SLOT( moveUp() ) );
    connect( this, SIGNAL( moveDown() ),  d->m_widget, SLOT( moveDown() ) );

    connect( d->m_widget, SIGNAL( zoomChanged( int ) ),
             this,        SLOT( changeZoom( int ) ) );

    connect( d->m_widget, SIGNAL( themeChanged( QString ) ),
             this,        SLOT( selectTheme( QString ) ) );
}

void NavigationWidget::changeZoom( int zoom )
{
    // There exists a circular signal/slot connection between MarbleWidget and this widget's
    // zoom slider. MarbleWidget prevents recursion, but it still loops one time unless
    // blocked here. Note that it would be possible to only connect the sliders
    // sliderMoved signal instead of its valueChanged signal above to break up the loop.
    // This however means that the slider cannot be operated with the mouse wheel, as this
    // does not emit the sliderMoved signal for some reason. Therefore the signal is blocked
    // below before calling setValue on the slider to avoid that it calls back to MarbleWidget,
    // and then un-blocked again to make user interaction possible.

    d->m_navigationUi.zoomSlider->blockSignals( true );

    d->m_navigationUi.zoomSlider->setValue( zoom );
    // As we have disabled all zoomSlider Signals, we have to update our buttons seperately.
    updateButtons( zoom );

    d->m_navigationUi.zoomSlider->blockSignals( false );
}

void NavigationWidget::searchLineChanged( const QString &search )
{
    d->m_searchTerm = search;
    // if search line is empty, restore original geonames
    if ( d->m_searchTerm.isEmpty() ) {
        // set the proxy list to the placemarkModel
        d->m_sortproxy->setSourceModel( d->m_widget->model()->placemarkModel() );
        d->m_sortproxy->sort( 0 );
        d->m_widget->model()->placemarkSelectionModel()->clear();

        // clear the local document
        d->m_widget->model()->treeModel()->removeDocument( d->m_document );
        d->m_document->clear();
        d->m_widget->model()->treeModel()->addDocument( d->m_document );
    }
    d->m_deferSearch.start( 500 );
}

void NavigationWidget::searchReturnPressed()
{
    // do nothing if search term empty
    if ( !d->m_searchTerm.isEmpty() ) {
        d->m_runnerManager->findPlacemarks( d->m_searchTerm );
    }
}

void NavigationWidget::search()
{
    d->m_deferSearch.stop();
    int  currentSelected = d->m_navigationUi.locationListView->currentIndex().row();
    d->m_navigationUi.locationListView->selectItem( d->m_searchTerm );
    if ( currentSelected != d->m_navigationUi.locationListView->currentIndex().row() )
        d->m_navigationUi.locationListView->activate();
}

void NavigationWidget::setLocations( QVector<GeoDataPlacemark*> locations )
{
    QTime t;
    t.start();

    // fill the local document with results
    d->m_widget->model()->placemarkSelectionModel()->clear();
    d->m_widget->model()->treeModel()->removeDocument( d->m_document );
    d->m_document->clear();
    foreach (GeoDataPlacemark *placemark, locations ) {
        d->m_document->append( new GeoDataPlacemark( *placemark ) );
    }
    d->m_widget->model()->treeModel()->addDocument( d->m_document );
    d->m_widget->centerOn( d->m_document->latLonAltBox() );

    // set the proxy list to the list of results
    d->m_sortproxy->setSourceModel( &d->m_treeModel );
    d->m_sortproxy->sort( 0 );
    mDebug() << "NavigationWidget (sort): Time elapsed:"<< t.elapsed() << " ms";
}

void NavigationWidget::selectTheme( const QString &theme )
{
    Q_UNUSED( theme )

    if( !d->m_widget )
        return;

    d->m_navigationUi.zoomSlider->setMinimum( d->m_widget->minimumZoom() );
    d->m_navigationUi.zoomSlider->setMaximum( d->m_widget->maximumZoom() );
    updateButtons( d->m_navigationUi.zoomSlider->value() );
}

void NavigationWidget::updateButtons( int value )
{
    if ( value <= d->m_navigationUi.zoomSlider->minimum() ) {
        d->m_navigationUi.zoomInButton->setEnabled( true );
        d->m_navigationUi.zoomOutButton->setEnabled( false );
    } else if ( value >= d->m_navigationUi.zoomSlider->maximum() ) {
        d->m_navigationUi.zoomInButton->setEnabled( false );
        d->m_navigationUi.zoomOutButton->setEnabled( true );
    } else {
        d->m_navigationUi.zoomInButton->setEnabled( true );
        d->m_navigationUi.zoomOutButton->setEnabled( true );
    }
}

void NavigationWidget::mapCenterOnSignal( const QModelIndex &index )
{
    if( !index.isValid() ) {
        return;
    }
    GeoDataObject *object
            = qVariantValue<GeoDataObject*>( index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole ) );
    if ( dynamic_cast<GeoDataPlacemark*>(object) )
    {
        GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(object);
        d->m_widget->centerOn( *placemark, true );
        d->m_widget->model()->placemarkSelectionModel()->select( d->m_sortproxy->mapToSource( index ), QItemSelectionModel::ClearAndSelect );
    }
}

void NavigationWidget::adjustForAnimation()
{
    // TODO: use signals here as well
    if ( !d->m_widget )
        return;

    d->m_widget->setViewContext( Animation );
}

void NavigationWidget::adjustForStill()
{
    // TODO: use signals here as well
    if ( !d->m_widget )
        return;

    d->m_widget->setViewContext( Still );
}

void NavigationWidget::resizeEvent ( QResizeEvent * )
{
    bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;

    if ( smallScreen || height() < 390 ) {
        if ( !d->m_navigationUi.zoomSlider->isHidden() ) {
            setUpdatesEnabled(false);
            d->m_navigationUi.zoomSlider->hide();
            d->m_navigationUi.m_pSpacerFrame->setSizePolicy( QSizePolicy::Preferred,
                                                             QSizePolicy::Expanding );
            setUpdatesEnabled(true);
        }
    } else {
        if ( d->m_navigationUi.zoomSlider->isHidden() ) {
            setUpdatesEnabled(false);
            d->m_navigationUi.zoomSlider->show();
            d->m_navigationUi.m_pSpacerFrame->setSizePolicy( QSizePolicy::Preferred,
                                                       QSizePolicy::Fixed );
            setUpdatesEnabled(true);
        }
    }
}

}

#include "NavigationWidget.moc"
<commit_msg>NavigationWidget: name the results document<commit_after>///
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn  <tackat@kde.org>
// Copyright 2007      Inge Wallin   <ingwa@kde.org>
// Copyright 2007      Thomas Zander <zander@kde.org>
// Copyright 2010      Bastian Holst <bastianholst@gmx.de>
//

// Self
#include "NavigationWidget.h"

// Marble
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "MarbleRunnerManager.h"
#include "MarblePlacemarkModel.h"
#include "GeoDataDocument.h"
#include "GeoDataTreeModel.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"

// Qt
#include <QtCore/QTime>
#include <QtCore/QTimer>
#include <QtGui/QSortFilterProxyModel>

using namespace Marble;

#include "ui_NavigationWidget.h"

namespace Marble
{

class NavigationWidgetPrivate
{
 public:
    Ui::NavigationWidget    m_navigationUi;
    MarbleWidget           *m_widget;
    QSortFilterProxyModel  *m_sortproxy;
    QString                 m_searchTerm;
    MarbleRunnerManager    *m_runnerManager;
    QTimer                  m_deferSearch;
    GeoDataTreeModel        m_treeModel;
    GeoDataDocument        *m_document;

    NavigationWidgetPrivate()
        : m_document( new GeoDataDocument ) {
    m_document->setDocumentRole( SearchResultDocument );
    m_document->setName("Search Results");
    m_treeModel.setRootDocument( m_document );
    };

};

NavigationWidget::NavigationWidget( QWidget *parent, Qt::WindowFlags f )
    : QWidget( parent, f ),
      d( new NavigationWidgetPrivate() )
{
    d->m_searchTerm.clear();
    d->m_widget = 0;

    d->m_navigationUi.setupUi( this );

    d->m_sortproxy = new QSortFilterProxyModel( this );
    d->m_navigationUi.locationListView->setModel( d->m_sortproxy );
    d->m_deferSearch.setSingleShot( true );
    connect ( &d->m_deferSearch, SIGNAL( timeout() ),
              this, SLOT( search()) );

    connect( d->m_navigationUi.goHomeButton,     SIGNAL( clicked() ),
             this,                               SIGNAL( goHome() ) );
    connect( d->m_navigationUi.zoomSlider,       SIGNAL( valueChanged( int ) ),
             this,                               SIGNAL( zoomChanged( int ) ) );
    connect( d->m_navigationUi.zoomInButton,     SIGNAL( clicked() ),
             this,                               SIGNAL( zoomIn() ) );
    connect( d->m_navigationUi.zoomOutButton,    SIGNAL( clicked() ),
             this,                               SIGNAL( zoomOut() ) );

    connect( d->m_navigationUi.zoomSlider,       SIGNAL( valueChanged( int ) ),
             this,                               SLOT( updateButtons( int ) ) );

    connect( d->m_navigationUi.moveLeftButton,   SIGNAL( clicked() ),
             this,                               SIGNAL( moveLeft() ) );
    connect( d->m_navigationUi.moveRightButton,  SIGNAL( clicked() ),
             this,                               SIGNAL( moveRight() ) );
    connect( d->m_navigationUi.moveUpButton,     SIGNAL( clicked() ),
             this,                               SIGNAL( moveUp() ) );
    connect( d->m_navigationUi.moveDownButton,   SIGNAL( clicked() ),
             this,                               SIGNAL( moveDown() ) );

    connect( d->m_navigationUi.locationListView, SIGNAL( activated( const QModelIndex& ) ),
             this,                               SLOT( mapCenterOnSignal( const QModelIndex& ) ) );

    connect( d->m_navigationUi.searchLineEdit,   SIGNAL( textChanged( const QString& ) ),
             this,                               SLOT( searchLineChanged( const QString& ) ) );
    connect( d->m_navigationUi.searchLineEdit,   SIGNAL( returnPressed() ),
             this,                               SLOT( searchReturnPressed() ) );

    connect( d->m_navigationUi.zoomSlider,       SIGNAL( sliderPressed() ),
             this,                               SLOT( adjustForAnimation() ) );
    connect( d->m_navigationUi.zoomSlider,       SIGNAL( sliderReleased() ),
             this,                               SLOT( adjustForStill() ) );
}

NavigationWidget::~NavigationWidget()
{
    delete d;
}

void NavigationWidget::setMarbleWidget( MarbleWidget *widget )
{
    d->m_runnerManager = new MarbleRunnerManager( widget->model()->pluginManager(), this );
    connect( d->m_runnerManager, SIGNAL( searchResultChanged( QVector<GeoDataPlacemark*> ) ),
             this,               SLOT( setLocations( QVector<GeoDataPlacemark*> ) ) );

    d->m_widget = widget;
    d->m_runnerManager->setModel( widget->model() );
    d->m_widget->model()->treeModel()->addDocument( d->m_document );

    d->m_sortproxy->setSortLocaleAware( true );
    d->m_sortproxy->setDynamicSortFilter( true );

    // Make us aware of all the Placemarks in the MarbleModel so that
    // we can search them.
    d->m_sortproxy->setSourceModel( d->m_widget->model()->placemarkModel() );
    d->m_sortproxy->sort( 0 );

    // Connect necessary signals.
    connect( this, SIGNAL( goHome() ),         d->m_widget, SLOT( goHome() ) );
    connect( this, SIGNAL( zoomChanged(int) ), d->m_widget, SLOT( zoomView( int ) ) );
    connect( this, SIGNAL( zoomIn() ),         d->m_widget, SLOT( zoomIn() ) );
    connect( this, SIGNAL( zoomOut() ),        d->m_widget, SLOT( zoomOut() ) );

    connect( this, SIGNAL( moveLeft() ),  d->m_widget, SLOT( moveLeft() ) );
    connect( this, SIGNAL( moveRight() ), d->m_widget, SLOT( moveRight() ) );
    connect( this, SIGNAL( moveUp() ),    d->m_widget, SLOT( moveUp() ) );
    connect( this, SIGNAL( moveDown() ),  d->m_widget, SLOT( moveDown() ) );

    connect( d->m_widget, SIGNAL( zoomChanged( int ) ),
             this,        SLOT( changeZoom( int ) ) );

    connect( d->m_widget, SIGNAL( themeChanged( QString ) ),
             this,        SLOT( selectTheme( QString ) ) );
}

void NavigationWidget::changeZoom( int zoom )
{
    // There exists a circular signal/slot connection between MarbleWidget and this widget's
    // zoom slider. MarbleWidget prevents recursion, but it still loops one time unless
    // blocked here. Note that it would be possible to only connect the sliders
    // sliderMoved signal instead of its valueChanged signal above to break up the loop.
    // This however means that the slider cannot be operated with the mouse wheel, as this
    // does not emit the sliderMoved signal for some reason. Therefore the signal is blocked
    // below before calling setValue on the slider to avoid that it calls back to MarbleWidget,
    // and then un-blocked again to make user interaction possible.

    d->m_navigationUi.zoomSlider->blockSignals( true );

    d->m_navigationUi.zoomSlider->setValue( zoom );
    // As we have disabled all zoomSlider Signals, we have to update our buttons seperately.
    updateButtons( zoom );

    d->m_navigationUi.zoomSlider->blockSignals( false );
}

void NavigationWidget::searchLineChanged( const QString &search )
{
    d->m_searchTerm = search;
    // if search line is empty, restore original geonames
    if ( d->m_searchTerm.isEmpty() ) {
        // set the proxy list to the placemarkModel
        d->m_sortproxy->setSourceModel( d->m_widget->model()->placemarkModel() );
        d->m_sortproxy->sort( 0 );
        d->m_widget->model()->placemarkSelectionModel()->clear();

        // clear the local document
        d->m_widget->model()->treeModel()->removeDocument( d->m_document );
        d->m_document->clear();
        d->m_widget->model()->treeModel()->addDocument( d->m_document );
    }
    d->m_deferSearch.start( 500 );
}

void NavigationWidget::searchReturnPressed()
{
    // do nothing if search term empty
    if ( !d->m_searchTerm.isEmpty() ) {
        d->m_runnerManager->findPlacemarks( d->m_searchTerm );
    }
}

void NavigationWidget::search()
{
    d->m_deferSearch.stop();
    int  currentSelected = d->m_navigationUi.locationListView->currentIndex().row();
    d->m_navigationUi.locationListView->selectItem( d->m_searchTerm );
    if ( currentSelected != d->m_navigationUi.locationListView->currentIndex().row() )
        d->m_navigationUi.locationListView->activate();
}

void NavigationWidget::setLocations( QVector<GeoDataPlacemark*> locations )
{
    QTime t;
    t.start();

    // fill the local document with results
    d->m_widget->model()->placemarkSelectionModel()->clear();
    d->m_widget->model()->treeModel()->removeDocument( d->m_document );
    d->m_document->clear();
    foreach (GeoDataPlacemark *placemark, locations ) {
        d->m_document->append( new GeoDataPlacemark( *placemark ) );
    }
    d->m_widget->model()->treeModel()->addDocument( d->m_document );
    d->m_widget->centerOn( d->m_document->latLonAltBox() );

    // set the proxy list to the list of results
    d->m_sortproxy->setSourceModel( &d->m_treeModel );
    d->m_sortproxy->sort( 0 );
    mDebug() << "NavigationWidget (sort): Time elapsed:"<< t.elapsed() << " ms";
}

void NavigationWidget::selectTheme( const QString &theme )
{
    Q_UNUSED( theme )

    if( !d->m_widget )
        return;

    d->m_navigationUi.zoomSlider->setMinimum( d->m_widget->minimumZoom() );
    d->m_navigationUi.zoomSlider->setMaximum( d->m_widget->maximumZoom() );
    updateButtons( d->m_navigationUi.zoomSlider->value() );
}

void NavigationWidget::updateButtons( int value )
{
    if ( value <= d->m_navigationUi.zoomSlider->minimum() ) {
        d->m_navigationUi.zoomInButton->setEnabled( true );
        d->m_navigationUi.zoomOutButton->setEnabled( false );
    } else if ( value >= d->m_navigationUi.zoomSlider->maximum() ) {
        d->m_navigationUi.zoomInButton->setEnabled( false );
        d->m_navigationUi.zoomOutButton->setEnabled( true );
    } else {
        d->m_navigationUi.zoomInButton->setEnabled( true );
        d->m_navigationUi.zoomOutButton->setEnabled( true );
    }
}

void NavigationWidget::mapCenterOnSignal( const QModelIndex &index )
{
    if( !index.isValid() ) {
        return;
    }
    GeoDataObject *object
            = qVariantValue<GeoDataObject*>( index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole ) );
    if ( dynamic_cast<GeoDataPlacemark*>(object) )
    {
        GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(object);
        d->m_widget->centerOn( *placemark, true );
        d->m_widget->model()->placemarkSelectionModel()->select( d->m_sortproxy->mapToSource( index ), QItemSelectionModel::ClearAndSelect );
    }
}

void NavigationWidget::adjustForAnimation()
{
    // TODO: use signals here as well
    if ( !d->m_widget )
        return;

    d->m_widget->setViewContext( Animation );
}

void NavigationWidget::adjustForStill()
{
    // TODO: use signals here as well
    if ( !d->m_widget )
        return;

    d->m_widget->setViewContext( Still );
}

void NavigationWidget::resizeEvent ( QResizeEvent * )
{
    bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;

    if ( smallScreen || height() < 390 ) {
        if ( !d->m_navigationUi.zoomSlider->isHidden() ) {
            setUpdatesEnabled(false);
            d->m_navigationUi.zoomSlider->hide();
            d->m_navigationUi.m_pSpacerFrame->setSizePolicy( QSizePolicy::Preferred,
                                                             QSizePolicy::Expanding );
            setUpdatesEnabled(true);
        }
    } else {
        if ( d->m_navigationUi.zoomSlider->isHidden() ) {
            setUpdatesEnabled(false);
            d->m_navigationUi.zoomSlider->show();
            d->m_navigationUi.m_pSpacerFrame->setSizePolicy( QSizePolicy::Preferred,
                                                       QSizePolicy::Fixed );
            setUpdatesEnabled(true);
        }
    }
}

}

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


<commit_before>//===-- InstCount.cpp - Collects the count of all instructions ------------===//
//
// This pass collects the count of all instructions and reports them
//
//
//===----------------------------------------------------------------------===//

#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/iOperators.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/Support/InstIterator.h"
#include "Support/Statistic.h"
#include <algorithm>

namespace {
  static Statistic<> NumReturnInst("instcount","Number of ReturnInsts");
  static Statistic<> NumBranchInst("instcount", "Number of BranchInsts");
  static Statistic<> NumPHINode("instcount", "Number of PHINodes");
  static Statistic<> NumCastInst("instcount", "Number of CastInsts");
  static Statistic<> NumCallInst("instcount", "Number of CallInsts");
  static Statistic<> NumMallocInst("instcount", "Number of MallocInsts");
  static Statistic<> NumAllocaInst("instcount", "Number of AllocaInsts");
  static Statistic<> NumFreeInst("instcount", "Number of FreeInsts");
  static Statistic<> NumLoadInst("instcount", "Number of LoadInsts");
  static Statistic<> NumStoreInst("instcount", "Number of StoreInsts");
  static Statistic<> NumGetElementPtrInst("instcount",
					  "Number of GetElementPtrInsts");

  static Statistic<> NumSwitchInst("instcount", "Number of SwitchInsts");
  static Statistic<> NumInvokeInst("instcount", "Number of InvokeInsts");
  static Statistic<> NumBinaryOperator("instcount",
				       "Total Number of BinaryOperators");

  static Statistic<> NumShiftInst("instcount", " Total Number of ShiftInsts");
  static Statistic<> NumShlInst("instcount", "Number of Left ShiftInsts");

  static Statistic<> NumShrInst("instcount", "Number of Right ShiftInsts");

  static Statistic<> NumAddInst("instcount", "Number of AddInsts");
  static Statistic<> NumSubInst("instcount", "Number of SubInsts");
  static Statistic<> NumMulInst("instcount", "Number of MulInsts");
  static Statistic<> NumDivInst("instcount", "Number of DivInsts");
  static Statistic<> NumRemInst("instcount", "Number of RemInsts");
  static Statistic<> NumAndInst("instcount", "Number of AndInsts");
  static Statistic<> NumOrInst("instcount", "Number of OrInsts");
  static Statistic<> NumXorInst("instcount", "Number of XorInsts");
  static Statistic<> NumSetCondInst("instcount", "Total Number of SetCondInsts");
  static Statistic<> NumSetEQInst("instcount", "Number of SetEQInsts");
  static Statistic<> NumSetNEInst("instcount", "Number of SetNEInsts");
  static Statistic<> NumSetLEInst("instcount", "Number of SetLEInsts");
  static Statistic<> NumSetGEInst("instcount", "Number of SetGEInsts");
  static Statistic<> NumSetLTInst("instcount", "Number of SetLTInsts");
  static Statistic<> NumSetGTInst("instcount", "Number of SetGTInsts");

  class InstCount : public Pass, public InstVisitor<InstCount> {
  private:
        friend class InstVisitor<InstCount>;

    void visitBinaryOperator(BinaryOperator &I);
    void visitShiftInst(ShiftInst &I);
    void visitSetCondInst(SetCondInst &I);

    inline void visitSwitchInst(SwitchInst &I) { NumSwitchInst++; }
    inline void visitInvokeInst(InvokeInst &I) { NumInvokeInst++; }
    inline void visitReturnInst(ReturnInst &I) { NumReturnInst++; }
    inline void visitBranchInst(BranchInst &I) { NumBranchInst++; }
    inline void visitPHINode(PHINode &I) { NumPHINode++; }
    inline void visitCastInst (CastInst &I) { NumCastInst++; }
    inline void visitCallInst (CallInst &I) { NumCallInst++; }
    inline void visitMallocInst(MallocInst &I) { NumMallocInst++; }
    inline void visitAllocaInst(AllocaInst &I) { NumAllocaInst++; }
    inline void visitFreeInst  (FreeInst   &I) { NumFreeInst++; }
    inline void visitLoadInst  (LoadInst   &I) { NumLoadInst++; }
    inline void visitStoreInst (StoreInst  &I) { NumStoreInst++; }
    inline void visitGetElementPtrInst(GetElementPtrInst &I) {
      NumGetElementPtrInst++; }

    inline void visitInstruction(Instruction &I) {
      std::cerr << "Instruction Count does not know about " << I;
      abort();
    }
  public:
    virtual bool run(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
  };

  RegisterAnalysis<InstCount> X("instcount",
		    	   "Counts the various types of Instructions");

}

// createInstCountPass - The public interface to this file...
Pass *createInstCountPass() { return new InstCount(); }

// InstCount::run - This is the main Analysis entry point for a
// function.
//
bool InstCount::run(Module &M) {
  for (Module::iterator mI = M.begin(), mE = M.end(); mI != mE; ++mI)
    for (inst_iterator I = inst_begin(*mI), E = inst_end(*mI); I != E; ++I)
      visit(*I);
  return false;
}

void InstCount::visitBinaryOperator(BinaryOperator &I) {
  NumBinaryOperator++;
  switch (I.getOpcode()) {
  case Instruction::Add: NumAddInst++; break;
  case Instruction::Sub: NumSubInst++; break;
  case Instruction::Mul: NumMulInst++; break;
  case Instruction::Div: NumDivInst++; break;
  case Instruction::Rem: NumRemInst++; break;
  case Instruction::And: NumAndInst++; break;
  case Instruction::Or: NumOrInst++; break;
  case Instruction::Xor: NumXorInst++; break;
  default : std::cerr<< " Wrong binary operator \n";
  }
}

void InstCount::visitSetCondInst(SetCondInst &I) {
  NumBinaryOperator++;
  NumSetCondInst++;
  switch (I.getOpcode()) {
  case Instruction::SetEQ: NumSetEQInst++; break;
  case Instruction::SetNE: NumSetNEInst++; break;
  case Instruction::SetLE: NumSetLEInst++; break;
  case Instruction::SetGE: NumSetGEInst++; break;
  case Instruction::SetLT: NumSetLTInst++; break;
  case Instruction::SetGT: NumSetGTInst++; break;
  default : std::cerr<< " Wrong SetCond Inst \n";
  }
}

void InstCount::visitShiftInst(ShiftInst &I) {
  NumShiftInst++;
  switch (I.getOpcode()) {
  case Instruction::Shl: NumShlInst++; break;
  case Instruction::Shr: NumShrInst++; break;
  default : std::cerr<< " Wrong ShiftInst \n";
  }
}
<commit_msg>Simplify code<commit_after>//===-- InstCount.cpp - Collects the count of all instructions ------------===//
//
// This pass collects the count of all instructions and reports them
//
//===----------------------------------------------------------------------===//

#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/Support/InstVisitor.h"
#include "Support/Statistic.h"

namespace {
#define HANDLE_INST(N, OPCODE, CLASS) \
    Statistic<> Num##OPCODE##Inst("instcount", "Number of " #OPCODE " insts");

#include "llvm/Instruction.def"

  class InstCount : public Pass, public InstVisitor<InstCount> {
    friend class InstVisitor<InstCount>;

#define HANDLE_INST(N, OPCODE, CLASS) \
    void visit##OPCODE(CLASS &) { Num##OPCODE##Inst++; }

#include "llvm/Instruction.def"

    void visitInstruction(Instruction &I) {
      std::cerr << "Instruction Count does not know about " << I;
      abort();
    }
  public:
    virtual bool run(Module &M);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }
    virtual void print(std::ostream &O, Module *M) const {}

  };

  RegisterAnalysis<InstCount> X("instcount",
                                "Counts the various types of Instructions");
}

// InstCount::run - This is the main Analysis entry point for a
// function.
//
bool InstCount::run(Module &M) {
  visit(M);
  return false;
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
// Copyright 2008      Carlos Licea <carlos.licea@kdemail.net>
//

#include "TextureColorizer.h"

#include <cmath>

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtGui/QColor>
#include <QtGui/QImage>
#include <QtGui/QPainter>

#include "global.h"
#include "GeoSceneDocument.h"
#include "GeoSceneSettings.h"
#include "ViewParams.h"
#include "ViewportParams.h"
#include "AbstractProjection.h"
#include "MathHelper.h"

using namespace Marble;

uint TextureColorizer::texturepalette[16][512];

TextureColorizer::TextureColorizer( const QString& seafile,
                                    const QString& landfile )
{
   generatePalette(seafile, landfile);
}

QString TextureColorizer::seafile() const
{
    return m_seafile;
}

QString TextureColorizer::landfile() const
{
    return m_landfile;
}

// This function takes two images, both in viewParams:
//  - The coast image, which has a number of colors where each color
//    represents a sort of terrain (ex: land/sea)
//  - The canvas image, which has a gray scale image, often
//    representing a height field.
//
// It then uses the values of the pixels in the coast image to select
// a color map.  The value of the pixel in the canvas image is used as
// an index into the selected color map and the resulting color is
// written back to the canvas image.  This way we can have different
// color schemes for land and water.
//
// In addition to this, a simple form of bump mapping is performed to
// increase the illusion of height differences (see the variable
// showRelief).
//

void TextureColorizer::colorize(ViewParams *viewParams)
{
    QImage        *origimg  = viewParams->canvasImage();
    const QImage  *coastimg = viewParams->coastImage();
    const qint64   radius   = viewParams->radius();

    const int  imgheight = origimg->height();
    const int  imgwidth  = origimg->width();
    const int  imgrx     = imgwidth / 2;
    const int  imgry     = imgheight / 2;
    // This variable is not used anywhere..
    const int  imgradius = imgrx * imgrx + imgry * imgry;

    const uint landoffscreen = qRgb(255,0,0);
    // const uint seaoffscreen = qRgb(0,0,0);
    const uint lakeoffscreen = qRgb(0,0,0);
    // const uint glaciercolor = qRgb(200,200,200);

    int     bump = 8;
    GpFifo  emboss;
    emboss.buffer = 0;

    bool showRelief;
    viewParams->mapTheme()->settings()->propertyValue( "relief", showRelief );

    if ( radius * radius > imgradius
         || viewParams->projection() == Equirectangular
         || viewParams->projection() == Mercator )
    {
        int yTop = 0;
        int yBottom = imgheight;

        if( viewParams->projection() == Equirectangular
            || viewParams->projection() == Mercator )
        {
            // Calculate translation of center point
            double  centerLon;
            double  centerLat;
            viewParams->centerCoordinates( centerLon, centerLat );

            const float rad2Pixel = (double)( 2 * radius ) / M_PI;
            if ( viewParams->projection() == Equirectangular ) {
                int yCenterOffset = (int)( centerLat * rad2Pixel );
                yTop = ( imgry - radius + yCenterOffset < 0)? 0 : imgry - radius + yCenterOffset;
                yBottom = ( imgry + yCenterOffset + radius > imgheight )? imgheight : imgry + yCenterOffset + radius;
            }
            else if ( viewParams->projection() == Mercator ) {
                int yCenterOffset = (int)( asinh( tan( centerLat ) ) * rad2Pixel  );
                yTop = ( imgry - 2 * radius + yCenterOffset < 0 ) ? 0 : imgry - 2 * radius + yCenterOffset;
                yBottom = ( imgry + 2 * radius + yCenterOffset > imgheight )? imgheight : imgry + 2 * radius + yCenterOffset;
            }
        }

        for (int y = yTop; y < yBottom; ++y) {

            QRgb  *writeData         = (QRgb*)( origimg->scanLine( y ) );
            const QRgb  *coastData   = (QRgb*)( coastimg->scanLine( y ) );

            uchar *readDataStart     = origimg->scanLine( y );
            const uchar *readDataEnd = readDataStart + imgwidth*4;

            emboss.buffer = 0;

            for ( uchar* readData = readDataStart;
		  readData < readDataEnd;
		  readData += 4, ++writeData, ++coastData )
	    {

                // Cheap Emboss / Bumpmapping
                const uchar&  grey = *readData; // qBlue(*data);

                if ( showRelief ) {
                    emboss.gpuint.x4 = grey;
                    emboss.buffer = emboss.buffer >> 8;
                    bump = ( emboss.gpuint.x1 + 8 - grey );
                    if ( bump  < 0 )  bump = 0;
                    if ( bump  > 15 ) bump = 15;
                }

                int alpha = qRed( *coastData );
                if ( alpha == 255 || alpha == 0 ) {
                    if ( *coastData == landoffscreen )
                        *writeData = texturepalette[bump][grey + 0x100];
                    else {
                        if (*coastData == lakeoffscreen)
                            *writeData = texturepalette[bump][0x055];
                        else {
                            *writeData = texturepalette[bump][grey];
                        }
                    }
                }
                else {
                    double c = 1.0 / 255.0;

                    if ( qRed( *coastData ) != 0 && qGreen( *coastData ) == 0) {

                        QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                        QRgb watercolor = (QRgb)(texturepalette[bump][grey]);

                        *writeData = qRgb(
                            (int) ( c * ( alpha * qRed( landcolor )
                            + ( 255 - alpha ) * qRed( watercolor ) ) ),
                            (int) ( c * ( alpha * qGreen( landcolor )
                            + ( 255 - alpha ) * qGreen( watercolor ) ) ),
                            (int) ( c * ( alpha * qBlue( landcolor )
                            + ( 255 - alpha ) * qBlue( watercolor ) ) )
                        );
                    }
                    else {

                        if ( qGreen( *coastData ) != 0 ) {

                            QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                            QRgb glaciercolor = (QRgb)(texturepalette[bump][grey]);

                            *writeData = qRgb(
                                (int) ( c * ( alpha * qRed( glaciercolor )
                                + ( 255 - alpha ) * qRed( landcolor ) ) ),
                                (int) ( c * ( alpha * qGreen( glaciercolor )
                                + ( 255 - alpha ) * qGreen( landcolor ) ) ),
                                (int) ( c * ( alpha * qBlue( glaciercolor )
                                + ( 255 - alpha ) * qBlue( landcolor ) ) )
                            );
                        }
                    }
                }
            }
        }
    }
    else {
        int yTop    = ( imgry-radius < 0 ) ? 0 : imgry-radius;
        const int yBottom = ( yTop == 0 ) ? imgheight : imgry + radius;

        for ( int y = yTop; y < yBottom; ++y ) {
            const int  dy = imgry - y;
            int  rx = (int)sqrt( (double)( radius * radius - dy * dy ) );
            int  xLeft  = 0;
            int  xRight = imgwidth;

            if ( imgrx-rx > 0 ) {
                xLeft  = imgrx - rx;
                xRight = imgrx + rx;
            }

            QRgb  *writeData         = (QRgb*)( origimg->scanLine( y ) )  + xLeft;
            const QRgb *coastData    = (QRgb*)( coastimg->scanLine( y ) ) + xLeft;

            uchar *readDataStart     = origimg->scanLine( y ) + xLeft * 4;
            const uchar *readDataEnd = origimg->scanLine( y ) + xRight * 4;

            for ( uchar* readData = readDataStart;
		  readData < readDataEnd;
		  readData += 4, ++writeData, ++coastData )
	    {
                // Cheap Embosss / Bumpmapping

                const uchar& grey = *readData; // qBlue(*data);

                if ( showRelief == true ) {
                    emboss.buffer = emboss.buffer >> 8;
                    emboss.gpuint.x4 = grey;
                    bump = ( emboss.gpuint.x1 + 16 - grey ) >> 1;

                    if ( bump > 15 ) bump = 15;
                    if ( bump < 0 )  bump = 0;
                }

                int alpha = qRed( *coastData );
                if ( alpha == 255 || alpha == 0 ) {
                    if ( *coastData == landoffscreen )
                        *writeData = texturepalette[bump][grey + 0x100];
                    else {
                        if (*coastData == lakeoffscreen)
                            *writeData = texturepalette[bump][0x055];
                        else {
                            *writeData = texturepalette[bump][grey];
                        }
                    }
                }
                else {
                    double c = 1.0 / 255.0;

                    if ( qRed( *coastData ) != 0 && qGreen( *coastData ) == 0) {

                        QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                        QRgb watercolor = (QRgb)(texturepalette[bump][grey]);

                        *writeData = qRgb(
                            (int) ( c * ( alpha * qRed( landcolor )
                            + ( 255 - alpha ) * qRed( watercolor ) ) ),
                            (int) ( c * ( alpha * qGreen( landcolor )
                            + ( 255 - alpha ) * qGreen( watercolor ) ) ),
                            (int) ( c * ( alpha * qBlue( landcolor )
                            + ( 255 - alpha ) * qBlue( watercolor ) ) )
                        );
                    }
                    else {

                        if ( qGreen( *coastData ) != 0 ) {

                            QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                            QRgb glaciercolor = (QRgb)(texturepalette[bump][grey]);

                            *writeData = qRgb(
                                (int) ( c * ( alpha * qRed( glaciercolor )
                                + ( 255 - alpha ) * qRed( landcolor ) ) ),
                                (int) ( c * ( alpha * qGreen( glaciercolor )
                                + ( 255 - alpha ) * qGreen( landcolor ) ) ),
                                (int) ( c * ( alpha * qBlue( glaciercolor )
                                + ( 255 - alpha ) * qBlue( landcolor ) ) )
                            );
                        }
                    }
                }
            }
        }
    }
}

void TextureColorizer::generatePalette(const QString& seafile,
				       const QString& landfile)
{
    for(int i = 0; i < 16; i++) {
        for(int j = 0; j < 512; j++) {
            texturepalette[i][j] = 0;
        }
    }
    QImage   gradientImage ( 256, 10, QImage::Format_RGB32 );
    QPainter  gradientPainter;
    gradientPainter.begin( &gradientImage );
    gradientPainter.setPen( Qt::NoPen );

    QImage    shadingImage ( 256, 10, QImage::Format_RGB32 );
    QPainter  shadingPainter;
    shadingPainter.begin( &shadingImage );
    shadingPainter.setPen( Qt::NoPen );

    int offset = 0;

    QStringList  filelist;
    filelist << seafile << landfile;

    foreach ( const QString &filename, filelist ) {

        QLinearGradient  gradient( 0, 0, 256, 0 );

        QFile  file( filename );
        file.open( QIODevice::ReadOnly );
        QTextStream  stream( &file );  // read the data from the file
        QString      evalstrg;

        while ( !stream.atEnd() ) {
            stream >> evalstrg;
            if ( !evalstrg.isEmpty() && evalstrg.contains( "=" ) ) {
                QString  colorValue = evalstrg.section( "=", 0, 0 );
                QString  colorPosition = evalstrg.section( "=", 1, 1 );
                gradient.setColorAt( colorPosition.toDouble(),
				     QColor( colorValue ) );
            }
        }
        gradientPainter.setBrush( gradient );
        gradientPainter.drawRect( 0, 0, 256, 3 );

        for ( int j = 0; j < 16; ++j ) {

            int  shadeIndex = 120 + j;

            for ( int i = 0; i < 256; ++i ) {

                    QRgb  shadeColor = gradientImage.pixel( i, 1 );
                    QLinearGradient  shadeGradient( 0, 0, 256, 0 );
                    shadeGradient.setColorAt(0.15, QColor(Qt::white));
                    shadeGradient.setColorAt(0.496, shadeColor);
                    shadeGradient.setColorAt(0.504, shadeColor);
                    shadeGradient.setColorAt(0.75, QColor(Qt::black));
                    shadingPainter.setBrush( shadeGradient );
                    shadingPainter.drawRect( 0, 0, 256, 3 );
                    QRgb  paletteColor = shadingImage.pixel( shadeIndex, 1 );

                    // populate texturepalette[][]
                    texturepalette[j][offset + i] = (uint)paletteColor;
            }
        }
        offset += 256;
    }
    shadingPainter.end();  // Need to explicitely tell painter lifetime to avoid crash
    gradientPainter.end(); // on some systems.

    m_seafile = seafile;
    m_landfile = landfile;
}
<commit_msg>Fix Krazy Error: spelling<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
// Copyright 2008      Carlos Licea <carlos.licea@kdemail.net>
//

#include "TextureColorizer.h"

#include <cmath>

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtGui/QColor>
#include <QtGui/QImage>
#include <QtGui/QPainter>

#include "global.h"
#include "GeoSceneDocument.h"
#include "GeoSceneSettings.h"
#include "ViewParams.h"
#include "ViewportParams.h"
#include "AbstractProjection.h"
#include "MathHelper.h"

using namespace Marble;

uint TextureColorizer::texturepalette[16][512];

TextureColorizer::TextureColorizer( const QString& seafile,
                                    const QString& landfile )
{
   generatePalette(seafile, landfile);
}

QString TextureColorizer::seafile() const
{
    return m_seafile;
}

QString TextureColorizer::landfile() const
{
    return m_landfile;
}

// This function takes two images, both in viewParams:
//  - The coast image, which has a number of colors where each color
//    represents a sort of terrain (ex: land/sea)
//  - The canvas image, which has a gray scale image, often
//    representing a height field.
//
// It then uses the values of the pixels in the coast image to select
// a color map.  The value of the pixel in the canvas image is used as
// an index into the selected color map and the resulting color is
// written back to the canvas image.  This way we can have different
// color schemes for land and water.
//
// In addition to this, a simple form of bump mapping is performed to
// increase the illusion of height differences (see the variable
// showRelief).
//

void TextureColorizer::colorize(ViewParams *viewParams)
{
    QImage        *origimg  = viewParams->canvasImage();
    const QImage  *coastimg = viewParams->coastImage();
    const qint64   radius   = viewParams->radius();

    const int  imgheight = origimg->height();
    const int  imgwidth  = origimg->width();
    const int  imgrx     = imgwidth / 2;
    const int  imgry     = imgheight / 2;
    // This variable is not used anywhere..
    const int  imgradius = imgrx * imgrx + imgry * imgry;

    const uint landoffscreen = qRgb(255,0,0);
    // const uint seaoffscreen = qRgb(0,0,0);
    const uint lakeoffscreen = qRgb(0,0,0);
    // const uint glaciercolor = qRgb(200,200,200);

    int     bump = 8;
    GpFifo  emboss;
    emboss.buffer = 0;

    bool showRelief;
    viewParams->mapTheme()->settings()->propertyValue( "relief", showRelief );

    if ( radius * radius > imgradius
         || viewParams->projection() == Equirectangular
         || viewParams->projection() == Mercator )
    {
        int yTop = 0;
        int yBottom = imgheight;

        if( viewParams->projection() == Equirectangular
            || viewParams->projection() == Mercator )
        {
            // Calculate translation of center point
            double  centerLon;
            double  centerLat;
            viewParams->centerCoordinates( centerLon, centerLat );

            const float rad2Pixel = (double)( 2 * radius ) / M_PI;
            if ( viewParams->projection() == Equirectangular ) {
                int yCenterOffset = (int)( centerLat * rad2Pixel );
                yTop = ( imgry - radius + yCenterOffset < 0)? 0 : imgry - radius + yCenterOffset;
                yBottom = ( imgry + yCenterOffset + radius > imgheight )? imgheight : imgry + yCenterOffset + radius;
            }
            else if ( viewParams->projection() == Mercator ) {
                int yCenterOffset = (int)( asinh( tan( centerLat ) ) * rad2Pixel  );
                yTop = ( imgry - 2 * radius + yCenterOffset < 0 ) ? 0 : imgry - 2 * radius + yCenterOffset;
                yBottom = ( imgry + 2 * radius + yCenterOffset > imgheight )? imgheight : imgry + 2 * radius + yCenterOffset;
            }
        }

        for (int y = yTop; y < yBottom; ++y) {

            QRgb  *writeData         = (QRgb*)( origimg->scanLine( y ) );
            const QRgb  *coastData   = (QRgb*)( coastimg->scanLine( y ) );

            uchar *readDataStart     = origimg->scanLine( y );
            const uchar *readDataEnd = readDataStart + imgwidth*4;

            emboss.buffer = 0;

            for ( uchar* readData = readDataStart;
		  readData < readDataEnd;
		  readData += 4, ++writeData, ++coastData )
	    {

                // Cheap Emboss / Bumpmapping
                const uchar&  grey = *readData; // qBlue(*data);

                if ( showRelief ) {
                    emboss.gpuint.x4 = grey;
                    emboss.buffer = emboss.buffer >> 8;
                    bump = ( emboss.gpuint.x1 + 8 - grey );
                    if ( bump  < 0 )  bump = 0;
                    if ( bump  > 15 ) bump = 15;
                }

                int alpha = qRed( *coastData );
                if ( alpha == 255 || alpha == 0 ) {
                    if ( *coastData == landoffscreen )
                        *writeData = texturepalette[bump][grey + 0x100];
                    else {
                        if (*coastData == lakeoffscreen)
                            *writeData = texturepalette[bump][0x055];
                        else {
                            *writeData = texturepalette[bump][grey];
                        }
                    }
                }
                else {
                    double c = 1.0 / 255.0;

                    if ( qRed( *coastData ) != 0 && qGreen( *coastData ) == 0) {

                        QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                        QRgb watercolor = (QRgb)(texturepalette[bump][grey]);

                        *writeData = qRgb(
                            (int) ( c * ( alpha * qRed( landcolor )
                            + ( 255 - alpha ) * qRed( watercolor ) ) ),
                            (int) ( c * ( alpha * qGreen( landcolor )
                            + ( 255 - alpha ) * qGreen( watercolor ) ) ),
                            (int) ( c * ( alpha * qBlue( landcolor )
                            + ( 255 - alpha ) * qBlue( watercolor ) ) )
                        );
                    }
                    else {

                        if ( qGreen( *coastData ) != 0 ) {

                            QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                            QRgb glaciercolor = (QRgb)(texturepalette[bump][grey]);

                            *writeData = qRgb(
                                (int) ( c * ( alpha * qRed( glaciercolor )
                                + ( 255 - alpha ) * qRed( landcolor ) ) ),
                                (int) ( c * ( alpha * qGreen( glaciercolor )
                                + ( 255 - alpha ) * qGreen( landcolor ) ) ),
                                (int) ( c * ( alpha * qBlue( glaciercolor )
                                + ( 255 - alpha ) * qBlue( landcolor ) ) )
                            );
                        }
                    }
                }
            }
        }
    }
    else {
        int yTop    = ( imgry-radius < 0 ) ? 0 : imgry-radius;
        const int yBottom = ( yTop == 0 ) ? imgheight : imgry + radius;

        for ( int y = yTop; y < yBottom; ++y ) {
            const int  dy = imgry - y;
            int  rx = (int)sqrt( (double)( radius * radius - dy * dy ) );
            int  xLeft  = 0;
            int  xRight = imgwidth;

            if ( imgrx-rx > 0 ) {
                xLeft  = imgrx - rx;
                xRight = imgrx + rx;
            }

            QRgb  *writeData         = (QRgb*)( origimg->scanLine( y ) )  + xLeft;
            const QRgb *coastData    = (QRgb*)( coastimg->scanLine( y ) ) + xLeft;

            uchar *readDataStart     = origimg->scanLine( y ) + xLeft * 4;
            const uchar *readDataEnd = origimg->scanLine( y ) + xRight * 4;

            for ( uchar* readData = readDataStart;
		  readData < readDataEnd;
		  readData += 4, ++writeData, ++coastData )
	    {
                // Cheap Embosss / Bumpmapping

                const uchar& grey = *readData; // qBlue(*data);

                if ( showRelief == true ) {
                    emboss.buffer = emboss.buffer >> 8;
                    emboss.gpuint.x4 = grey;
                    bump = ( emboss.gpuint.x1 + 16 - grey ) >> 1;

                    if ( bump > 15 ) bump = 15;
                    if ( bump < 0 )  bump = 0;
                }

                int alpha = qRed( *coastData );
                if ( alpha == 255 || alpha == 0 ) {
                    if ( *coastData == landoffscreen )
                        *writeData = texturepalette[bump][grey + 0x100];
                    else {
                        if (*coastData == lakeoffscreen)
                            *writeData = texturepalette[bump][0x055];
                        else {
                            *writeData = texturepalette[bump][grey];
                        }
                    }
                }
                else {
                    double c = 1.0 / 255.0;

                    if ( qRed( *coastData ) != 0 && qGreen( *coastData ) == 0) {

                        QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                        QRgb watercolor = (QRgb)(texturepalette[bump][grey]);

                        *writeData = qRgb(
                            (int) ( c * ( alpha * qRed( landcolor )
                            + ( 255 - alpha ) * qRed( watercolor ) ) ),
                            (int) ( c * ( alpha * qGreen( landcolor )
                            + ( 255 - alpha ) * qGreen( watercolor ) ) ),
                            (int) ( c * ( alpha * qBlue( landcolor )
                            + ( 255 - alpha ) * qBlue( watercolor ) ) )
                        );
                    }
                    else {

                        if ( qGreen( *coastData ) != 0 ) {

                            QRgb landcolor  = (QRgb)(texturepalette[bump][grey + 0x100]);
                            QRgb glaciercolor = (QRgb)(texturepalette[bump][grey]);

                            *writeData = qRgb(
                                (int) ( c * ( alpha * qRed( glaciercolor )
                                + ( 255 - alpha ) * qRed( landcolor ) ) ),
                                (int) ( c * ( alpha * qGreen( glaciercolor )
                                + ( 255 - alpha ) * qGreen( landcolor ) ) ),
                                (int) ( c * ( alpha * qBlue( glaciercolor )
                                + ( 255 - alpha ) * qBlue( landcolor ) ) )
                            );
                        }
                    }
                }
            }
        }
    }
}

void TextureColorizer::generatePalette(const QString& seafile,
				       const QString& landfile)
{
    for(int i = 0; i < 16; i++) {
        for(int j = 0; j < 512; j++) {
            texturepalette[i][j] = 0;
        }
    }
    QImage   gradientImage ( 256, 10, QImage::Format_RGB32 );
    QPainter  gradientPainter;
    gradientPainter.begin( &gradientImage );
    gradientPainter.setPen( Qt::NoPen );

    QImage    shadingImage ( 256, 10, QImage::Format_RGB32 );
    QPainter  shadingPainter;
    shadingPainter.begin( &shadingImage );
    shadingPainter.setPen( Qt::NoPen );

    int offset = 0;

    QStringList  filelist;
    filelist << seafile << landfile;

    foreach ( const QString &filename, filelist ) {

        QLinearGradient  gradient( 0, 0, 256, 0 );

        QFile  file( filename );
        file.open( QIODevice::ReadOnly );
        QTextStream  stream( &file );  // read the data from the file
        QString      evalstrg;

        while ( !stream.atEnd() ) {
            stream >> evalstrg;
            if ( !evalstrg.isEmpty() && evalstrg.contains( "=" ) ) {
                QString  colorValue = evalstrg.section( "=", 0, 0 );
                QString  colorPosition = evalstrg.section( "=", 1, 1 );
                gradient.setColorAt( colorPosition.toDouble(),
				     QColor( colorValue ) );
            }
        }
        gradientPainter.setBrush( gradient );
        gradientPainter.drawRect( 0, 0, 256, 3 );

        for ( int j = 0; j < 16; ++j ) {

            int  shadeIndex = 120 + j;

            for ( int i = 0; i < 256; ++i ) {

                    QRgb  shadeColor = gradientImage.pixel( i, 1 );
                    QLinearGradient  shadeGradient( 0, 0, 256, 0 );
                    shadeGradient.setColorAt(0.15, QColor(Qt::white));
                    shadeGradient.setColorAt(0.496, shadeColor);
                    shadeGradient.setColorAt(0.504, shadeColor);
                    shadeGradient.setColorAt(0.75, QColor(Qt::black));
                    shadingPainter.setBrush( shadeGradient );
                    shadingPainter.drawRect( 0, 0, 256, 3 );
                    QRgb  paletteColor = shadingImage.pixel( shadeIndex, 1 );

                    // populate texturepalette[][]
                    texturepalette[j][offset + i] = (uint)paletteColor;
            }
        }
        offset += 256;
    }
    shadingPainter.end();  // Need to explicitly tell painter lifetime to avoid crash
    gradientPainter.end(); // on some systems.

    m_seafile = seafile;
    m_landfile = landfile;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkCenteredEuler3DTransformTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>

#include "itkCenteredEuler3DTransform.h"
#include "vnl/vnl_vector_fixed.h"
#include "itkVector.h"

int itkCenteredEuler3DTransformTest(int,char *[] )
{

  std::cout << "==================================" << std::endl;
  std::cout << "Testing Centered Euler Angles 3D Transform" << std::endl << std::endl;

  const double epsilon = 1e-10;
  const unsigned int N = 3;
  bool Ok = true;

  typedef itk::CenteredEuler3DTransform<double>  EulerTransformType;
  EulerTransformType::Pointer eulerTransform = EulerTransformType::New();

  // Testing Identity
  std::cout << "Testing identity transform: ";
  eulerTransform->SetIdentity();

  EulerTransformType::OffsetType offset = eulerTransform->GetOffset();
  if( offset[0] != 0.0
     || offset[1] != 0.0
     || offset[2] != 0.0
    )
  {
     std::cout << "[ FAILED ]" << std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "[ PASSED ]" << std::endl;

  // 15 degrees in radians
  const double angleX = 15.0 * atan( 1.0f ) / 45.0;
  const double cx = cos(angleX);
  const double sx = sin(angleX);

  // 10 degrees in radians
  const double angleY = 10.0 * atan( 1.0f ) / 45.0;
  const double cy = cos(angleY);
  const double sy = sin(angleY);

  // 5 degrees in radians
  const double angleZ = 5.0 * atan( 1.0f ) / 45.0;
  const double cz = cos(angleZ);
  const double sz = sin(angleZ);

  std::cout << "Testing Rotation:";
  eulerTransform->SetRotation(angleX,angleY,angleZ);

  // Rotate an itk::Point
  EulerTransformType::InputPointType::ValueType pInit[3] = {10,-5,3};
  EulerTransformType::InputPointType p = pInit;
  EulerTransformType::InputPointType q;

  itk::Matrix<double,3,3> RotationX;
  RotationX[0][0]=1;RotationX[0][1]=0;RotationX[0][2]=0;
  RotationX[1][0]=0;RotationX[1][1]=cx;RotationX[1][2]=-sx;
  RotationX[2][0]=0;RotationX[2][1]=sx;RotationX[2][2]=cx;

  itk::Matrix<double,3,3> RotationY;
  RotationY[0][0]=cy;RotationY[0][1]=0;RotationY[0][2]=sy;
  RotationY[1][0]=0;RotationY[1][1]=1;RotationY[1][2]=0;
  RotationY[2][0]=-sy;RotationY[2][1]=0;RotationY[2][2]=cy;

  itk::Matrix<double,3,3> RotationZ;
  RotationZ[0][0]=cz;RotationZ[0][1]=-sz;RotationZ[0][2]=0;
  RotationZ[1][0]=sz;RotationZ[1][1]=cz;RotationZ[1][2]=0;
  RotationZ[2][0]=0;RotationZ[2][1]=0;RotationZ[2][2]=1;

  q = RotationZ*RotationX*RotationY*p; // standard transformation

  EulerTransformType::OutputPointType r;
  r = eulerTransform->TransformPoint( p );
  for(unsigned int i=0; i<N; i++)
  {
     if( fabs( q[i]- r[i] ) > epsilon )
     {
        Ok = false;
        break;
     }
  }
  if( !Ok )
  {
    std::cerr << "Error rotating point   : " << p << std::endl;
    std::cerr << "Result should be       : " << q << std::endl;
    std::cerr << "Reported Result is     : " << r << std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout << " [ PASSED ] " << std::endl;
  }

  std::cout << "Testing Translation:";

  eulerTransform->SetRotation(0,0,0);

  EulerTransformType::OffsetType::ValueType ioffsetInit[3] = {1,-4,8};
  EulerTransformType::OffsetType ioffset = ioffsetInit;

  eulerTransform->SetOffset( ioffset );
  std::cout << "eulerTransform: " << eulerTransform;

  q = p + ioffset;

  r = eulerTransform->TransformPoint( p );
  for(unsigned int i=0; i<N; i++)
  {
    if( fabs( q[i]- r[i] ) > epsilon )
    {
      Ok = false;
      break;
    }
  }
  if( !Ok )
  {
    std::cerr << "Error translating point: " << p << std::endl;
    std::cerr << "Result should be       : " << q << std::endl;
    std::cerr << "Reported Result is     : " << r << std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout << " [ PASSED ] " << std::endl;
  }

   // Testing Parameters
  std::cout << "Testing Set/Get Parameters: " ;
  EulerTransformType::ParametersType parameters(6);
  for(unsigned int i=0;i<6;i++)
  {
    parameters[i]=i;
  }

  eulerTransform->SetParameters(parameters);
  EulerTransformType::ParametersType parameters_result = eulerTransform->GetParameters();

  if( parameters_result[0] != 0.0
      || parameters_result[1] != 1.0
      || parameters_result[2] != 2.0
      || parameters_result[3] != 3.0
      || parameters_result[4] != 4.0
      || parameters_result[5] != 5.0
    )
  {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << " [ PASSED ] " << std::endl;

  // Testing Jacobian
  std::cout << "Testing Jacobian: ";
  for(unsigned int i=0;i<3;i++)
  {
    pInit[i]=0;
  }

  EulerTransformType::JacobianType  jacobian = eulerTransform->GetJacobian(pInit);

  if( jacobian[0][0] != 0.0 || jacobian[0][1] != 0.0
      || jacobian[0][2] != 0.0 ||jacobian[0][3] != 1.0
      || jacobian[0][4] != 0.0 ||jacobian[0][5] != 0.0
      || jacobian[1][0] != 0.0 || jacobian[1][1] != 0.0
      || jacobian[1][2] != 0.0 ||jacobian[1][3] != 0.0
      || jacobian[1][4] != 1.0 ||jacobian[1][5] != 0.0
      || jacobian[2][0] != 0.0 || jacobian[2][1] != 0.0
      || jacobian[2][2] != 0.0 ||jacobian[2][3] != 0.0
      || jacobian[2][4] != 0.0 ||jacobian[2][5] != 1.0
    )
  {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << " [ PASSED ] " << std::endl;

  // Really test the Jacobian
  for( unsigned int p = 0; p < 2; p++ )
    {
    std::cout << "Testing Jacobian when ComputeZYX is ";
    if ( p == 0 )
      {
      std::cout << "true" << std::endl;
      eulerTransform->SetComputeZYX( true );
      }
    else
      {
      std::cout << "false" << std::endl;
      eulerTransform->SetComputeZYX( false );
      }

    parameters.Fill( 0.0 );
    parameters[0] = 0.2 / 180.0 * vnl_math::pi;
    parameters[1] = -1.0 / 180.0 * vnl_math::pi;
    parameters[2] = 2.4 / 180.0 * vnl_math::pi;
    parameters[3] = 5.0;
    parameters[4] = 6.0;
    parameters[5] = 8.0;

    eulerTransform->SetParameters( parameters );

    pInit[0] = 1.0;
    pInit[1] = 1.5;
    pInit[2] = 2.6;

    jacobian = eulerTransform->GetJacobian( pInit );
    std::cout << jacobian << std::endl;

    EulerTransformType::JacobianType approxJacobian = jacobian;

    for( unsigned int k = 0; k < eulerTransform->GetNumberOfParameters(); k++ )
      {
      const double delta = 0.001;
      EulerTransformType::ParametersType plusParameters;
      EulerTransformType::ParametersType minusParameters;

      plusParameters = parameters;
      minusParameters = parameters;
      plusParameters[k] += delta;
      minusParameters[k] -= delta;

      EulerTransformType::OutputPointType plusPoint;
      EulerTransformType::OutputPointType minusPoint;

      eulerTransform->SetParameters( plusParameters );
      plusPoint = eulerTransform->TransformPoint( pInit );
      eulerTransform->SetParameters( minusParameters );
      minusPoint = eulerTransform->TransformPoint( pInit );

      for( unsigned int j = 0; j < 3; j++ )
        {
        double approxDerivative = ( plusPoint[j] - minusPoint[j] ) / ( 2.0 * delta );
        double computedDerivative = jacobian[j][k];
        approxJacobian[j][k] = approxDerivative;
        if ( vnl_math_abs( approxDerivative - computedDerivative ) > 1e-5 )
          {
          std::cerr << "Error computing Jacobian [" << j << "][" << k << "]" << std::endl;
          std::cerr << "Result should be: " << approxDerivative << std::endl;
          std::cerr << "Reported result is: " << computedDerivative << std::endl;
          std::cerr << " [ FAILED ] " << std::endl;
          return EXIT_FAILURE;
          }
        }
      }

    std::cout << approxJacobian << std::endl;
    std::cout << " [ PASSED ] " << std::endl;

  }

  std::cout << "Testing Angle from matrix : ";
  eulerTransform->SetIdentity();

  eulerTransform->SetRotation(0.2,0.1,0.3);

  EulerTransformType::Pointer t2 = EulerTransformType::New();
  t2->SetIdentity();
  t2->Compose(eulerTransform);
  if( (fabs(t2->GetParameters()[0]-0.2)>0.0001)
    || (fabs(t2->GetParameters()[1]-0.1)>0.0001)
    || (fabs(t2->GetParameters()[2]-0.3)>0.0001)
    )
    {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << " [ PASSED ] " << std::endl;

  std::cout << "Testing Angle from matrix (ZYX) : ";
  eulerTransform->SetIdentity();
  eulerTransform->SetComputeZYX(true);
  eulerTransform->SetRotation(0.2,0.1,0.3);

  t2->SetIdentity();
  t2->SetComputeZYX(true);
  t2->Compose(eulerTransform);

  if( (fabs(t2->GetParameters()[0]-0.2)>0.0001)
    || (fabs(t2->GetParameters()[1]-0.1)>0.0001)
    || (fabs(t2->GetParameters()[2]-0.3)>0.0001)
    )
    {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << " [ PASSED ] " << std::endl;

  EulerTransformType::Pointer t3 = EulerTransformType::New();

  t2->GetInverse( t3 );

  return EXIT_SUCCESS;

}
<commit_msg>STYLE: added a non-zero center to verify the correct computation of the Jacobian. (BUG #1257).<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkCenteredEuler3DTransformTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>

#include "itkCenteredEuler3DTransform.h"
#include "vnl/vnl_vector_fixed.h"
#include "itkVector.h"

int itkCenteredEuler3DTransformTest(int,char *[] )
{

  std::cout << "==================================" << std::endl;
  std::cout << "Testing Centered Euler Angles 3D Transform" << std::endl << std::endl;

  const double epsilon = 1e-10;
  const unsigned int N = 3;
  bool Ok = true;

  typedef itk::CenteredEuler3DTransform<double>  EulerTransformType;
  EulerTransformType::Pointer eulerTransform = EulerTransformType::New();

  // Testing Identity
  std::cout << "Testing identity transform: ";
  eulerTransform->SetIdentity();

  EulerTransformType::OffsetType offset = eulerTransform->GetOffset();
  if( offset[0] != 0.0
     || offset[1] != 0.0
     || offset[2] != 0.0
    )
  {
     std::cout << "[ FAILED ]" << std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "[ PASSED ]" << std::endl;

  // 15 degrees in radians
  const double angleX = 15.0 * atan( 1.0f ) / 45.0;
  const double cx = cos(angleX);
  const double sx = sin(angleX);

  // 10 degrees in radians
  const double angleY = 10.0 * atan( 1.0f ) / 45.0;
  const double cy = cos(angleY);
  const double sy = sin(angleY);

  // 5 degrees in radians
  const double angleZ = 5.0 * atan( 1.0f ) / 45.0;
  const double cz = cos(angleZ);
  const double sz = sin(angleZ);

  std::cout << "Testing Rotation:";
  eulerTransform->SetRotation(angleX,angleY,angleZ);

  // Rotate an itk::Point
  EulerTransformType::InputPointType::ValueType pInit[3] = {10,-5,3};
  EulerTransformType::InputPointType p = pInit;
  EulerTransformType::InputPointType q;

  itk::Matrix<double,3,3> RotationX;
  RotationX[0][0]=1;RotationX[0][1]=0;RotationX[0][2]=0;
  RotationX[1][0]=0;RotationX[1][1]=cx;RotationX[1][2]=-sx;
  RotationX[2][0]=0;RotationX[2][1]=sx;RotationX[2][2]=cx;

  itk::Matrix<double,3,3> RotationY;
  RotationY[0][0]=cy;RotationY[0][1]=0;RotationY[0][2]=sy;
  RotationY[1][0]=0;RotationY[1][1]=1;RotationY[1][2]=0;
  RotationY[2][0]=-sy;RotationY[2][1]=0;RotationY[2][2]=cy;

  itk::Matrix<double,3,3> RotationZ;
  RotationZ[0][0]=cz;RotationZ[0][1]=-sz;RotationZ[0][2]=0;
  RotationZ[1][0]=sz;RotationZ[1][1]=cz;RotationZ[1][2]=0;
  RotationZ[2][0]=0;RotationZ[2][1]=0;RotationZ[2][2]=1;

  q = RotationZ*RotationX*RotationY*p; // standard transformation

  EulerTransformType::OutputPointType r;
  r = eulerTransform->TransformPoint( p );
  for(unsigned int i=0; i<N; i++)
  {
     if( fabs( q[i]- r[i] ) > epsilon )
     {
        Ok = false;
        break;
     }
  }
  if( !Ok )
  {
    std::cerr << "Error rotating point   : " << p << std::endl;
    std::cerr << "Result should be       : " << q << std::endl;
    std::cerr << "Reported Result is     : " << r << std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout << " [ PASSED ] " << std::endl;
  }

  std::cout << "Testing Translation:";

  eulerTransform->SetRotation(0,0,0);

  EulerTransformType::OffsetType::ValueType ioffsetInit[3] = {1,-4,8};
  EulerTransformType::OffsetType ioffset = ioffsetInit;

  eulerTransform->SetOffset( ioffset );
  std::cout << "eulerTransform: " << eulerTransform;

  q = p + ioffset;

  r = eulerTransform->TransformPoint( p );
  for(unsigned int i=0; i<N; i++)
  {
    if( fabs( q[i]- r[i] ) > epsilon )
    {
      Ok = false;
      break;
    }
  }
  if( !Ok )
  {
    std::cerr << "Error translating point: " << p << std::endl;
    std::cerr << "Result should be       : " << q << std::endl;
    std::cerr << "Reported Result is     : " << r << std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout << " [ PASSED ] " << std::endl;
  }

   // Testing Parameters
  std::cout << "Testing Set/Get Parameters: " ;
  EulerTransformType::ParametersType parameters(6);
  for(unsigned int i=0;i<6;i++)
  {
    parameters[i]=i;
  }

  eulerTransform->SetParameters(parameters);
  EulerTransformType::ParametersType parameters_result = eulerTransform->GetParameters();

  if( parameters_result[0] != 0.0
      || parameters_result[1] != 1.0
      || parameters_result[2] != 2.0
      || parameters_result[3] != 3.0
      || parameters_result[4] != 4.0
      || parameters_result[5] != 5.0
    )
  {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << " [ PASSED ] " << std::endl;

  // Testing Jacobian
  std::cout << "Testing Jacobian: ";
  for(unsigned int i=0;i<3;i++)
  {
    pInit[i]=0;
  }

  EulerTransformType::JacobianType  jacobian = eulerTransform->GetJacobian(pInit);

  if( jacobian[0][0] != 0.0 || jacobian[0][1] != 0.0
      || jacobian[0][2] != 0.0 ||jacobian[0][3] != 1.0
      || jacobian[0][4] != 0.0 ||jacobian[0][5] != 0.0
      || jacobian[1][0] != 0.0 || jacobian[1][1] != 0.0
      || jacobian[1][2] != 0.0 ||jacobian[1][3] != 0.0
      || jacobian[1][4] != 1.0 ||jacobian[1][5] != 0.0
      || jacobian[2][0] != 0.0 || jacobian[2][1] != 0.0
      || jacobian[2][2] != 0.0 ||jacobian[2][3] != 0.0
      || jacobian[2][4] != 0.0 ||jacobian[2][5] != 1.0
    )
  {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << " [ PASSED ] " << std::endl;

  // Really test the Jacobian
  EulerTransformType::InputPointType center;
  center[0] = 0.2;
  center[1] = 7.0;
  center[2] = 4.0;
  eulerTransform->SetCenter( center );

  eulerTransform->Print( std::cout );

  for( unsigned int p = 0; p < 2; p++ )
    {
    std::cout << "Testing Jacobian when ComputeZYX is ";
    if ( p == 0 )
      {
      std::cout << "true" << std::endl;
      eulerTransform->SetComputeZYX( true );
      }
    else
      {
      std::cout << "false" << std::endl;
      eulerTransform->SetComputeZYX( false );
      }

    parameters.Fill( 0.0 );
    parameters[0] = 0.2 / 180.0 * vnl_math::pi;
    parameters[1] = -1.0 / 180.0 * vnl_math::pi;
    parameters[2] = 2.4 / 180.0 * vnl_math::pi;
    parameters[3] = 5.0;
    parameters[4] = 6.0;
    parameters[5] = 8.0;

    eulerTransform->SetParameters( parameters );

    pInit[0] = 1.0;
    pInit[1] = 1.5;
    pInit[2] = 2.6;

    jacobian = eulerTransform->GetJacobian( pInit );
    std::cout << jacobian << std::endl;

    EulerTransformType::JacobianType approxJacobian = jacobian;

    for( unsigned int k = 0; k < eulerTransform->GetNumberOfParameters(); k++ )
      {
      const double delta = 0.001;
      EulerTransformType::ParametersType plusParameters;
      EulerTransformType::ParametersType minusParameters;

      plusParameters = parameters;
      minusParameters = parameters;
      plusParameters[k] += delta;
      minusParameters[k] -= delta;

      EulerTransformType::OutputPointType plusPoint;
      EulerTransformType::OutputPointType minusPoint;

      eulerTransform->SetParameters( plusParameters );
      plusPoint = eulerTransform->TransformPoint( pInit );
      eulerTransform->SetParameters( minusParameters );
      minusPoint = eulerTransform->TransformPoint( pInit );

      for( unsigned int j = 0; j < 3; j++ )
        {
        double approxDerivative = ( plusPoint[j] - minusPoint[j] ) / ( 2.0 * delta );
        double computedDerivative = jacobian[j][k];
        approxJacobian[j][k] = approxDerivative;
        if ( vnl_math_abs( approxDerivative - computedDerivative ) > 1e-5 )
          {
          std::cerr << "Error computing Jacobian [" << j << "][" << k << "]" << std::endl;
          std::cerr << "Result should be: " << approxDerivative << std::endl;
          std::cerr << "Reported result is: " << computedDerivative << std::endl;
          std::cerr << " [ FAILED ] " << std::endl;
          return EXIT_FAILURE;
          }
        }
      }

    std::cout << approxJacobian << std::endl;
    std::cout << " [ PASSED ] " << std::endl;

  }

  std::cout << "Testing Angle from matrix : ";
  eulerTransform->SetIdentity();

  eulerTransform->SetRotation(0.2,0.1,0.3);

  EulerTransformType::Pointer t2 = EulerTransformType::New();
  t2->SetIdentity();
  t2->Compose(eulerTransform);
  if( (fabs(t2->GetParameters()[0]-0.2)>0.0001)
    || (fabs(t2->GetParameters()[1]-0.1)>0.0001)
    || (fabs(t2->GetParameters()[2]-0.3)>0.0001)
    )
    {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << " [ PASSED ] " << std::endl;

  std::cout << "Testing Angle from matrix (ZYX) : ";
  eulerTransform->SetIdentity();
  eulerTransform->SetComputeZYX(true);
  eulerTransform->SetRotation(0.2,0.1,0.3);

  t2->SetIdentity();
  t2->SetComputeZYX(true);
  t2->Compose(eulerTransform);

  if( (fabs(t2->GetParameters()[0]-0.2)>0.0001)
    || (fabs(t2->GetParameters()[1]-0.1)>0.0001)
    || (fabs(t2->GetParameters()[2]-0.3)>0.0001)
    )
    {
    std::cout << " [ FAILED ] " << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << " [ PASSED ] " << std::endl;

  EulerTransformType::Pointer t3 = EulerTransformType::New();

  t2->GetInverse( t3 );

  return EXIT_SUCCESS;

}
<|endoftext|>