Add skeleton edit UI

master
Jeremy Hu 2018-03-12 00:02:15 +08:00
parent 283e76b1b6
commit d3e82ea306
15 changed files with 509 additions and 48 deletions

View File

@ -12,6 +12,18 @@ HEADERS += src/modelingwidget.h
SOURCES += src/skeletoneditwidget.cpp SOURCES += src/skeletoneditwidget.cpp
HEADERS += src/skeletoneditwidget.h HEADERS += src/skeletoneditwidget.h
SOURCES += src/skeletoneditgraphicsview.cpp
HEADERS += src/skeletoneditgraphicsview.h
SOURCES += src/skeletoneditnodeitem.cpp
HEADERS += src/skeletoneditnodeitem.h
SOURCES += src/skeletoneditedgeitem.cpp
HEADERS += src/skeletoneditedgeitem.h
SOURCES += src/skeletontomesh.cpp
HEADERS += src/skeletontomesh.h
SOURCES += src/mesh.cpp SOURCES += src/mesh.cpp
HEADERS += src/mesh.h HEADERS += src/mesh.h

View File

@ -1,10 +1,14 @@
#include "mainwindow.h"
#include "skeletoneditwidget.h"
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QPushButton> #include <QPushButton>
#include <QButtonGroup> #include <QButtonGroup>
#include <QGridLayout> #include <QGridLayout>
#include <QToolBar> #include <QToolBar>
#include <QThread>
#include <assert.h>
#include "mainwindow.h"
#include "skeletoneditwidget.h"
#include "meshlite.h"
#include "skeletontomesh.h"
MainWindow::MainWindow() MainWindow::MainWindow()
{ {
@ -36,14 +40,15 @@ MainWindow::MainWindow()
motionButton->adjustSize(); motionButton->adjustSize();
modelButton->adjustSize(); modelButton->adjustSize();
SkeletonEditWidget *skeletonEditWidget = new SkeletonEditWidget; m_skeletonEditWidget = new SkeletonEditWidget;
ModelingWidget *modelViewWidget = new ModelingWidget;
modelViewWidget->setFixedSize(128, 128); m_modelingWidget = new ModelingWidget;
m_modelingWidget->setFixedSize(128, 128);
QPushButton *changeTurnaroundButton = new QPushButton("Change turnaround.."); QPushButton *changeTurnaroundButton = new QPushButton("Change turnaround..");
QVBoxLayout *rightLayout = new QVBoxLayout; QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(modelViewWidget); rightLayout->addWidget(m_modelingWidget);
rightLayout->addSpacing(10); rightLayout->addSpacing(10);
rightLayout->addWidget(changeTurnaroundButton); rightLayout->addWidget(changeTurnaroundButton);
rightLayout->addStretch(); rightLayout->addStretch();
@ -61,7 +66,7 @@ MainWindow::MainWindow()
QHBoxLayout *middleLayout = new QHBoxLayout; QHBoxLayout *middleLayout = new QHBoxLayout;
middleLayout->addLayout(leftLayout); middleLayout->addLayout(leftLayout);
middleLayout->addWidget(skeletonEditWidget); middleLayout->addWidget(m_skeletonEditWidget);
middleLayout->addLayout(rightLayout); middleLayout->addLayout(rightLayout);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout *mainLayout = new QVBoxLayout;
@ -74,5 +79,36 @@ MainWindow::MainWindow()
setCentralWidget(centralWidget); setCentralWidget(centralWidget);
setWindowTitle(tr("Dust 3D")); setWindowTitle(tr("Dust 3D"));
bool connectResult;
connectResult = connect(addAction, SIGNAL(triggered(bool)), m_skeletonEditWidget->graphicsView(), SLOT(turnOnAddNodeMode()));
assert(connectResult);
connectResult = connectResult = connect(selectAction, SIGNAL(triggered(bool)), m_skeletonEditWidget->graphicsView(), SLOT(turnOffAddNodeMode()));
assert(connectResult);
connectResult = connect(m_skeletonEditWidget->graphicsView(), SIGNAL(nodesChanged()), this, SLOT(skeletonChanged()));
assert(connectResult);
} }
void MainWindow::meshReady()
{
SkeletonToMesh *worker = dynamic_cast<SkeletonToMesh *>(sender());
if (worker) {
m_modelingWidget->updateMesh(worker->takeResultMesh());
}
}
void MainWindow::skeletonChanged()
{
QThread *thread = new QThread;
SkeletonToMesh *worker = new SkeletonToMesh(m_skeletonEditWidget->graphicsView());
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), this, SLOT(meshReady()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}

