Add thickness support
parent
24fbff4218
commit
f405ac0ede
|
@ -24,7 +24,7 @@ int main(int argc, char ** argv)
|
|||
darkPalette.setColor(QPalette::ButtonText, QColor(239,239,239));
|
||||
darkPalette.setColor(QPalette::BrightText, Qt::red);
|
||||
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||
darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||
darkPalette.setColor(QPalette::Highlight, QColor(252, 102, 33));
|
||||
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
|
||||
qApp->setPalette(darkPalette);
|
||||
qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #fc6621; border: 1px solid white; }");
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <QStackedWidget>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QBuffer>
|
||||
#include <QFormLayout>
|
||||
#include <QComboBox>
|
||||
#include <assert.h>
|
||||
#include "mainwindow.h"
|
||||
#include "skeletonwidget.h"
|
||||
|
@ -52,6 +54,14 @@ MainWindow::MainWindow()
|
|||
topLayout->addLayout(topButtonsLayout);
|
||||
topLayout->addWidget(hrWidget);
|
||||
|
||||
m_edgePropertyWidget = new QWidget;
|
||||
QFormLayout *formLayout = new QFormLayout;
|
||||
QComboBox *edgeTypeBox = new QComboBox;
|
||||
edgeTypeBox->addItem("Spine", "Spine");
|
||||
edgeTypeBox->addItem("Attach", "Attach");
|
||||
formLayout->addRow(tr("Edge Type:"), edgeTypeBox);
|
||||
m_edgePropertyWidget->setLayout(formLayout);
|
||||
|
||||
QVBoxLayout *modelRightLayout = new QVBoxLayout;
|
||||
|
||||
modelRightLayout->addSpacing(20);
|
||||
|
@ -75,6 +85,10 @@ MainWindow::MainWindow()
|
|||
modelRightLayout->addWidget(saveModelAsButton);
|
||||
saveModelAsButton->hide();
|
||||
|
||||
modelRightLayout->addSpacing(20);
|
||||
|
||||
modelRightLayout->addWidget(m_edgePropertyWidget);
|
||||
|
||||
modelRightLayout->addStretch();
|
||||
|
||||
SkeletonWidget *skeletonWidget = new SkeletonWidget(this);
|
||||
|
|
|
@ -22,6 +22,7 @@ private:
|
|||
QStackedWidget *m_stackedWidget;
|
||||
QString m_saveModelAs;
|
||||
SkeletonWidget *m_skeletonWidget;
|
||||
QWidget *m_edgePropertyWidget;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,27 @@ SkeletonEditEdgeItem::SkeletonEditEdgeItem(QGraphicsItem *parent) :
|
|||
m_secondNode(NULL)
|
||||
{
|
||||
setData(0, "edge");
|
||||
QPen pen(Theme::skeletonMasterNodeBorderColor);
|
||||
m_checked = false;
|
||||
updateAppearance();
|
||||
}
|
||||
|
||||
void SkeletonEditEdgeItem::setChecked(bool checked)
|
||||
{
|
||||
if (m_checked == checked) {
|
||||
return;
|
||||
}
|
||||
m_checked = checked;
|
||||
updateAppearance();
|
||||
}
|
||||
|
||||
bool SkeletonEditEdgeItem::checked()
|
||||
{
|
||||
return m_checked;
|
||||
}
|
||||
|
||||
void SkeletonEditEdgeItem::updateAppearance()
|
||||
{
|
||||
QPen pen(m_checked ? Theme::skeletonMasterNodeBorderHighlightColor : Theme::skeletonMasterNodeBorderColor);
|
||||
pen.setWidth(Theme::skeletonMasterNodeBorderSize);
|
||||
setPen(pen);
|
||||
}
|
||||
|
|
|
@ -12,9 +12,14 @@ public:
|
|||
SkeletonEditNodeItem *firstNode();
|
||||
SkeletonEditNodeItem *secondNode();
|
||||
bool connects(SkeletonEditNodeItem *nodeItem);
|
||||
void setChecked(bool checked);
|
||||
bool checked();
|
||||
private:
|
||||
SkeletonEditNodeItem *m_firstNode;
|
||||
SkeletonEditNodeItem *m_secondNode;
|
||||
bool m_checked;
|
||||
private:
|
||||
void updateAppearance();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include "skeletoneditgraphicsview.h"
|
||||
#include "skeletoneditnodeitem.h"
|
||||
#include "skeletoneditedgeitem.h"
|
||||
|
@ -21,7 +22,8 @@ SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
|
|||
m_lastHoverNodeItem(NULL),
|
||||
m_lastMousePos(0, 0),
|
||||
m_isMovingNodeItem(false),
|
||||
m_backgroundLoaded(false)
|
||||
m_backgroundLoaded(false),
|
||||
m_selectedEdgeItem(NULL)
|
||||
{
|
||||
setScene(new QGraphicsScene());
|
||||
|
||||
|
@ -76,7 +78,7 @@ SkeletonEditNodeItem *SkeletonEditGraphicsView::findNodeItemByPos(QPointF pos)
|
|||
for (it = list.begin(); it != list.end(); ++it) {
|
||||
if ((*it)->data(0).toString() == "node") {
|
||||
SkeletonEditNodeItem *nodeItem = static_cast<SkeletonEditNodeItem *>(*it);
|
||||
if (nodeItem->rect().contains(pos)) {
|
||||
if (nodeItem->shape().contains(pos)) {
|
||||
return nodeItem;
|
||||
}
|
||||
}
|
||||
|
@ -84,11 +86,45 @@ SkeletonEditNodeItem *SkeletonEditGraphicsView::findNodeItemByPos(QPointF pos)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SkeletonEditEdgeItem *SkeletonEditGraphicsView::findEdgeItemByPos(QPointF pos)
|
||||
{
|
||||
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->shape().contains(pos)) {
|
||||
return edgeItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkeletonEditEdgeItem *SkeletonEditGraphicsView::findEdgeItemByNodePair(SkeletonEditNodeItem *first,
|
||||
SkeletonEditNodeItem *second)
|
||||
{
|
||||
QList<QGraphicsItem *>::iterator it;
|
||||
QList<QGraphicsItem *> list = scene()->items();
|
||||
assert(first != second);
|
||||
for (it = list.begin(); it != list.end(); ++it) {
|
||||
if ((*it)->data(0).toString() == "edge") {
|
||||
SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it);
|
||||
if ((edgeItem->firstNode() == first || edgeItem->secondNode() == first) &&
|
||||
(edgeItem->firstNode() == second || edgeItem->secondNode() == second)) {
|
||||
return edgeItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mousePressEvent(event);
|
||||
if (!m_backgroundLoaded)
|
||||
return;
|
||||
QPointF pos = mapToScene(event->pos());
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
if (!m_inAddNodeMode) {
|
||||
if (m_lastHoverNodeItem) {
|
||||
|
@ -99,9 +135,27 @@ void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
|
|||
setNextStartNodeItem(NULL);
|
||||
}
|
||||
}
|
||||
SkeletonEditEdgeItem *edgeItem = findEdgeItemByPos(pos);
|
||||
if (edgeItem) {
|
||||
if (m_selectedEdgeItem != edgeItem) {
|
||||
if (m_selectedEdgeItem) {
|
||||
m_selectedEdgeItem->setChecked(false);
|
||||
m_selectedEdgeItem = NULL;
|
||||
}
|
||||
edgeItem->setChecked(true);
|
||||
m_selectedEdgeItem = edgeItem;
|
||||
emit edgeCheckStateChanged();
|
||||
}
|
||||
} else {
|
||||
if (m_selectedEdgeItem) {
|
||||
m_selectedEdgeItem->setChecked(false);
|
||||
m_selectedEdgeItem = NULL;
|
||||
emit edgeCheckStateChanged();
|
||||
}
|
||||
}
|
||||
m_lastMousePos = mapToScene(event->pos());
|
||||
}
|
||||
}
|
||||
m_lastMousePos = pos;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
|
@ -195,10 +249,20 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
|||
return;
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
if (m_inAddNodeMode) {
|
||||
SkeletonEditNodeItem *masterNode = new SkeletonEditNodeItem(m_pendingNodeItem->rect());
|
||||
if (m_lastHoverNodeItem && m_nextStartNodeItem && m_lastHoverNodeItem != m_nextStartNodeItem) {
|
||||
if (!findEdgeItemByNodePair(m_lastHoverNodeItem->master(), m_nextStartNodeItem)) {
|
||||
SkeletonEditEdgeItem *newEdge = new SkeletonEditEdgeItem();
|
||||
newEdge->setNodes(m_nextStartNodeItem, m_lastHoverNodeItem->master());
|
||||
scene()->addItem(newEdge);
|
||||
emit nodesChanged();
|
||||
}
|
||||
} else {
|
||||
float newNodeX = m_pendingNodeItem->x();
|
||||
QRectF newNodeRect = m_pendingNodeItem->rect();
|
||||
SkeletonEditNodeItem *masterNode = new SkeletonEditNodeItem(newNodeRect);
|
||||
scene()->addItem(masterNode);
|
||||
QRectF slaveRect = m_pendingNodeItem->rect();
|
||||
float x = m_pendingNodeItem->x() + m_pendingNodeItem->rect().width() / 2;
|
||||
QRectF slaveRect = newNodeRect;
|
||||
float x = newNodeX + newNodeRect.width() / 2;
|
||||
slaveRect.translate(findXForSlave(x) - x, 0);
|
||||
SkeletonEditNodeItem *slaveNode = new SkeletonEditNodeItem(slaveRect);
|
||||
scene()->addItem(slaveNode);
|
||||
|
@ -219,6 +283,7 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
|||
setNextStartNodeItem(masterNode);
|
||||
emit nodesChanged();
|
||||
}
|
||||
}
|
||||
m_isMovingNodeItem = false;
|
||||
}
|
||||
}
|
||||
|
@ -260,7 +325,6 @@ void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
|
|||
moveTo.y() + m_pendingNodeItem->rect().height() / 2)));
|
||||
}
|
||||
if (!m_isMovingNodeItem) {
|
||||
if (!m_inAddNodeMode) {
|
||||
SkeletonEditNodeItem *hoverNodeItem = findNodeItemByPos(pos);
|
||||
if (hoverNodeItem) {
|
||||
hoverNodeItem->setHighlighted(true);
|
||||
|
@ -270,12 +334,6 @@ void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
|
|||
m_lastHoverNodeItem->setHighlighted(false);
|
||||
m_lastHoverNodeItem = hoverNodeItem;
|
||||
}
|
||||
} else {
|
||||
if (m_lastHoverNodeItem) {
|
||||
m_lastHoverNodeItem->setHighlighted(false);
|
||||
m_lastHoverNodeItem = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
QPointF curMousePos = pos;
|
||||
if (m_lastHoverNodeItem) {
|
||||
|
@ -363,10 +421,8 @@ void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)
|
|||
delta = delta < 0 ? -1.0 : 1.0;
|
||||
AddItemRadius(m_pendingNodeItem, delta);
|
||||
if (!m_inAddNodeMode && m_lastHoverNodeItem) {
|
||||
if (canAddItemRadius(m_lastHoverNodeItem, delta) &&
|
||||
canAddItemRadius(m_lastHoverNodeItem->pair(), delta)) {
|
||||
if (canAddItemRadius(m_lastHoverNodeItem, delta)) {
|
||||
AddItemRadius(m_lastHoverNodeItem, delta);
|
||||
AddItemRadius(m_lastHoverNodeItem->pair(), delta);
|
||||
}
|
||||
emit nodesChanged();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ signals:
|
|||
void sizeChanged();
|
||||
void nodesChanged();
|
||||
void changeTurnaroundTriggered();
|
||||
void edgeCheckStateChanged();
|
||||
public slots:
|
||||
void turnOffAddNodeMode();
|
||||
void turnOnAddNodeMode();
|
||||
|
@ -45,10 +46,14 @@ private:
|
|||
QPointF m_lastMousePos;
|
||||
bool m_isMovingNodeItem;
|
||||
bool m_backgroundLoaded;
|
||||
SkeletonEditEdgeItem *m_selectedEdgeItem;
|
||||
private:
|
||||
void toggleAddNodeMode();
|
||||
void applyAddNodeMode();
|
||||
SkeletonEditNodeItem *findNodeItemByPos(QPointF pos);
|
||||
SkeletonEditEdgeItem *findEdgeItemByPos(QPointF pos);
|
||||
SkeletonEditEdgeItem *findEdgeItemByNodePair(SkeletonEditNodeItem *first,
|
||||
SkeletonEditNodeItem *second);
|
||||
void setNextStartNodeItem(SkeletonEditNodeItem *item);
|
||||
float findXForSlave(float x);
|
||||
bool canNodeItemMoveTo(SkeletonEditNodeItem *item, QPointF moveTo);
|
||||
|
|
|
@ -4,13 +4,20 @@
|
|||
#include "skeletoneditedgeitem.h"
|
||||
#include <vector>
|
||||
|
||||
#define USE_CARVE 1
|
||||
|
||||
#if USE_CARVE == 1
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# include <carve_config.h>
|
||||
#endif
|
||||
#include <carve/carve.hpp>
|
||||
#include <carve/csg.hpp>
|
||||
#include <carve/input.hpp>
|
||||
#endif
|
||||
|
||||
#define MAX_VERTICES_PER_FACE 100
|
||||
|
||||
#if USE_CARVE == 0
|
||||
// Polygon_mesh_processing/corefinement_mesh_union.cpp
|
||||
// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2corefinement_mesh_union_8cpp-example.html#a2
|
||||
// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2triangulate_faces_example_8cpp-example.html
|
||||
|
@ -20,14 +27,10 @@
|
|||
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
|
||||
// Modified from https://wiki.qt.io/QThreads_general_usage
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Surface_mesh<K::Point_3> CgalMesh;
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
#define MAX_VERTICES_PER_FACE 100
|
||||
|
||||
CgalMesh *makeCgalMeshFromMeshlite(void *meshlite, int meshId)
|
||||
{
|
||||
CgalMesh *mesh = new CgalMesh;
|
||||
|
@ -115,6 +118,10 @@ CgalMesh *unionCgalMeshs(CgalMesh *first, CgalMesh *second)
|
|||
return mesh;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_CARVE == 1
|
||||
|
||||
carve::poly::Polyhedron *makeCarveMeshFromMeshlite(void *meshlite, int meshId)
|
||||
{
|
||||
carve::input::PolyhedronData data;
|
||||
|
@ -187,6 +194,8 @@ carve::poly::Polyhedron *unionCarveMeshs(carve::poly::Polyhedron *first,
|
|||
return new carve::poly::Polyhedron(*result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct NodeItemInfo
|
||||
{
|
||||
int index;
|
||||
|
@ -231,6 +240,7 @@ SkeletonToMesh::SkeletonToMesh(SkeletonEditGraphicsView *graphicsView) :
|
|||
node.originZ = nodeItem->slave()->origin().x();
|
||||
node.bmeshNodeId = -1;
|
||||
node.radius = nodeItem->radius();
|
||||
node.thickness = nodeItem->slave()->radius();
|
||||
|
||||
info.index = skeletonGroup->nodes.size();
|
||||
info.neighborCount = 1;
|
||||
|
@ -267,8 +277,6 @@ Mesh *SkeletonToMesh::takeResultMesh()
|
|||
return mesh;
|
||||
}
|
||||
|
||||
#define USE_CARVE 1
|
||||
|
||||
#if USE_CARVE
|
||||
#define ExternalMesh carve::poly::Polyhedron
|
||||
#define makeExternalMeshFromMeshlite makeCarveMeshFromMeshlite
|
||||
|
@ -334,7 +342,8 @@ void SkeletonToMesh::process()
|
|||
float y = (node->originY - top - height / 2) / height;
|
||||
float z = (node->originZ - zLeft - zWidth / 2) / height;
|
||||
float r = node->radius / height;
|
||||
node->bmeshNodeId = meshlite_bmesh_add_node(context, group->bmeshId, x, y, z, r);
|
||||
float t = node->thickness / height;
|
||||
node->bmeshNodeId = meshlite_bmesh_add_node(context, group->bmeshId, x, y, z, r, t);
|
||||
}
|
||||
for (size_t j = 0; j < group->edges.size(); j++) {
|
||||
SkeletonNode *firstNode = &group->nodes[group->edges[j].firstNode];
|
||||
|
|
|
@ -13,6 +13,7 @@ struct SkeletonNode
|
|||
float originY;
|
||||
float originZ;
|
||||
float radius;
|
||||
float thickness;
|
||||
int bmeshNodeId;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
QColor Theme::skeletonMasterNodeBorderColor = QColor(0xfc, 0x66, 0x21, 128);
|
||||
QColor Theme::skeletonMasterNodeBorderHighlightColor = QColor(0xfc, 0x66, 0x21);
|
||||
QColor Theme::skeletonMasterNodeFillColor = QColor(0xfc, 0x66, 0x21, 50);
|
||||
int Theme::skeletonMasterNodeBorderSize = 2;
|
||||
int Theme::skeletonMasterNodeBorderSize = 7;
|
||||
QColor Theme::skeletonSlaveNodeBorderColor = QColor(0xcc, 0xcc, 0xcc, 64);
|
||||
QColor Theme::skeletonSlaveNodeBorderHighlightColor = QColor(0xcc, 0xcc, 0xcc);
|
||||
QColor Theme::skeletonSlaveNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 25);
|
||||
int Theme::skeletonSlaveNodeBorderSize = 2;
|
||||
int Theme::skeletonSlaveNodeBorderSize = 7;
|
||||
QString Theme::tabButtonSelectedStylesheet = "QPushButton { color: #efefef; background-color: #fc6621; border: 0px; padding-top: 2px; padding-bottom: 2px; padding-left: 25px; padding-right: 25px;}";
|
||||
QString Theme::tabButtonStylesheet = "QPushButton { color: #efefef; background-color: #353535; border: 0px; padding-top: 2px; padding-bottom: 2px; padding-left: 25px; padding-right: 25px;}";
|
||||
|
||||
|
|
Loading…
Reference in New Issue