<commit_before>#include "musicsongsearchonlinewidget.h"
#include "musictextdownloadthread.h"
#include "musicdatadownloadthread.h"
#include "musicdata2downloadthread.h"
#include "musicsongdownloadthread.h"
#include "musicbgthemedownload.h"
#include "musicnetworkthread.h"
#include "musicmydownloadrecordobject.h"
#include "musiclocalsongsearchrecordobject.h"
#include "musicmessagebox.h"
#include "musicconnectionpool.h"

#include <QDateTime>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QButtonGroup>
#include <QMediaPlayer>

MusicSongSearchOnlineTableWidget::MusicSongSearchOnlineTableWidget(QWidget *parent)
    : MusicQueryTableWidget(parent), m_audition(NULL)
{
    setColumnCount(6);
    QHeaderView *headerview = horizontalHeader();
    headerview->resizeSection(0,30);
    headerview->resizeSection(1,215);
    headerview->resizeSection(2,166);
    headerview->resizeSection(3,50);
    headerview->resizeSection(4,26);
    headerview->resizeSection(5,26);
    setTransparent(255);

    m_previousAuditionRow = -1;
    M_Connection->setValue("MusicSongSearchOnlineTableWidget", this);
}

MusicSongSearchOnlineTableWidget::~MusicSongSearchOnlineTableWidget()
{
    delete m_audition;
    clearAllItems();
}

void MusicSongSearchOnlineTableWidget::startSearchQuery(const QString &text)
{
    ////////////////////////////////////////////////
    MusicSearchRecord record;
    MusicLocalSongSearchRecordObject search(this);
    if(!search.readSearchXMLConfig())
    {
        return;
    }
    search.readSearchConfig( record );
    record.m_names.insert(0, text);
    record.m_times.insert(0, QString::number(QDateTime::currentMSecsSinceEpoch()));
    search.writeSearchConfig( record );
    ////////////////////////////////////////////////
    QString currentQuality;
    emit getQualityString(currentQuality);
    if(!currentQuality.isEmpty())
    {
        m_downLoadManager->setSearchQuality(currentQuality);
    }
    m_downLoadManager->startSearchSong(MusicQuery, m_searchText = text);
}

void MusicSongSearchOnlineTableWidget::researchQueryByQuality()
{
    startSearchQuery(m_searchText);
}

void MusicSongSearchOnlineTableWidget::clearAllItems()
{
    MusicAbstractTableWidget::clear();
    setColumnCount(6);
}

void MusicSongSearchOnlineTableWidget::creatSearchedItems(const QString &songname,
                               const QString &artistname, const QString &time)
{
    int count;
    setRowCount(count = m_downLoadManager->getSongIdIndex());

    QTableWidgetItem *item = new QTableWidgetItem;
    item->setData(Qt::DisplayRole, false);
    item->setData(AUDITION_ROLE, AUDITION_STOP);
    setItem(count - 1, 0, item);

                      item = new QTableWidgetItem(songname);
    item->setTextColor(QColor(50,50,50));
    item->setTextAlignment(Qt::AlignCenter);
    item->setToolTip(songname);
    setItem(count - 1, 1, item);

                      item = new QTableWidgetItem(artistname);
    item->setTextColor(QColor(50,50,50));
    item->setTextAlignment(Qt::AlignCenter);
    item->setToolTip(artistname);
    setItem(count - 1, 2, item);

                      item = new QTableWidgetItem(time);
    item->setTextColor(QColor(50,50,50));
    item->setTextAlignment(Qt::AlignCenter);
    setItem(count - 1, 3, item);

                      item = new QTableWidgetItem(QIcon(QString::fromUtf8(":/image/addtoplaylist")),"");
    item->setTextAlignment(Qt::AlignCenter);
    setItem(count - 1, 4, item);

                      item = new QTableWidgetItem(QIcon(QString::fromUtf8(":/share/musicdownload")),"");
    item->setTextAlignment(Qt::AlignCenter);
    setItem(count - 1, 5, item);
}

void MusicSongSearchOnlineTableWidget::listCellClicked(int row, int col)
{
    MusicQueryTableWidget::listCellClicked(row, col);
    switch(col)
    {
        case 4:
            addSearchMusicToPlayList(row);
            break;
        case 5:
            musicDownloadLocal(row);
            break;
        default:
            break;
    }
    emit auditionIsPlaying( item(row, 0)->data(AUDITION_ROLE).toInt() == AUDITION_STOP );
}

void MusicSongSearchOnlineTableWidget::contextMenuEvent(QContextMenuEvent *event)
{
    MusicQueryTableWidget::contextMenuEvent(event);
    QMenu rightClickMenu(this);
    createContextMenu(rightClickMenu);

    QAction *playAction = rightClickMenu.addAction(QIcon(":/contextMenu/play"), tr("musicPlay"));
    QAction *addAction = rightClickMenu.addAction(tr("musicAdd"));
    rightClickMenu.insertAction(rightClickMenu.actions().first(), addAction);
    rightClickMenu.insertAction(addAction, playAction);
    m_actionGroup->addAction( playAction );
    m_actionGroup->addAction( addAction );
    rightClickMenu.exec(QCursor::pos());
}

void MusicSongSearchOnlineTableWidget::actionGroupClick(QAction *action)
{
    MusicQueryTableWidget::actionGroupClick(action);
    int row = currentRow();
    switch( findActionGroup(action) )
    {
        case 4: auditionToMusic(row); break;
        case 5: addSearchMusicToPlayList(row); break;
    }
}

void MusicSongSearchOnlineTableWidget::auditionToMusic(int row)
{
    MStringLists musicSongInfo(m_downLoadManager->getMusicSongInfo());
    if(musicSongInfo.isEmpty() || row < 0)
    {
        return;
    }
    if(m_audition == NULL)
    {
        m_audition = new QMediaPlayer(this);
    }
    m_audition->setMedia(QUrl(musicSongInfo[row][0]));
    m_audition->play();
    if(m_previousAuditionRow != -1)
    {
        item(m_previousAuditionRow, 0)->setData(AUDITION_ROLE, AUDITION_STOP);
    }
    item(m_previousAuditionRow = row, 0)->setData(AUDITION_ROLE, AUDITION_PLAY);
    emit auditionIsPlaying(false);
}

void MusicSongSearchOnlineTableWidget::auditionToMusicStop(int row)
{
    if(m_audition)
    {
        m_audition->stop();
    }
    if(row < 0)
    {
        return;
    }
    item(row, 0)->setData(AUDITION_ROLE, AUDITION_STOP);
    emit auditionIsPlaying(true);
}

void MusicSongSearchOnlineTableWidget::addSearchMusicToPlayList(int row)
{
    if(!M_NETWORK->isOnline())
    {   //no network connection
        emit showDownLoadInfoFor(MusicObject::DisConnection);
        return;
    }
    emit showDownLoadInfoFor(MusicObject::Buffing);
    musicDownloadLocal(row);
    emit muiscSongToPlayListChanged( item(row, 2)->text() + " - " + item(row, 1)->text() );
}

void MusicSongSearchOnlineTableWidget::musicDownloadLocal(int row)
{
    if(!M_NETWORK->isOnline())
    {   //no network connection
        emit showDownLoadInfoFor(MusicObject::DisConnection);
        return;
    }
    if(row < 0)
    {
        return;
    }
    emit showDownLoadInfoFor(MusicObject::DownLoading);
    MStringLists musicSongInfo(m_downLoadManager->getMusicSongInfo());
    QString musicSong =  item(row, 2)->text() + " - " + item(row, 1)->text() ;
    QString downloadName = MUSIC_DOWNLOAD + musicSong + MUSIC_FILE;

    ////////////////////////////////////////////////
    MusicDownloadRecord record;
    MusicMyDownloadRecordObject down(this);
    if(!down.readDownloadXMLConfig())
    {
        return;
    }

    down.readDownloadConfig( record );
    record.m_names << musicSong;
    record.m_paths << QFileInfo(downloadName).absoluteFilePath();
    record.m_sizes << musicSongInfo[row][4];
    down.writeDownloadConfig( record );
    ////////////////////////////////////////////////

    MusicSongDownloadThread *downSong = new MusicSongDownloadThread( musicSongInfo[row][0],
                                                       downloadName, Download_Music, this);
    downSong->startToDownload();

    (new MusicTextDownLoadThread(musicSongInfo[row][1],LRC_DOWNLOAD +
                                 musicSong + LRC_FILE, Download_Lrc, this))->startToDownload();
    (new MusicData2DownloadThread(musicSongInfo[row][2],
         ART_DOWNLOAD + musicSongInfo[row][3] + SKN_FILE, Download_SmlBG, this))->startToDownload();

    ///download big picture
    new MusicBgThemeDownload(musicSongInfo[row][3], musicSongInfo[row][3], this);
}

void MusicSongSearchOnlineTableWidget::itemDoubleClicked(int row, int column)
{
    if(column <= 0 || row < 0)
    {
        return;
    }
    addSearchMusicToPlayList(row);
}

MusicSongSearchOnlineWidget::MusicSongSearchOnlineWidget(QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *boxLayout = new QVBoxLayout(this);
    boxLayout->setMargin(0);
    boxLayout->setSpacing(0);

    QWidget *toolWidget = new QWidget(this);
    toolWidget->setFixedHeight(65);
    QPalette pal(palette());
    pal.setColor(QPalette::Background, Qt::white);
    toolWidget->setAutoFillBackground(true);
    toolWidget->setPalette(pal);

    m_searchTableWidget = new  MusicSongSearchOnlineTableWidget(this);
    boxLayout->addWidget(toolWidget);
    boxLayout->addWidget(m_searchTableWidget);
    setLayout(boxLayout);

    createToolWidget();
    connect(m_searchTableWidget, SIGNAL(auditionIsPlaying(bool)), SLOT(auditionIsPlaying(bool)));
}

MusicSongSearchOnlineWidget::~MusicSongSearchOnlineWidget()
{
    delete m_playButton;
    delete m_textLabel;
    delete m_searchTableWidget;
}

void MusicSongSearchOnlineWidget::startSearchQuery(const QString &name) const
{
    m_searchTableWidget->startSearchQuery(name);
    m_textLabel->setText(tr(" find <font color=red> %1 </font> result").arg(name));
}

void MusicSongSearchOnlineWidget::createToolWidget()
{
    m_textLabel = new QLabel(this);
    m_textLabel->setGeometry(0, 0, 280, 30);
    m_textLabel->setText(tr(" find no result"));

    QLabel *colorLabel = new QLabel(this);
    colorLabel->setStyleSheet(MusicUIObject::MCustomStyle16);
    colorLabel->setGeometry(0, 30, width(), 35);

    QCheckBox *label_checkBox = new QCheckBox(this);
    label_checkBox->setStyleSheet(MusicUIObject::MCheckBoxStyle01);
    label_checkBox->setGeometry(7, 40, 20, 20);
    connect(label_checkBox, SIGNAL(clicked(bool)), m_searchTableWidget,
                            SLOT(setSelectedAllItems(bool)));

    QLabel *Label1 = new QLabel(tr("Song"), this);
    Label1->setStyleSheet(MusicUIObject::MCustomStyle17);
    Label1->setGeometry(120, 40, 60, 20);
    QLabel *Label2 = new QLabel(tr("Artist"), this);
    Label2->setStyleSheet(MusicUIObject::MCustomStyle17);
    Label2->setGeometry(310, 40, 60, 20);
    QLabel *Label3 = new QLabel(tr("Operator"), this);
    Label3->setStyleSheet(MusicUIObject::MCustomStyle17);
    Label3->setGeometry(435, 40, 60, 20);

    m_playButton = new QPushButton(tr("Play"), this);
    m_playButton->setGeometry(295, 5, 70, 20);
    m_playButton->setStyleSheet(MusicUIObject::MPushButtonStyle01);
    m_playButton->setCursor(QCursor(Qt::PointingHandCursor));

    QPushButton *addButton = new QPushButton(tr("Add"), this);
    addButton->setGeometry(370, 5, 70, 20);
    addButton->setStyleSheet(MusicUIObject::MPushButtonStyle01);
    addButton->setCursor(QCursor(Qt::PointingHandCursor));

    QPushButton *downloadButton = new QPushButton(tr("Download"), this);
    downloadButton->setGeometry(445, 5, 70, 20);
    downloadButton->setStyleSheet(MusicUIObject::MPushButtonStyle01);
    downloadButton->setCursor(QCursor(Qt::PointingHandCursor));

    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->addButton(m_playButton, 0);
    buttonGroup->addButton(addButton, 1);
    buttonGroup->addButton(downloadButton, 2);
    connect(buttonGroup, SIGNAL(buttonClicked(int)), SLOT(buttonClicked(int)));
}

void MusicSongSearchOnlineWidget::buttonClicked(int index)
{
    MIntList list = m_searchTableWidget->getSelectedItems();
    if(list.isEmpty())
    {
        MusicMessageBox message;
        message.setText(tr("Please Select One Item First!"));
        message.exec();
        return;
    }
    foreach(int row, list)
    {
        switch(index)
        {
            case 0:
                m_playButton->text() == tr("Play") ? m_searchTableWidget->auditionToMusic(row)
                                                   : m_searchTableWidget->auditionToMusicStop(row);
                break;
            case 1:
                m_searchTableWidget->listCellClicked(row, 4);
                break;
            case 2:
                m_searchTableWidget->listCellClicked(row, 5);
                break;
            default:
                break;
        }
    }
}

