Add branch sperate joint wrap
parent
64ce4e6843
commit
7df312cff5
|
@ -169,6 +169,12 @@ MainWindow::MainWindow()
|
||||||
"selection"));
|
"selection"));
|
||||||
connect(pasteAct, &QAction::triggered, this, &MainWindow::paste);
|
connect(pasteAct, &QAction::triggered, this, &MainWindow::paste);
|
||||||
|
|
||||||
|
QAction *markAsBranchAct = new QAction(tr("Mark as &Branch"), this);
|
||||||
|
connect(markAsBranchAct, &QAction::triggered, skeletonWidget->graphicsView(), &SkeletonEditGraphicsView::markAsBranch);
|
||||||
|
|
||||||
|
QAction *markAsTrunkAct = new QAction(tr("Mark as &Trunk"), this);
|
||||||
|
connect(markAsTrunkAct, &QAction::triggered, skeletonWidget->graphicsView(), &SkeletonEditGraphicsView::markAsTrunk);
|
||||||
|
|
||||||
QAction *changeTurnaroundAct = new QAction(tr("&Change Turnaround..."), this);
|
QAction *changeTurnaroundAct = new QAction(tr("&Change Turnaround..."), this);
|
||||||
connect(changeTurnaroundAct, &QAction::triggered, skeletonWidget, &SkeletonWidget::changeTurnaround);
|
connect(changeTurnaroundAct, &QAction::triggered, skeletonWidget, &SkeletonWidget::changeTurnaround);
|
||||||
|
|
||||||
|
@ -187,6 +193,9 @@ MainWindow::MainWindow()
|
||||||
editMenu->addAction(copyAct);
|
editMenu->addAction(copyAct);
|
||||||
editMenu->addAction(pasteAct);
|
editMenu->addAction(pasteAct);
|
||||||
editMenu->addSeparator();
|
editMenu->addSeparator();
|
||||||
|
editMenu->addAction(markAsBranchAct);
|
||||||
|
editMenu->addAction(markAsTrunkAct);
|
||||||
|
editMenu->addSeparator();
|
||||||
editMenu->addAction(changeTurnaroundAct);
|
editMenu->addAction(changeTurnaroundAct);
|
||||||
|
|
||||||
bool connectResult = false;
|
bool connectResult = false;
|
||||||
|
|
|
@ -508,6 +508,7 @@ void SkeletonEditGraphicsView::loadFromSnapshot(SkeletonSnapshot *snapshot)
|
||||||
(*snapshotNode)["y"].toFloat() * yMul,
|
(*snapshotNode)["y"].toFloat() * yMul,
|
||||||
(*snapshotNode)["radius"].toFloat() * radiusMul);
|
(*snapshotNode)["radius"].toFloat() * radiusMul);
|
||||||
nodeItem->setSideColorName((*snapshotNode)["sideColorName"]);
|
nodeItem->setSideColorName((*snapshotNode)["sideColorName"]);
|
||||||
|
nodeItem->markAsBranch("true" == (*snapshotNode)["isBranch"]);
|
||||||
nodeItemMap[nodeIterator->first] = nodeItem;
|
nodeItemMap[nodeIterator->first] = nodeItem;
|
||||||
}
|
}
|
||||||
for (nodeIterator = snapshot->nodes.begin(); nodeIterator != snapshot->nodes.end(); nodeIterator++) {
|
for (nodeIterator = snapshot->nodes.begin(); nodeIterator != snapshot->nodes.end(); nodeIterator++) {
|
||||||
|
@ -543,6 +544,7 @@ void SkeletonEditGraphicsView::saveToSnapshot(SkeletonSnapshot *snapshot)
|
||||||
(*snapshotNode)["id"] = nodeId;
|
(*snapshotNode)["id"] = nodeId;
|
||||||
(*snapshotNode)["sideColorName"] = nodeItem->sideColorName();
|
(*snapshotNode)["sideColorName"] = nodeItem->sideColorName();
|
||||||
(*snapshotNode)["radius"] = QString("%1").arg(nodeItem->radius());
|
(*snapshotNode)["radius"] = QString("%1").arg(nodeItem->radius());
|
||||||
|
(*snapshotNode)["isBranch"] = QString("%1").arg(nodeItem->isBranch() ? "true" : "false");
|
||||||
QPointF origin = nodeItem->origin();
|
QPointF origin = nodeItem->origin();
|
||||||
(*snapshotNode)["x"] = QString("%1").arg(origin.x());
|
(*snapshotNode)["x"] = QString("%1").arg(origin.x());
|
||||||
(*snapshotNode)["y"] = QString("%1").arg(origin.y());
|
(*snapshotNode)["y"] = QString("%1").arg(origin.y());
|
||||||
|
@ -574,4 +576,20 @@ void SkeletonEditGraphicsView::saveToSnapshot(SkeletonSnapshot *snapshot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonEditGraphicsView::markAsBranch()
|
||||||
|
{
|
||||||
|
if (m_nextStartNodeItem) {
|
||||||
|
m_nextStartNodeItem->markAsBranch(true);
|
||||||
|
m_nextStartNodeItem->nextSidePair()->markAsBranch(true);
|
||||||
|
emit nodesChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonEditGraphicsView::markAsTrunk()
|
||||||
|
{
|
||||||
|
if (m_nextStartNodeItem) {
|
||||||
|
m_nextStartNodeItem->markAsBranch(false);
|
||||||
|
m_nextStartNodeItem->nextSidePair()->markAsBranch(false);
|
||||||
|
emit nodesChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
void turnOffAddNodeMode();
|
void turnOffAddNodeMode();
|
||||||
void turnOnAddNodeMode();
|
void turnOnAddNodeMode();
|
||||||
|
void markAsBranch();
|
||||||
|
void markAsTrunk();
|
||||||
public:
|
public:
|
||||||
SkeletonEditGraphicsView(QWidget *parent = 0);
|
SkeletonEditGraphicsView(QWidget *parent = 0);
|
||||||
void updateBackgroundImage(const QImage &image);
|
void updateBackgroundImage(const QImage &image);
|
||||||
|
|
|
@ -8,12 +8,24 @@ SkeletonEditNodeItem::SkeletonEditNodeItem(const QRectF &rect, QGraphicsItem *pa
|
||||||
m_checked(false),
|
m_checked(false),
|
||||||
m_nextSidePair(NULL),
|
m_nextSidePair(NULL),
|
||||||
m_sideColor(Theme::red),
|
m_sideColor(Theme::red),
|
||||||
m_sideColorName("red")
|
m_sideColorName("red"),
|
||||||
|
m_isBranch(false)
|
||||||
{
|
{
|
||||||
setData(0, "node");
|
setData(0, "node");
|
||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonEditNodeItem::markAsBranch(bool isBranch)
|
||||||
|
{
|
||||||
|
m_isBranch = isBranch;
|
||||||
|
updateAppearance();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkeletonEditNodeItem::isBranch()
|
||||||
|
{
|
||||||
|
return m_isBranch;
|
||||||
|
}
|
||||||
|
|
||||||
const QString &SkeletonEditNodeItem::sideColorName()
|
const QString &SkeletonEditNodeItem::sideColorName()
|
||||||
{
|
{
|
||||||
return m_sideColorName;
|
return m_sideColorName;
|
||||||
|
@ -98,7 +110,7 @@ void SkeletonEditNodeItem::setOrigin(QPointF point)
|
||||||
void SkeletonEditNodeItem::updateAppearance()
|
void SkeletonEditNodeItem::updateAppearance()
|
||||||
{
|
{
|
||||||
QColor penColor = m_sideColor;
|
QColor penColor = m_sideColor;
|
||||||
penColor.setAlphaF(m_checked ? Theme::checkedAlpha : Theme::normalAlpha);
|
penColor.setAlphaF(m_checked ? Theme::checkedAlpha : (m_isBranch ? Theme::branchAlpha : Theme::normalAlpha));
|
||||||
QPen pen(penColor);
|
QPen pen(penColor);
|
||||||
pen.setWidth(Theme::skeletonNodeBorderSize);
|
pen.setWidth(Theme::skeletonNodeBorderSize);
|
||||||
setPen(pen);
|
setPen(pen);
|
||||||
|
|
|
@ -19,6 +19,8 @@ public:
|
||||||
void setHovered(bool hovered);
|
void setHovered(bool hovered);
|
||||||
bool checked();
|
bool checked();
|
||||||
void setChecked(bool checked);
|
void setChecked(bool checked);
|
||||||
|
void markAsBranch(bool isBranch);
|
||||||
|
bool isBranch();
|
||||||
SkeletonEditNodeItem *nextSidePair();
|
SkeletonEditNodeItem *nextSidePair();
|
||||||
void setNextSidePair(SkeletonEditNodeItem *nodeItem);
|
void setNextSidePair(SkeletonEditNodeItem *nodeItem);
|
||||||
const QColor &sideColor();
|
const QColor &sideColor();
|
||||||
|
@ -32,6 +34,7 @@ private:
|
||||||
SkeletonEditNodeItem *m_nextSidePair;
|
SkeletonEditNodeItem *m_nextSidePair;
|
||||||
QColor m_sideColor;
|
QColor m_sideColor;
|
||||||
QString m_sideColorName;
|
QString m_sideColorName;
|
||||||
|
bool m_isBranch;
|
||||||
private:
|
private:
|
||||||
void updateAppearance();
|
void updateAppearance();
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,71 @@ void SkeletonSnapshot::splitByConnectivity(std::vector<SkeletonSnapshot> *groups
|
||||||
{
|
{
|
||||||
std::map<QString, std::vector<QString>> nodeLinkMap;
|
std::map<QString, std::vector<QString>> nodeLinkMap;
|
||||||
std::map<QString, std::map<QString, QString>>::iterator edgeIterator;
|
std::map<QString, std::map<QString, QString>>::iterator edgeIterator;
|
||||||
|
std::map<QString, int> neighborCountMap;
|
||||||
|
for (edgeIterator = edges.begin(); edgeIterator != edges.end(); edgeIterator++) {
|
||||||
|
neighborCountMap[edgeIterator->second["from"]]++;
|
||||||
|
neighborCountMap[edgeIterator->second["to"]]++;
|
||||||
|
}
|
||||||
|
int nextNewXnodeId = 1;
|
||||||
|
std::vector<std::pair<QString, QString>> newPendingEdges;
|
||||||
|
for (edgeIterator = edges.begin(); edgeIterator != edges.end(); ) {
|
||||||
|
std::map<QString, QString> *oneNode = &nodes[edgeIterator->second["from"]];
|
||||||
|
std::map<QString, QString> *linkNode = &nodes[edgeIterator->second["to"]];
|
||||||
|
if ("true" != (*oneNode)["isBranch"]) {
|
||||||
|
oneNode = &nodes[edgeIterator->second["to"]];
|
||||||
|
linkNode = &nodes[edgeIterator->second["from"]];
|
||||||
|
if ("true" != (*oneNode)["isBranch"]) {
|
||||||
|
edgeIterator++;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (neighborCountMap[(*linkNode)["id"]] < 3) {
|
||||||
|
edgeIterator++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (neighborCountMap[(*linkNode)["id"]] < 3) {
|
||||||
|
edgeIterator++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("red" == (*oneNode)["sideColorName"]) {
|
||||||
|
QString nodeId = QString("nodex%1").arg(nextNewXnodeId++);
|
||||||
|
std::map<QString, QString> *newNode = &nodes[nodeId];
|
||||||
|
*newNode = *linkNode;
|
||||||
|
(*newNode)["id"] = nodeId;
|
||||||
|
(*newNode)["radius"] = (*newNode)["radius"].toFloat() / 2;
|
||||||
|
|
||||||
|
std::map<QString, QString> *pairNode = &nodes[(*oneNode)["nextSidePair"]];
|
||||||
|
QString pairNodeId = QString("nodex%1").arg(nextNewXnodeId++);
|
||||||
|
std::map<QString, QString> *newPairNode = &nodes[pairNodeId];
|
||||||
|
*newPairNode = *pairNode;
|
||||||
|
(*newPairNode)["id"] = pairNodeId;
|
||||||
|
(*newPairNode)["radius"] = (*newPairNode)["radius"].toFloat() / 2;
|
||||||
|
|
||||||
|
(*newNode)["nextSidePair"] = pairNodeId;
|
||||||
|
(*newPairNode)["nextSidePair"] = nodeId;
|
||||||
|
|
||||||
|
newPendingEdges.push_back(std::make_pair((*oneNode)["id"], nodeId));
|
||||||
|
}
|
||||||
|
|
||||||
|
edgeIterator = edges.erase(edgeIterator);
|
||||||
|
}
|
||||||
|
int nextNewXedgeId = 1;
|
||||||
|
for (size_t i = 0; i < newPendingEdges.size(); i++) {
|
||||||
|
QString edgeId = QString("edgex%1").arg(nextNewXedgeId++);
|
||||||
|
std::map<QString, QString> *newEdge = &edges[edgeId];
|
||||||
|
(*newEdge)["id"] = edgeId;
|
||||||
|
(*newEdge)["from"] = newPendingEdges[i].first;
|
||||||
|
(*newEdge)["to"] = newPendingEdges[i].second;
|
||||||
|
|
||||||
|
edgeId = QString("edgex%1").arg(nextNewXedgeId++);
|
||||||
|
newEdge = &edges[edgeId];
|
||||||
|
(*newEdge)["id"] = edgeId;
|
||||||
|
(*newEdge)["from"] = nodes[newPendingEdges[i].first]["nextSidePair"];
|
||||||
|
(*newEdge)["to"] = nodes[newPendingEdges[i].second]["nextSidePair"];
|
||||||
|
}
|
||||||
for (edgeIterator = edges.begin(); edgeIterator != edges.end(); edgeIterator++) {
|
for (edgeIterator = edges.begin(); edgeIterator != edges.end(); edgeIterator++) {
|
||||||
nodeLinkMap[edgeIterator->second["from"]].push_back(edgeIterator->second["to"]);
|
nodeLinkMap[edgeIterator->second["from"]].push_back(edgeIterator->second["to"]);
|
||||||
nodeLinkMap[edgeIterator->second["to"]].push_back(edgeIterator->second["from"]);
|
nodeLinkMap[edgeIterator->second["to"]].push_back(edgeIterator->second["from"]);
|
||||||
|
|
|
@ -236,6 +236,8 @@ Mesh *SkeletonToMesh::takeResultMesh()
|
||||||
void SkeletonToMesh::process()
|
void SkeletonToMesh::process()
|
||||||
{
|
{
|
||||||
std::vector<SkeletonSnapshot> groups;
|
std::vector<SkeletonSnapshot> groups;
|
||||||
|
QRectF globalFront = m_snapshot.boundingBoxFront();
|
||||||
|
QRectF globalSide = m_snapshot.boundingBoxSide();
|
||||||
m_snapshot.splitByConnectivity(&groups);
|
m_snapshot.splitByConnectivity(&groups);
|
||||||
|
|
||||||
std::vector<int> meshIds;
|
std::vector<int> meshIds;
|
||||||
|
@ -257,9 +259,9 @@ void SkeletonToMesh::process()
|
||||||
std::map<QString, std::map<QString, QString>>::iterator nextSidePair = skeleton->nodes.find(nodeIterator->second["nextSidePair"]);
|
std::map<QString, std::map<QString, QString>>::iterator nextSidePair = skeleton->nodes.find(nodeIterator->second["nextSidePair"]);
|
||||||
if (nextSidePair == skeleton->nodes.end())
|
if (nextSidePair == skeleton->nodes.end())
|
||||||
continue;
|
continue;
|
||||||
float x = (nodeIterator->second["x"].toFloat() - front.left()) / canvasHeight;
|
float x = (nodeIterator->second["x"].toFloat() - globalFront.left()) / canvasHeight;
|
||||||
float y = (nodeIterator->second["y"].toFloat()) / canvasHeight;
|
float y = (nodeIterator->second["y"].toFloat() - globalFront.top()) / canvasHeight;
|
||||||
float z = (nextSidePair->second["x"].toFloat() - side.left()) / canvasHeight;
|
float z = (nextSidePair->second["x"].toFloat() - globalSide.left()) / canvasHeight;
|
||||||
float r = nodeIterator->second["radius"].toFloat() / canvasHeight;
|
float r = nodeIterator->second["radius"].toFloat() / canvasHeight;
|
||||||
float t = nextSidePair->second["radius"].toFloat() / canvasHeight;
|
float t = nextSidePair->second["radius"].toFloat() / canvasHeight;
|
||||||
int bmeshNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, r, t);
|
int bmeshNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, r, t);
|
||||||
|
|
|
@ -18,6 +18,7 @@ QColor Theme::red = QColor(0xfc, 0x66, 0x21);
|
||||||
QColor Theme::green = QColor(0xaa, 0xeb, 0xc4);
|
QColor Theme::green = QColor(0xaa, 0xeb, 0xc4);
|
||||||
QColor Theme::blue = QColor(0x2a, 0x5a, 0xac);
|
QColor Theme::blue = QColor(0x2a, 0x5a, 0xac);
|
||||||
float Theme::normalAlpha = 128.0 / 255;
|
float Theme::normalAlpha = 128.0 / 255;
|
||||||
|
float Theme::branchAlpha = 64.0 / 255;
|
||||||
float Theme::checkedAlpha = 1.0;
|
float Theme::checkedAlpha = 1.0;
|
||||||
float Theme::fillAlpha = 50.0 / 255;
|
float Theme::fillAlpha = 50.0 / 255;
|
||||||
int Theme::skeletonNodeBorderSize = 1;
|
int Theme::skeletonNodeBorderSize = 1;
|
||||||
|
|
|
@ -12,6 +12,7 @@ public:
|
||||||
static QColor blue;
|
static QColor blue;
|
||||||
static float normalAlpha;
|
static float normalAlpha;
|
||||||
static float checkedAlpha;
|
static float checkedAlpha;
|
||||||
|
static float branchAlpha;
|
||||||
static float fillAlpha;
|
static float fillAlpha;
|
||||||
static int skeletonNodeBorderSize;
|
static int skeletonNodeBorderSize;
|
||||||
static int skeletonEdgeWidth;
|
static int skeletonEdgeWidth;
|
||||||
|
|
Loading…
Reference in New Issue