View File

@ -1,17 +1,20 @@
#ifndef MAIN_WINDOW_H #ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H #define MAIN_WINDOW_H
#include <QMainWindow> #include <QMainWindow>
#include "modelingwidget.h" #include "modelingwidget.h"
#include "skeletoneditwidget.h"
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
MainWindow(); MainWindow();
public slots:
void skeletonChanged();
void meshReady();
private: private:
ModelingWidget *modelingWidget; ModelingWidget *m_modelingWidget;
SkeletonEditWidget *m_skeletonEditWidget;
}; };
#endif #endif

View File

@ -3,7 +3,6 @@
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QCoreApplication> #include <QCoreApplication>
#include <math.h> #include <math.h>
#include "meshlite.h"
// Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html // Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html
@ -15,7 +14,9 @@ ModelingWidget::ModelingWidget(QWidget *parent)
m_yRot(0), m_yRot(0),
m_zRot(0), m_zRot(0),
m_program(0), m_program(0),
m_mesh(NULL) m_renderVertexCount(0),
m_mesh(NULL),
m_meshUpdated(false)
{ {
m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
// --transparent causes the clear color to be transparent. Therefore, on systems that // --transparent causes the clear color to be transparent. Therefore, on systems that
@ -25,16 +26,6 @@ ModelingWidget::ModelingWidget(QWidget *parent)
fmt.setAlphaBufferSize(8); fmt.setAlphaBufferSize(8);
setFormat(fmt); setFormat(fmt);
} }
void *lite = meshlite_create_context();
int first = meshlite_import(lite, "../assets/cube.obj");
int second = meshlite_import(lite, "../assets/ball.obj");
meshlite_scale(lite, first, 0.65);
int merged = meshlite_union(lite, first, second);
int triangulate = meshlite_triangulate(lite, merged);
//meshlite_export(lite, triangulate, "/Users/jeremy/testlib.obj");
Mesh *mesh = new Mesh(lite, triangulate);
updateMesh(mesh);
} }
ModelingWidget::~ModelingWidget() ModelingWidget::~ModelingWidget()
@ -96,7 +87,8 @@ void ModelingWidget::cleanup()
if (m_program == nullptr) if (m_program == nullptr)
return; return;
makeCurrent(); makeCurrent();
m_modelVbo.destroy(); if (m_modelVbo.isCreated())
m_modelVbo.destroy();
delete m_program; delete m_program;
m_program = 0; m_program = 0;
doneCurrent(); doneCurrent();
@ -169,7 +161,8 @@ void ModelingWidget::initializeGL()
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelingWidget::cleanup); connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelingWidget::cleanup);
initializeOpenGLFunctions(); initializeOpenGLFunctions();
glClearColor(0.2078, 0.2078, 0.2078, m_transparent ? 0 : 1); QColor bgcolor = QWidget::palette().color(QWidget::backgroundRole());
glClearColor(bgcolor.redF(), bgcolor.greenF(), bgcolor.blueF(), m_transparent ? 0 : 1);
m_program = new QOpenGLShaderProgram; m_program = new QOpenGLShaderProgram;
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
@ -189,15 +182,10 @@ void ModelingWidget::initializeGL()
// at all. Nonetheless the below code works in all cases and makes // at all. Nonetheless the below code works in all cases and makes
// sure there is a VAO when one is needed. // sure there is a VAO when one is needed.
m_vao.create(); m_vao.create();
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); //QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
// Setup our vertex buffer object.
m_modelVbo.create();
m_modelVbo.bind();
m_modelVbo.allocate(m_mesh->vertices(), m_mesh->vertexCount() * sizeof(Vertex));
// Store the vertex attribute bindings for the program. // Store the vertex attribute bindings for the program.
setupVertexAttribs();
// Our camera never changes in this example. // Our camera never changes in this example.
m_camera.setToIdentity(); m_camera.setToIdentity();
@ -232,13 +220,34 @@ void ModelingWidget::paintGL()
m_world.rotate(m_zRot / 16.0f, 0, 0, 1); m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
{
QMutexLocker lock(&m_meshMutex);
if (m_meshUpdated) {
if (m_mesh) {
// Setup our vertex buffer object.
if (m_modelVbo.isCreated())
m_modelVbo.destroy();
m_modelVbo.create();
m_modelVbo.bind();
m_modelVbo.allocate(m_mesh->vertices(), m_mesh->vertexCount() * sizeof(Vertex));
m_renderVertexCount = m_mesh->vertexCount();
setupVertexAttribs();
} else {
m_renderVertexCount = 0;
}
m_meshUpdated = false;
}
}
m_program->bind(); m_program->bind();
m_program->setUniformValue(m_projMatrixLoc, m_proj); m_program->setUniformValue(m_projMatrixLoc, m_proj);
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world); m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
QMatrix3x3 normalMatrix = m_world.normalMatrix(); QMatrix3x3 normalMatrix = m_world.normalMatrix();
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix); m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
glDrawArrays(GL_TRIANGLES, 0, m_mesh->vertexCount()); if (m_renderVertexCount > 0)
glDrawArrays(GL_TRIANGLES, 0, m_renderVertexCount);
m_program->release(); m_program->release();
} }
@ -275,6 +284,8 @@ void ModelingWidget::updateMesh(Mesh *mesh)
if (mesh != m_mesh) { if (mesh != m_mesh) {
delete m_mesh; delete m_mesh;
m_mesh = mesh; m_mesh = mesh;
m_meshUpdated = true;
update();
} }
} }