void MusicSongSearchOnlineWidget::auditionIsPlaying(bool play)
{
    m_playButton->setText(play ? tr("Play") : tr("Stop"));
}
<commit_msg>fix addSearchMusicToPlayList index out of range[201560]<commit_after>#include "musicsongsearchonlinewidget.h"
#include "musictextdownloadthread.h"
#include "musicdatadownloadthread.h"
#include "musicdata2downloadthread.h"
#include "musicsongdownloadthread.h"
#include "musicbgthemedownload.h"
#include "musicnetworkthread.h"
#include "musicmydownloadrecordobject.h"
#include "musiclocalsongsearchrecordobject.h"
#include "musicmessagebox.h"
#include "musicconnectionpool.h"

#include <QDateTime>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QButtonGroup>
#include <QMediaPlayer>

MusicSongSearchOnlineTableWidget::MusicSongSearchOnlineTableWidget(QWidget *parent)
    : MusicQueryTableWidget(parent), m_audition(NULL)
{
    setColumnCount(6);
    QHeaderView *headerview = horizontalHeader();
    headerview->resizeSection(0,30);
    headerview->resizeSection(1,215);
    headerview->resizeSection(2,166);
    headerview->resizeSection(3,50);
    headerview->resizeSection(4,26);
    headerview->resizeSection(5,26);
    setTransparent(255);

    m_previousAuditionRow = -1;
    M_Connection->setValue("MusicSongSearchOnlineTableWidget", this);
}

MusicSongSearchOnlineTableWidget::~MusicSongSearchOnlineTableWidget()
{
    delete m_audition;
    clearAllItems();
}

void MusicSongSearchOnlineTableWidget::startSearchQuery(const QString &text)
{
    ////////////////////////////////////////////////
    MusicSearchRecord record;
    MusicLocalSongSearchRecordObject search(this);
    if(!search.readSearchXMLConfig())
    {
        return;
    }
    search.readSearchConfig( record );
    record.m_names.insert(0, text);
    record.m_times.insert(0, QString::number(QDateTime::currentMSecsSinceEpoch()));
    search.writeSearchConfig( record );
    ////////////////////////////////////////////////
    QString currentQuality;
    emit getQualityString(currentQuality);
    if(!currentQuality.isEmpty())
    {
        m_downLoadManager->setSearchQuality(currentQuality);
    }
    m_downLoadManager->startSearchSong(MusicQuery, m_searchText = text);
}

void MusicSongSearchOnlineTableWidget::researchQueryByQuality()
{
    startSearchQuery(m_searchText);
}

void MusicSongSearchOnlineTableWidget::clearAllItems()
{
    MusicAbstractTableWidget::clear();
    setColumnCount(6);
}

void MusicSongSearchOnlineTableWidget::creatSearchedItems(const QString &songname,
                               const QString &artistname, const QString &time)
{
    int count;
    setRowCount(count = m_downLoadManager->getSongIdIndex());

    QTableWidgetItem *item = new QTableWidgetItem;
    item->setData(Qt::DisplayRole, false);
    item->setData(AUDITION_ROLE, AUDITION_STOP);
    setItem(count - 1, 0, item);

                      item = new QTableWidgetItem(songname);
    item->setTextColor(QColor(50,50,50));
    item->setTextAlignment(Qt::AlignCenter);
    item->setToolTip(songname);
    setItem(count - 1, 1, item);

                      item = new QTableWidgetItem(artistname);
    item->setTextColor(QColor(50,50,50));
    item->setTextAlignment(Qt::AlignCenter);
    item->setToolTip(artistname);
    setItem(count - 1, 2, item);

                      item = new QTableWidgetItem(time);
    item->setTextColor(QColor(50,50,50));
    item->setTextAlignment(Qt::AlignCenter);
    setItem(count - 1, 3, item);

                      item = new QTableWidgetItem(QIcon(QString::fromUtf8(":/image/addtoplaylist")),"");
    item->setTextAlignment(Qt::AlignCenter);
    setItem(count - 1, 4, item);

                      item = new QTableWidgetItem(QIcon(QString::fromUtf8(":/share/musicdownload")),"");
    item->setTextAlignment(Qt::AlignCenter);
    setItem(count - 1, 5, item);
}

void MusicSongSearchOnlineTableWidget::listCellClicked(int row, int col)
{
    MusicQueryTableWidget::listCellClicked(row, col);
    switch(col)
    {
        case 4:
            addSearchMusicToPlayList(row);
            break;
        case 5:
            musicDownloadLocal(row);
            break;
        default:
            break;
    }
    emit auditionIsPlaying( item(row, 0)->data(AUDITION_ROLE).toInt() == AUDITION_STOP );
}

void MusicSongSearchOnlineTableWidget::contextMenuEvent(QContextMenuEvent *event)
{
    MusicQueryTableWidget::contextMenuEvent(event);
    QMenu rightClickMenu(this);
    createContextMenu(rightClickMenu);

    QAction *playAction = rightClickMenu.addAction(QIcon(":/contextMenu/play"), tr("musicPlay"));
    QAction *addAction = rightClickMenu.addAction(tr("musicAdd"));
    rightClickMenu.insertAction(rightClickMenu.actions().first(), addAction);
    rightClickMenu.insertAction(addAction, playAction);
    m_actionGroup->addAction( playAction );
    m_actionGroup->addAction( addAction );
    rightClickMenu.exec(QCursor::pos());
}

void MusicSongSearchOnlineTableWidget::actionGroupClick(QAction *action)
{
    MusicQueryTableWidget::actionGroupClick(action);
    int row = currentRow();
    switch( findActionGroup(action) )
    {
        case 4: auditionToMusic(row); break;
        case 5: addSearchMusicToPlayList(row); break;
    }
}

void MusicSongSearchOnlineTableWidget::auditionToMusic(int row)
{
    MStringLists musicSongInfo(m_downLoadManager->getMusicSongInfo());
    if(musicSongInfo.isEmpty() || row < 0)
    {
        return;
    }
    if(m_audition == NULL)
    {
        m_audition = new QMediaPlayer(this);
    }
    m_audition->setMedia(QUrl(musicSongInfo[row][0]));
    m_audition->play();
    if(m_previousAuditionRow != -1)
    {
        item(m_previousAuditionRow, 0)->setData(AUDITION_ROLE, AUDITION_STOP);
    }
    item(m_previousAuditionRow = row, 0)->setData(AUDITION_ROLE, AUDITION_PLAY);
    emit auditionIsPlaying(false);
}

void MusicSongSearchOnlineTableWidget::auditionToMusicStop(int row)
{
    if(m_audition)
    {
        m_audition->stop();
    }
    if(row < 0)
    {
        return;
    }
    item(row, 0)->setData(AUDITION_ROLE, AUDITION_STOP);
    emit auditionIsPlaying(true);
}

void MusicSongSearchOnlineTableWidget::addSearchMusicToPlayList(int row)
{
    if(!M_NETWORK->isOnline())
    {   //no network connection
        emit showDownLoadInfoFor(MusicObject::DisConnection);
        return;
    }
    if(row < 0)
    {
        return;
    }
    emit showDownLoadInfoFor(MusicObject::Buffing);
    musicDownloadLocal(row);
    emit muiscSongToPlayListChanged( item(row, 2)->text() + " - " + item(row, 1)->text() );
}

void MusicSongSearchOnlineTableWidget::musicDownloadLocal(int row)
{
    if(!M_NETWORK->isOnline())
    {   //no network connection
        emit showDownLoadInfoFor(MusicObject::DisConnection);
        return;
    }
    if(row < 0)
    {
        return;
    }
    emit showDownLoadInfoFor(MusicObject::DownLoading);
    MStringLists musicSongInfo(m_downLoadManager->getMusicSongInfo());
    QString musicSong =  item(row, 2)->text() + " - " + item(row, 1)->text() ;
    QString downloadName = MUSIC_DOWNLOAD + musicSong + MUSIC_FILE;

    ////////////////////////////////////////////////
    MusicDownloadRecord record;
    MusicMyDownloadRecordObject down(this);
    if(!down.readDownloadXMLConfig())
    {
        return;
    }

    down.readDownloadConfig( record );
    record.m_names << musicSong;
    record.m_paths << QFileInfo(downloadName).absoluteFilePath();
    record.m_sizes << musicSongInfo[row][4];
    down.writeDownloadConfig( record );
    ////////////////////////////////////////////////

    MusicSongDownloadThread *downSong = new MusicSongDownloadThread( musicSongInfo[row][0],
                                                       downloadName, Download_Music, this);
    downSong->startToDownload();

    (new MusicTextDownLoadThread(musicSongInfo[row][1],LRC_DOWNLOAD +
                                 musicSong + LRC_FILE, Download_Lrc, this))->startToDownload();
    (new MusicData2DownloadThread(musicSongInfo[row][2],
         ART_DOWNLOAD + musicSongInfo[row][3] + SKN_FILE, Download_SmlBG, this))->startToDownload();

    ///download big picture
    new MusicBgThemeDownload(musicSongInfo[row][3], musicSongInfo[row][3], this);
}

void MusicSongSearchOnlineTableWidget::itemDoubleClicked(int row, int column)
{
    if(column <= 0 || row < 0)
    {
        return;
    }
    addSearchMusicToPlayList(row);
}

MusicSongSearchOnlineWidget::MusicSongSearchOnlineWidget(QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *boxLayout = new QVBoxLayout(this);
    boxLayout->setMargin(0);
    boxLayout->setSpacing(0);

    QWidget *toolWidget = new QWidget(this);
    toolWidget->setFixedHeight(65);
    QPalette pal(palette());
    pal.setColor(QPalette::Background, Qt::white);
    toolWidget->setAutoFillBackground(true);
    toolWidget->setPalette(pal);

    m_searchTableWidget = new  MusicSongSearchOnlineTableWidget(this);
    boxLayout->addWidget(toolWidget);
    boxLayout->addWidget(m_searchTableWidget);
    setLayout(boxLayout);

    createToolWidget();
    connect(m_searchTableWidget, SIGNAL(auditionIsPlaying(bool)), SLOT(auditionIsPlaying(bool)));
}

MusicSongSearchOnlineWidget::~MusicSongSearchOnlineWidget()
{
    delete m_playButton;
    delete m_textLabel;
    delete m_searchTableWidget;
}

void MusicSongSearchOnlineWidget::startSearchQuery(const QString &name) const
{
    m_searchTableWidget->startSearchQuery(name);
    m_textLabel->setText(tr(" find <font color=red> %1 </font> result").arg(name));
}

void MusicSongSearchOnlineWidget::createToolWidget()
{
    m_textLabel = new QLabel(this);
    m_textLabel->setGeometry(0, 0, 280, 30);
    m_textLabel->setText(tr(" find no result"));

    QLabel *colorLabel = new QLabel(this);
    colorLabel->setStyleSheet(MusicUIObject::MCustomStyle16);
    colorLabel->setGeometry(0, 30, width(), 35);

    QCheckBox *label_checkBox = new QCheckBox(this);
    label_checkBox->setStyleSheet(MusicUIObject::MCheckBoxStyle01);
    label_checkBox->setGeometry(7, 40, 20, 20);
    connect(label_checkBox, SIGNAL(clicked(bool)), m_searchTableWidget,
                            SLOT(setSelectedAllItems(bool)));

    QLabel *Label1 = new QLabel(tr("Song"), this);
    Label1->setStyleSheet(MusicUIObject::MCustomStyle17);
    Label1->setGeometry(120, 40, 60, 20);
    QLabel *Label2 = new QLabel(tr("Artist"), this);
    Label2->setStyleSheet(MusicUIObject::MCustomStyle17);
    Label2->setGeometry(310, 40, 60, 20);
    QLabel *Label3 = new QLabel(tr("Operator"), this);
    Label3->setStyleSheet(MusicUIObject::MCustomStyle17);
    Label3->setGeometry(435, 40, 60, 20);

    m_playButton = new QPushButton(tr("Play"), this);
    m_playButton->setGeometry(295, 5, 70, 20);
    m_playButton->setStyleSheet(MusicUIObject::MPushButtonStyle01);
    m_playButton->setCursor(QCursor(Qt::PointingHandCursor));

    QPushButton *addButton = new QPushButton(tr("Add"), this);
    addButton->setGeometry(370, 5, 70, 20);
    addButton->setStyleSheet(MusicUIObject::MPushButtonStyle01);
    addButton->setCursor(QCursor(Qt::PointingHandCursor));

    QPushButton *downloadButton = new QPushButton(tr("Download"), this);
    downloadButton->setGeometry(445, 5, 70, 20);
    downloadButton->setStyleSheet(MusicUIObject::MPushButtonStyle01);
    downloadButton->setCursor(QCursor(Qt::PointingHandCursor));

    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->addButton(m_playButton, 0);
    buttonGroup->addButton(addButton, 1);
    buttonGroup->addButton(downloadButton, 2);
    connect(buttonGroup, SIGNAL(buttonClicked(int)), SLOT(buttonClicked(int)));
}

