Add skeleton to mesh generation(finished other side)

master
Jeremy Hu 2018-03-12 17:41:16 +08:00
parent 14bce78a4a
commit 5b597b0f0c
10 changed files with 155 additions and 18 deletions

View File

@ -24,6 +24,9 @@ HEADERS += src/skeletoneditedgeitem.h
SOURCES += src/skeletontomesh.cpp SOURCES += src/skeletontomesh.cpp
HEADERS += src/skeletontomesh.h HEADERS += src/skeletontomesh.h
SOURCES += src/theme.cpp
HEADERS += src/theme.h
SOURCES += src/mesh.cpp SOURCES += src/mesh.cpp
HEADERS += src/mesh.h HEADERS += src/mesh.h

View File

@ -1,5 +1,6 @@
#include <QPen> #include <QPen>
#include "skeletoneditedgeitem.h" #include "skeletoneditedgeitem.h"
#include "theme.h"
SkeletonEditEdgeItem::SkeletonEditEdgeItem(QGraphicsItem *parent) : SkeletonEditEdgeItem::SkeletonEditEdgeItem(QGraphicsItem *parent) :
QGraphicsLineItem(parent), QGraphicsLineItem(parent),
@ -7,8 +8,8 @@ SkeletonEditEdgeItem::SkeletonEditEdgeItem(QGraphicsItem *parent) :
m_secondNode(NULL) m_secondNode(NULL)
{ {
setData(0, "edge"); setData(0, "edge");
QPen pen(Qt::darkGray); QPen pen(Theme::skeletonMasterNodeBorderColor);
pen.setWidth(15); pen.setWidth(Theme::skeletonMasterNodeBorderSize);
setPen(pen); setPen(pen);
} }
@ -19,6 +20,11 @@ void SkeletonEditEdgeItem::setNodes(SkeletonEditNodeItem *first, SkeletonEditNod
updatePosition(); updatePosition();
} }
bool SkeletonEditEdgeItem::connects(SkeletonEditNodeItem *nodeItem)
{
return m_firstNode == nodeItem || m_secondNode == nodeItem;
}
void SkeletonEditEdgeItem::updatePosition() void SkeletonEditEdgeItem::updatePosition()
{ {
if (m_firstNode && m_secondNode) { if (m_firstNode && m_secondNode) {

View File

@ -11,6 +11,7 @@ public:
void updatePosition(); void updatePosition();
SkeletonEditNodeItem *firstNode(); SkeletonEditNodeItem *firstNode();
SkeletonEditNodeItem *secondNode(); SkeletonEditNodeItem *secondNode();
bool connects(SkeletonEditNodeItem *nodeItem);
private: private:
SkeletonEditNodeItem *m_firstNode; SkeletonEditNodeItem *m_firstNode;
SkeletonEditNodeItem *m_secondNode; SkeletonEditNodeItem *m_secondNode;

View File

@ -12,7 +12,8 @@ SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
m_pendingEdgeItem(NULL), m_pendingEdgeItem(NULL),
m_inAddNodeMode(true), m_inAddNodeMode(true),
m_nextStartNodeItem(NULL), m_nextStartNodeItem(NULL),
m_lastHoverNodeItem(NULL) m_lastHoverNodeItem(NULL),
m_lastMousePos(0, 0)
{ {
setScene(new QGraphicsScene()); setScene(new QGraphicsScene());
@ -76,25 +77,38 @@ void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (!m_inAddNodeMode) { if (!m_inAddNodeMode) {
if (m_lastHoverNodeItem) { if (m_lastHoverNodeItem) {
setNextStartNodeItem(m_lastHoverNodeItem); setNextStartNodeItem(m_lastHoverNodeItem->master());
m_lastHoverNodeItem = NULL; m_lastHoverNodeItem = NULL;
} }
} }
} }
m_lastMousePos = mapToScene(event->pos());
}
float SkeletonEditGraphicsView::findXForSlave(float x)
{
return x - m_backgroundItem->boundingRect().width() / 4;
} }
void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event) void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{ {
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (m_inAddNodeMode) { if (m_inAddNodeMode) {
SkeletonEditNodeItem *newNode = new SkeletonEditNodeItem(m_pendingNodeItem->rect()); SkeletonEditNodeItem *masterNode = new SkeletonEditNodeItem(m_pendingNodeItem->rect());
scene()->addItem(newNode); scene()->addItem(masterNode);
QRectF slaveRect = m_pendingNodeItem->rect();
float x = m_pendingNodeItem->x() + m_pendingNodeItem->rect().width() / 2;
slaveRect.translate(findXForSlave(x) - x, 0);
SkeletonEditNodeItem *slaveNode = new SkeletonEditNodeItem(slaveRect);
scene()->addItem(slaveNode);
masterNode->setSlave(slaveNode);
slaveNode->setMaster(masterNode);
if (m_nextStartNodeItem) { if (m_nextStartNodeItem) {
SkeletonEditEdgeItem *newEdge = new SkeletonEditEdgeItem(); SkeletonEditEdgeItem *newEdge = new SkeletonEditEdgeItem();
newEdge->setNodes(newNode, m_nextStartNodeItem); newEdge->setNodes(masterNode, m_nextStartNodeItem);
scene()->addItem(newEdge); scene()->addItem(newEdge);
} }
setNextStartNodeItem(newNode); setNextStartNodeItem(masterNode);
emit nodesChanged(); emit nodesChanged();
} }
} else if (event->button() == Qt::RightButton) { } else if (event->button() == Qt::RightButton) {
@ -141,6 +155,32 @@ void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
m_lastHoverNodeItem = NULL; m_lastHoverNodeItem = NULL;
} }
} }
QPointF curMousePos = pos;
if (m_lastHoverNodeItem) {
if (event->buttons() & Qt::LeftButton) {
QRectF rect = m_lastHoverNodeItem->rect();
if (m_lastHoverNodeItem->isMaster()) {
rect.translate(curMousePos.x() - m_lastMousePos.x(), curMousePos.y() - m_lastMousePos.y());
QRectF slaveRect = m_lastHoverNodeItem->slave()->rect();
slaveRect.translate(0, curMousePos.y() - m_lastMousePos.y());
m_lastHoverNodeItem->slave()->setRect(slaveRect);
} else {
rect.translate(curMousePos.x() - m_lastMousePos.x(), 0);
}
m_lastHoverNodeItem->setRect(rect);
QList<QGraphicsItem *>::iterator it;
QList<QGraphicsItem *> list = scene()->items();
for (it = list.begin(); it != list.end(); ++it) {
if ((*it)->data(0).toString() == "edge") {
SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it);
if (edgeItem->connects(m_lastHoverNodeItem))
edgeItem->updatePosition();
}
}
emit nodesChanged();
}
}
m_lastMousePos = curMousePos;
} }
void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event) void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)

