Add rotate operation to menu

- Add rotate 90/-90 degree to facilitate nodes editing
- Enable docs.dust3d.org domain
master
Jeremy Hu 2018-06-15 17:58:46 +08:00
parent d05c43d714
commit e26095981b
7 changed files with 71 additions and 11 deletions

View File

@ -1,13 +1,13 @@
<a href="https://dust3d.readthedocs.io/en/latest/install.html" target="_blank"><image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/dust3d-logo.png" width="81" height="50"></a> <a href="http://docs.dust3d.org/en/latest/install.html" target="_blank"><image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/dust3d-logo.png" width="81" height="50"></a>
[![appveyor status](https://ci.appveyor.com/api/projects/status/github/huxingyi/dust3d?branch=master&svg=true)](https://ci.appveyor.com/project/huxingyi/dust3d) [![travis status](https://travis-ci.org/huxingyi/dust3d.svg?branch=master)](https://travis-ci.org/huxingyi/dust3d) [![readthedocs status](https://readthedocs.org/projects/dust3d/badge/?version=latest)](https://dust3d.readthedocs.io/en/latest/?badge=latest) [![appveyor status](https://ci.appveyor.com/api/projects/status/github/huxingyi/dust3d?branch=master&svg=true)](https://ci.appveyor.com/project/huxingyi/dust3d) [![travis status](https://travis-ci.org/huxingyi/dust3d.svg?branch=master)](https://travis-ci.org/huxingyi/dust3d) [![readthedocs status](https://readthedocs.org/projects/dust3d/badge/?version=latest)](http://docs.dust3d.org/en/latest/?badge=latest)
Overview Overview
---------- ----------
Dust3D is a brand new 3D modeling software. It helps you create a 3D watertight base model in seconds. Use it to speed up your character modeling in game making, 3D printing, and so on. Dust3D is a brand new 3D modeling software. It helps you create a 3D watertight base model in seconds. Use it to speed up your character modeling in game making, 3D printing, and so on.
[Download Dust3D](https://dust3d.readthedocs.io/en/latest/install.html) [Download Dust3D](http://docs.dust3d.org/en/latest/install.html)
[Online Dust3D Reference Guide](https://dust3d.readthedocs.io/en/latest/index.html) [Online Dust3D Reference Guide](http://docs.dust3d.org)
Examples Examples
---------------------- ----------------------
@ -15,19 +15,19 @@ Examples
<a href="https://youtu.be/wQerDObDjOs" target="_blank"><image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-mosquito/make-a-3d-model-from-scratch-using-dust3d-video-thumbnail.png" width="480" height="270"></a> <a href="https://youtu.be/wQerDObDjOs" target="_blank"><image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-mosquito/make-a-3d-model-from-scratch-using-dust3d-video-thumbnail.png" width="480" height="270"></a>
[Modeling Ant using Dust3D](https://dust3d.readthedocs.io/en/latest/examples/modeling-ant/index.html) [Modeling Ant using Dust3D](http://docs.dust3d.org/en/latest/examples/modeling-ant/index.html)
<a href="https://dust3d.readthedocs.io/en/latest/examples/modeling-ant/index.html"> <a href="http://docs.dust3d.org/en/latest/examples/modeling-ant/index.html">
<image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-ant/modeling-ant-dust3d-screenshot.png" width="320" height="192"></a> <image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-ant/modeling-ant-dust3d-screenshot.png" width="320" height="192"></a>
[Modeling Camel using Dust3D](https://dust3d.readthedocs.io/en/latest/examples/modeling-camel/index.html) [Modeling Camel using Dust3D](http://docs.dust3d.org/en/latest/examples/modeling-camel/index.html)
<a href="https://dust3d.readthedocs.io/en/latest/examples/modeling-camel/index.html"> <a href="http://docs.dust3d.org/en/latest/examples/modeling-camel/index.html">
<image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-camel/modeling-camel-dust3d-screenshot.png" width="320" height="192"></a> <image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-camel/modeling-camel-dust3d-screenshot.png" width="320" height="192"></a>
[Modeling Horse using Dust3D](https://dust3d.readthedocs.io/en/latest/examples/modeling-horse/index.html) [Modeling Horse using Dust3D](http://docs.dust3d.org/en/latest/examples/modeling-horse/index.html)
<a href="https://dust3d.readthedocs.io/en/latest/examples/modeling-horse/index.html"> <a href="http://docs.dust3d.org/en/latest/examples/modeling-horse/index.html">
<image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-horse/modeling-horse-dust3d-screenshot.png" width="320" height="192"></a> <image src="https://raw.githubusercontent.com/huxingyi/dust3d/master/docs/examples/modeling-horse/modeling-horse-dust3d-screenshot.png" width="320" height="192"></a>
Free Dust3D Models Free Dust3D Models

View File

@ -85,6 +85,14 @@ V Flip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Flip selected nodes vertically. Flip selected nodes vertically.
Rotate 90 (Clockwise)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rotate selected nodes 90 degree. If you can hardly edit some nodes in normal front/side view, rotate it then edit it, and rotate it back after you finish editing.
Rotate 90 (Counterclockwise)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rotate selected nodes -90 degree.
Align To Align To
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Align selected nodes with center anchor globally or selected nodes' center locally. Normally, the center anchor(a Triangle) is not show up, you can turn on the Part Mirror to make it visible, then turn Part Mirror off, the center anchor would not gone once showed. Align selected nodes with center anchor globally or selected nodes' center locally. Normally, the center anchor(a Triangle) is not show up, you can turn on the Part Mirror to make it visible, then turn Part Mirror off, the center anchor would not gone once showed.

View File

@ -11,7 +11,7 @@ isEmpty(VERSION) {
REPOSITORY_URL = "https://github.com/huxingyi/dust3d" REPOSITORY_URL = "https://github.com/huxingyi/dust3d"
ISSUES_URL = "https://github.com/huxingyi/dust3d/issues" ISSUES_URL = "https://github.com/huxingyi/dust3d/issues"
REFERENCE_GUIDE_URL = "https://dust3d.readthedocs.io" REFERENCE_GUIDE_URL = "http://docs.dust3d.org"
QMAKE_TARGET_COMPANY = Dust3D QMAKE_TARGET_COMPANY = Dust3D
QMAKE_TARGET_PRODUCT = Dust3D QMAKE_TARGET_PRODUCT = Dust3D

View File

@ -304,6 +304,18 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
connect(m_flipVerticallyAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::flipVertically); connect(m_flipVerticallyAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::flipVertically);
m_editMenu->addAction(m_flipVerticallyAction); m_editMenu->addAction(m_flipVerticallyAction);
m_rotateClockwiseAction = new QAction(tr("Rotate 90 (Clockwise)"), this);
connect(m_rotateClockwiseAction, &QAction::triggered, [=] {
m_graphicsWidget->rotateClockwise90Degree();
});
m_editMenu->addAction(m_rotateClockwiseAction);
m_rotateCounterclockwiseAction = new QAction(tr("Rotate 90 (Counterclockwise)"), this);
connect(m_rotateCounterclockwiseAction, &QAction::triggered, [=] {
m_graphicsWidget->rotateCounterclockwise90Degree();
});
m_editMenu->addAction(m_rotateCounterclockwiseAction);
m_alignToMenu = new QMenu(tr("Align To")); m_alignToMenu = new QMenu(tr("Align To"));
m_alignToGlobalCenterAction = new QAction(tr("Global Center"), this); m_alignToGlobalCenterAction = new QAction(tr("Global Center"), this);
@ -376,6 +388,8 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
m_pasteAction->setEnabled(m_document->hasPastableContentInClipboard()); m_pasteAction->setEnabled(m_document->hasPastableContentInClipboard());
m_flipHorizontallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection()); m_flipHorizontallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_flipVerticallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection()); m_flipVerticallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_rotateClockwiseAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_rotateCounterclockwiseAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_alignToGlobalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled()); m_alignToGlobalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
m_alignToGlobalVerticalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled()); m_alignToGlobalVerticalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
m_alignToGlobalHorizontalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled()); m_alignToGlobalHorizontalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());

View File

@ -94,6 +94,8 @@ private:
QAction *m_pasteAction; QAction *m_pasteAction;
QAction *m_flipHorizontallyAction; QAction *m_flipHorizontallyAction;
QAction *m_flipVerticallyAction; QAction *m_flipVerticallyAction;
QAction *m_rotateClockwiseAction;
QAction *m_rotateCounterclockwiseAction;
QMenu *m_alignToMenu; QMenu *m_alignToMenu;
QAction *m_alignToGlobalCenterAction; QAction *m_alignToGlobalCenterAction;

View File

@ -174,6 +174,18 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
contextMenu.addAction(&flipVerticallyAction); contextMenu.addAction(&flipVerticallyAction);
} }
QAction rotateClockwiseAction(tr("Rotate 90 (Clockwise)"), this);
if (hasMultipleSelection()) {
connect(&rotateClockwiseAction, &QAction::triggered, this, &SkeletonGraphicsWidget::rotateClockwise90Degree);
contextMenu.addAction(&rotateClockwiseAction);
}
QAction rotateCounterclockwiseAction(tr("Rotate 90 (Counterclockwise)"), this);
if (hasMultipleSelection()) {
connect(&rotateCounterclockwiseAction, &QAction::triggered, this, &SkeletonGraphicsWidget::rotateCounterclockwise90Degree);
contextMenu.addAction(&rotateCounterclockwiseAction);
}
QAction alignToLocalCenterAction(tr("Local Center"), this); QAction alignToLocalCenterAction(tr("Local Center"), this);
QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this); QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this);
QAction alignToLocalHorizontalCenterAction(tr("Local Horizontal Center"), this); QAction alignToLocalHorizontalCenterAction(tr("Local Horizontal Center"), this);
@ -921,6 +933,7 @@ void SkeletonGraphicsWidget::flipHorizontally()
if (nodeItems.empty()) if (nodeItems.empty())
return; return;
QVector2D center = centerOfNodeItemSet(nodeItems); QVector2D center = centerOfNodeItemSet(nodeItems);
emit batchChangeBegin();
for (const auto &nodeItem: nodeItems) { for (const auto &nodeItem: nodeItems) {
QPointF origin = nodeItem->origin(); QPointF origin = nodeItem->origin();
float offset = origin.x() - center.x(); float offset = origin.x() - center.x();
@ -931,6 +944,8 @@ void SkeletonGraphicsWidget::flipHorizontally()
emit moveNodeBy(nodeItem->id(), 0, 0, unifiedOffset); emit moveNodeBy(nodeItem->id(), 0, 0, unifiedOffset);
} }
} }
emit batchChangeEnd();
emit groupOperationAdded();
} }
void SkeletonGraphicsWidget::flipVertically() void SkeletonGraphicsWidget::flipVertically()
@ -940,12 +955,31 @@ void SkeletonGraphicsWidget::flipVertically()
if (nodeItems.empty()) if (nodeItems.empty())
return; return;
QVector2D center = centerOfNodeItemSet(nodeItems); QVector2D center = centerOfNodeItemSet(nodeItems);
emit batchChangeBegin();
for (const auto &nodeItem: nodeItems) { for (const auto &nodeItem: nodeItems) {
QPointF origin = nodeItem->origin(); QPointF origin = nodeItem->origin();
float offset = origin.y() - center.y(); float offset = origin.y() - center.y();
float unifiedOffset = -sceneRadiusToUnified(offset * 2); float unifiedOffset = -sceneRadiusToUnified(offset * 2);
emit moveNodeBy(nodeItem->id(), 0, unifiedOffset, 0); emit moveNodeBy(nodeItem->id(), 0, unifiedOffset, 0);
} }
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::rotateClockwise90Degree()
{
emit batchChangeBegin();
emit rotateSelected(90);
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::rotateCounterclockwise90Degree()
{
emit batchChangeBegin();
emit rotateSelected(360 - 90);
emit batchChangeEnd();
emit groupOperationAdded();
} }
bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event) bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event)

View File

@ -436,6 +436,8 @@ public slots:
void copy(); void copy();
void flipHorizontally(); void flipHorizontally();
void flipVertically(); void flipVertically();
void rotateClockwise90Degree();
void rotateCounterclockwise90Degree();
void removeAllContent(); void removeAllContent();
void breakSelected(); void breakSelected();
void connectSelected(); void connectSelected();