void MusicSongSearchOnlineWidget::buttonClicked(int index)
{
    MIntList list = m_searchTableWidget->getSelectedItems();
    if(list.isEmpty())
    {
        MusicMessageBox message;
        message.setText(tr("Please Select One Item First!"));
        message.exec();
        return;
    }
    foreach(int row, list)
    {
        switch(index)
        {
            case 0:
                m_playButton->text() == tr("Play") ? m_searchTableWidget->auditionToMusic(row)
                                                   : m_searchTableWidget->auditionToMusicStop(row);
                break;
            case 1:
                m_searchTableWidget->listCellClicked(row, 4);
                break;
            case 2:
                m_searchTableWidget->listCellClicked(row, 5);
                break;
            default:
                break;
        }
    }
}

void MusicSongSearchOnlineWidget::auditionIsPlaying(bool play)
{
    m_playButton->setText(play ? tr("Play") : tr("Stop"));
}
<|endoftext|>


<commit_before>#include "stdafx.h"

#include "RendererModule.h"

#include <SOIL.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>

#include "ShaderManager.h"

GLuint windowWidth = 800;
GLuint windowHeight = 600;
const char * windowTitle = "Real-timeish Cloud Renderer";

GLuint billboardShaderProgram;
GLuint vao;
GLuint circleTex;
GLuint volumeTexture;

RendererModule::RendererModule() {};

bool RendererModule::initialize( int gridX, int gridY, int gridZ ) {

	// Initialize GLFW and opens a window
	if( glfwInit() != GL_TRUE ) {
		return false;
	}

	glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
	glfwOpenWindowHint( GLFW_WINDOW_NO_RESIZE, GL_TRUE );
	glfwOpenWindowHint( GLFW_OPENGL_PROFILE, 0 );

	if (glfwOpenWindow( windowWidth, windowHeight, 0, 0, 0, 0, 24, 8,
		GLFW_WINDOW ) != GL_TRUE) {
			glfwTerminate();
			return false;
	}
	glfwSetWindowTitle( windowTitle );

	// Initialize GLEW
	glewExperimental = GL_TRUE;
	GLenum err = glewInit();
	if(err != GLEW_OK) {
		std::cerr << "Failed to initialize GLEW: " <<
			glewGetErrorString(err) << "\n";
		exit( EXIT_FAILURE );
	}

	std::cout << "Running OpenGL version " << glGetString(GL_VERSION) << "\n";

	glGenVertexArrays( 1, &vao );
	glBindVertexArray( vao );

	// Load and compile shaders
	ShaderManager shaderManager;
	billboardShaderProgram = shaderManager.createFromFile(
		"BillboardShader.vert", "BillboardShader.frag" );
	glUseProgram( billboardShaderProgram );

	// Generate the textures
	glGenTextures( 1, &circleTex );
	glBindTexture( GL_TEXTURE_2D, circleTex );
	glGenTextures( 1, &volumeTexture );
	glBindTexture( GL_TEXTURE_3D, volumeTexture );

	int iWidth, iHeight;
	unsigned char* image;

	// Load the particle texture
	const char* path = "particle_texture.jpg";
	image = SOIL_load_image( path, &iWidth, &iHeight, 0, SOIL_LOAD_RGBA );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA,
		GL_UNSIGNED_BYTE, image );
	SOIL_free_image_data( image );

	// Select OpenGL texture parameters
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glGenerateMipmap( GL_TEXTURE_2D );

	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glGenerateMipmap( GL_TEXTURE_3D );

	// A single billboard data
	float vertexSize = 1.8f;
	float vertices[] = {
	//	Vertex position		      Texcoords
		-vertexSize,  vertexSize, 0.0f, 1.0f,  		// Vertex 1 (-X,  Y)
		-vertexSize, -vertexSize, 0.0f, 0.0f,		// Vertex 2 (-X, -Y)
		 vertexSize,  vertexSize, 1.0f, 1.0f,		// Vertex 3 ( X,  Y)
		 vertexSize,  vertexSize, 1.0f, 1.0f,		// Vertex 3 ( X,  Y)
		-vertexSize, -vertexSize, 0.0f, 0.0f,		// Vertex 2 (-X, -Y)
		 vertexSize, -vertexSize, 1.0f, 0.0f		// Vertex 4 ( X, -Y)
	};
	GLuint vbo;
	glGenBuffers( 1, &vbo ); // Generate 1 buffer
	glBindBuffer( GL_ARRAY_BUFFER, vbo );
	glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices,
		GL_STATIC_DRAW );

	// Define data layout
	GLint posAttrib = glGetAttribLocation( billboardShaderProgram,
		"vertPos" );
	glEnableVertexAttribArray( posAttrib );
	glVertexAttribPointer( posAttrib, 2, GL_FLOAT, GL_FALSE,
		4*sizeof(float), 0 );

	GLint texAttrib = glGetAttribLocation( billboardShaderProgram,
		"texCoord" );
	glEnableVertexAttribArray( texAttrib );
	glVertexAttribPointer( texAttrib, 2, GL_FLOAT, GL_FALSE,
		4*sizeof(float), (void*)( 2*sizeof(float) ) );

	// Initialize the camera and the projection matrices
	camera.initialize( gridX, gridY, gridZ );
	perspectiveProjection = glm::perspective( 85.0f,
		(float)windowWidth / (float)windowHeight, 0.4f, 300.0f );
	orthographicProjection = glm::ortho( -(gridX/2.0f), gridX/2.0f,
		-(gridY/2.0f), gridY/2.0f, 0.0f, 500.0f );

	// Set the sun position and sun position matrix (looking at the center of
	// the cloud)
	sunPosition = glm::vec3( 300, 250, 250 );
	glm::vec3 lookAtPoint = glm::vec3( gridX/2, gridY/2, -gridZ/2 );
	sunTransformation = glm::lookAt( sunPosition,
		lookAtPoint, glm::vec3(0, 0, 1));

	return true;

}

void RendererModule::draw( SimulationData* data, GLFWmutex simMutex, double time ) {

	// Update the camera
	camera.updateCamera();

	// Place the camera in the sun position
	GLint uniView = glGetUniformLocation( billboardShaderProgram, "view" );
	glUniformMatrix4fv( uniView, 1, GL_FALSE, glm::value_ptr( sunTransformation ) );

	// Set the parallel projection
	GLint uniProj = glGetUniformLocation( billboardShaderProgram, "proj" );
	glUniformMatrix4fv( uniProj, 1, GL_FALSE, glm::value_ptr( orthographicProjection ) );

	// Clear the screen with white color
	glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// Lock mutex because we will use data, which is shared with simulation
	glfwLockMutex( simMutex );

	shadeClouds( data, time );

	// Place the camera at the viewpoint
	glm::mat4 view = camera.getLookAtMatrix();
	glUniformMatrix4fv( uniView, 1, GL_FALSE, glm::value_ptr( view ) );

	// Set perspective projection
	glUniformMatrix4fv( uniProj, 1, GL_FALSE, glm::value_ptr( perspectiveProjection ) );

	// Clear the screen with background (sky) color
	glClearColor( 155/256.0f, 225/256.0f, 251/256.0f, 1.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	renderClouds( data, time );

	glfwUnlockMutex( simMutex );

	// Check for errors
	GLint glErr = glGetError();
	if ( glErr ) std::cout << "OpenGL error " << glErr << "!\n";

	// Swap the buffer
	glfwSwapBuffers();

}

// Shade clouds by performing volume ray casting
void RendererModule::shadeClouds( SimulationData* data, double time ) {

	int x = data->getGridLength();
	int y = data->getGridWidth();
	int z = data->getGridHeight();

	// Convert float*** to float* (stream of data)
	float* texData = new float[x*y*z];
	int pos = 0;
	for( int i = 0; i < x; ++i ) // TODO: might be wrong order
		for( int j = 0; j < y; ++j )
			for( int k = 0; k < z; ++k ) {
				texData[pos] = data->prevDen[i][j][k];
				++pos;
			}

	// Fill the data into 3D texture. A texture cell includes only one
	// component (GL_RED = density, float).
	glTexImage3D( GL_TEXTURE_3D, 0, GL_R32F, x, y, z, 0, GL_RED,
		GL_FLOAT, texData );

}

void RendererModule::renderClouds( SimulationData* data, double time ) {

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable( GL_BLEND );

	GLint uniPosition = glGetUniformLocation( billboardShaderProgram, "position" );
	GLint uniAlpha = glGetUniformLocation( billboardShaderProgram, "alpha" );

	int x = data->getGridLength();
	int y = data->getGridWidth();
	int z = data->getGridHeight();

	// Calculate relative difference for linear interpolation
	float relDiff = (time - data->nextTime)/(data->nextTime - data->prevTime);
	if( relDiff > 1.0f )relDiff = 1.0f;

	for( int i = 0; i < x; ++i )
		for( int j = 0; j < y; ++j )
			for( int k = 0; k < z; ++k ) {
				if( data->nextDen[i][j][k] > 0.0f ) {

					// Lineary interpolate the density
					float density = data->prevDen[i][j][k] + relDiff
						* (data->nextDen[i][j][k] - data->prevDen[i][j][k] );

					if( density > 0.0f) {
						// Build a translation (model) matrix in the shader,
						// because it's a lot faster than creating the matrix
						// here.
						glUniform3f( uniPosition, i, j, -k );
						glUniform1f( uniAlpha, density );

						glDrawArrays( GL_TRIANGLES, 0, 6 );
					}
				}
			}
}

void RendererModule::terminate() {

	glDeleteProgram( billboardShaderProgram );
	// Todo : delete shaders
	glDeleteTextures( 1, &circleTex );
	glDeleteVertexArrays( 1, &vao );

	// Terminate GLFW
	glfwTerminate();

}<commit_msg>Delete volume texture<commit_after>#include "stdafx.h"

#include "RendererModule.h"

#include <SOIL.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>

#include "ShaderManager.h"

GLuint windowWidth = 800;
GLuint windowHeight = 600;
const char * windowTitle = "Real-timeish Cloud Renderer";

GLuint billboardShaderProgram;
GLuint vao;
GLuint circleTex;
GLuint volumeTexture;

RendererModule::RendererModule() {};

bool RendererModule::initialize( int gridX, int gridY, int gridZ ) {

	// Initialize GLFW and opens a window
	if( glfwInit() != GL_TRUE ) {
		return false;
	}

	glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
	glfwOpenWindowHint( GLFW_WINDOW_NO_RESIZE, GL_TRUE );
	glfwOpenWindowHint( GLFW_OPENGL_PROFILE, 0 );

	if (glfwOpenWindow( windowWidth, windowHeight, 0, 0, 0, 0, 24, 8,
		GLFW_WINDOW ) != GL_TRUE) {
			glfwTerminate();
			return false;
	}
	glfwSetWindowTitle( windowTitle );

	// Initialize GLEW
	glewExperimental = GL_TRUE;
	GLenum err = glewInit();
	if(err != GLEW_OK) {
		std::cerr << "Failed to initialize GLEW: " <<
			glewGetErrorString(err) << "\n";
		exit( EXIT_FAILURE );
	}

	std::cout << "Running OpenGL version " << glGetString(GL_VERSION) << "\n";

	glGenVertexArrays( 1, &vao );
	glBindVertexArray( vao );

	// Load and compile shaders
	ShaderManager shaderManager;
	billboardShaderProgram = shaderManager.createFromFile(
		"BillboardShader.vert", "BillboardShader.frag" );
	glUseProgram( billboardShaderProgram );

	// Generate the textures
	glGenTextures( 1, &circleTex );
	glBindTexture( GL_TEXTURE_2D, circleTex );
	glGenTextures( 1, &volumeTexture );
	glBindTexture( GL_TEXTURE_3D, volumeTexture );

	int iWidth, iHeight;
	unsigned char* image;

	// Load the particle texture
	const char* path = "particle_texture.jpg";
	image = SOIL_load_image( path, &iWidth, &iHeight, 0, SOIL_LOAD_RGBA );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA,
		GL_UNSIGNED_BYTE, image );
	SOIL_free_image_data( image );

	// Select OpenGL texture parameters
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glGenerateMipmap( GL_TEXTURE_2D );

	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glGenerateMipmap( GL_TEXTURE_3D );

	// A single billboard data
	float vertexSize = 1.8f;
	float vertices[] = {
	//	Vertex position		      Texcoords
		-vertexSize,  vertexSize, 0.0f, 1.0f,  		// Vertex 1 (-X,  Y)
		-vertexSize, -vertexSize, 0.0f, 0.0f,		// Vertex 2 (-X, -Y)
		 vertexSize,  vertexSize, 1.0f, 1.0f,		// Vertex 3 ( X,  Y)
		 vertexSize,  vertexSize, 1.0f, 1.0f,		// Vertex 3 ( X,  Y)
		-vertexSize, -vertexSize, 0.0f, 0.0f,		// Vertex 2 (-X, -Y)
		 vertexSize, -vertexSize, 1.0f, 0.0f		// Vertex 4 ( X, -Y)
	};
	GLuint vbo;
	glGenBuffers( 1, &vbo ); // Generate 1 buffer
	glBindBuffer( GL_ARRAY_BUFFER, vbo );
	glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices,
		GL_STATIC_DRAW );

	// Define data layout
	GLint posAttrib = glGetAttribLocation( billboardShaderProgram,
		"vertPos" );
	glEnableVertexAttribArray( posAttrib );
	glVertexAttribPointer( posAttrib, 2, GL_FLOAT, GL_FALSE,
		4*sizeof(float), 0 );

	GLint texAttrib = glGetAttribLocation( billboardShaderProgram,
		"texCoord" );
	glEnableVertexAttribArray( texAttrib );
	glVertexAttribPointer( texAttrib, 2, GL_FLOAT, GL_FALSE,
		4*sizeof(float), (void*)( 2*sizeof(float) ) );

	// Initialize the camera and the projection matrices
	camera.initialize( gridX, gridY, gridZ );
	perspectiveProjection = glm::perspective( 85.0f,
		(float)windowWidth / (float)windowHeight, 0.4f, 300.0f );
	orthographicProjection = glm::ortho( -(gridX/2.0f), gridX/2.0f,
		-(gridY/2.0f), gridY/2.0f, 0.0f, 500.0f );

	// Set the sun position and sun position matrix (looking at the center of
	// the cloud)
	sunPosition = glm::vec3( 300, 250, 250 );
	glm::vec3 lookAtPoint = glm::vec3( gridX/2, gridY/2, -gridZ/2 );
	sunTransformation = glm::lookAt( sunPosition,
		lookAtPoint, glm::vec3(0, 0, 1));

	return true;

}