View File

@ -55,6 +55,7 @@ private:
QOpenGLVertexArrayObject m_vao; QOpenGLVertexArrayObject m_vao;
QOpenGLBuffer m_modelVbo; QOpenGLBuffer m_modelVbo;
QOpenGLShaderProgram *m_program; QOpenGLShaderProgram *m_program;
int m_renderVertexCount;
int m_projMatrixLoc; int m_projMatrixLoc;
int m_mvMatrixLoc; int m_mvMatrixLoc;
int m_normalMatrixLoc; int m_normalMatrixLoc;
@ -66,6 +67,7 @@ private:
Mesh *m_mesh; Mesh *m_mesh;
QMutex m_meshMutex; QMutex m_meshMutex;
bool m_meshUpdated;
}; };
#endif #endif

View File

@ -0,0 +1,27 @@
#include <QPen>
#include "skeletoneditedgeitem.h"
SkeletonEditEdgeItem::SkeletonEditEdgeItem(QGraphicsItem *parent) :
QGraphicsLineItem(parent),
m_firstNode(NULL),
m_secondNode(NULL)
{
QPen pen(Qt::darkGray);
pen.setWidth(15);
setPen(pen);
}
void SkeletonEditEdgeItem::setNodes(SkeletonEditNodeItem *first, SkeletonEditNodeItem *second)
{
m_firstNode = first;
m_secondNode = second;
updatePosition();
}
void SkeletonEditEdgeItem::updatePosition()
{
if (m_firstNode && m_secondNode) {
QLineF line(m_firstNode->origin(), m_secondNode->origin());
setLine(line);
}
}

View File

@ -0,0 +1,17 @@
#ifndef SKELETON_EDIT_EDGE_ITEM_H
#define SKELETON_EDIT_EDGE_ITEM_H
#include <QGraphicsEllipseItem>
#include "skeletoneditnodeitem.h"
class SkeletonEditEdgeItem : public QGraphicsLineItem
{
public:
SkeletonEditEdgeItem(QGraphicsItem *parent = 0);
void setNodes(SkeletonEditNodeItem *first, SkeletonEditNodeItem *second);
void updatePosition();
private:
SkeletonEditNodeItem *m_firstNode;
SkeletonEditNodeItem *m_secondNode;
};
#endif

View File

