Add project file(.ds3) reader and writer
parent
130ffdae79
commit
ff19efa188
|
@ -10,9 +10,6 @@ HEADERS += src/mainwindow.h
|
|||
SOURCES += src/modelingwidget.cpp
|
||||
HEADERS += src/modelingwidget.h
|
||||
|
||||
SOURCES += src/skeletoneditwidget.cpp
|
||||
HEADERS += src/skeletoneditwidget.h
|
||||
|
||||
SOURCES += src/skeletoneditgraphicsview.cpp
|
||||
HEADERS += src/skeletoneditgraphicsview.h
|
||||
|
||||
|
@ -31,8 +28,8 @@ HEADERS += src/turnaroundloader.h
|
|||
SOURCES += src/skeletonwidget.cpp
|
||||
HEADERS += src/skeletonwidget.h
|
||||
|
||||
SOURCES += src/combineeditwidget.cpp
|
||||
HEADERS += src/combineeditwidget.h
|
||||
SOURCES += src/ds3file.cpp
|
||||
HEADERS += src/ds3file.h
|
||||
|
||||
SOURCES += src/theme.cpp
|
||||
HEADERS += src/theme.h
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#include <QGridLayout>
|
||||
#include "combineeditwidget.h"
|
||||
|
||||
CombineEditWidget::CombineEditWidget(QWidget *parent) :
|
||||
QFrame(parent)
|
||||
{
|
||||
m_modelingWidget = new ModelingWidget(this);
|
||||
|
||||
QGridLayout *mainLayout = new QGridLayout;
|
||||
mainLayout->addWidget(m_modelingWidget, 0, 0, 1, 1);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
ModelingWidget *CombineEditWidget::modelingWidget()
|
||||
{
|
||||
return m_modelingWidget;
|
||||
}
|
||||
|
||||
void CombineEditWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QFrame::resizeEvent(event);
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef COMBINE_EDIT_WIDGET_H
|
||||
#define COMBINE_EDIT_WIDGET_H
|
||||
#include <QFrame>
|
||||
#include "modelingwidget.h"
|
||||
|
||||
class CombineEditWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void sizeChanged();
|
||||
public:
|
||||
CombineEditWidget(QWidget *parent = 0);
|
||||
ModelingWidget *modelingWidget();
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
private:
|
||||
ModelingWidget *m_modelingWidget;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,160 @@
|
|||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QXmlStreamReader>
|
||||
#include "ds3file.h"
|
||||
|
||||
QString Ds3FileReader::m_applicationName = QString("DUST3D");
|
||||
QString Ds3FileReader::m_fileFormatVersion = QString("1.0");
|
||||
QString Ds3FileReader::m_headFormat = QString("xml");
|
||||
|
||||
QString Ds3FileReader::readFirstLine()
|
||||
{
|
||||
QString firstLine;
|
||||
QFile file(m_filename);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QTextStream in(&file);
|
||||
if (!in.atEnd()) {
|
||||
firstLine = in.readLine();
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
Ds3FileReader::Ds3FileReader(const QString &filename) :
|
||||
m_headerIsGood(false),
|
||||
m_binaryOffset(0)
|
||||
{
|
||||
m_filename = filename;
|
||||
QString firstLine = readFirstLine();
|
||||
QStringList tokens = firstLine.split(" ");
|
||||
if (tokens.length() < 4) {
|
||||
return;
|
||||
}
|
||||
if (tokens[0] != Ds3FileReader::m_applicationName) {
|
||||
return;
|
||||
}
|
||||
if (tokens[1] != Ds3FileReader::m_fileFormatVersion) {
|
||||
return;
|
||||
}
|
||||
if (tokens[2] != Ds3FileReader::m_headFormat) {
|
||||
return;
|
||||
}
|
||||
m_binaryOffset = tokens[3].toLongLong();
|
||||
QFile file(m_filename);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
QString header = QString::fromUtf8(file.read(m_binaryOffset).constData()).mid(firstLine.size()).trimmed();
|
||||
QXmlStreamReader xml(header);
|
||||
bool ds3TagEntered = false;
|
||||
while (!xml.atEnd()) {
|
||||
xml.readNext();
|
||||
if (xml.isStartElement()) {
|
||||
if (xml.name() == "ds3") {
|
||||
ds3TagEntered = true;
|
||||
m_headerIsGood = true;
|
||||
} else {
|
||||
if (ds3TagEntered) {
|
||||
Ds3ReaderItem readerItem;
|
||||
readerItem.type = xml.name().toString().trimmed();
|
||||
readerItem.name = xml.attributes().value("name").toString().trimmed();
|
||||
readerItem.offset = xml.attributes().value("offset").toLongLong();
|
||||
readerItem.size = xml.attributes().value("size").toLongLong();
|
||||
m_items.push_back(readerItem);
|
||||
m_itemsMap[readerItem.name] = readerItem;
|
||||
}
|
||||
}
|
||||
} else if (xml.isEndElement()) {
|
||||
if (xml.name() == "ds3") {
|
||||
ds3TagEntered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ds3FileReader::loadItem(const QString &name, QByteArray *byteArray)
|
||||
{
|
||||
byteArray->clear();
|
||||
if (!m_headerIsGood)
|
||||
return;
|
||||
if (m_itemsMap.find(name) == m_itemsMap.end()) {
|
||||
return;
|
||||
}
|
||||
Ds3ReaderItem readerItem = m_itemsMap[name];
|
||||
QFile file(m_filename);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
if (!file.seek(m_binaryOffset + readerItem.offset)) {
|
||||
return;
|
||||
}
|
||||
*byteArray = file.read(readerItem.size);
|
||||
}
|
||||
|
||||
const QList<Ds3ReaderItem> &Ds3FileReader::items()
|
||||
{
|
||||
return m_items;
|
||||
}
|
||||
|
||||
bool Ds3FileWriter::add(const QString &name, const QString &type, const QByteArray *byteArray)
|
||||
{
|
||||
if (m_itemsMap.find(name) != m_itemsMap.end()) {
|
||||
return false;
|
||||
}
|
||||
Ds3WriterItem writerItem;
|
||||
writerItem.type = type;
|
||||
writerItem.name = name;
|
||||
writerItem.byteArray = byteArray;
|
||||
m_itemsMap[name] = writerItem;
|
||||
m_items.push_back(writerItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ds3FileWriter::save(const QString &filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray headerXml;
|
||||
{
|
||||
QXmlStreamWriter stream(&headerXml);
|
||||
stream.setAutoFormatting(true);
|
||||
stream.writeStartDocument();
|
||||
stream.writeStartElement("ds3");
|
||||
|
||||
long long offset = 0;
|
||||
for (int i = 0; i < m_items.size(); i++) {
|
||||
Ds3WriterItem *writerItem = &m_items[i];
|
||||
stream.writeStartElement(writerItem->type);
|
||||
stream.writeAttribute("name", QString("%1").arg(writerItem->name));
|
||||
stream.writeAttribute("offset", QString("%1").arg(offset));
|
||||
stream.writeAttribute("size", QString("%1").arg(writerItem->byteArray->size()));
|
||||
offset += writerItem->byteArray->size();
|
||||
stream.writeEndElement();
|
||||
}
|
||||
|
||||
stream.writeEndElement();
|
||||
stream.writeEndDocument();
|
||||
}
|
||||
char firstLine[1024];
|
||||
int firstLineSizeExcludeSizeSelf = sprintf(firstLine, "%s %s %s ",
|
||||
Ds3FileReader::m_applicationName.toUtf8().constData(),
|
||||
Ds3FileReader::m_fileFormatVersion.toUtf8().constData(),
|
||||
Ds3FileReader::m_headFormat.toUtf8().constData());
|
||||
unsigned int headerSize = firstLineSizeExcludeSizeSelf + 12 + headerXml.size();
|
||||
char headerSizeString[100] = {0};
|
||||
sprintf(headerSizeString, "%010u\r\n", headerSize);
|
||||
file.write(firstLine, firstLineSizeExcludeSizeSelf);
|
||||
file.write(headerSizeString, strlen(headerSizeString));
|
||||
file.write(headerXml);
|
||||
for (int i = 0; i < m_items.size(); i++) {
|
||||
Ds3WriterItem *writerItem = &m_items[i];
|
||||
file.write(*writerItem->byteArray);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef DS3_FILE_H
|
||||
#define DS3_FILE_H
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
DUST3D 1.0 xml 12345
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ds3>
|
||||
<model name="ant.xml" offset="0" size="1024"/>
|
||||
<asset name="ant.jpg" offset="1024" size="279306"/>
|
||||
</ds3>
|
||||
... Binary content ...
|
||||
*/
|
||||
|
||||
class Ds3ReaderItem
|
||||
{
|
||||
public:
|
||||
QString type;
|
||||
QString name;
|
||||
long long offset;
|
||||
long long size;
|
||||
};
|
||||
|
||||
class Ds3FileReader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Ds3FileReader(const QString &filename);
|
||||
void loadItem(const QString &name, QByteArray *byteArray);
|
||||
const QList<Ds3ReaderItem> &items();
|
||||
static QString m_applicationName;
|
||||
static QString m_fileFormatVersion;
|
||||
static QString m_headFormat;
|
||||
private:
|
||||
std::map<QString, Ds3ReaderItem> m_itemsMap;
|
||||
QList<Ds3ReaderItem> m_items;
|
||||
QString m_filename;
|
||||
private:
|
||||
QString readFirstLine();
|
||||
bool m_headerIsGood;
|
||||
long long m_binaryOffset;
|
||||
};
|
||||
|
||||
class Ds3WriterItem
|
||||
{
|
||||
public:
|
||||
QString type;
|
||||
QString name;
|
||||
const QByteArray *byteArray;
|
||||
};
|
||||
|
||||
class Ds3FileWriter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool add(const QString &name, const QString &type, const QByteArray *byteArray);
|
||||
bool save(const QString &filename);
|
||||
private:
|
||||
std::map<QString, Ds3WriterItem> m_itemsMap;
|
||||
QList<Ds3WriterItem> m_items;
|
||||
QString m_filename;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -8,17 +8,18 @@
|
|||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QStackedWidget>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QBuffer>
|
||||
#include <assert.h>
|
||||
#include "mainwindow.h"
|
||||
#include "skeletonwidget.h"
|
||||
#include "combineeditwidget.h"
|
||||
#include "theme.h"
|
||||
#include "ds3file.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
m_partsPageButton = new QPushButton("Parts");
|
||||
m_combinePageButton = new QPushButton("Combine");
|
||||
m_motionPageButton = new QPushButton("Motion");
|
||||
m_modelPageButton = new QPushButton("Model");
|
||||
m_sharePageButton = new QPushButton("Share");
|
||||
|
||||
QWidget *hrWidget = new QWidget;
|
||||
hrWidget->setFixedHeight(2);
|
||||
|
@ -27,25 +28,22 @@ MainWindow::MainWindow()
|
|||
hrWidget->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QButtonGroup *pageButtonGroup = new QButtonGroup;
|
||||
pageButtonGroup->addButton(m_partsPageButton);
|
||||
pageButtonGroup->addButton(m_combinePageButton);
|
||||
pageButtonGroup->addButton(m_motionPageButton);
|
||||
pageButtonGroup->addButton(m_modelPageButton);
|
||||
pageButtonGroup->addButton(m_sharePageButton);
|
||||
|
||||
m_partsPageButton->setCheckable(true);
|
||||
m_combinePageButton->setCheckable(true);
|
||||
m_motionPageButton->setCheckable(true);
|
||||
m_modelPageButton->setCheckable(true);
|
||||
m_sharePageButton->setCheckable(true);
|
||||
|
||||
pageButtonGroup->setExclusive(true);
|
||||
|
||||
m_combinePageButton->setChecked(true);
|
||||
m_modelPageButton->setChecked(true);
|
||||
|
||||
QHBoxLayout *topButtonsLayout = new QHBoxLayout;
|
||||
topButtonsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
topButtonsLayout->setSpacing(0);
|
||||
topButtonsLayout->addStretch();
|
||||
topButtonsLayout->addWidget(m_partsPageButton);
|
||||
topButtonsLayout->addWidget(m_combinePageButton);
|
||||
topButtonsLayout->addWidget(m_motionPageButton);
|
||||
topButtonsLayout->addWidget(m_modelPageButton);
|
||||
topButtonsLayout->addWidget(m_sharePageButton);
|
||||
topButtonsLayout->addStretch();
|
||||
|
||||
QVBoxLayout *topLayout = new QVBoxLayout;
|
||||
|
@ -54,86 +52,46 @@ MainWindow::MainWindow()
|
|||
topLayout->addLayout(topButtonsLayout);
|
||||
topLayout->addWidget(hrWidget);
|
||||
|
||||
QVBoxLayout *partsRightLayout = new QVBoxLayout;
|
||||
QVBoxLayout *modelRightLayout = new QVBoxLayout;
|
||||
|
||||
partsRightLayout->addSpacing(20);
|
||||
modelRightLayout->addSpacing(20);
|
||||
|
||||
QPushButton *changeTurnaroundButton = new QPushButton(" Change Turnaround ");
|
||||
partsRightLayout->addWidget(changeTurnaroundButton);
|
||||
modelRightLayout->addWidget(changeTurnaroundButton);
|
||||
|
||||
QPushButton *exportPartsModelButton = new QPushButton(" Export Model(.obj) ");
|
||||
partsRightLayout->addWidget(exportPartsModelButton);
|
||||
QPushButton *exportPartsModelButton = new QPushButton(" Export ");
|
||||
modelRightLayout->addWidget(exportPartsModelButton);
|
||||
|
||||
QPushButton *newPartsButton = new QPushButton(" New Parts ");
|
||||
partsRightLayout->addWidget(newPartsButton);
|
||||
QPushButton *newModelButton = new QPushButton(" New ");
|
||||
modelRightLayout->addWidget(newModelButton);
|
||||
|
||||
QPushButton *loadPartsButton = new QPushButton(" Load Parts ");
|
||||
partsRightLayout->addWidget(loadPartsButton);
|
||||
QPushButton *loadModelButton = new QPushButton(" Load ");
|
||||
modelRightLayout->addWidget(loadModelButton);
|
||||
|
||||
QPushButton *savePartsButton = new QPushButton(" Save Parts ");
|
||||
partsRightLayout->addWidget(savePartsButton);
|
||||
QPushButton *saveModelButton = new QPushButton(" Save ");
|
||||
modelRightLayout->addWidget(saveModelButton);
|
||||
|
||||
QPushButton *savePartsAsButton = new QPushButton(" Save Parts as ");
|
||||
partsRightLayout->addWidget(savePartsAsButton);
|
||||
savePartsAsButton->hide();
|
||||
QPushButton *saveModelAsButton = new QPushButton(" Save as ");
|
||||
modelRightLayout->addWidget(saveModelAsButton);
|
||||
saveModelAsButton->hide();
|
||||
|
||||
partsRightLayout->addStretch();
|
||||
modelRightLayout->addStretch();
|
||||
|
||||
SkeletonWidget *skeletonWidget = new SkeletonWidget(this);
|
||||
m_skeletonWidget = skeletonWidget;
|
||||
|
||||
QHBoxLayout *partsPageLayout = new QHBoxLayout;
|
||||
partsPageLayout->addWidget(skeletonWidget);
|
||||
partsPageLayout->addLayout(partsRightLayout);
|
||||
QHBoxLayout *modelPageLayout = new QHBoxLayout;
|
||||
modelPageLayout->addWidget(skeletonWidget);
|
||||
modelPageLayout->addLayout(modelRightLayout);
|
||||
|
||||
QWidget *partsPageWidget = new QWidget;
|
||||
partsPageWidget->setLayout(partsPageLayout);
|
||||
QWidget *modelPageWidget = new QWidget;
|
||||
modelPageWidget->setLayout(modelPageLayout);
|
||||
|
||||
QVBoxLayout *combineRightLayout = new QVBoxLayout;
|
||||
|
||||
combineRightLayout->addSpacing(20);
|
||||
|
||||
QPushButton *importPartsToCombineButton = new QPushButton(" Import Parts ");
|
||||
combineRightLayout->addWidget(importPartsToCombineButton);
|
||||
|
||||
QPushButton *exportCombineModelButton = new QPushButton(" Export Model(.obj) ");
|
||||
combineRightLayout->addWidget(exportCombineModelButton);
|
||||
|
||||
QPushButton *newCombineButton = new QPushButton(" New Combine ");
|
||||
combineRightLayout->addWidget(newCombineButton);
|
||||
|
||||
QPushButton *loadCombineButton = new QPushButton(" Load Combine ");
|
||||
combineRightLayout->addWidget(loadCombineButton);
|
||||
|
||||
QPushButton *saveCombineButton = new QPushButton(" Save Combine ");
|
||||
combineRightLayout->addWidget(saveCombineButton);
|
||||
|
||||
QPushButton *saveCombineAsButton = new QPushButton(" Save Combine as ");
|
||||
combineRightLayout->addWidget(saveCombineAsButton);
|
||||
saveCombineAsButton->hide();
|
||||
|
||||
combineRightLayout->addStretch();
|
||||
|
||||
combineRightLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
|
||||
CombineEditWidget *combineEditWidget = new CombineEditWidget();
|
||||
|
||||
QHBoxLayout *combinePageLayout = new QHBoxLayout;
|
||||
combinePageLayout->addSpacing(10);
|
||||
combinePageLayout->addWidget(combineEditWidget);
|
||||
combinePageLayout->addStretch();
|
||||
combinePageLayout->addLayout(combineRightLayout);
|
||||
combinePageLayout->addSpacing(10);
|
||||
|
||||
QWidget *combinePageWidget = new QWidget;
|
||||
combinePageWidget->setLayout(combinePageLayout);
|
||||
|
||||
QWidget *motionPageWidget = new QWidget;
|
||||
QWidget *sharePageWidget = new QWidget;
|
||||
|
||||
QStackedWidget *stackedWidget = new QStackedWidget;
|
||||
stackedWidget->addWidget(partsPageWidget);
|
||||
stackedWidget->addWidget(combinePageWidget);
|
||||
stackedWidget->addWidget(motionPageWidget);
|
||||
stackedWidget->addWidget(modelPageWidget);
|
||||
stackedWidget->addWidget(sharePageWidget);
|
||||
|
||||
m_stackedWidget = stackedWidget;
|
||||
|
||||
|
@ -152,60 +110,85 @@ MainWindow::MainWindow()
|
|||
connectResult = connect(changeTurnaroundButton, SIGNAL(clicked()), skeletonWidget, SLOT(changeTurnaround()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(m_partsPageButton, SIGNAL(clicked()), this, SLOT(updatePageButtons()));
|
||||
connectResult = connect(m_modelPageButton, SIGNAL(clicked()), this, SLOT(updatePageButtons()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(m_combinePageButton, SIGNAL(clicked()), this, SLOT(updatePageButtons()));
|
||||
connectResult = connect(m_sharePageButton, SIGNAL(clicked()), this, SLOT(updatePageButtons()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(m_motionPageButton, SIGNAL(clicked()), this, SLOT(updatePageButtons()));
|
||||
connectResult = connect(saveModelButton, SIGNAL(clicked()), this, SLOT(saveModel()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(savePartsButton, SIGNAL(clicked()), this, SLOT(saveParts()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(loadPartsButton, SIGNAL(clicked()), this, SLOT(loadParts()));
|
||||
connectResult = connect(loadModelButton, SIGNAL(clicked()), this, SLOT(loadModel()));
|
||||
assert(connectResult);
|
||||
|
||||
updatePageButtons();
|
||||
}
|
||||
|
||||
void MainWindow::loadParts()
|
||||
void MainWindow::loadModel()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName(this,
|
||||
tr("Load Parts"), ".",
|
||||
tr("Xml files (*.xml)"));
|
||||
tr("Load Model"), ".",
|
||||
tr("Dust 3D Project (*.ds3)"));
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
m_skeletonWidget->graphicsView()->loadFromXml(filename);
|
||||
Ds3FileReader ds3Reader(filename);
|
||||
for (int i = 0; i < ds3Reader.items().size(); ++i) {
|
||||
Ds3ReaderItem item = ds3Reader.items().at(i);
|
||||
if (item.type == "model") {
|
||||
QByteArray data;
|
||||
ds3Reader.loadItem(item.name, &data);
|
||||
QXmlStreamReader xmlReader(data);
|
||||
m_skeletonWidget->graphicsView()->loadFromXmlStream(xmlReader);
|
||||
} else if (item.type == "asset") {
|
||||
if (item.name == "canvas.png") {
|
||||
QByteArray data;
|
||||
ds3Reader.loadItem(item.name, &data);
|
||||
QImage image = QImage::fromData(data, "PNG");
|
||||
m_skeletonWidget->graphicsView()->updateBackgroundImage(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::saveParts()
|
||||
void MainWindow::saveModel()
|
||||
{
|
||||
if (m_savePartsAs.isEmpty()) {
|
||||
m_savePartsAs = QFileDialog::getSaveFileName(this,
|
||||
tr("Save Parts"), ".",
|
||||
tr("Xml files (*.xml)"));
|
||||
if (m_savePartsAs.isEmpty()) {
|
||||
if (m_saveModelAs.isEmpty()) {
|
||||
m_saveModelAs = QFileDialog::getSaveFileName(this,
|
||||
tr("Save Model"), ".",
|
||||
tr("Dust 3D Project (*.ds3)"));
|
||||
if (m_saveModelAs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_skeletonWidget->graphicsView()->saveToXml(m_savePartsAs);
|
||||
|
||||
Ds3FileWriter ds3Writer;
|
||||
|
||||
QByteArray modelXml;
|
||||
QXmlStreamWriter stream(&modelXml);
|
||||
m_skeletonWidget->graphicsView()->saveToXmlStream(&stream);
|
||||
if (modelXml.size() > 0)
|
||||
ds3Writer.add("model1.xml", "model", &modelXml);
|
||||
|
||||
QByteArray imageByteArray;
|
||||
QBuffer pngBuffer(&imageByteArray);
|
||||
pngBuffer.open(QIODevice::WriteOnly);
|
||||
m_skeletonWidget->graphicsView()->backgroundImage().save(&pngBuffer, "PNG");
|
||||
if (imageByteArray.size() > 0)
|
||||
ds3Writer.add("canvas.png", "asset", &imageByteArray);
|
||||
|
||||
ds3Writer.save(m_saveModelAs);
|
||||
}
|
||||
|
||||
void MainWindow::updatePageButtons()
|
||||
{
|
||||
if (m_partsPageButton->isChecked()) {
|
||||
if (m_modelPageButton->isChecked()) {
|
||||
m_stackedWidget->setCurrentIndex(0);
|
||||
}
|
||||
if (m_combinePageButton->isChecked()) {
|
||||
if (m_sharePageButton->isChecked()) {
|
||||
m_stackedWidget->setCurrentIndex(1);
|
||||
}
|
||||
if (m_motionPageButton->isChecked()) {
|
||||
m_stackedWidget->setCurrentIndex(2);
|
||||
}
|
||||
m_partsPageButton->setStyleSheet(m_partsPageButton->isChecked() ? Theme::tabButtonSelectedStylesheet : Theme::tabButtonStylesheet);
|
||||
m_combinePageButton->setStyleSheet(m_combinePageButton->isChecked() ? Theme::tabButtonSelectedStylesheet : Theme::tabButtonStylesheet);
|
||||
m_motionPageButton->setStyleSheet(m_motionPageButton->isChecked() ? Theme::tabButtonSelectedStylesheet : Theme::tabButtonStylesheet);
|
||||
m_modelPageButton->setStyleSheet(m_modelPageButton->isChecked() ? Theme::tabButtonSelectedStylesheet : Theme::tabButtonStylesheet);
|
||||
m_sharePageButton->setStyleSheet(m_sharePageButton->isChecked() ? Theme::tabButtonSelectedStylesheet : Theme::tabButtonStylesheet);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,13 @@ public:
|
|||
MainWindow();
|
||||
public slots:
|
||||
void updatePageButtons();
|
||||
void saveParts();
|
||||
void loadParts();
|
||||
void saveModel();
|
||||
void loadModel();
|
||||
private:
|
||||
QPushButton *m_partsPageButton;
|
||||
QPushButton *m_combinePageButton;
|
||||
QPushButton *m_motionPageButton;
|
||||
QPushButton *m_modelPageButton;
|
||||
QPushButton *m_sharePageButton;
|
||||
QStackedWidget *m_stackedWidget;
|
||||
QString m_savePartsAs;
|
||||
QString m_saveModelAs;
|
||||
SkeletonWidget *m_skeletonWidget;
|
||||
};
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ static const char *fragmentShaderSourceCore =
|
|||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.99, 0.4, 0.13);\n"
|
||||
" highp vec3 color = vec3(1.0, 1.0, 1.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" fragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
@ -134,7 +134,7 @@ static const char *fragmentShaderSource =
|
|||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.99, 0.4, 0.13);\n"
|
||||
" highp vec3 color = vec3(1.0, 1.0, 1.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" gl_FragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <QGraphicsPixmapItem>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
@ -48,7 +49,7 @@ void SkeletonEditGraphicsView::toggleAddNodeMode()
|
|||
void SkeletonEditGraphicsView::applyAddNodeMode()
|
||||
{
|
||||
m_pendingNodeItem->setVisible(m_inAddNodeMode);
|
||||
m_pendingEdgeItem->setVisible(m_inAddNodeMode);
|
||||
m_pendingEdgeItem->setVisible(m_inAddNodeMode && m_nextStartNodeItem);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
|
@ -93,6 +94,10 @@ void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
|
|||
if (m_lastHoverNodeItem) {
|
||||
setNextStartNodeItem(m_lastHoverNodeItem->master());
|
||||
m_lastHoverNodeItem = NULL;
|
||||
} else {
|
||||
if (m_nextStartNodeItem) {
|
||||
setNextStartNodeItem(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +107,8 @@ void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
|
|||
void SkeletonEditGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseDoubleClickEvent(event);
|
||||
emit changeTurnaroundTriggered();
|
||||
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
||||
emit changeTurnaroundTriggered();
|
||||
}
|
||||
|
||||
float SkeletonEditGraphicsView::findXForSlave(float x)
|
||||
|
@ -110,6 +116,21 @@ float SkeletonEditGraphicsView::findXForSlave(float x)
|
|||
return x - m_backgroundItem->boundingRect().width() / 4;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
QWidget::keyPressEvent(event);
|
||||
if (!m_backgroundLoaded)
|
||||
return;
|
||||
if (event->key() == Qt::Key_A)
|
||||
toggleAddNodeMode();
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QFrame::resizeEvent(event);
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
|
@ -135,8 +156,6 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
|||
emit nodesChanged();
|
||||
}
|
||||
m_isMovingNodeItem = false;
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
toggleAddNodeMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,6 +332,16 @@ void SkeletonEditGraphicsView::updateBackgroundImage(const QImage &image)
|
|||
}
|
||||
}
|
||||
|
||||
QPixmap SkeletonEditGraphicsView::backgroundImage()
|
||||
{
|
||||
return m_backgroundItem->pixmap();
|
||||
}
|
||||
|
||||
bool SkeletonEditGraphicsView::hasBackgroundImage()
|
||||
{
|
||||
return m_backgroundLoaded;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::adjustItems(QSizeF oldSceneSize, QSizeF newSceneSize)
|
||||
{
|
||||
if (oldSceneSize == newSceneSize)
|
||||
|
@ -338,13 +367,8 @@ void SkeletonEditGraphicsView::adjustItems(QSizeF oldSceneSize, QSizeF newSceneS
|
|||
}
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::loadFromXml(const QString &filename)
|
||||
void SkeletonEditGraphicsView::loadFromXmlStream(QXmlStreamReader &reader)
|
||||
{
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float radiusMul = 1.0;
|
||||
float xMul = 1.0;
|
||||
float yMul = radiusMul;
|
||||
|
@ -353,33 +377,34 @@ void SkeletonEditGraphicsView::loadFromXml(const QString &filename)
|
|||
std::vector<std::map<QString, QString>> pendingEdges;
|
||||
std::map<QString, SkeletonEditNodeItem *> addedNodeMapById;
|
||||
|
||||
QXmlStreamReader xml;
|
||||
xml.setDevice(&file);
|
||||
while (!xml.atEnd()) {
|
||||
xml.readNext();
|
||||
printf("tokenString:%s\n", xml.tokenString().toUtf8().constData());
|
||||
if (xml.isStartElement()) {
|
||||
printf("name:%s\n", xml.name().toUtf8().constData());
|
||||
if (xml.name() == "canvas") {
|
||||
QString canvasWidth = xml.attributes().value("width").toString();
|
||||
QString canvasHeight = xml.attributes().value("height").toString();
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.isStartElement()) {
|
||||
if (reader.name() == "canvas") {
|
||||
QString canvasWidth = reader.attributes().value("width").toString();
|
||||
QString canvasHeight = reader.attributes().value("height").toString();
|
||||
float canvasHeightWidth = canvasWidth.toFloat();
|
||||
float canvasHeightVal = canvasHeight.toFloat();
|
||||
if (!hasBackgroundImage()) {
|
||||
QPixmap emptyImage((int)canvasHeightWidth, (int)canvasHeightVal);
|
||||
emptyImage.fill(QWidget::palette().color(QWidget::backgroundRole()));
|
||||
updateBackgroundImage(emptyImage.toImage());
|
||||
}
|
||||
if (canvasHeightVal > 0)
|
||||
radiusMul = (float)scene()->sceneRect().height() / canvasHeightVal;
|
||||
if (canvasHeightWidth > 0)
|
||||
xMul = (float)scene()->sceneRect().width() / canvasHeightWidth;
|
||||
yMul = radiusMul;
|
||||
} else if (xml.name() == "origin") {
|
||||
} else if (reader.name() == "origin") {
|
||||
if (pendingNodes.size() > 0) {
|
||||
pendingNodes[pendingNodes.size() - 1]["x"] = QString("%1").arg(xml.attributes().value("x").toString().toFloat() * xMul);
|
||||
pendingNodes[pendingNodes.size() - 1]["y"] = QString("%1").arg(xml.attributes().value("y").toString().toFloat() * yMul);
|
||||
pendingNodes[pendingNodes.size() - 1]["x"] = QString("%1").arg(reader.attributes().value("x").toString().toFloat() * xMul);
|
||||
pendingNodes[pendingNodes.size() - 1]["y"] = QString("%1").arg(reader.attributes().value("y").toString().toFloat() * yMul);
|
||||
}
|
||||
} else if (xml.name() == "node") {
|
||||
QString nodeId = xml.attributes().value("id").toString();
|
||||
QString nodeType = xml.attributes().value("type").toString();
|
||||
QString nodePairId = xml.attributes().value("pair").toString();
|
||||
QString nodeRadius = xml.attributes().value("radius").toString();
|
||||
} else if (reader.name() == "node") {
|
||||
QString nodeId = reader.attributes().value("id").toString();
|
||||
QString nodeType = reader.attributes().value("type").toString();
|
||||
QString nodePairId = reader.attributes().value("pair").toString();
|
||||
QString nodeRadius = reader.attributes().value("radius").toString();
|
||||
std::map<QString, QString> pendingNode;
|
||||
pendingNode["id"] = nodeId;
|
||||
pendingNode["type"] = nodeType;
|
||||
|
@ -388,10 +413,10 @@ void SkeletonEditGraphicsView::loadFromXml(const QString &filename)
|
|||
pendingNode["x"] = "0";
|
||||
pendingNode["y"] = "0";
|
||||
pendingNodes.push_back(pendingNode);
|
||||
} else if (xml.name() == "edge") {
|
||||
QString edgeId = xml.attributes().value("id").toString();
|
||||
QString edgeFromNodeId = xml.attributes().value("from").toString();
|
||||
QString edgeToNodeId = xml.attributes().value("to").toString();
|
||||
} else if (reader.name() == "edge") {
|
||||
QString edgeId = reader.attributes().value("id").toString();
|
||||
QString edgeFromNodeId = reader.attributes().value("from").toString();
|
||||
QString edgeToNodeId = reader.attributes().value("to").toString();
|
||||
if (!edgeFromNodeId.isEmpty() && !edgeToNodeId.isEmpty()) {
|
||||
std::map<QString, QString> pendingEdge;
|
||||
pendingEdge["id"] = edgeId;
|
||||
|
@ -431,18 +456,14 @@ void SkeletonEditGraphicsView::loadFromXml(const QString &filename)
|
|||
emit nodesChanged();
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::saveToXml(const QString &filename)
|
||||
void SkeletonEditGraphicsView::saveToXmlStream(QXmlStreamWriter *writer)
|
||||
{
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
writer->setAutoFormatting(true);
|
||||
writer->writeStartDocument();
|
||||
|
||||
QXmlStreamWriter stream(&file);
|
||||
stream.setAutoFormatting(true);
|
||||
stream.writeStartDocument();
|
||||
|
||||
stream.writeStartElement("canvas");
|
||||
stream.writeAttribute("width", QString("%1").arg(scene()->sceneRect().width()));
|
||||
stream.writeAttribute("height", QString("%1").arg(scene()->sceneRect().height()));
|
||||
writer->writeStartElement("canvas");
|
||||
writer->writeAttribute("width", QString("%1").arg(scene()->sceneRect().width()));
|
||||
writer->writeAttribute("height", QString("%1").arg(scene()->sceneRect().height()));
|
||||
|
||||
QList<QGraphicsItem *>::iterator it;
|
||||
QList<QGraphicsItem *> list = scene()->items();
|
||||
|
@ -455,40 +476,40 @@ void SkeletonEditGraphicsView::saveToXml(const QString &filename)
|
|||
nextNodeId++;
|
||||
}
|
||||
}
|
||||
stream.writeStartElement("nodes");
|
||||
writer->writeStartElement("nodes");
|
||||
for (it = list.begin(); it != list.end(); ++it) {
|
||||
if ((*it)->data(0).toString() == "node") {
|
||||
SkeletonEditNodeItem *nodeItem = static_cast<SkeletonEditNodeItem *>(*it);
|
||||
stream.writeStartElement("node");
|
||||
stream.writeAttribute("id", QString("node%1").arg(nodeIdMap[nodeItem]));
|
||||
stream.writeAttribute("type", nodeItem->isMaster() ? "master" : "slave");
|
||||
stream.writeAttribute("pair", QString("node%1").arg(nodeIdMap[nodeItem->pair()]));
|
||||
stream.writeAttribute("radius", QString("%1").arg(nodeItem->radius()));
|
||||
stream.writeStartElement("origin");
|
||||
writer->writeStartElement("node");
|
||||
writer->writeAttribute("id", QString("node%1").arg(nodeIdMap[nodeItem]));
|
||||
writer->writeAttribute("type", nodeItem->isMaster() ? "master" : "slave");
|
||||
writer->writeAttribute("pair", QString("node%1").arg(nodeIdMap[nodeItem->pair()]));
|
||||
writer->writeAttribute("radius", QString("%1").arg(nodeItem->radius()));
|
||||
writer->writeStartElement("origin");
|
||||
QPointF origin = nodeItem->origin();
|
||||
stream.writeAttribute("x", QString("%1").arg(origin.x()));
|
||||
stream.writeAttribute("y", QString("%1").arg(origin.y()));
|
||||
stream.writeEndElement();
|
||||
stream.writeEndElement();
|
||||
writer->writeAttribute("x", QString("%1").arg(origin.x()));
|
||||
writer->writeAttribute("y", QString("%1").arg(origin.y()));
|
||||
writer->writeEndElement();
|
||||
writer->writeEndElement();
|
||||
}
|
||||
}
|
||||
stream.writeEndElement();
|
||||
stream.writeStartElement("edges");
|
||||
writer->writeEndElement();
|
||||
writer->writeStartElement("edges");
|
||||
int nextEdgeId = 1;
|
||||
for (it = list.begin(); it != list.end(); ++it) {
|
||||
if ((*it)->data(0).toString() == "edge") {
|
||||
SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it);
|
||||
stream.writeStartElement("edge");
|
||||
stream.writeAttribute("id", QString("edge%1").arg(nextEdgeId));
|
||||
stream.writeAttribute("from", QString("node%1").arg(nodeIdMap[edgeItem->firstNode()]));
|
||||
stream.writeAttribute("to", QString("node%1").arg(nodeIdMap[edgeItem->secondNode()]));
|
||||
stream.writeEndElement();
|
||||
writer->writeStartElement("edge");
|
||||
writer->writeAttribute("id", QString("edge%1").arg(nextEdgeId));
|
||||
writer->writeAttribute("from", QString("node%1").arg(nodeIdMap[edgeItem->firstNode()]));
|
||||
writer->writeAttribute("to", QString("node%1").arg(nodeIdMap[edgeItem->secondNode()]));
|
||||
writer->writeEndElement();
|
||||
nextEdgeId++;
|
||||
}
|
||||
}
|
||||
stream.writeEndElement();
|
||||
writer->writeEndElement();
|
||||
|
||||
stream.writeEndElement();
|
||||
stream.writeEndDocument();
|
||||
writer->writeEndElement();
|
||||
writer->writeEndDocument();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#define SKELETON_EDIT_GRAPHICS_VIEW_H
|
||||
#include <QGraphicsView>
|
||||
#include <QMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include "skeletoneditnodeitem.h"
|
||||
#include "skeletoneditedgeitem.h"
|
||||
|
||||
|
@ -9,6 +12,7 @@ class SkeletonEditGraphicsView : public QGraphicsView
|
|||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void sizeChanged();
|
||||
void nodesChanged();
|
||||
void changeTurnaroundTriggered();
|
||||
public slots:
|
||||
|
@ -17,14 +21,18 @@ public slots:
|
|||
public:
|
||||
SkeletonEditGraphicsView(QWidget *parent = 0);
|
||||
void updateBackgroundImage(const QImage &image);
|
||||
void saveToXml(const QString &filename);
|
||||
void loadFromXml(const QString &filename);
|
||||
void saveToXmlStream(QXmlStreamWriter *writer);
|
||||
void loadFromXmlStream(QXmlStreamReader &reader);
|
||||
bool hasBackgroundImage();
|
||||
QPixmap backgroundImage();
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
private:
|
||||
QGraphicsPixmapItem *m_backgroundItem;
|
||||
QGraphicsEllipseItem *m_pendingNodeItem;
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
#include "skeletoneditwidget.h"
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QGridLayout>
|
||||
#include <QGraphicsPixmapItem>
|
||||
|
||||
// Modifed from http://doc.qt.io/qt-5/qtwidgets-graphicsview-chip-view-cpp.html
|
||||
|
||||
SkeletonEditWidget::SkeletonEditWidget(QWidget *parent) :
|
||||
QFrame(parent)
|
||||
{
|
||||
m_graphicsView = new SkeletonEditGraphicsView(this);
|
||||
m_graphicsView->setRenderHint(QPainter::Antialiasing, false);
|
||||
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
m_graphicsView->setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern));
|
||||
|
||||
QGridLayout *mainLayout = new QGridLayout;
|
||||
mainLayout->addWidget(m_graphicsView, 0, 0, 1, 1);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
SkeletonEditGraphicsView *SkeletonEditWidget::graphicsView()
|
||||
{
|
||||
return m_graphicsView;
|
||||
}
|
||||
|
||||
void SkeletonEditWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QFrame::resizeEvent(event);
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
void SkeletonEditWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QFrame::mouseMoveEvent(event);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef SKELETON_EDIT_WIDGET_H
|
||||
#define SKELETON_EDIT_WIDGET_H
|
||||
#include <QFrame>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QMouseEvent>
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include "skeletoneditgraphicsview.h"
|
||||
|
||||
class SkeletonEditWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void sizeChanged();
|
||||
public:
|
||||
SkeletonEditWidget(QWidget *parent = 0);
|
||||
SkeletonEditGraphicsView *graphicsView();
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
private:
|
||||
SkeletonEditGraphicsView *m_graphicsView;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -34,6 +34,7 @@ SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) :
|
|||
node.originX = origin.x();
|
||||
node.originY = origin.y();
|
||||
node.originZ = nodeItem->slave()->origin().x();
|
||||
node.processed = false;
|
||||
node.bmeshNodeId = -1;
|
||||
node.radius = nodeItem->radius();
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ struct SkeletonNode
|
|||
float originY;
|
||||
float originZ;
|
||||
float radius;
|
||||
bool processed;
|
||||
int bmeshNodeId;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <QDesktopWidget>
|
||||
#include <assert.h>
|
||||
#include "skeletonwidget.h"
|
||||
#include "skeletoneditwidget.h"
|
||||
#include "meshlite.h"
|
||||
#include "skeletontomesh.h"
|
||||
#include "turnaroundloader.h"
|
||||
|
@ -24,7 +23,12 @@ SkeletonWidget::SkeletonWidget(QWidget *parent) :
|
|||
QHBoxLayout *topLayout = new QHBoxLayout;
|
||||
topLayout->addStretch();
|
||||
|
||||
m_skeletonEditWidget = new SkeletonEditWidget;
|
||||
m_graphicsView = new SkeletonEditGraphicsView(this);
|
||||
m_graphicsView->setRenderHint(QPainter::Antialiasing, false);
|
||||
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
m_graphicsView->setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern));
|
||||
|
||||
m_modelingWidget = new ModelingWidget(this);
|
||||
m_modelingWidget->setMinimumSize(128, 128);
|
||||
|
@ -59,7 +63,7 @@ SkeletonWidget::SkeletonWidget(QWidget *parent) :
|
|||
|
||||
QHBoxLayout *middleLayout = new QHBoxLayout;
|
||||
middleLayout->addLayout(leftLayout);
|
||||
middleLayout->addWidget(m_skeletonEditWidget);
|
||||
middleLayout->addWidget(m_graphicsView);
|
||||
middleLayout->addLayout(rightLayout);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
|
@ -73,19 +77,19 @@ SkeletonWidget::SkeletonWidget(QWidget *parent) :
|
|||
|
||||
bool connectResult;
|
||||
|
||||
connectResult = connect(addAction, SIGNAL(triggered(bool)), m_skeletonEditWidget->graphicsView(), SLOT(turnOnAddNodeMode()));
|
||||
connectResult = connect(addAction, SIGNAL(triggered(bool)), m_graphicsView, SLOT(turnOnAddNodeMode()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connectResult = connect(selectAction, SIGNAL(triggered(bool)), m_skeletonEditWidget->graphicsView(), SLOT(turnOffAddNodeMode()));
|
||||
connectResult = connectResult = connect(selectAction, SIGNAL(triggered(bool)), m_graphicsView, SLOT(turnOffAddNodeMode()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(m_skeletonEditWidget->graphicsView(), SIGNAL(nodesChanged()), this, SLOT(skeletonChanged()));
|
||||
connectResult = connect(m_graphicsView, SIGNAL(nodesChanged()), this, SLOT(skeletonChanged()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(m_skeletonEditWidget, SIGNAL(sizeChanged()), this, SLOT(turnaroundChanged()));
|
||||
connectResult = connect(m_graphicsView, SIGNAL(sizeChanged()), this, SLOT(turnaroundChanged()));
|
||||
assert(connectResult);
|
||||
|
||||
connectResult = connect(m_skeletonEditWidget->graphicsView(), SIGNAL(changeTurnaroundTriggered()), this, SLOT(changeTurnaround()));
|
||||
connectResult = connect(m_graphicsView, SIGNAL(changeTurnaroundTriggered()), this, SLOT(changeTurnaround()));
|
||||
assert(connectResult);
|
||||
|
||||
//connectResult = connect(clipButton, SIGNAL(clicked()), this, SLOT(saveClip()));
|
||||
|
@ -94,7 +98,7 @@ SkeletonWidget::SkeletonWidget(QWidget *parent) :
|
|||
|
||||
SkeletonEditGraphicsView *SkeletonWidget::graphicsView()
|
||||
{
|
||||
return m_skeletonEditWidget->graphicsView();
|
||||
return m_graphicsView;
|
||||
}
|
||||
|
||||
void SkeletonWidget::showModelingWidgetAtCorner()
|
||||
|
@ -130,7 +134,7 @@ void SkeletonWidget::skeletonChanged()
|
|||
m_skeletonDirty = false;
|
||||
|
||||
QThread *thread = new QThread;
|
||||
m_skeletonToMesh = new SkeletonToMesh(m_skeletonEditWidget->graphicsView());
|
||||
m_skeletonToMesh = new SkeletonToMesh(m_graphicsView);
|
||||
m_skeletonToMesh->moveToThread(thread);
|
||||
connect(thread, SIGNAL(started()), m_skeletonToMesh, SLOT(process()));
|
||||
connect(m_skeletonToMesh, SIGNAL(finished()), this, SLOT(meshReady()));
|
||||
|
@ -153,7 +157,7 @@ void SkeletonWidget::turnaroundChanged()
|
|||
|
||||
QThread *thread = new QThread;
|
||||
m_turnaroundLoader = new TurnaroundLoader(m_turnaroundFilename,
|
||||
m_skeletonEditWidget->rect().size());
|
||||
m_graphicsView->rect().size());
|
||||
m_turnaroundLoader->moveToThread(thread);
|
||||
connect(thread, SIGNAL(started()), m_turnaroundLoader, SLOT(process()));
|
||||
connect(m_turnaroundLoader, SIGNAL(finished()), this, SLOT(turnaroundImageReady()));
|
||||
|
@ -166,7 +170,7 @@ void SkeletonWidget::turnaroundImageReady()
|
|||
{
|
||||
QImage *backgroundImage = m_turnaroundLoader->takeResultImage();
|
||||
if (backgroundImage && backgroundImage->width() > 0 && backgroundImage->height() > 0) {
|
||||
m_skeletonEditWidget->graphicsView()->updateBackgroundImage(*backgroundImage);
|
||||
m_graphicsView->updateBackgroundImage(*backgroundImage);
|
||||
}
|
||||
delete backgroundImage;
|
||||
delete m_turnaroundLoader;
|
||||
|
@ -187,13 +191,3 @@ void SkeletonWidget::changeTurnaround()
|
|||
turnaroundChanged();
|
||||
}
|
||||
|
||||
void SkeletonWidget::saveClip()
|
||||
{
|
||||
QImage image = m_modelingWidget->grabFramebuffer();
|
||||
//QTableWidgetItem *item = new QTableWidgetItem;
|
||||
//item->setSizeHint(QSize(32, 32));
|
||||
//item->setIcon(QPixmap::fromImage(image.scaled(32, 32)));
|
||||
//m_clipTableWidget->insertRow(m_clipTableWidget->rowCount());
|
||||
//m_clipTableWidget->setItem(m_clipTableWidget->rowCount() - 1, 0, item);
|
||||
//image.save("/Users/jeremy/Repositories/dust3d/gl.png");
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include "modelingwidget.h"
|
||||
#include "skeletoneditwidget.h"
|
||||
#include "skeletontomesh.h"
|
||||
#include "turnaroundloader.h"
|
||||
#include "skeletoneditgraphicsview.h"
|
||||
|
@ -22,11 +21,10 @@ public slots:
|
|||
void turnaroundChanged();
|
||||
void turnaroundImageReady();
|
||||
void changeTurnaround();
|
||||
void saveClip();
|
||||
void showModelingWidgetAtCorner();
|
||||
private:
|
||||
ModelingWidget *m_modelingWidget;
|
||||
SkeletonEditWidget *m_skeletonEditWidget;
|
||||
SkeletonEditGraphicsView *m_graphicsView;
|
||||
SkeletonToMesh *m_skeletonToMesh;
|
||||
bool m_skeletonDirty;
|
||||
TurnaroundLoader *m_turnaroundLoader;
|
||||
|
|
Loading…
Reference in New Issue