void RendererModule::draw( SimulationData* data, GLFWmutex simMutex, double time ) {

	// Update the camera
	camera.updateCamera();

	// Place the camera in the sun position
	GLint uniView = glGetUniformLocation( billboardShaderProgram, "view" );
	glUniformMatrix4fv( uniView, 1, GL_FALSE, glm::value_ptr( sunTransformation ) );

	// Set the parallel projection
	GLint uniProj = glGetUniformLocation( billboardShaderProgram, "proj" );
	glUniformMatrix4fv( uniProj, 1, GL_FALSE, glm::value_ptr( orthographicProjection ) );

	// Clear the screen with white color
	glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// Lock mutex because we will use data, which is shared with simulation
	glfwLockMutex( simMutex );

	shadeClouds( data, time );

	// Place the camera at the viewpoint
	glm::mat4 view = camera.getLookAtMatrix();
	glUniformMatrix4fv( uniView, 1, GL_FALSE, glm::value_ptr( view ) );

	// Set perspective projection
	glUniformMatrix4fv( uniProj, 1, GL_FALSE, glm::value_ptr( perspectiveProjection ) );

	// Clear the screen with background (sky) color
	glClearColor( 155/256.0f, 225/256.0f, 251/256.0f, 1.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	renderClouds( data, time );

	glfwUnlockMutex( simMutex );

	// Check for errors
	GLint glErr = glGetError();
	if ( glErr ) std::cout << "OpenGL error " << glErr << "!\n";

	// Swap the buffer
	glfwSwapBuffers();

}

// Shade clouds by performing volume ray casting
void RendererModule::shadeClouds( SimulationData* data, double time ) {

	int x = data->getGridLength();
	int y = data->getGridWidth();
	int z = data->getGridHeight();

	// Convert float*** to float* (stream of data)
	float* texData = new float[x*y*z];
	int pos = 0;
	for( int i = 0; i < x; ++i ) // TODO: might be wrong order
		for( int j = 0; j < y; ++j )
			for( int k = 0; k < z; ++k ) {
				texData[pos] = data->prevDen[i][j][k];
				++pos;
			}

	// Fill the data into 3D texture. A texture cell includes only one
	// component (GL_RED = density, float).
	glTexImage3D( GL_TEXTURE_3D, 0, GL_R32F, x, y, z, 0, GL_RED,
		GL_FLOAT, texData );

}

void RendererModule::renderClouds( SimulationData* data, double time ) {

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable( GL_BLEND );

	GLint uniPosition = glGetUniformLocation( billboardShaderProgram, "position" );
	GLint uniAlpha = glGetUniformLocation( billboardShaderProgram, "alpha" );

	int x = data->getGridLength();
	int y = data->getGridWidth();
	int z = data->getGridHeight();

	// Calculate relative difference for linear interpolation
	float relDiff = (time - data->nextTime)/(data->nextTime - data->prevTime);
	if( relDiff > 1.0f )relDiff = 1.0f;

	for( int i = 0; i < x; ++i )
		for( int j = 0; j < y; ++j )
			for( int k = 0; k < z; ++k ) {
				if( data->nextDen[i][j][k] > 0.0f ) {

					// Lineary interpolate the density
					float density = data->prevDen[i][j][k] + relDiff
						* (data->nextDen[i][j][k] - data->prevDen[i][j][k] );

					if( density > 0.0f) {
						// Build a translation (model) matrix in the shader,
						// because it's a lot faster than creating the matrix
						// here.
						glUniform3f( uniPosition, i, j, -k );
						glUniform1f( uniAlpha, density );

						glDrawArrays( GL_TRIANGLES, 0, 6 );
					}
				}
			}
}

void RendererModule::terminate() {

	glDeleteProgram( billboardShaderProgram );
	// Todo : delete shaders
	glDeleteTextures( 1, &circleTex );
	glDeleteTextures( 1, &volumeTexture );
	glDeleteVertexArrays( 1, &vao );

	// Terminate GLFW
	glfwTerminate();

}<|endoftext|>


<commit_before>/*
 * warp_image.cxx
 *
 *  Created on: Mar 27, 2014
 *      Author: oesteban
 */

#include "warp_image.h"

#include <vnl/vnl_matrix.h>
#include <vnl/vnl_diag_matrix.h>
#include <sstream>

int main(int argc, char *argv[]) {
	std::string outPrefix = "displ";
	std::string fieldname,maskfile;
	std::vector< std::string > fixedImageNames, movingSurfaceNames;

	bpo::options_description all_desc("Usage");
	all_desc.add_options()
			("help,h", "show help message")
			("images,I", bpo::value < std::vector<std::string>	> (&fixedImageNames)->multitoken()->required(), "fixed image file")
			("surfaces,S", bpo::value < std::vector<std::string>	> (&movingSurfaceNames)->multitoken(),	"moving image file")
			("displacement-field,F", bpo::value < std::string >(&fieldname), "displacement field" )
			("mask,M", bpo::value< std::string >(&maskfile), "mask file" )
			("output-prefix,o", bpo::value < std::string > (&outPrefix), "prefix for output files");

	bpo::variables_map vm;
	bpo::store(	bpo::parse_command_line( argc, argv, all_desc ), vm);
	bpo::notify(vm);

	if (vm.count("help") || vm.size() == 0 ) {
		std::cout << all_desc << std::endl;
		return 1;
	}

	DisplacementFieldReaderPointer fread = DisplacementFieldReaderType::New();
	fread->SetFileName( fieldname );
	fread->Update();
	DisplacementFieldPointer field = fread->GetOutput();

	// Direction issues
	typename ChannelType::DirectionType itk;
	itk.SetIdentity();
	itk(0,0)=-1.0;
	itk(1,1)=-1.0;

	typename ReaderType::Pointer rref = ReaderType::New();
	rref->SetFileName( fixedImageNames[0] );
	rref->Update();

	typename ChannelType::Pointer im = rref->GetOutput();
	typename ChannelType::DirectionType dir = im->GetDirection();
	typename ChannelType::PointType ref_orig = im->GetOrigin();

	// Read and transform mask, if present
	MaskPointer mask;

	if (vm.count( "mask" ) ) {
		typename ReaderType::Pointer rmask = ReaderType::New();
		rmask->SetFileName( maskfile );
		rmask->Update();

		ChannelPointer im = rmask->GetOutput();
		im->SetDirection( dir * itk );
		im->SetOrigin( itk * ref_orig );

		WarpFilterPointer res = WarpFilter::New();
		res->SetInput( im );
		res->SetOutputParametersFromImage( rmask->GetOutput() );
		res->SetInterpolator( NearestNeighborInterpolateImageFunction::New() );
		res->SetDisplacementField( field );
		res->Update();

		ChannelPointer im_res = res->GetOutput();
		im_res->SetDirection( dir );
		im_res->SetOrigin( ref_orig );

		typename Binarize::Pointer bin = Binarize::New();
		bin->SetInput( im_res );
		bin->SetLowerThreshold( 0.01 );
		bin->SetOutsideValue( 0 );
		bin->SetInsideValue( 1 );
		bin->Update();
		mask = bin->GetOutput();

		typename MaskWriter::Pointer wm = MaskWriter::New();
		wm->SetInput( mask );
		wm->SetFileName( (outPrefix + "_mask_warped.nii.gz").c_str() );
		wm->Update();
	}

	// Read and transform images if present
	for( size_t i = 0; i<fixedImageNames.size(); i++) {
		typename ReaderType::Pointer r = ReaderType::New();
		r->SetFileName( fixedImageNames[i] );
		r->Update();

		typename ChannelType::Pointer im = r->GetOutput();
		typename ChannelType::DirectionType dir = im->GetDirection();
		typename ChannelType::PointType ref_orig = im->GetOrigin();

		im->SetDirection( dir * itk );
		im->SetOrigin( itk * ref_orig );

		WarpFilterPointer res = WarpFilter::New();
		res->SetInterpolator( itk::BSplineInterpolateImageFunction< ChannelType, ScalarType >::New() );
		res->SetOutputParametersFromImage( im );
		res->SetInput( im );
		res->SetDisplacementField( field );
		res->Update();

		typename ChannelType::Pointer im_res = res->GetOutput();
		im_res->SetDirection( dir );
		im_res->SetOrigin( ref_orig );

		if (mask.IsNotNull()) {
			typename MaskFilter::Pointer mm = MaskFilter::New();
			mm->SetMaskImage( mask );
			mm->SetInput( im_res );
			mm->Update();

			im_res = mm->GetOutput();
		}

		std::stringstream ss;
		ss.str("");
		ss << outPrefix << "_warped_" << i << ".nii.gz";
		typename WriterType::Pointer w = WriterType::New();
		w->SetInput( im_res );
		w->SetFileName( ss.str().c_str() );
		w->Update();

	}

	TransformPointer transform;
	if ( movingSurfaceNames.size() > 0 ) {
		transform = TransformType::New();
	}

	for( size_t i = 0; i<movingSurfaceNames.size(); i++){
		MeshReaderPointer r = MeshReaderType::New();
		r->SetFileName( movingSurfaceNames[i] );
		r->Update();

		MeshPointer mesh = r->GetOutput();

		PointsIterator p_it = mesh->GetPoints()->Begin();
		PointsIterator p_end = mesh->GetPoints()->End();

		MeshPointType p;
		while ( p_it!=p_end ) {
			p = p_it.Value();
			p_it.Value()+= p - transform->TransformPoint( p );
			++p_it;
		}

		MeshWriterPointer wmesh = MeshWriterType::New();
		std::stringstream ss;
		ss << outPrefix << "_warped_" << i << ".vtk";
		wmesh->SetFileName( ss.str().c_str() );
		wmesh->SetInput( mesh );
		wmesh->Update();

	}

}

<commit_msg>fixed bug in warp_image<commit_after>/*
 * warp_image.cxx
 *
 *  Created on: Mar 27, 2014
 *      Author: oesteban
 */

#include "warp_image.h"

#include <vnl/vnl_matrix.h>
#include <vnl/vnl_diag_matrix.h>
#include <sstream>

int main(int argc, char *argv[]) {
	std::string outPrefix = "displ";
	std::string fieldname,maskfile;
	std::vector< std::string > fixedImageNames, movingSurfaceNames;

	bpo::options_description all_desc("Usage");
	all_desc.add_options()
			("help,h", "show help message")
			("images,I", bpo::value < std::vector<std::string>	> (&fixedImageNames)->multitoken()->required(), "fixed image file")
			("surfaces,S", bpo::value < std::vector<std::string>	> (&movingSurfaceNames)->multitoken(),	"moving image file")
			("displacement-field,F", bpo::value < std::string >(&fieldname), "displacement field" )
			("mask,M", bpo::value< std::string >(&maskfile), "mask file" )
			("output-prefix,o", bpo::value < std::string > (&outPrefix), "prefix for output files");

	bpo::variables_map vm;
	bpo::store(	bpo::parse_command_line( argc, argv, all_desc ), vm);
	bpo::notify(vm);

	if (vm.count("help") || vm.size() == 0 ) {
		std::cout << all_desc << std::endl;
		return 1;
	}

	DisplacementFieldReaderPointer fread = DisplacementFieldReaderType::New();
	fread->SetFileName( fieldname );
	fread->Update();
	DisplacementFieldPointer field = fread->GetOutput();

	// Direction issues
	typename ChannelType::DirectionType itk;
	itk.SetIdentity();
	itk(0,0)=-1.0;
	itk(1,1)=-1.0;

	typename ReaderType::Pointer rref = ReaderType::New();
	rref->SetFileName( fixedImageNames[0] );
	rref->Update();

	typename ChannelType::Pointer im = rref->GetOutput();
	typename ChannelType::DirectionType dir = im->GetDirection();
	typename ChannelType::PointType ref_orig = im->GetOrigin();

	// Read and transform mask, if present
	MaskPointer mask;

	if (vm.count( "mask" ) ) {
		typename ReaderType::Pointer rmask = ReaderType::New();
		rmask->SetFileName( maskfile );
		rmask->Update();

		ChannelPointer im = rmask->GetOutput();
		im->SetDirection( dir * itk );
		im->SetOrigin( itk * ref_orig );

		WarpFilterPointer res = WarpFilter::New();
		res->SetInput( im );
		res->SetOutputParametersFromImage( rmask->GetOutput() );
		res->SetInterpolator( NearestNeighborInterpolateImageFunction::New() );
		res->SetDisplacementField( field );
		res->Update();

		ChannelPointer im_res = res->GetOutput();
		im_res->SetDirection( dir );
		im_res->SetOrigin( ref_orig );

		typename Binarize::Pointer bin = Binarize::New();
		bin->SetInput( im_res );
		bin->SetLowerThreshold( 0.01 );
		bin->SetOutsideValue( 0 );
		bin->SetInsideValue( 1 );
		bin->Update();
		mask = bin->GetOutput();

		typename MaskWriter::Pointer wm = MaskWriter::New();
		wm->SetInput( mask );
		wm->SetFileName( (outPrefix + "_mask_warped.nii.gz").c_str() );
		wm->Update();
	}

	// Read and transform images if present
	for( size_t i = 0; i<fixedImageNames.size(); i++) {
		typename ReaderType::Pointer r = ReaderType::New();
		r->SetFileName( fixedImageNames[i] );
		r->Update();

		typename ChannelType::Pointer im = r->GetOutput();
		typename ChannelType::DirectionType dir = im->GetDirection();
		typename ChannelType::PointType ref_orig = im->GetOrigin();

		im->SetDirection( dir * itk );
		im->SetOrigin( itk * ref_orig );

		WarpFilterPointer res = WarpFilter::New();
		res->SetInterpolator( itk::BSplineInterpolateImageFunction< ChannelType, ScalarType >::New() );
		res->SetOutputParametersFromImage( im );
		res->SetInput( im );
		res->SetDisplacementField( field );
		res->Update();

		typename ChannelType::Pointer im_res = res->GetOutput();
		im_res->SetDirection( dir );
		im_res->SetOrigin( ref_orig );

		if (mask.IsNotNull()) {
			typename MaskFilter::Pointer mm = MaskFilter::New();
			mm->SetMaskImage( mask );
			mm->SetInput( im_res );
			mm->Update();

			im_res = mm->GetOutput();
		}

		std::stringstream ss;
		ss.str("");
		ss << outPrefix << "_warped_" << i << ".nii.gz";
		typename WriterType::Pointer w = WriterType::New();
		w->SetInput( im_res );
		w->SetFileName( ss.str().c_str() );
		w->Update();

	}

	TransformPointer transform;
	if ( movingSurfaceNames.size() > 0 ) {
		transform = TransformType::New();
		transform->SetDisplacementField(field);
	}

	for( size_t i = 0; i<movingSurfaceNames.size(); i++){
		MeshReaderPointer r = MeshReaderType::New();
		r->SetFileName( movingSurfaceNames[i] );
		r->Update();

		MeshPointer mesh = r->GetOutput();

		PointsIterator p_it = mesh->GetPoints()->Begin();
		PointsIterator p_end = mesh->GetPoints()->End();

		MeshPointType p;
		while ( p_it!=p_end ) {
			p = p_it.Value();
			p_it.Value()+= p - transform->TransformPoint( p );
			++p_it;
		}

		MeshWriterPointer wmesh = MeshWriterType::New();
		std::stringstream ss;
		ss << outPrefix << "_warped_" << i << ".vtk";
		wmesh->SetFileName( ss.str().c_str() );
		wmesh->SetInput( mesh );
		wmesh->Update();

	}

}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkUnicodeString.cxx

-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/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 notice for more information.

=========================================================================*/

#include "vtkUnicodeString.h"

#include <vtkObject.h>
#include <utf8.h>

#include <map>
#include <stdexcept>

///////////////////////////////////////////////////////////////////////////
// vtkUnicodeString::const_iterator

vtkUnicodeString::const_iterator::const_iterator()
{
}

vtkUnicodeString::const_iterator::const_iterator(std::string::const_iterator position) :
  Position(position)
{
}

vtkUnicodeString::value_type vtkUnicodeString::const_iterator::operator*() const
{
  return vtk_utf8::unchecked::peek_next(this->Position);
}

bool vtkUnicodeString::const_iterator::operator==(const const_iterator& rhs) const
{
  return this->Position == rhs.Position;
}

bool vtkUnicodeString::const_iterator::operator!=(const const_iterator& rhs) const
{
  return !(*this == rhs);
}

vtkUnicodeString::const_iterator& vtkUnicodeString::const_iterator::operator++()
{
  vtk_utf8::unchecked::next(this->Position);
  return *this;
}

vtkUnicodeString::const_iterator vtkUnicodeString::const_iterator::operator++(int)
{
  const_iterator result(this->Position);
  vtk_utf8::unchecked::next(this->Position);
  return result;
}

vtkUnicodeString::const_iterator& vtkUnicodeString::const_iterator::operator--()
{
  vtk_utf8::unchecked::prior(this->Position);
  return *this;
}

vtkUnicodeString::const_iterator vtkUnicodeString::const_iterator::operator--(int)
{
  const_iterator result(this->Position);
  vtk_utf8::unchecked::prior(this->Position);
  return result;
}

///////////////////////////////////////////////////////////////////////////
// vtkUnicodeString::back_insert_iterator

// We provide our own implementation of std::back_insert_iterator for
// use with MSVC 6, where push_back() isn't implemented for std::string.

class vtkUnicodeString::back_insert_iterator
{
public:
  back_insert_iterator(std::string& container) :
    Container(&container)
  {
  }

  back_insert_iterator& operator*()
  {
    return *this;
  }

  back_insert_iterator& operator++()
  {
    return *this;
  }

  back_insert_iterator& operator++(int)
  {
    return *this;
  }

  back_insert_iterator& operator=(std::string::const_reference value)
  {
    this->Container->push_back(value);
    return *this;
  }

private:
  std::string* Container;
};

///////////////////////////////////////////////////////////////////////////
// vtkUnicodeString

vtkUnicodeString::vtkUnicodeString()
{
}

vtkUnicodeString::vtkUnicodeString(const vtkUnicodeString& rhs) :
  Storage(rhs.Storage)
{
}

vtkUnicodeString::vtkUnicodeString(size_type count, value_type character)
{
  for(size_type i = 0; i != count; ++i)
    vtk_utf8::append(character, vtkUnicodeString::back_insert_iterator(this->Storage));
}

vtkUnicodeString::vtkUnicodeString(const_iterator first, const_iterator last) :
  Storage(first.Position, last.Position)
{
}

bool vtkUnicodeString::is_utf8(const char* value)
{
  return vtkUnicodeString::is_utf8(std::string(value ? value : ""));
}

bool vtkUnicodeString::is_utf8(const std::string& value)
{
  return vtk_utf8::is_valid(value.begin(), value.end());
}

vtkUnicodeString vtkUnicodeString::from_utf8(const char* value)
{
  return vtkUnicodeString::from_utf8(std::string(value ? value : ""));
}

vtkUnicodeString vtkUnicodeString::from_utf8(const char* begin, const char* end)
{
  vtkUnicodeString result;
  if(vtk_utf8::is_valid(begin, end))
    {
    result.Storage = std::string(begin, end);
    }
  else
    {
    vtkGenericWarningMacro("vtkUnicodeString::from_utf8(): not a valid UTF-8 string.");
    }
  return result;
}

vtkUnicodeString vtkUnicodeString::from_utf8(const std::string& value)
{
  vtkUnicodeString result;
  if(vtk_utf8::is_valid(value.begin(), value.end()))
    {
    result.Storage = value;
    }
  else
    {
    vtkGenericWarningMacro("vtkUnicodeString::from_utf8(): not a valid UTF-8 string.");
    }
  return result;
}

vtkUnicodeString vtkUnicodeString::from_utf16(const vtkTypeUInt16* value)
{
  vtkUnicodeString result;

  if(value)
    {
    size_type length = 0;
    while(value[length])
      ++length;

    try
      {
      vtk_utf8::utf16to8(value, value + length, vtkUnicodeString::back_insert_iterator(result.Storage));
      }
    catch(vtk_utf8::invalid_utf16&)
      {
      vtkGenericWarningMacro(<< "vtkUnicodeString::from_utf16(): not a valid UTF-16 string.");
      }
    }

  return result;
}

vtkUnicodeString& vtkUnicodeString::operator=(const vtkUnicodeString& rhs)
{
  if(this == &rhs)
    return *this;

  this->Storage = rhs.Storage;
  return *this;
}

vtkUnicodeString::const_iterator vtkUnicodeString::begin() const
{
  return const_iterator(this->Storage.begin());
}

vtkUnicodeString::const_iterator vtkUnicodeString::end() const
{
  return const_iterator(this->Storage.end());
}

vtkUnicodeString::value_type vtkUnicodeString::at(size_type offset) const
{
  if(offset >= this->character_count())
    throw std::out_of_range("character out-of-range");

  std::string::const_iterator iterator = this->Storage.begin();
  vtk_utf8::unchecked::advance(iterator, offset);
  return vtk_utf8::unchecked::peek_next(iterator);
}

vtkUnicodeString::value_type vtkUnicodeString::operator[](size_type offset) const
{
  std::string::const_iterator iterator = this->Storage.begin();
  vtk_utf8::unchecked::advance(iterator, offset);
  return vtk_utf8::unchecked::peek_next(iterator);
}

const char* vtkUnicodeString::utf8_str() const
{
  return this->Storage.c_str();
}

void vtkUnicodeString::utf8_str(std::string& result) const
{
  result = this->Storage;
}

std::vector<vtkTypeUInt16> vtkUnicodeString::utf16_str() const
{
  std::vector<vtkTypeUInt16> result;
  vtk_utf8::unchecked::utf8to16(this->Storage.begin(), this->Storage.end(), std::back_inserter(result));
  return result;
}

void vtkUnicodeString::utf16_str(std::vector<vtkTypeUInt16>& result) const
{
  result.clear();
  vtk_utf8::unchecked::utf8to16(this->Storage.begin(), this->Storage.end(), std::back_inserter(result));
}

vtkUnicodeString::size_type vtkUnicodeString::byte_count() const
{
  return this->Storage.size();
}

vtkUnicodeString::size_type vtkUnicodeString::character_count() const
{
  return vtk_utf8::unchecked::distance(this->Storage.begin(), this->Storage.end());
}

bool vtkUnicodeString::empty() const
{
  return this->Storage.empty();
}

const vtkUnicodeString::size_type vtkUnicodeString::npos = std::string::npos;

vtkUnicodeString& vtkUnicodeString::operator+=(value_type value)
{
  this->push_back(value);
  return *this;
}

vtkUnicodeString& vtkUnicodeString::operator+=(const vtkUnicodeString& rhs)
{
  this->append(rhs);
  return *this;
}

void vtkUnicodeString::push_back(value_type character)
{
  try
    {
    vtk_utf8::append(character, vtkUnicodeString::back_insert_iterator(this->Storage));
    }
  catch(vtk_utf8::invalid_code_point&)
    {
    vtkGenericWarningMacro("vtkUnicodeString::push_back(): " << character << "is not a valid Unicode code point");
    }
}

void vtkUnicodeString::append(const vtkUnicodeString& value)
{
  this->Storage.append(value.Storage);
}

void vtkUnicodeString::append(size_type count, value_type character)
{
  try
    {
    this->Storage.append(vtkUnicodeString(count, character).Storage);
    }
  catch(vtk_utf8::invalid_code_point&)
    {
    vtkGenericWarningMacro("vtkUnicodeString::append(): " << character << "is not a valid Unicode code point");
    }
}

void vtkUnicodeString::append(const_iterator first, const_iterator last)
{
#if defined (__BORLANDC__) && (__BORLANDC__ < 0x0580)
  this->Storage.append(first.Position, last.Position - first.Position);
#else
  this->Storage.append(first.Position, last.Position);
#endif
}

void vtkUnicodeString::assign(const vtkUnicodeString& value)
{
  this->Storage.assign(value.Storage);
}

void vtkUnicodeString::assign(size_type count, value_type character)
{
  try
    {
    this->Storage.assign(vtkUnicodeString(count, character).Storage);
    }
  catch(vtk_utf8::invalid_code_point&)
    {
    vtkGenericWarningMacro("vtkUnicodeString::assign(): " << character << "is not a valid Unicode code point");
    }
}

void vtkUnicodeString::assign(const_iterator first, const_iterator last)
{
#if defined (__BORLANDC__) && (__BORLANDC__ < 0x0580)
  this->Storage.assign(first.Position, last.Position - first.Position);
#else
  this->Storage.assign(first.Position, last.Position);
#endif
}

void vtkUnicodeString::clear()
{
  // We use erase() because MSVC 6 doesn't provide clear() ...
  this->Storage.erase(this->Storage.begin(), this->Storage.end());
}

vtkUnicodeString vtkUnicodeString::fold_case() const
{
  typedef std::map<value_type, vtkUnicodeString> map_t;

  static map_t map;
  if(map.empty())
    {
    #include <vtkUnicodeCaseFoldData.h>

    for(value_type* i = &vtkUnicodeCaseFoldData[0]; *i; ++i)
      {
      const value_type code = *i;
      vtkUnicodeString mapping;
      for(++i; *i; ++i)
        {
        mapping.push_back(*i);
        }
      map.insert(std::make_pair(code, mapping));
      }
    }

  vtkUnicodeString result;

  for(vtkUnicodeString::const_iterator source = this->begin(); source != this->end(); ++source)
    {
    map_t::const_iterator target = map.find(*source);
    if(target != map.end())
      {
      result.append(target->second);
      }
    else
      {
      result.push_back(*source);
      }
    }

  return result;
}

int vtkUnicodeString::compare(const vtkUnicodeString& rhs) const
{
  return this->Storage.compare(rhs.Storage);
}

vtkUnicodeString vtkUnicodeString::substr(size_type offset, size_type count) const
{
  std::string::const_iterator from = this->Storage.begin();
  std::string::const_iterator last = this->Storage.end();

  while(from != last && offset--)
    vtk_utf8::unchecked::advance(from, 1);

  std::string::const_iterator to = from;
  while(to != last && count--)
    vtk_utf8::unchecked::advance(to, 1);

  return vtkUnicodeString(from, to);
}

void vtkUnicodeString::swap(vtkUnicodeString& rhs)
{
  std::swap(this->Storage, rhs.Storage);
}

bool operator==(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) == 0;
}