View File

@ -29,10 +29,12 @@ private:
bool m_inAddNodeMode; bool m_inAddNodeMode;
SkeletonEditNodeItem *m_nextStartNodeItem; SkeletonEditNodeItem *m_nextStartNodeItem;
SkeletonEditNodeItem *m_lastHoverNodeItem; SkeletonEditNodeItem *m_lastHoverNodeItem;
QPointF m_lastMousePos;
void toggleAddNodeMode(); void toggleAddNodeMode();
void applyAddNodeMode(); void applyAddNodeMode();
SkeletonEditNodeItem *findNodeItemByPos(QPointF pos); SkeletonEditNodeItem *findNodeItemByPos(QPointF pos);
void setNextStartNodeItem(SkeletonEditNodeItem *item); void setNextStartNodeItem(SkeletonEditNodeItem *item);
float findXForSlave(float x);
}; };

View File

@ -1,19 +1,52 @@
#include <QPen> #include <QPen>
#include "skeletoneditnodeitem.h" #include "skeletoneditnodeitem.h"
#include "theme.h"
SkeletonEditNodeItem::SkeletonEditNodeItem(const QRectF &rect, QGraphicsItem *parent) : SkeletonEditNodeItem::SkeletonEditNodeItem(const QRectF &rect, QGraphicsItem *parent) :
QGraphicsEllipseItem(rect, parent), QGraphicsEllipseItem(rect, parent),
m_highlighted(false), m_highlighted(false),
m_isNextStartNode(false) m_isNextStartNode(false),
m_master(NULL),
m_slave(NULL)
{ {
setData(0, "node"); setData(0, "node");
updateBorder(); updateBorder();
} }
bool SkeletonEditNodeItem::isSlave()
{
return NULL != m_master;
}
bool SkeletonEditNodeItem::isMaster()
{
return NULL == m_master;
}
SkeletonEditNodeItem *SkeletonEditNodeItem::master()
{
return m_master ? m_master : this;
}
void SkeletonEditNodeItem::setMaster(SkeletonEditNodeItem *nodeItem)
{
m_master = nodeItem;
}
void SkeletonEditNodeItem::setSlave(SkeletonEditNodeItem *nodeItem)
{
m_slave = nodeItem;
}
SkeletonEditNodeItem *SkeletonEditNodeItem::slave()
{
return m_slave;
}
QPointF SkeletonEditNodeItem::origin() QPointF SkeletonEditNodeItem::origin()
{ {
return QPointF(rect().left() + rect().width() / 2, return QPointF(rect().x() + rect().width() / 2,
rect().top() + rect().height() / 2); rect().y() + rect().height() / 2);
} }
float SkeletonEditNodeItem::radius() float SkeletonEditNodeItem::radius()
@ -25,10 +58,14 @@ void SkeletonEditNodeItem::setHighlighted(bool highlighted)
{ {
m_highlighted = highlighted; m_highlighted = highlighted;
if (m_highlighted) { if (m_highlighted) {
setBrush(QBrush(Qt::gray)); setBrush(QBrush(isMaster() ? Theme::skeletonMasterNodeFillColor : Theme::skeletonSlaveNodeFillColor));
} else { } else {
setBrush(QBrush(Qt::transparent)); setBrush(QBrush(Qt::transparent));
} }
if (m_slave)
{
m_slave->setHighlighted(highlighted);
}
} }
void SkeletonEditNodeItem::setIsNextStartNode(bool isNextStartNode) void SkeletonEditNodeItem::setIsNextStartNode(bool isNextStartNode)
@ -39,7 +76,9 @@ void SkeletonEditNodeItem::setIsNextStartNode(bool isNextStartNode)
void SkeletonEditNodeItem::updateBorder() void SkeletonEditNodeItem::updateBorder()
{ {
QPen pen(m_isNextStartNode ? Qt::black : Qt::darkGray); QPen pen(m_isNextStartNode ?
pen.setWidth(15); (isMaster() ? Theme::skeletonMasterNodeBorderHighlightColor : Theme::skeletonSlaveNodeBorderHighlightColor) :
(isMaster() ? Theme::skeletonMasterNodeBorderColor : Theme::skeletonSlaveNodeBorderColor));
pen.setWidth(isMaster() ? Theme::skeletonMasterNodeBorderSize : Theme::skeletonSlaveNodeBorderSize);
setPen(pen); setPen(pen);
} }