@ -0,0 +1,181 @@
#include <QGraphicsPixmapItem>
#include "skeletoneditgraphicsview.h"
#include "skeletoneditnodeitem.h"
#include "skeletoneditedgeitem.h"
qreal SkeletonEditGraphicsView::m_initialNodeSize = 128;
qreal SkeletonEditGraphicsView::m_minimalNodeSize = 32;
SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
QGraphicsView(parent),
m_pendingNodeItem(NULL),
m_pendingEdgeItem(NULL),
m_inAddNodeMode(true),
m_nextStartNodeItem(NULL),
m_lastHoverNodeItem(NULL)
{
setScene(new QGraphicsScene());
setMouseTracking(true);
QImage image("../assets/male_werewolf_turnaround_lineart_by_jennette_brown.png");
m_backgroundItem = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene()->addItem(m_backgroundItem);
m_pendingNodeItem = new QGraphicsEllipseItem(0, 0, m_initialNodeSize, m_initialNodeSize);
scene()->addItem(m_pendingNodeItem);
m_pendingEdgeItem = new QGraphicsLineItem(0, 0, 0, 0);
scene()->addItem(m_pendingEdgeItem);
applyAddNodeMode();
}
void SkeletonEditGraphicsView::toggleAddNodeMode()
{
m_inAddNodeMode = !m_inAddNodeMode;
applyAddNodeMode();
}
void SkeletonEditGraphicsView::applyAddNodeMode()
{
m_pendingNodeItem->setVisible(m_inAddNodeMode);
m_pendingEdgeItem->setVisible(m_inAddNodeMode);
setMouseTracking(true);
}
void SkeletonEditGraphicsView::turnOffAddNodeMode()
{
m_inAddNodeMode = false;
applyAddNodeMode();
}
void SkeletonEditGraphicsView::turnOnAddNodeMode()
{
m_inAddNodeMode = true;
applyAddNodeMode();
}
SkeletonEditNodeItem *SkeletonEditGraphicsView::findNodeItemByPos(QPointF pos)
{
QList<QGraphicsItem *>::iterator it;
QList<QGraphicsItem *> list = scene()->items();
for (it = list.begin(); it != list.end(); ++it) {
SkeletonEditNodeItem *nodeItem = dynamic_cast<SkeletonEditNodeItem *>(*it);
if (nodeItem) {
SkeletonEditNodeItem *nodeItem = (SkeletonEditNodeItem *)(*it);
if (nodeItem->rect().contains(pos)) {
return nodeItem;
}
}
}
return NULL;
}
void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
if (!m_inAddNodeMode) {
if (m_lastHoverNodeItem) {
setNextStartNodeItem(m_lastHoverNodeItem);
m_lastHoverNodeItem = NULL;
}
}
}
}
void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
if (m_inAddNodeMode) {
SkeletonEditNodeItem *newNode = new SkeletonEditNodeItem(m_pendingNodeItem->rect());
scene()->addItem(newNode);
if (m_nextStartNodeItem) {
SkeletonEditEdgeItem *newEdge = new SkeletonEditEdgeItem();
newEdge->setNodes(newNode, m_nextStartNodeItem);
scene()->addItem(newEdge);
}
setNextStartNodeItem(newNode);
emit nodesChanged();
}
} else if (event->button() == Qt::RightButton) {
if (m_inAddNodeMode) {
toggleAddNodeMode();
}
}
}
void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
QWidget::mouseMoveEvent(event);
QPointF pos = mapToScene(event->pos());
QPointF moveTo = QPointF(pos.x() - m_pendingNodeItem->rect().width() / 2, pos.y() - m_pendingNodeItem->rect().height() / 2);
if (moveTo.x() < 0)
moveTo.setX(0);
if (moveTo.y() < 0)
moveTo.setY(0);
if (moveTo.x() + m_pendingNodeItem->rect().width() >= m_backgroundItem->boundingRect().width())
moveTo.setX(m_backgroundItem->boundingRect().width() - m_pendingNodeItem->rect().width());
if (moveTo.y() + m_pendingNodeItem->rect().height() >= m_backgroundItem->boundingRect().height())
moveTo.setY(m_backgroundItem->boundingRect().height() - m_pendingNodeItem->rect().height());
QSizeF oldSize = m_pendingNodeItem->rect().size();
m_pendingNodeItem->setRect(moveTo.x(), moveTo.y(),
oldSize.width(),
oldSize.height());
if (m_nextStartNodeItem) {
m_pendingEdgeItem->setLine(QLineF(m_nextStartNodeItem->origin(), QPointF(moveTo.x() + m_pendingNodeItem->rect().width() / 2,
moveTo.y() + m_pendingNodeItem->rect().height() / 2)));
}
if (!m_inAddNodeMode) {
SkeletonEditNodeItem *hoverNodeItem = findNodeItemByPos(pos);
if (hoverNodeItem) {
hoverNodeItem->setHighlighted(true);
}
if (hoverNodeItem != m_lastHoverNodeItem) {
if (m_lastHoverNodeItem)
m_lastHoverNodeItem->setHighlighted(false);
m_lastHoverNodeItem = hoverNodeItem;
}
} else {
if (m_lastHoverNodeItem) {
m_lastHoverNodeItem->setHighlighted(false);
m_lastHoverNodeItem = NULL;
}
}
}
void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)
{
QWidget::wheelEvent(event);
qreal delta = event->delta();
QSizeF oldSize = m_pendingNodeItem->rect().size();
QPointF originPt = QPointF(m_pendingNodeItem->rect().left() + oldSize.width() / 2,
m_pendingNodeItem->rect().top() + oldSize.height() / 2);
QSizeF newSize = QSizeF(oldSize.width() + delta, oldSize.height() + delta);
if (newSize.width() < m_minimalNodeSize || newSize.height() < m_minimalNodeSize) {
newSize.setWidth(m_minimalNodeSize);
newSize.setHeight(m_minimalNodeSize);
}
QPointF newLeftTop = QPointF(originPt.x() - newSize.width() / 2,
originPt.y() - newSize.height() / 2);
if (newLeftTop.x() < 0 || newLeftTop.x() + newSize.width() >= m_backgroundItem->boundingRect().width())
return;
if (newLeftTop.y() < 0 || newLeftTop.y() + newSize.height() >= m_backgroundItem->boundingRect().height())
return;
m_pendingNodeItem->setRect(newLeftTop.x(),
newLeftTop.y(),
newSize.width(),
newSize.height());
}
void SkeletonEditGraphicsView::setNextStartNodeItem(SkeletonEditNodeItem *item)
{
if (m_nextStartNodeItem != item) {
if (m_nextStartNodeItem)
m_nextStartNodeItem->setIsNextStartNode(false);
}
m_nextStartNodeItem = item;
if (m_nextStartNodeItem)
m_nextStartNodeItem->setIsNextStartNode(true);
}