bool operator!=(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) != 0;
}

bool operator<(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) < 0;
}

bool operator<=(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) <= 0;
}

bool operator>=(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) >= 0;
}

bool operator>(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) > 0;
}
<commit_msg>Removed MSVC 6 workaround<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkUnicodeString.cxx

-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/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 notice for more information.

=========================================================================*/

#include "vtkUnicodeString.h"

#include <vtkObject.h>
#include <utf8.h>

#include <map>
#include <stdexcept>

///////////////////////////////////////////////////////////////////////////
// vtkUnicodeString::const_iterator

vtkUnicodeString::const_iterator::const_iterator()
{
}

vtkUnicodeString::const_iterator::const_iterator(std::string::const_iterator position) :
  Position(position)
{
}

vtkUnicodeString::value_type vtkUnicodeString::const_iterator::operator*() const
{
  return vtk_utf8::unchecked::peek_next(this->Position);
}

bool vtkUnicodeString::const_iterator::operator==(const const_iterator& rhs) const
{
  return this->Position == rhs.Position;
}

bool vtkUnicodeString::const_iterator::operator!=(const const_iterator& rhs) const
{
  return !(*this == rhs);
}

vtkUnicodeString::const_iterator& vtkUnicodeString::const_iterator::operator++()
{
  vtk_utf8::unchecked::next(this->Position);
  return *this;
}