View File

@ -2,6 +2,8 @@
#define SKELETON_EDIT_NODE_ITEM_H #define SKELETON_EDIT_NODE_ITEM_H
#include <QGraphicsEllipseItem> #include <QGraphicsEllipseItem>
class SkeletonEditEdgeItem;
class SkeletonEditNodeItem : public QGraphicsEllipseItem class SkeletonEditNodeItem : public QGraphicsEllipseItem
{ {
public: public:
@ -10,9 +12,17 @@ public:
float radius(); float radius();
void setHighlighted(bool highlited); void setHighlighted(bool highlited);
void setIsNextStartNode(bool isNextStartNode); void setIsNextStartNode(bool isNextStartNode);
bool isSlave();
bool isMaster();
void setMaster(SkeletonEditNodeItem *nodeItem);
void setSlave(SkeletonEditNodeItem *nodeItem);
SkeletonEditNodeItem *master();
SkeletonEditNodeItem *slave();
private: private:
bool m_highlighted; bool m_highlighted;
bool m_isNextStartNode; bool m_isNextStartNode;
SkeletonEditNodeItem *m_master;
SkeletonEditNodeItem *m_slave;
void updateBorder(); void updateBorder();
}; };

View File

@ -33,7 +33,7 @@ SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) :
node.originX = origin.x(); node.originX = origin.x();
node.originY = origin.y(); node.originY = origin.y();
node.originZ = 0; node.originZ = nodeItem->slave()->origin().x();
node.bmeshNodeId = -1; node.bmeshNodeId = -1;
node.radius = nodeItem->radius(); node.radius = nodeItem->radius();
@ -79,8 +79,10 @@ void SkeletonToMesh::process()
return; return;
} }
float left = -1; float left = -1;
float right = -1;
float top = -1; float top = -1;
float bottom = -1; float bottom = -1;
float zLeft = -1;
for (size_t i = 0; i < m_nodes.size(); i++) { for (size_t i = 0; i < m_nodes.size(); i++) {
SkeletonNode *node = &m_nodes[i]; SkeletonNode *node = &m_nodes[i];
if (left < 0 || node->originX < left) { if (left < 0 || node->originX < left) {
@ -89,9 +91,15 @@ void SkeletonToMesh::process()
if (top < 0 || node->originY < top) { if (top < 0 || node->originY < top) {
top = node->originY; top = node->originY;
} }
if (node->originX > right) {
right = node->originX;
}
if (node->originY > bottom) { if (node->originY > bottom) {
bottom = node->originY; bottom = node->originY;
} }
if (zLeft < 0 || node->originZ < zLeft) {
zLeft = node->originZ;
}
} }
float height = bottom - top; float height = bottom - top;
if (height <= 0) { if (height <= 0) {
@ -102,9 +110,9 @@ void SkeletonToMesh::process()
int bmesh = meshlite_bmesh_create(context); int bmesh = meshlite_bmesh_create(context);
for (size_t i = 0; i < m_nodes.size(); i++) { for (size_t i = 0; i < m_nodes.size(); i++) {
SkeletonNode *node = &m_nodes[i]; SkeletonNode *node = &m_nodes[i];
float x = (node->originX - left) / height; float x = (node->originX - left - height / 2) / height;
float y = (node->originY - top) / height; float y = (node->originY - top - height / 2) / height;
float z = node->originZ / height; float z = (node->originZ - zLeft - height / 2) / height;
float r = node->radius / height; float r = node->radius / height;
node->bmeshNodeId = meshlite_bmesh_add_node(context, bmesh, x, y, z, r); node->bmeshNodeId = meshlite_bmesh_add_node(context, bmesh, x, y, z, r);
} }

10
src/theme.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "theme.h"
QColor Theme::skeletonMasterNodeBorderColor = QColor(0x33, 0x33, 0x33, 128);
QColor Theme::skeletonMasterNodeBorderHighlightColor = QColor(0x00, 0x00, 0x00, 200);
QColor Theme::skeletonMasterNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 128);
int Theme::skeletonMasterNodeBorderSize = 15;
QColor Theme::skeletonSlaveNodeBorderColor = QColor(0x33, 0x33, 0x33, 128);
QColor Theme::skeletonSlaveNodeBorderHighlightColor = QColor(0x00, 0x00, 0x00, 200);
QColor Theme::skeletonSlaveNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 128);
int Theme::skeletonSlaveNodeBorderSize = 15;

18
src/theme.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef THEME_H
#define THEME_H
#include <QColor>
class Theme
{
public:
static QColor skeletonMasterNodeBorderColor;
static QColor skeletonMasterNodeBorderHighlightColor;
static QColor skeletonMasterNodeFillColor;
static int skeletonMasterNodeBorderSize;
static QColor skeletonSlaveNodeBorderColor;
static QColor skeletonSlaveNodeBorderHighlightColor;
static QColor skeletonSlaveNodeFillColor;
static int skeletonSlaveNodeBorderSize;
};
#endif