diff --git a/dust3d.pro b/dust3d.pro index a8c45535..c3a00a71 100644 --- a/dust3d.pro +++ b/dust3d.pro @@ -18,12 +18,6 @@ HEADERS += src/modelofflinerender.h SOURCES += src/modelwidget.cpp HEADERS += src/modelwidget.h -SOURCES += src/skeletonnodepropertywidget.cpp -HEADERS += src/skeletonnodepropertywidget.h - -SOURCES += src/skeletonedgepropertywidget.cpp -HEADERS += src/skeletonedgepropertywidget.h - SOURCES += src/skeletondocument.cpp HEADERS += src/skeletondocument.h @@ -33,9 +27,6 @@ HEADERS += src/skeletondocumentwindow.h SOURCES += src/skeletongraphicswidget.cpp HEADERS += src/skeletongraphicswidget.h -SOURCES += src/skeletonhistorylistwidget.cpp -HEADERS += src/skeletonhistorylistwidget.h - SOURCES += src/skeletonpartlistwidget.cpp HEADERS += src/skeletonpartlistwidget.h diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index a01479fc..bf0b4b0c 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -117,6 +117,7 @@ void MeshGenerator::process() void *meshliteContext = meshlite_create_context(); std::map partBmeshMap; std::map bmeshNodeMap; + bool hasSubdiv = false; QRectF mainProfile, sideProfile; resolveBoundingBox(&mainProfile, &sideProfile); @@ -207,8 +208,10 @@ void MeshGenerator::process() int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId, 0); if (isTrueValueString(part->second["subdived"])) { int subdivedMeshId = subdivMesh(meshliteContext, meshId); - if (subdivedMeshId > 0) + if (subdivedMeshId > 0) { meshId = subdivedMeshId; + hasSubdiv = true; + } } if (m_requirePartPreviewMap.find(partIdIt) != m_requirePartPreviewMap.end()) { ModelOfflineRender *render = m_partPreviewRenderMap[partIdIt]; @@ -227,7 +230,7 @@ void MeshGenerator::process() } else if (meshIds.size() > 0) { mergedMeshId = meshIds[0]; } - if (mergedMeshId > 0) { + if (mergedMeshId > 0 && !hasSubdiv) { mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId); } diff --git a/src/modelofflinerender.cpp b/src/modelofflinerender.cpp index af689c7d..d803bb06 100644 --- a/src/modelofflinerender.cpp +++ b/src/modelofflinerender.cpp @@ -54,8 +54,8 @@ QImage ModelOfflineRender::toImage(const QSize &size) m_context->functions()->glViewport(0, 0, size.width(), size.height()); if (nullptr != m_mesh) { - int xRot = 0; - int yRot = 0; + int xRot = -30 * 16; + int yRot = 45 * 16; int zRot = 0; QMatrix4x4 proj; QMatrix4x4 camera; diff --git a/src/modelwidget.cpp b/src/modelwidget.cpp index 9c8d0b39..acfb0c01 100644 --- a/src/modelwidget.cpp +++ b/src/modelwidget.cpp @@ -13,8 +13,8 @@ bool ModelWidget::m_transparent = true; ModelWidget::ModelWidget(QWidget *parent) : QOpenGLWidget(parent), - m_xRot(0), - m_yRot(0), + m_xRot(-30 * 16), + m_yRot(45 * 16), m_zRot(0), m_program(nullptr), m_moveStarted(false), diff --git a/src/skeletondocument.cpp b/src/skeletondocument.cpp index a7235880..4fb17bb0 100644 --- a/src/skeletondocument.cpp +++ b/src/skeletondocument.cpp @@ -482,26 +482,6 @@ void SkeletonDocument::splitPartByEdge(std::vector> *groups, } } -void SkeletonDocument::setEdgeBranchMode(QUuid edgeId, SkeletonEdgeBranchMode mode) -{ - auto edgeIt = edgeMap.find(edgeId); - if (edgeIt == edgeMap.end()) { - qDebug() << "Find edge failed:" << edgeId; - return; - } - edgeIt->second.branchMode = mode; -} - -void SkeletonDocument::setNodeRootMarkMode(QUuid nodeId, SkeletonNodeRootMarkMode mode) -{ - auto nodeIt = nodeMap.find(nodeId); - if (nodeIt == nodeMap.end()) { - qDebug() << "Find node failed:" << nodeId; - return; - } - nodeIt->second.rootMarkMode = mode; -} - void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot, const std::set &limitNodeIds) const { std::set limitPartIds; @@ -532,7 +512,6 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot, const std::setmoveToThread(thread); - //m_meshGenerator->addPreviewRequirement(); for (auto &part: partMap) { - //if (part.second.previewIsObsolete) { - // part.second.previewIsObsolete = false; - m_meshGenerator->addPartPreviewRequirement(part.first.toString()); - //} + m_meshGenerator->addPartPreviewRequirement(part.first.toString()); } connect(thread, &QThread::started, m_meshGenerator, &MeshGenerator::process); connect(m_meshGenerator, &MeshGenerator::finished, this, &SkeletonDocument::meshReady); @@ -895,3 +817,12 @@ bool SkeletonDocument::hasPastableContentInClipboard() const return false; } +bool SkeletonDocument::undoable() const +{ + return !m_undoItems.empty(); +} + +bool SkeletonDocument::redoable() const +{ + return !m_redoItems.empty(); +} diff --git a/src/skeletondocument.h b/src/skeletondocument.h index b7d0a4b3..984b2cf8 100644 --- a/src/skeletondocument.h +++ b/src/skeletondocument.h @@ -11,16 +11,6 @@ #include "mesh.h" #include "meshgenerator.h" -enum class SkeletonNodeRootMarkMode -{ - Auto = 0, - MarkAsRoot, - MarkAsNotRoot -}; - -const char *SkeletonNodeRootMarkModeToString(SkeletonNodeRootMarkMode mode); -SkeletonNodeRootMarkMode SkeletonNodeRootMarkModeFromString(const QString &mode); - class SkeletonNode { public: @@ -28,8 +18,7 @@ public: x(0), y(0), z(0), - radius(0), - rootMarkMode(SkeletonNodeRootMarkMode::Auto) + radius(0) { id = withId.isNull() ? QUuid::createUuid() : withId; } @@ -48,34 +37,19 @@ public: float y; float z; float radius; - bool xMirrored; - bool zMirrored; - SkeletonNodeRootMarkMode rootMarkMode; std::vector edgeIds; }; -enum class SkeletonEdgeBranchMode -{ - Auto = 0, - Trivial, - NoTrivial -}; - -const char *SkeletonEdgeBranchModeToString(SkeletonEdgeBranchMode mode); -SkeletonEdgeBranchMode SkeletonEdgeBranchModeFromString(const QString &mode); - class SkeletonEdge { public: - SkeletonEdge(const QUuid &withId=QUuid()) : - branchMode(SkeletonEdgeBranchMode::Auto) + SkeletonEdge(const QUuid &withId=QUuid()) { id = withId.isNull() ? QUuid::createUuid() : withId; } QUuid id; QUuid partId; QString name; - SkeletonEdgeBranchMode branchMode; std::vector nodeIds; QUuid neighborOf(QUuid nodeId) const { @@ -95,12 +69,10 @@ public: bool subdived; QImage preview; std::vector nodeIds; - bool previewIsObsolete; SkeletonPart(const QUuid &withId=QUuid()) : visible(true), locked(false), - subdived(false), - previewIsObsolete(true) + subdived(false) { id = withId.isNull() ? QUuid::createUuid() : withId; } @@ -171,6 +143,8 @@ public: QImage preview; void updateTurnaround(const QImage &image); bool hasPastableContentInClipboard() const; + bool undoable() const; + bool redoable() const; public slots: void removeNode(QUuid nodeId); void removeEdge(QUuid edgeId); @@ -182,8 +156,6 @@ public slots: void setNodeRadius(QUuid nodeId, float radius); void addEdge(QUuid fromNodeId, QUuid toNodeId); void setEditMode(SkeletonDocumentEditMode mode); - void setEdgeBranchMode(QUuid edgeId, SkeletonEdgeBranchMode mode); - void setNodeRootMarkMode(QUuid nodeId, SkeletonNodeRootMarkMode mode); void uiReady(); void generateMesh(); void meshReady(); diff --git a/src/skeletondocumentwindow.cpp b/src/skeletondocumentwindow.cpp index 16deac23..dae69cbc 100644 --- a/src/skeletondocumentwindow.cpp +++ b/src/skeletondocumentwindow.cpp @@ -9,8 +9,6 @@ #include "skeletondocumentwindow.h" #include "skeletongraphicswidget.h" #include "skeletonpartlistwidget.h" -#include "skeletonedgepropertywidget.h" -#include "skeletonnodepropertywidget.h" #include "theme.h" SkeletonDocumentWindow::SkeletonDocumentWindow() : @@ -41,18 +39,6 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : QPushButton *zoomOutButton = new QPushButton(QChar(fa::searchminus)); initButton(zoomOutButton); - QPushButton *changeTurnaroundButton = new QPushButton(QChar(fa::image)); - initButton(changeTurnaroundButton); - - QPushButton *markCenterButton = new QPushButton(QChar(fa::bullseye)); - initButton(markCenterButton); - - QPushButton *markTrivialBranchButton = new QPushButton(QChar(fa::link)); - initButton(markTrivialBranchButton); - - QPushButton *markMirrorButton = new QPushButton(QChar(fa::clone)); - initButton(markMirrorButton); - toolButtonLayout->addWidget(undoButton); toolButtonLayout->addSpacing(10); toolButtonLayout->addWidget(addButton); @@ -60,12 +46,6 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : toolButtonLayout->addWidget(dragButton); toolButtonLayout->addWidget(zoomInButton); toolButtonLayout->addWidget(zoomOutButton); - //toolButtonLayout->addSpacing(10); - //toolButtonLayout->addWidget(changeTurnaroundButton); - //toolButtonLayout->addSpacing(30); - //toolButtonLayout->addWidget(markCenterButton); - //toolButtonLayout->addWidget(markTrivialBranchButton); - //toolButtonLayout->addWidget(markMirrorButton); QLabel *dust3dJezzasoftLabel = new QLabel; QImage dust3dJezzasoftImage; @@ -105,36 +85,10 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : SkeletonPartListWidget *partListWidget = new SkeletonPartListWidget(m_document); partListWidget->setMaximumWidth(Theme::previewImageSize); - //QTabWidget *firstTabWidget = new QTabWidget; - //firstTabWidget->setFont(Theme::awesome()->font(Theme::toolIconFontSize * 3 / 4)); - //firstTabWidget->setMaximumWidth(200); - //firstTabWidget->addTab(partListWidget, QChar(fa::puzzlepiece)); - //firstTabWidget->addTab(new QWidget, QChar(fa::history)); - //firstTabWidget->addTab(new QWidget, QChar(fa::wrench)); - - //SkeletonEdgePropertyWidget *edgePropertyWidget = new SkeletonEdgePropertyWidget(m_document); - //SkeletonNodePropertyWidget *nodePropertyWidget = new SkeletonNodePropertyWidget(m_document); - - //QVBoxLayout *propertyLayout = new QVBoxLayout; - //propertyLayout->addWidget(edgePropertyWidget); - //propertyLayout->addWidget(nodePropertyWidget); - - //QWidget *propertyWidget = new QWidget; - //propertyWidget->setLayout(propertyLayout); - - //QTabWidget *secondTabWidget = new QTabWidget; - //secondTabWidget->setFont(Theme::awesome()->font(Theme::toolIconFontSize * 3 / 4)); - //secondTabWidget->setMaximumWidth(200); - //secondTabWidget->setMaximumHeight(90); - //secondTabWidget->addTab(propertyWidget, QChar(fa::adjust)); - QVBoxLayout *mainRightLayout = new QVBoxLayout; mainRightLayout->setSpacing(0); - //mainRightLayout->setContentsMargins(5, 5, 5, 5); mainRightLayout->setContentsMargins(0, 0, 0, 0); mainRightLayout->addWidget(partListWidget); - //mainRightLayout->addWidget(firstTabWidget); - //mainRightLayout->addWidget(secondTabWidget); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->setSpacing(0); @@ -155,8 +109,6 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : connect(m_document, &SkeletonDocument::turnaroundChanged, graphicsWidget, &SkeletonGraphicsWidget::turnaroundChanged); - connect(changeTurnaroundButton, &QPushButton::clicked, this, &SkeletonDocumentWindow::changeTurnaround); - connect(undoButton, &QPushButton::clicked, [=]() { m_document->undo(); }); diff --git a/src/skeletonedgepropertywidget.cpp b/src/skeletonedgepropertywidget.cpp deleted file mode 100644 index fcdd9b33..00000000 --- a/src/skeletonedgepropertywidget.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include "skeletonedgepropertywidget.h" - -SkeletonEdgePropertyWidget::SkeletonEdgePropertyWidget(const SkeletonDocument *document) : - m_branchModeComboBox(nullptr), - m_document(document) -{ - m_branchModeComboBox = new QComboBox; - - m_branchModeComboBox->insertItem(0, tr("Auto"), (int)SkeletonEdgeBranchMode::Auto); - m_branchModeComboBox->insertItem(1, tr("No Trivial"), (int)SkeletonEdgeBranchMode::NoTrivial); - m_branchModeComboBox->insertItem(2, tr("Trivial"), (int)SkeletonEdgeBranchMode::Trivial); - - QFormLayout *formLayout = new QFormLayout; - formLayout->addRow(tr("Joint Branch Mode:"), m_branchModeComboBox); - - setLayout(formLayout); - - hide(); - - connect(m_branchModeComboBox, static_cast(&QComboBox::currentIndexChanged), [=](int index) { - if (-1 != index) { - int mode = m_branchModeComboBox->itemData(index).toInt(); - emit setEdgeBranchMode(m_edgeId, static_cast(mode)); - } - }); -} - -void SkeletonEdgePropertyWidget::showProperties(QUuid edgeId) -{ - m_edgeId = edgeId; - updateData(); - show(); -} - -void SkeletonEdgePropertyWidget::updateData() -{ - const SkeletonEdge *edge = m_document->findEdge(m_edgeId); - if (nullptr == edge) { - hide(); - return; - } - int selectIndex = m_branchModeComboBox->findData((int)edge->branchMode); - m_branchModeComboBox->setCurrentIndex(selectIndex); -} - -QUuid SkeletonEdgePropertyWidget::currentEdgeId() -{ - return m_edgeId; -} diff --git a/src/skeletonedgepropertywidget.h b/src/skeletonedgepropertywidget.h deleted file mode 100644 index 5e8282b2..00000000 --- a/src/skeletonedgepropertywidget.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SKELETON_EDGE_PROPERTY_WIDGET_H -#define SKELETON_EDGE_PROPERTY_WIDGET_H -#include -#include -#include -#include "skeletondocument.h" - -class SkeletonEdgePropertyWidget : public QWidget -{ - Q_OBJECT -signals: - void setEdgeBranchMode(QUuid edgeId, SkeletonEdgeBranchMode mode); -public slots: - void showProperties(QUuid edgeId); -public: - SkeletonEdgePropertyWidget(const SkeletonDocument *document); - QUuid currentEdgeId(); -private: - void updateData(); -private: - QComboBox *m_branchModeComboBox; - const SkeletonDocument *m_document; - QUuid m_edgeId; -}; - -#endif diff --git a/src/skeletongraphicswidget.cpp b/src/skeletongraphicswidget.cpp index b995d85b..5ca43861 100644 --- a/src/skeletongraphicswidget.cpp +++ b/src/skeletongraphicswidget.cpp @@ -77,61 +77,73 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos) QMenu contextMenu(this); - QAction addAction("Add..", this); + QAction addAction(tr("Add.."), this); connect(&addAction, &QAction::triggered, [=]() { emit setEditMode(SkeletonDocumentEditMode::Add); }); contextMenu.addAction(&addAction); - QAction deleteAction("Delete", this); + QAction undoAction(tr("Undo"), this); + if (m_document->undoable()) { + connect(&undoAction, &QAction::triggered, m_document, &SkeletonDocument::undo); + contextMenu.addAction(&undoAction); + } + + QAction redoAction(tr("Redo"), this); + if (m_document->redoable()) { + connect(&redoAction, &QAction::triggered, m_document, &SkeletonDocument::redo); + contextMenu.addAction(&redoAction); + } + + QAction deleteAction(tr("Delete"), this); if (!m_rangeSelectionSet.empty()) { connect(&deleteAction, &QAction::triggered, this, &SkeletonGraphicsWidget::deleteSelected); contextMenu.addAction(&deleteAction); } - QAction cutAction("Cut", this); + QAction cutAction(tr("Cut"), this); if (!m_rangeSelectionSet.empty()) { connect(&cutAction, &QAction::triggered, this, &SkeletonGraphicsWidget::cut); contextMenu.addAction(&cutAction); } - QAction copyAction("Copy", this); + QAction copyAction(tr("Copy"), this); if (!m_rangeSelectionSet.empty()) { connect(©Action, &QAction::triggered, this, &SkeletonGraphicsWidget::copy); contextMenu.addAction(©Action); } - QAction pasteAction("Paste", this); + QAction pasteAction(tr("Paste"), this); if (m_document->hasPastableContentInClipboard()) { connect(&pasteAction, &QAction::triggered, m_document, &SkeletonDocument::paste); contextMenu.addAction(&pasteAction); } - QAction flipHorizontallyAction("H Flip", this); + QAction flipHorizontallyAction(tr("H Flip"), this); if (!m_rangeSelectionSet.empty() && !isSingleNodeSelected()) { connect(&flipHorizontallyAction, &QAction::triggered, this, &SkeletonGraphicsWidget::flipHorizontally); contextMenu.addAction(&flipHorizontallyAction); } - QAction flipVerticallyAction("V Flip", this); + QAction flipVerticallyAction(tr("V Flip"), this); if (!m_rangeSelectionSet.empty() && !isSingleNodeSelected()) { connect(&flipVerticallyAction, &QAction::triggered, this, &SkeletonGraphicsWidget::flipVertically); contextMenu.addAction(&flipVerticallyAction); } - QAction selectAllAction("Select All", this); + QAction selectAllAction(tr("Select All"), this); if (!nodeItemMap.empty()) { connect(&selectAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::selectAll); contextMenu.addAction(&selectAllAction); } - QAction selectPartAllAction("Select Part", this); + QAction selectPartAllAction(tr("Select Part"), this); if (!nodeItemMap.empty()) { connect(&selectPartAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::selectPartAll); contextMenu.addAction(&selectPartAllAction); } - QAction unselectAllAction("Unselect All", this); + QAction unselectAllAction(tr("Unselect All"), this); if (!m_rangeSelectionSet.empty()) { connect(&unselectAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::unselectAll); contextMenu.addAction(&unselectAllAction); @@ -139,7 +151,7 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos) contextMenu.addSeparator(); - QAction changeTurnaroundAction("Change Turnaround..", this); + QAction changeTurnaroundAction(tr("Change Turnaround.."), this); connect(&changeTurnaroundAction, &QAction::triggered, [=]() { emit changeTurnaround(); }); diff --git a/src/skeletonhistorylistwidget.cpp b/src/skeletonhistorylistwidget.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/skeletonhistorylistwidget.h b/src/skeletonhistorylistwidget.h deleted file mode 100644 index e69de29b..00000000 diff --git a/src/skeletonnodepropertywidget.cpp b/src/skeletonnodepropertywidget.cpp deleted file mode 100644 index 88a88101..00000000 --- a/src/skeletonnodepropertywidget.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include "skeletonnodepropertywidget.h" - -SkeletonNodePropertyWidget::SkeletonNodePropertyWidget(const SkeletonDocument *document) : - m_rootMarkModeComboBox(nullptr), - m_document(document) -{ - m_rootMarkModeComboBox = new QComboBox; - - m_rootMarkModeComboBox->insertItem(0, tr("Auto"), (int)SkeletonNodeRootMarkMode::Auto); - m_rootMarkModeComboBox->insertItem(1, tr("Mark as Root"), (int)SkeletonNodeRootMarkMode::MarkAsRoot); - m_rootMarkModeComboBox->insertItem(2, tr("Mark as Not Root"), (int)SkeletonNodeRootMarkMode::MarkAsNotRoot); - - QFormLayout *formLayout = new QFormLayout; - formLayout->addRow(tr("Root Mark:"), m_rootMarkModeComboBox); - - setLayout(formLayout); - - hide(); - - connect(m_rootMarkModeComboBox, static_cast(&QComboBox::currentIndexChanged), [=](int index) { - if (-1 != index) { - int mode = m_rootMarkModeComboBox->itemData(index).toInt(); - emit setNodeRootMarkMode(m_nodeId, static_cast(mode)); - } - }); -} - -void SkeletonNodePropertyWidget::showProperties(QUuid nodeId) -{ - m_nodeId = nodeId; - updateData(); - show(); -} - -void SkeletonNodePropertyWidget::updateData() -{ - const SkeletonNode *node = m_document->findNode(m_nodeId); - if (nullptr == node) { - hide(); - return; - } - int selectIndex = m_rootMarkModeComboBox->findData((int)node->rootMarkMode); - m_rootMarkModeComboBox->setCurrentIndex(selectIndex); -} - -QUuid SkeletonNodePropertyWidget::currentNodeId() -{ - return m_nodeId; -} diff --git a/src/skeletonnodepropertywidget.h b/src/skeletonnodepropertywidget.h deleted file mode 100644 index 6f3dcd95..00000000 --- a/src/skeletonnodepropertywidget.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SKELETON_NODE_PROPERTY_WIDGET_H -#define SKELETON_NODE_PROPERTY_WIDGET_H -#include -#include -#include -#include "skeletondocument.h" - -class SkeletonNodePropertyWidget : public QWidget -{ - Q_OBJECT -signals: - void setNodeRootMarkMode(QUuid nodeId, SkeletonNodeRootMarkMode mode); -public slots: - void showProperties(QUuid nodeId); -public: - SkeletonNodePropertyWidget(const SkeletonDocument *document); - QUuid currentNodeId(); -private: - void updateData(); -private: - QComboBox *m_rootMarkModeComboBox; - const SkeletonDocument *m_document; - QUuid m_nodeId; -}; - -#endif