vtkUnicodeString::const_iterator vtkUnicodeString::const_iterator::operator++(int)
{
  const_iterator result(this->Position);
  vtk_utf8::unchecked::next(this->Position);
  return result;
}

vtkUnicodeString::const_iterator& vtkUnicodeString::const_iterator::operator--()
{
  vtk_utf8::unchecked::prior(this->Position);
  return *this;
}

vtkUnicodeString::const_iterator vtkUnicodeString::const_iterator::operator--(int)
{
  const_iterator result(this->Position);
  vtk_utf8::unchecked::prior(this->Position);
  return result;
}

///////////////////////////////////////////////////////////////////////////
// vtkUnicodeString::back_insert_iterator

// We provide our own implementation of std::back_insert_iterator for
// use with MSVC 6, where push_back() isn't implemented for std::string.

class vtkUnicodeString::back_insert_iterator
{
public:
  back_insert_iterator(std::string& container) :
    Container(&container)
  {
  }

  back_insert_iterator& operator*()
  {
    return *this;
  }

  back_insert_iterator& operator++()
  {
    return *this;
  }

  back_insert_iterator& operator++(int)
  {
    return *this;
  }

  back_insert_iterator& operator=(std::string::const_reference value)
  {
    this->Container->push_back(value);
    return *this;
  }

private:
  std::string* Container;
};

///////////////////////////////////////////////////////////////////////////
// vtkUnicodeString

vtkUnicodeString::vtkUnicodeString()
{
}

vtkUnicodeString::vtkUnicodeString(const vtkUnicodeString& rhs) :
  Storage(rhs.Storage)
{
}

vtkUnicodeString::vtkUnicodeString(size_type count, value_type character)
{
  for(size_type i = 0; i != count; ++i)
    vtk_utf8::append(character, vtkUnicodeString::back_insert_iterator(this->Storage));
}

vtkUnicodeString::vtkUnicodeString(const_iterator first, const_iterator last) :
  Storage(first.Position, last.Position)
{
}

bool vtkUnicodeString::is_utf8(const char* value)
{
  return vtkUnicodeString::is_utf8(std::string(value ? value : ""));
}

bool vtkUnicodeString::is_utf8(const std::string& value)
{
  return vtk_utf8::is_valid(value.begin(), value.end());
}

vtkUnicodeString vtkUnicodeString::from_utf8(const char* value)
{
  return vtkUnicodeString::from_utf8(std::string(value ? value : ""));
}

vtkUnicodeString vtkUnicodeString::from_utf8(const char* begin, const char* end)
{
  vtkUnicodeString result;
  if(vtk_utf8::is_valid(begin, end))
    {
    result.Storage = std::string(begin, end);
    }
  else
    {
    vtkGenericWarningMacro("vtkUnicodeString::from_utf8(): not a valid UTF-8 string.");
    }
  return result;
}

vtkUnicodeString vtkUnicodeString::from_utf8(const std::string& value)
{
  vtkUnicodeString result;
  if(vtk_utf8::is_valid(value.begin(), value.end()))
    {
    result.Storage = value;
    }
  else
    {
    vtkGenericWarningMacro("vtkUnicodeString::from_utf8(): not a valid UTF-8 string.");
    }
  return result;
}

vtkUnicodeString vtkUnicodeString::from_utf16(const vtkTypeUInt16* value)
{
  vtkUnicodeString result;

  if(value)
    {
    size_type length = 0;
    while(value[length])
      ++length;

    try
      {
      vtk_utf8::utf16to8(value, value + length, vtkUnicodeString::back_insert_iterator(result.Storage));
      }
    catch(vtk_utf8::invalid_utf16&)
      {
      vtkGenericWarningMacro(<< "vtkUnicodeString::from_utf16(): not a valid UTF-16 string.");
      }
    }

  return result;
}

vtkUnicodeString& vtkUnicodeString::operator=(const vtkUnicodeString& rhs)
{
  if(this == &rhs)
    return *this;

  this->Storage = rhs.Storage;
  return *this;
}

vtkUnicodeString::const_iterator vtkUnicodeString::begin() const
{
  return const_iterator(this->Storage.begin());
}

vtkUnicodeString::const_iterator vtkUnicodeString::end() const
{
  return const_iterator(this->Storage.end());
}

vtkUnicodeString::value_type vtkUnicodeString::at(size_type offset) const
{
  if(offset >= this->character_count())
    throw std::out_of_range("character out-of-range");

  std::string::const_iterator iterator = this->Storage.begin();
  vtk_utf8::unchecked::advance(iterator, offset);
  return vtk_utf8::unchecked::peek_next(iterator);
}

vtkUnicodeString::value_type vtkUnicodeString::operator[](size_type offset) const
{
  std::string::const_iterator iterator = this->Storage.begin();
  vtk_utf8::unchecked::advance(iterator, offset);
  return vtk_utf8::unchecked::peek_next(iterator);
}

const char* vtkUnicodeString::utf8_str() const
{
  return this->Storage.c_str();
}

void vtkUnicodeString::utf8_str(std::string& result) const
{
  result = this->Storage;
}

std::vector<vtkTypeUInt16> vtkUnicodeString::utf16_str() const
{
  std::vector<vtkTypeUInt16> result;
  vtk_utf8::unchecked::utf8to16(this->Storage.begin(), this->Storage.end(), std::back_inserter(result));
  return result;
}

void vtkUnicodeString::utf16_str(std::vector<vtkTypeUInt16>& result) const
{
  result.clear();
  vtk_utf8::unchecked::utf8to16(this->Storage.begin(), this->Storage.end(), std::back_inserter(result));
}

vtkUnicodeString::size_type vtkUnicodeString::byte_count() const
{
  return this->Storage.size();
}

vtkUnicodeString::size_type vtkUnicodeString::character_count() const
{
  return vtk_utf8::unchecked::distance(this->Storage.begin(), this->Storage.end());
}

bool vtkUnicodeString::empty() const
{
  return this->Storage.empty();
}

const vtkUnicodeString::size_type vtkUnicodeString::npos = std::string::npos;

vtkUnicodeString& vtkUnicodeString::operator+=(value_type value)
{
  this->push_back(value);
  return *this;
}

vtkUnicodeString& vtkUnicodeString::operator+=(const vtkUnicodeString& rhs)
{
  this->append(rhs);
  return *this;
}

void vtkUnicodeString::push_back(value_type character)
{
  try
    {
    vtk_utf8::append(character, vtkUnicodeString::back_insert_iterator(this->Storage));
    }
  catch(vtk_utf8::invalid_code_point&)
    {
    vtkGenericWarningMacro("vtkUnicodeString::push_back(): " << character << "is not a valid Unicode code point");
    }
}

void vtkUnicodeString::append(const vtkUnicodeString& value)
{
  this->Storage.append(value.Storage);
}

void vtkUnicodeString::append(size_type count, value_type character)
{
  try
    {
    this->Storage.append(vtkUnicodeString(count, character).Storage);
    }
  catch(vtk_utf8::invalid_code_point&)
    {
    vtkGenericWarningMacro("vtkUnicodeString::append(): " << character << "is not a valid Unicode code point");
    }
}

void vtkUnicodeString::append(const_iterator first, const_iterator last)
{
#if defined (__BORLANDC__) && (__BORLANDC__ < 0x0580)
  this->Storage.append(first.Position, last.Position - first.Position);
#else
  this->Storage.append(first.Position, last.Position);
#endif
}

void vtkUnicodeString::assign(const vtkUnicodeString& value)
{
  this->Storage.assign(value.Storage);
}

void vtkUnicodeString::assign(size_type count, value_type character)
{
  try
    {
    this->Storage.assign(vtkUnicodeString(count, character).Storage);
    }
  catch(vtk_utf8::invalid_code_point&)
    {
    vtkGenericWarningMacro("vtkUnicodeString::assign(): " << character << "is not a valid Unicode code point");
    }
}

void vtkUnicodeString::assign(const_iterator first, const_iterator last)
{
#if defined (__BORLANDC__) && (__BORLANDC__ < 0x0580)
  this->Storage.assign(first.Position, last.Position - first.Position);
#else
  this->Storage.assign(first.Position, last.Position);
#endif
}

void vtkUnicodeString::clear()
{
  this->Storage.clear();
}

vtkUnicodeString vtkUnicodeString::fold_case() const
{
  typedef std::map<value_type, vtkUnicodeString> map_t;

  static map_t map;
  if(map.empty())
    {
    #include <vtkUnicodeCaseFoldData.h>

    for(value_type* i = &vtkUnicodeCaseFoldData[0]; *i; ++i)
      {
      const value_type code = *i;
      vtkUnicodeString mapping;
      for(++i; *i; ++i)
        {
        mapping.push_back(*i);
        }
      map.insert(std::make_pair(code, mapping));
      }
    }

  vtkUnicodeString result;

  for(vtkUnicodeString::const_iterator source = this->begin(); source != this->end(); ++source)
    {
    map_t::const_iterator target = map.find(*source);
    if(target != map.end())
      {
      result.append(target->second);
      }
    else
      {
      result.push_back(*source);
      }
    }

  return result;
}

int vtkUnicodeString::compare(const vtkUnicodeString& rhs) const
{
  return this->Storage.compare(rhs.Storage);
}

vtkUnicodeString vtkUnicodeString::substr(size_type offset, size_type count) const
{
  std::string::const_iterator from = this->Storage.begin();
  std::string::const_iterator last = this->Storage.end();

  while(from != last && offset--)
    vtk_utf8::unchecked::advance(from, 1);

  std::string::const_iterator to = from;
  while(to != last && count--)
    vtk_utf8::unchecked::advance(to, 1);

  return vtkUnicodeString(from, to);
}

void vtkUnicodeString::swap(vtkUnicodeString& rhs)
{
  std::swap(this->Storage, rhs.Storage);
}

bool operator==(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) == 0;
}

bool operator!=(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) != 0;
}

bool operator<(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) < 0;
}

bool operator<=(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) <= 0;
}

bool operator>=(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) >= 0;
}