View File

@ -0,0 +1,39 @@
#ifndef SKELETON_EDIT_GRAPHICS_VIEW_H
#define SKELETON_EDIT_GRAPHICS_VIEW_H
#include <QGraphicsView>
#include <QMouseEvent>
#include "skeletoneditnodeitem.h"
#include "skeletoneditedgeitem.h"
class SkeletonEditGraphicsView : public QGraphicsView
{
Q_OBJECT
signals:
void nodesChanged();
public slots:
void turnOffAddNodeMode();
void turnOnAddNodeMode();
public:
SkeletonEditGraphicsView(QWidget *parent = 0);
protected:
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
QGraphicsPixmapItem *m_backgroundItem;
QGraphicsEllipseItem *m_pendingNodeItem;
QGraphicsLineItem *m_pendingEdgeItem;
static qreal m_initialNodeSize;
static qreal m_minimalNodeSize;
bool m_inAddNodeMode;
SkeletonEditNodeItem *m_nextStartNodeItem;
SkeletonEditNodeItem *m_lastHoverNodeItem;
void toggleAddNodeMode();
void applyAddNodeMode();
SkeletonEditNodeItem *findNodeItemByPos(QPointF pos);
void setNextStartNodeItem(SkeletonEditNodeItem *item);
};
#endif

View File

@ -0,0 +1,39 @@
#include <QPen>
#include "skeletoneditnodeitem.h"
SkeletonEditNodeItem::SkeletonEditNodeItem(const QRectF &rect, QGraphicsItem *parent) :
QGraphicsEllipseItem(rect, parent),
m_highlighted(false),
m_isNextStartNode(false)
{
updateBorder();
}
QPointF SkeletonEditNodeItem::origin()
{
return QPointF(rect().left() + rect().width() / 2,
rect().top() + rect().height() / 2);
}
void SkeletonEditNodeItem::setHighlighted(bool highlighted)
{
m_highlighted = highlighted;
if (m_highlighted) {
setBrush(QBrush(Qt::gray));
} else {
setBrush(QBrush(Qt::transparent));
}
}
void SkeletonEditNodeItem::setIsNextStartNode(bool isNextStartNode)
{
m_isNextStartNode = isNextStartNode;
updateBorder();
}
void SkeletonEditNodeItem::updateBorder()
{
QPen pen(m_isNextStartNode ? Qt::black : Qt::darkGray);
pen.setWidth(15);
setPen(pen);
}

View File

@ -0,0 +1,19 @@
#ifndef SKELETON_EDIT_NODE_ITEM_H
#define SKELETON_EDIT_NODE_ITEM_H
#include <QGraphicsEllipseItem>
class SkeletonEditNodeItem : public QGraphicsEllipseItem
{
public:
SkeletonEditNodeItem(const QRectF &rect, QGraphicsItem *parent = 0);
QPointF origin();
void setHighlighted(bool highlited);
void setIsNextStartNode(bool isNextStartNode);
private:
bool m_highlighted;
bool m_isNextStartNode;
void updateBorder();
};
#endif