bool operator>(const vtkUnicodeString& lhs, const vtkUnicodeString& rhs)
{
  return lhs.compare(rhs) > 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: i18nmap.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:34:53 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SVARRAY_HXX
#include <svtools/svarray.hxx>
#endif

#ifndef _XMLOFF_I18NMAP_HXX
#include "i18nmap.hxx"
#endif

#ifdef _USE_NAMESPACE
using namespace rtl;
#endif

class SvI18NMapEntry_Impl
{
    USHORT          nKind;
    OUString        aName;
    OUString        aNewName;

public:

    const OUString& GetNewName() const { return aNewName; }

    SvI18NMapEntry_Impl( USHORT nKnd, const OUString& rName,
                         const OUString& rNewName ) :
        nKind( nKnd ),
        aName( rName ),
        aNewName( rNewName )
    {}

    SvI18NMapEntry_Impl( USHORT nKnd, const OUString& rName ) :
        nKind( nKnd ),
        aName( rName )
    {}

    BOOL operator==( const SvI18NMapEntry_Impl& r ) const
    {
        return nKind == r.nKind &&
               aName == r.aName;
    }

    BOOL operator<( const SvI18NMapEntry_Impl& r ) const
    {
        return nKind < r.nKind ||
               ( nKind == r.nKind &&
                 aName < r.aName);
    }
};

typedef SvI18NMapEntry_Impl *SvI18NMapEntry_ImplPtr;
SV_DECL_PTRARR_SORT_DEL( SvI18NMap_Impl, SvI18NMapEntry_ImplPtr, 20, 5 )
SV_IMPL_OP_PTRARR_SORT( SvI18NMap_Impl, SvI18NMapEntry_ImplPtr )

// ---------------------------------------------------------------------

SvI18NMapEntry_Impl *SvI18NMap::_Find( USHORT nKind,
                                     const OUString& rName ) const
{
    SvI18NMapEntry_Impl *pRet = 0;
    SvI18NMapEntry_Impl aTst( nKind, rName );

    USHORT nPos;
    if( pImpl->Seek_Entry( &aTst, &nPos ) )
    {
        pRet = (*pImpl)[nPos];
    }

    return pRet;
}

SvI18NMap::SvI18NMap() :
    pImpl( 0 )
{
    pImpl = new SvI18NMap_Impl;
}

SvI18NMap::~SvI18NMap()
{
    delete pImpl;
}

void SvI18NMap::Add( USHORT nKind, const OUString& rName,
                     const OUString& rNewName )
{
    SvI18NMapEntry_Impl *pEntry = _Find( nKind, rName );
    DBG_ASSERT( !pEntry, "SvI18NMap::Add: item registered already" );
    if( !pEntry )
    {
        pEntry = new SvI18NMapEntry_Impl( nKind, rName, rNewName );
        pImpl->Insert( pEntry );
    }
}

const OUString& SvI18NMap::Get( USHORT nKind, const OUString& rName ) const
{
    SvI18NMapEntry_Impl *pEntry = _Find( nKind, rName );
    if( pEntry )
        return pEntry->GetNewName();
    else
        return rName;
}

<commit_msg>INTEGRATION: CWS vgcleanupmacros (1.2.126); FILE MERGED 2006/05/17 11:24:06 vg 1.2.126.1: #i65486# cleanup:remove obsolete macros<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: i18nmap.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2006-06-02 12:33:58 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SVARRAY_HXX
#include <svtools/svarray.hxx>
#endif

#ifndef _XMLOFF_I18NMAP_HXX
#include "i18nmap.hxx"
#endif

using namespace rtl;

class SvI18NMapEntry_Impl
{
    USHORT          nKind;
    OUString        aName;
    OUString        aNewName;

public:

    const OUString& GetNewName() const { return aNewName; }

    SvI18NMapEntry_Impl( USHORT nKnd, const OUString& rName,
                         const OUString& rNewName ) :
        nKind( nKnd ),
        aName( rName ),
        aNewName( rNewName )
    {}

    SvI18NMapEntry_Impl( USHORT nKnd, const OUString& rName ) :
        nKind( nKnd ),
        aName( rName )
    {}

    BOOL operator==( const SvI18NMapEntry_Impl& r ) const
    {
        return nKind == r.nKind &&
               aName == r.aName;
    }

    BOOL operator<( const SvI18NMapEntry_Impl& r ) const
    {
        return nKind < r.nKind ||
               ( nKind == r.nKind &&
                 aName < r.aName);
    }
};

typedef SvI18NMapEntry_Impl *SvI18NMapEntry_ImplPtr;
SV_DECL_PTRARR_SORT_DEL( SvI18NMap_Impl, SvI18NMapEntry_ImplPtr, 20, 5 )
SV_IMPL_OP_PTRARR_SORT( SvI18NMap_Impl, SvI18NMapEntry_ImplPtr )

// ---------------------------------------------------------------------

SvI18NMapEntry_Impl *SvI18NMap::_Find( USHORT nKind,
                                     const OUString& rName ) const
{
    SvI18NMapEntry_Impl *pRet = 0;
    SvI18NMapEntry_Impl aTst( nKind, rName );

    USHORT nPos;
    if( pImpl->Seek_Entry( &aTst, &nPos ) )
    {
        pRet = (*pImpl)[nPos];
    }

    return pRet;
}

SvI18NMap::SvI18NMap() :
    pImpl( 0 )
{
    pImpl = new SvI18NMap_Impl;
}

SvI18NMap::~SvI18NMap()
{
    delete pImpl;
}

void SvI18NMap::Add( USHORT nKind, const OUString& rName,
                     const OUString& rNewName )
{
    SvI18NMapEntry_Impl *pEntry = _Find( nKind, rName );
    DBG_ASSERT( !pEntry, "SvI18NMap::Add: item registered already" );
    if( !pEntry )
    {
        pEntry = new SvI18NMapEntry_Impl( nKind, rName, rNewName );
        pImpl->Insert( pEntry );
    }
}

const OUString& SvI18NMap::Get( USHORT nKind, const OUString& rName ) const
{
    SvI18NMapEntry_Impl *pEntry = _Find( nKind, rName );
    if( pEntry )
        return pEntry->GetNewName();
    else
        return rName;
}

<|endoftext|>


<commit_before>#include "IO.h"
#include <utils/stringutils.h>
#include <sstream>
#include <fstream>
#include <string.h>
#include <errors.h>

#if HAVE_ASSIMP
#include <assimp/Importer.hpp>      // C++ importer interface
#include <assimp/scene.h>           // Output data structure
#include <assimp/postprocess.h>     // Post processing flags

using namespace Assimp;
#endif

namespace Meshing {

///Returns true if the extension is a file type that we can load from
bool CanLoadTriMeshExt(const char* ext)
{
  if(0==strcmp(ext,"tri")) return true;
  else if(0==strcmp(ext,"off")) return true;
  else {
#if HAVE_ASSIMP
    Assimp::Importer importer;
    string dext = "."+string(ext);
    return importer.IsExtensionSupported(dext.c_str());
#endif
  }
  return false;
}

///Returns true if the extension is a file type that we can save to
bool CanSaveTriMeshExt(const char* ext)
{
  if(0==strcmp(ext,"tri")) return true;
  else if(0==strcmp(ext,"off")) return true;
  else {
#if HAVE_ASSIMP
    //TODO: check exporter
#endif
  }
  return false;
}

///Import will try to determine the file type via the file extension
bool Import(const char* fn,TriMesh& tri)
{
  const char* ext=FileExtension(fn);
  if(0==strcmp(ext,"tri")) {
    return LoadMultipleTriMeshes(fn,tri);
  }
  else {
#if HAVE_ASSIMP
    if(!LoadAssimp(fn,tri)) {
      fprintf(stderr,"Import(TriMesh): file %s could not be loaded\n",fn);
      return false;
    }
    else {
      return true;
    }
#else
    if(0==strcmp(ext,"wrl")) {
      ifstream in(fn,ios::in);
      if(!in) return false;
      return LoadVRML(in,tri);
    }
    else if(0==strcmp(ext,"off")) {
      ifstream in(fn,ios::in);
      if(!in) return false;
      return LoadOFF(in,tri);
    }
    else {
      fprintf(stderr,"Import(TriMesh): file extension %s not recognized\n",ext);
      return false;
    }
#endif
  }
}

bool Export(const char* fn,const TriMesh& tri)
{
  const char* ext=FileExtension(fn);
  if(0==strcmp(ext,"tri")) {
    ofstream out(fn,ios::out);
    if(!out) return false;
    out<<tri;
    return true;
  }
  else {
#if HAVE_ASSIMP
    if(!SaveAssimp(fn,tri)) {
      fprintf(stderr,"Export(TriMesh): file %s could not be saved to type %s\n",fn,ext);
      return false;
    }
    else {
      return true;
    }
#else
    if(0==strcmp(ext,"wrl")) {
      ofstream out(fn,ios::out);
      if(!out) return false;
      return SaveVRML(out,tri);
    }
    else if(0==strcmp(ext,"off")) {
      ofstream out(fn,ios::out);
      if(!out) return false;
      return SaveOFF(out,tri);
    }
    else {
      fprintf(stderr,"Export(TriMesh): file extension %s not recognized\n",ext);
      return false;
    }
#endif
  }
}

///Loads from VRML file format
bool LoadVRML(std::istream& in,TriMesh& tri)
{
  fprintf(stderr,"LoadVRML not implemented yet\n");
  return false;
}

///Saves to VRML file format
bool SaveVRML(std::ostream& out,const TriMesh& tri)
{
  fprintf(stderr,"SaveVRML not implemented yet\n");
  return false;
}

///Loads from the GeomView Object File Format (OFF)
bool LoadOFF(std::istream& in,TriMesh& tri)
{
  string tag;
  in>>tag;
  if(tag != "OFF") {
    fprintf(stderr,"LoadOFF: not a proper OFF file\n");
    return false;
  }
  int mode = 0; //0: waiting for sizes, 1: reading verts, 2: reading tris
  int numFaces = 0;
  int vertIndex=0,faceIndex=0;
  string line;
  while(in) {
    getline(in,line);
    if(in.bad()) return false;
    if(line.length() == 0) continue;
    if(line[0] == '#') continue; //comment line
    if(mode == 0) {
      stringstream ss(line);
      int nv,nf,ne;
      ss>>nv>>nf>>ne;
      if(ss.bad()) {
	in.setstate(ios::badbit);
	return false;
      }
      tri.verts.resize(nv);
      tri.tris.resize(0);
      numFaces = nf;
      mode = 1;
    }
    if(mode == 1) {
      if((int)tri.verts.size() == vertIndex) mode=2;
      else {
	stringstream ss(line);
	ss >> tri.verts[vertIndex];
	if(ss.bad()) {
	  in.setstate(ios::badbit);
	  return false;
	}
	//ignore RGBA colors
	vertIndex++;
      }
    }
    if(mode == 2) {
      if(faceIndex == numFaces) return true;
      else {
	stringstream ss(line);
	int nv;
	vector<int> face;
	ss >> nv;
	if(ss.bad()) {
	  in.setstate(ios::badbit);
	  return false;
	}
	for(int i=0;i<nv;i++) {
	  int v;
	  ss>>v;
	  face.push_back(v);
	}
	if(ss.bad()) {
	  in.setstate(ios::badbit);
	  return false;
	}
	//ignore RGBA colors

	//triangulate faces, assume convex
	for(int i=1;i+1<nv;i++) {
	  tri.tris.push_back(IntTriple(face[0],face[i],face[i+1]));
	}

	faceIndex++;
      }
    }
  }
  return false;
}

///Saves to the GeomView Object File Format (OFF)
bool SaveOFF(std::ostream& out,const TriMesh& tri)
{
  out<<"OFF"<<endl;
  out<<tri.verts.size()<<" "<<tri.tris.size()<<" 0"<<endl;
  for(size_t i=0;i<tri.verts.size();i++)
    out<<tri.verts[i]<<endl;
  for(size_t i=0;i<tri.tris.size();i++)
    out<<"3  "<<tri.tris[i]<<endl;
  return true;
}

#if HAVE_ASSIMP

bool LoadAssimp(const char* fn, TriMesh& mesh)
{
	vector<TriMesh> models;
	if(!LoadAssimp(fn,models)) return false;
	mesh.Merge(models);
	return true;
}

void Cast(const aiMatrix4x4& a,Matrix4& out)
{
  out(0,0) = a.a1;
  out(0,1) = a.a2;
  out(0,2) = a.a3;
  out(0,3) = a.a4;
  out(1,0) = a.b1;
  out(1,1) = a.b2;
  out(1,2) = a.b3;
  out(1,3) = a.b4;
  out(2,0) = a.c1;
  out(2,1) = a.c2;
  out(2,2) = a.c3;
  out(2,3) = a.c4;
  out(3,0) = a.d1;
  out(3,1) = a.d2;
  out(3,2) = a.d3;
  out(3,3) = a.d4;
}

bool WalkAssimpNodes(const char* fn,const aiScene* scene,const aiNode* node,const Matrix4& Tparent,vector<TriMesh>& models)
{
  //cout<<node->mName.C_Str()<<" transform: "<<endl;
  Matrix4 T;
  Cast(node->mTransformation,T);
  //cout<<T<<endl;
  T = Tparent * T;
  //cout<<"final: "<<T<<endl;
  //if(node->mNumMeshes != 0)
  //getchar();

  for (unsigned int i = 0; i < node->mNumMeshes; i++) {
    unsigned int m = node->mMeshes[i];
    if (scene->mMeshes && scene->mMeshes[m]) {
      if (scene->mMeshes[m]->HasFaces()) {
	int nfaces = scene->mMeshes[m]->mNumFaces;
	int nverts = scene->mMeshes[m]->mNumVertices;
	models.resize(models.size()+1);
	models.back().tris.resize(nfaces);
	models.back().verts.resize(nverts);
	for (int j = 0; j < nfaces; j++) {
	  const aiFace& face = scene->mMeshes[m]->mFaces[j];
	  Assert(face.mNumIndices == 3);
	  models.back().tris[j].set(face.mIndices[0], face.mIndices[1], face.mIndices[2]);
	}
	for (int j = 0; j < nverts; j++) {
	  const aiVector3D& vert = scene->mMeshes[m]->mVertices[j];
	  T.mulPoint(Vector3((double)vert.x, (double)vert.y, (double)vert.z),models.back().verts[j]);
	}
	if(!models.back().IsValid()) {
	  cerr<<"Warning: the triangle mesh is invalid or has degenerate triangles."<<endl;
	  cerr<<"Continuing may have unexpected results."<<endl;
	  cerr<<"Press enter to continue."<<endl;
	  getchar();
	}

      } else {
	cout << "Error processing " << fn << ", no faces!" << endl;
	return false;
      }
    } else {
      cout << "Error processing " << fn << ", no mesh!" << endl;
      return false;
    }
  }
  for(unsigned int i=0;i<node->mNumChildren;i++)
    if(!WalkAssimpNodes(fn,scene,node->mChildren[i],T,models)) return false;
  return true;
}

bool LoadAssimp(const char* fn, vector<TriMesh>& models)
{
	Assimp::Importer importer;
	const aiScene* scene = importer.ReadFile(fn, aiProcess_Triangulate);
	// If the import failed, report it
	if (!scene || scene->mNumMeshes == 0) {
		std::cout << "AssimpImporter:"<<importer.GetErrorString() << std::endl;
		cout << "AssimpImporter:"<<"Error Processing " << fn << "!" << endl;
		return false;
	}
	models.resize(0);
	Matrix4 Tident; Tident.setIdentity();
	/*
	Matrix4 Tyz;
	Tyz.setZero();
	Tyz(0,0) = 1;
	Tyz(1,2) = -1;
	Tyz(2,1) = 1;
	Tyz(3,3) = 1;
	*/
	//if(!WalkAssimpNodes(fn,scene,scene->mRootNode,Tyz,models)) {
	if(!WalkAssimpNodes(fn,scene,scene->mRootNode,Tident,models)) {
	  cout << "AssimpImporter:"<<"Error Processing " << fn << "!" << endl;
	  return false;
	}
	return true;
}

bool SaveAssimp(const char* fn, const TriMesh& model)
{
  cout<<"Assimp saving not defined yet"<<endl;
  return false;
}

#else

bool LoadAssimp(const char* fn, TriMesh& mesh)
{
	cout<<"No Assimp Importer defined!"<<endl;
	return false;
}

bool LoadAssimp(const char* fn, vector<TriMesh>& meshes)
{
	cout<<"No Assimp Importer defined!"<<endl;
	return false;
}

bool SaveAssimp(const char* fn, const TriMesh& mesh)
{
	cout<<"No Assimp Exporter defined!"<<endl;
	return false;
}

#endif

} //namespace Meshing
<commit_msg>Meshes with no faces are now a warning rather than an error<commit_after>#include "IO.h"
#include <utils/stringutils.h>
#include <sstream>
#include <fstream>
#include <string.h>
#include <errors.h>

#if HAVE_ASSIMP
#include <assimp/Importer.hpp>      // C++ importer interface
#include <assimp/scene.h>           // Output data structure
#include <assimp/postprocess.h>     // Post processing flags

using namespace Assimp;
#endif

namespace Meshing {

///Returns true if the extension is a file type that we can load from
bool CanLoadTriMeshExt(const char* ext)
{
  if(0==strcmp(ext,"tri")) return true;
  else if(0==strcmp(ext,"off")) return true;
  else {
#if HAVE_ASSIMP
    Assimp::Importer importer;
    string dext = "."+string(ext);
    return importer.IsExtensionSupported(dext.c_str());
#endif
  }
  return false;
}

///Returns true if the extension is a file type that we can save to
bool CanSaveTriMeshExt(const char* ext)
{
  if(0==strcmp(ext,"tri")) return true;
  else if(0==strcmp(ext,"off")) return true;
  else {
#if HAVE_ASSIMP
    //TODO: check exporter
#endif
  }
  return false;
}

///Import will try to determine the file type via the file extension
bool Import(const char* fn,TriMesh& tri)
{
  const char* ext=FileExtension(fn);
  if(0==strcmp(ext,"tri")) {
    return LoadMultipleTriMeshes(fn,tri);
  }
  else {
#if HAVE_ASSIMP
    if(!LoadAssimp(fn,tri)) {
      fprintf(stderr,"Import(TriMesh): file %s could not be loaded\n",fn);
      return false;
    }
    else {
      return true;
    }
#else
    if(0==strcmp(ext,"wrl")) {
      ifstream in(fn,ios::in);
      if(!in) return false;
      return LoadVRML(in,tri);
    }
    else if(0==strcmp(ext,"off")) {
      ifstream in(fn,ios::in);
      if(!in) return false;
      return LoadOFF(in,tri);
    }
    else {
      fprintf(stderr,"Import(TriMesh): file extension %s not recognized\n",ext);
      return false;
    }
#endif
  }
}

bool Export(const char* fn,const TriMesh& tri)
{
  const char* ext=FileExtension(fn);
  if(0==strcmp(ext,"tri")) {
    ofstream out(fn,ios::out);
    if(!out) return false;
    out<<tri;
    return true;
  }
  else {
#if HAVE_ASSIMP
    if(!SaveAssimp(fn,tri)) {
      fprintf(stderr,"Export(TriMesh): file %s could not be saved to type %s\n",fn,ext);
      return false;
    }
    else {
      return true;
    }
#else
    if(0==strcmp(ext,"wrl")) {
      ofstream out(fn,ios::out);
      if(!out) return false;
      return SaveVRML(out,tri);
    }
    else if(0==strcmp(ext,"off")) {
      ofstream out(fn,ios::out);
      if(!out) return false;
      return SaveOFF(out,tri);
    }
    else {
      fprintf(stderr,"Export(TriMesh): file extension %s not recognized\n",ext);
      return false;
    }
#endif
  }
}

///Loads from VRML file format
bool LoadVRML(std::istream& in,TriMesh& tri)
{
  fprintf(stderr,"LoadVRML not implemented yet\n");
  return false;
}

///Saves to VRML file format
bool SaveVRML(std::ostream& out,const TriMesh& tri)
{
  fprintf(stderr,"SaveVRML not implemented yet\n");
  return false;
}

///Loads from the GeomView Object File Format (OFF)
bool LoadOFF(std::istream& in,TriMesh& tri)
{
  string tag;
  in>>tag;
  if(tag != "OFF") {
    fprintf(stderr,"LoadOFF: not a proper OFF file\n");
    return false;
  }
  int mode = 0; //0: waiting for sizes, 1: reading verts, 2: reading tris
  int numFaces = 0;
  int vertIndex=0,faceIndex=0;
  string line;
  while(in) {
    getline(in,line);
    if(in.bad()) return false;
    if(line.length() == 0) continue;
    if(line[0] == '#') continue; //comment line
    if(mode == 0) {
      stringstream ss(line);
      int nv,nf,ne;
      ss>>nv>>nf>>ne;
      if(ss.bad()) {
	in.setstate(ios::badbit);
	return false;
      }
      tri.verts.resize(nv);
      tri.tris.resize(0);
      numFaces = nf;
      mode = 1;
    }
    if(mode == 1) {
      if((int)tri.verts.size() == vertIndex) mode=2;
      else {
	stringstream ss(line);
	ss >> tri.verts[vertIndex];
	if(ss.bad()) {
	  in.setstate(ios::badbit);
	  return false;
	}
	//ignore RGBA colors
	vertIndex++;
      }
    }
    if(mode == 2) {
      if(faceIndex == numFaces) return true;
      else {
	stringstream ss(line);
	int nv;
	vector<int> face;
	ss >> nv;
	if(ss.bad()) {
	  in.setstate(ios::badbit);
	  return false;
	}
	for(int i=0;i<nv;i++) {
	  int v;
	  ss>>v;
	  face.push_back(v);
	}
	if(ss.bad()) {
	  in.setstate(ios::badbit);
	  return false;
	}
	//ignore RGBA colors

	//triangulate faces, assume convex
	for(int i=1;i+1<nv;i++) {
	  tri.tris.push_back(IntTriple(face[0],face[i],face[i+1]));
	}

	faceIndex++;
      }
    }
  }
  return false;
}

///Saves to the GeomView Object File Format (OFF)
bool SaveOFF(std::ostream& out,const TriMesh& tri)
{
  out<<"OFF"<<endl;
  out<<tri.verts.size()<<" "<<tri.tris.size()<<" 0"<<endl;
  for(size_t i=0;i<tri.verts.size();i++)
    out<<tri.verts[i]<<endl;
  for(size_t i=0;i<tri.tris.size();i++)
    out<<"3  "<<tri.tris[i]<<endl;
  return true;
}

#if HAVE_ASSIMP

bool LoadAssimp(const char* fn, TriMesh& mesh)
{
	vector<TriMesh> models;
	if(!LoadAssimp(fn,models)) return false;
	mesh.Merge(models);
	return true;
}

void Cast(const aiMatrix4x4& a,Matrix4& out)
{
  out(0,0) = a.a1;
  out(0,1) = a.a2;
  out(0,2) = a.a3;
  out(0,3) = a.a4;
  out(1,0) = a.b1;
  out(1,1) = a.b2;
  out(1,2) = a.b3;
  out(1,3) = a.b4;
  out(2,0) = a.c1;
  out(2,1) = a.c2;
  out(2,2) = a.c3;
  out(2,3) = a.c4;
  out(3,0) = a.d1;
  out(3,1) = a.d2;
  out(3,2) = a.d3;
  out(3,3) = a.d4;
}

bool WalkAssimpNodes(const char* fn,const aiScene* scene,const aiNode* node,const Matrix4& Tparent,vector<TriMesh>& models)
{
  //cout<<node->mName.C_Str()<<" transform: "<<endl;
  Matrix4 T;
  Cast(node->mTransformation,T);
  //cout<<T<<endl;
  T = Tparent * T;
  //cout<<"final: "<<T<<endl;
  //if(node->mNumMeshes != 0)
  //getchar();

  for (unsigned int i = 0; i < node->mNumMeshes; i++) {
    unsigned int m = node->mMeshes[i];
    if (scene->mMeshes && scene->mMeshes[m]) {
      if (scene->mMeshes[m]->HasFaces()) {
	int nfaces = scene->mMeshes[m]->mNumFaces;
	int nverts = scene->mMeshes[m]->mNumVertices;
	models.resize(models.size()+1);
	models.back().tris.resize(nfaces);
	models.back().verts.resize(nverts);
	for (int j = 0; j < nfaces; j++) {
	  const aiFace& face = scene->mMeshes[m]->mFaces[j];
	  Assert(face.mNumIndices == 3);
	  models.back().tris[j].set(face.mIndices[0], face.mIndices[1], face.mIndices[2]);
	}
	for (int j = 0; j < nverts; j++) {
	  const aiVector3D& vert = scene->mMeshes[m]->mVertices[j];
	  T.mulPoint(Vector3((double)vert.x, (double)vert.y, (double)vert.z),models.back().verts[j]);
	}
	if(!models.back().IsValid()) {
	  cerr<<"Warning: the triangle mesh is invalid or has degenerate triangles."<<endl;
	  cerr<<"Continuing may have unexpected results."<<endl;
	  cerr<<"Press enter to continue."<<endl;
	  getchar();
	}

      } else {
	cout << "AssimpImporter: Warning, " << fn << ", mesh "<<m<<" has no faces" << endl;
      }
    } else {
      cout << "AssimpImporter: Warning, " << fn << " has no mesh" << endl;
    }
  }
  for(unsigned int i=0;i<node->mNumChildren;i++)
    if(!WalkAssimpNodes(fn,scene,node->mChildren[i],T,models)) return false;
  return true;
}

bool LoadAssimp(const char* fn, vector<TriMesh>& models)
{
	Assimp::Importer importer;
	const aiScene* scene = importer.ReadFile(fn, aiProcess_Triangulate);
	// If the import failed, report it
	if (!scene || scene->mNumMeshes == 0) {
		std::cout << "AssimpImporter:"<<importer.GetErrorString() << std::endl;
		cout << "AssimpImporter:"<<"Error Processing " << fn << "!" << endl;
		return false;
	}
	models.resize(0);
	Matrix4 Tident; Tident.setIdentity();
	/*
	Matrix4 Tyz;
	Tyz.setZero();
	Tyz(0,0) = 1;
	Tyz(1,2) = -1;
	Tyz(2,1) = 1;
	Tyz(3,3) = 1;
	*/
	//if(!WalkAssimpNodes(fn,scene,scene->mRootNode,Tyz,models)) {
	if(!WalkAssimpNodes(fn,scene,scene->mRootNode,Tident,models)) {
	  cout << "AssimpImporter:"<<"Error Processing " << fn << "!" << endl;
	  return false;
	}
	return true;
}

bool SaveAssimp(const char* fn, const TriMesh& model)
{
  cout<<"Assimp saving not defined yet"<<endl;
  return false;
}

#else

bool LoadAssimp(const char* fn, TriMesh& mesh)
{
	cout<<"No Assimp Importer defined!"<<endl;
	return false;
}

bool LoadAssimp(const char* fn, vector<TriMesh>& meshes)
{
	cout<<"No Assimp Importer defined!"<<endl;
	return false;
}

bool SaveAssimp(const char* fn, const TriMesh& mesh)
{
	cout<<"No Assimp Exporter defined!"<<endl;
	return false;
}

#endif

} //namespace Meshing
<|endoftext|>