View File

@ -6,23 +6,34 @@
// Modifed from http://doc.qt.io/qt-5/qtwidgets-graphicsview-chip-view-cpp.html // Modifed from http://doc.qt.io/qt-5/qtwidgets-graphicsview-chip-view-cpp.html
SkeletonEditWidget::SkeletonEditWidget(QFrame *parent) SkeletonEditWidget::SkeletonEditWidget(QFrame *parent) :
: QFrame(parent) QFrame(parent)
{ {
//setFrameStyle(Sunken | StyledPanel); m_graphicsView = new SkeletonEditGraphicsView(this);
m_graphicsView->setRenderHint(QPainter::Antialiasing, false);
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
graphicsView = new QGraphicsView(this); m_graphicsView->setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern));
graphicsView->setRenderHint(QPainter::Antialiasing, false);
scene = new QGraphicsScene();
graphicsView->setScene(scene);
QImage image("../assets/male_werewolf_turnaround_lineart_by_jennette_brown.png");
QGraphicsPixmapItem *backgroundItem = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene->addItem(backgroundItem);
QGridLayout *mainLayout = new QGridLayout; QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(graphicsView, 0, 0, 1, 1); mainLayout->addWidget(m_graphicsView, 0, 0, 1, 1);
setLayout(mainLayout); setLayout(mainLayout);
} }
SkeletonEditGraphicsView *SkeletonEditWidget::graphicsView()
{
return m_graphicsView;
}
void SkeletonEditWidget::resizeEvent(QResizeEvent *event)
{
QFrame::resizeEvent(event);
m_graphicsView->fitInView(QRectF(0, 0, m_graphicsView->scene()->width(), m_graphicsView->scene()->height()), Qt::KeepAspectRatio);
}
void SkeletonEditWidget::mouseMoveEvent(QMouseEvent *event)
{
QFrame::mouseMoveEvent(event);
}

View File

@ -3,15 +3,22 @@
#include <QFrame> #include <QFrame>
#include <QGraphicsView> #include <QGraphicsView>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QMouseEvent>
#include <QGraphicsEllipseItem>
#include "skeletoneditgraphicsview.h"
class SkeletonEditWidget : public QFrame class SkeletonEditWidget : public QFrame
{ {
Q_OBJECT Q_OBJECT
public: public:
SkeletonEditWidget(QFrame *parent = 0); SkeletonEditWidget(QFrame *parent = 0);
SkeletonEditGraphicsView *graphicsView();
protected:
void resizeEvent(QResizeEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private: private:
QGraphicsView *graphicsView; SkeletonEditGraphicsView *m_graphicsView;
QGraphicsScene *scene;
}; };
#endif #endif

34
src/skeletontomesh.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "skeletontomesh.h"
#include "meshlite.h"
// Modified from https://wiki.qt.io/QThreads_general_usage
SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) :
m_mesh(NULL)
{
}
SkeletonToMesh::~SkeletonToMesh()
{
delete m_mesh;
}
Mesh *SkeletonToMesh::takeResultMesh()
{
Mesh *mesh = m_mesh;
m_mesh = NULL;
return mesh;
}
void SkeletonToMesh::process()
{
void *lite = meshlite_create_context();
int first = meshlite_import(lite, "../assets/cube.obj");
int second = meshlite_import(lite, "../assets/ball.obj");
meshlite_scale(lite, first, 0.65);
int merged = meshlite_union(lite, first, second);
int triangulate = meshlite_triangulate(lite, merged);
//meshlite_export(lite, triangulate, "/Users/jeremy/testlib.obj");
m_mesh = new Mesh(lite, triangulate);
emit finished();
}

23
src/skeletontomesh.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef SKELETON_TO_MESH_H
#define SKELETON_TO_MESH_H
#include <QObject>
#include <QList>
#include "skeletoneditgraphicsview.h"
#include "mesh.h"
class SkeletonToMesh : public QObject
{
Q_OBJECT
public:
SkeletonToMesh(SkeletonEditGraphicsView *graphicsView);
~SkeletonToMesh();
Mesh *takeResultMesh();
signals:
void finished();
public slots:
void process();
private:
Mesh *m_mesh;
};
#endif