Add more align options.

- Add local align.
- Fix crash in multiple nodes collapse case.
master
Jeremy Hu 2018-06-02 17:34:48 +08:00
parent 1391a3b8c0
commit f2625a7ca2
6 changed files with 172 additions and 18 deletions

View File

@ -85,9 +85,9 @@ V Flip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Flip selected nodes vertically.
Align to Center
Align To
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Align selected nodes vertically with center anchor. 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.
Mark As
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -41,9 +41,16 @@ typename CGAL::Surface_mesh<typename Kernel::Point_3> *makeCgalMeshFromMeshlite(
assert(vertexArrayLen == vertexCount * 3);
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> vertices;
for (int i = 0; i < vertexCount; i++) {
vertices.push_back(mesh->add_vertex(typename Kernel::Point_3(vertexPositions[offset + 0],
vertexPositions[offset + 1],
vertexPositions[offset + 2])));
float x = vertexPositions[offset + 0];
float y = vertexPositions[offset + 1];
float z = vertexPositions[offset + 2];
if (std::isnan(x) || std::isinf(x))
x = 0;
if (std::isnan(y) || std::isinf(y))
y = 0;
if (std::isnan(z) || std::isinf(z))
z = 0;
vertices.push_back(mesh->add_vertex(typename Kernel::Point_3(x, y, z)));
offset += 3;
}
int faceCount = meshlite_get_face_count(meshlite, meshId);
@ -53,13 +60,15 @@ typename CGAL::Surface_mesh<typename Kernel::Point_3> *makeCgalMeshFromMeshlite(
while (i < filledLength) {
int num = faceVertexNumAndIndices[i++];
assert(num > 0 && num <= MAX_VERTICES_PER_FACE);
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> faceIndices;
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> faceVertexIndices;
for (int j = 0; j < num; j++) {
int index = faceVertexNumAndIndices[i++];
assert(index >= 0 && index < vertexCount);
faceIndices.push_back(vertices[index]);
faceVertexIndices.push_back(vertices[index]);
}
if (faceVertexIndices.size() >= 3) {
mesh->add_face(faceVertexIndices);
}
mesh->add_face(faceIndices);
}
delete[] faceVertexNumAndIndices;
delete[] vertexPositions;

View File

@ -303,9 +303,33 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
connect(m_flipVerticallyAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::flipVertically);
m_editMenu->addAction(m_flipVerticallyAction);
m_alignToCenterAction = new QAction(tr("Align to Center"), this);
connect(m_alignToCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToCenter);
m_editMenu->addAction(m_alignToCenterAction);
m_alignToMenu = new QMenu(tr("Align To"));
m_alignToGlobalCenterAction = new QAction(tr("Global Center"), this);
connect(m_alignToGlobalCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToGlobalCenter);
m_alignToMenu->addAction(m_alignToGlobalCenterAction);
m_alignToGlobalVerticalCenterAction = new QAction(tr("Global Vertical Center"), this);
connect(m_alignToGlobalVerticalCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToGlobalVerticalCenter);
m_alignToMenu->addAction(m_alignToGlobalVerticalCenterAction);
m_alignToGlobalHorizontalCenterAction = new QAction(tr("Global Horizontal Center"), this);
connect(m_alignToGlobalHorizontalCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToGlobalHorizontalCenter);
m_alignToMenu->addAction(m_alignToGlobalHorizontalCenterAction);
m_alignToLocalCenterAction = new QAction(tr("Local Center"), this);
connect(m_alignToLocalCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToLocalCenter);
m_alignToMenu->addAction(m_alignToLocalCenterAction);
m_alignToLocalVerticalCenterAction = new QAction(tr("Local Vertical Center"), this);
connect(m_alignToLocalVerticalCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToLocalVerticalCenter);
m_alignToMenu->addAction(m_alignToLocalVerticalCenterAction);
m_alignToLocalHorizontalCenterAction = new QAction(tr("Local Horizontal Center"), this);
connect(m_alignToLocalHorizontalCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToLocalHorizontalCenter);
m_alignToMenu->addAction(m_alignToLocalHorizontalCenterAction);
m_editMenu->addMenu(m_alignToMenu);
m_markAsMenu = new QMenu(tr("Mark As"));
@ -351,7 +375,13 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
m_pasteAction->setEnabled(m_document->hasPastableContentInClipboard());
m_flipHorizontallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_flipVerticallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_alignToCenterAction->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_alignToGlobalHorizontalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
m_alignToLocalCenterAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_alignToLocalVerticalCenterAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_alignToLocalHorizontalCenterAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_alignToMenu->setEnabled((m_graphicsWidget->hasSelection() && m_document->originSettled()) || m_graphicsWidget->hasMultipleSelection());
m_markAsMenu->setEnabled(m_graphicsWidget->hasNodeSelection());
m_selectAllAction->setEnabled(m_graphicsWidget->hasItems());
m_selectPartAllAction->setEnabled(m_graphicsWidget->hasItems());

View File

@ -91,7 +91,15 @@ private:
QAction *m_pasteAction;
QAction *m_flipHorizontallyAction;
QAction *m_flipVerticallyAction;
QAction *m_alignToCenterAction;
QMenu *m_alignToMenu;
QAction *m_alignToGlobalCenterAction;
QAction *m_alignToGlobalVerticalCenterAction;
QAction *m_alignToGlobalHorizontalCenterAction;
QAction *m_alignToLocalCenterAction;
QAction *m_alignToLocalVerticalCenterAction;
QAction *m_alignToLocalHorizontalCenterAction;
QAction *m_selectAllAction;
QAction *m_selectPartAllAction;
QAction *m_unselectAllAction;

View File

@ -176,9 +176,40 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
QAction alignToCenterAction(tr("Align to Center"), this);
if (hasSelection() && m_document->originSettled()) {
connect(&alignToCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToCenter);
connect(&alignToCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalVerticalCenter);
contextMenu.addAction(&alignToCenterAction);
}
QAction alignToLocalCenterAction(tr("Local Center"), this);
QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this);
QAction alignToLocalHorizontalCenterAction(tr("Local Horizontal Center"), this);
QAction alignToGlobalCenterAction(tr("Global Center"), this);
QAction alignToGlobalVerticalCenterAction(tr("Global Vertical Center"), this);
QAction alignToGlobalHorizontalCenterAction(tr("Global Horizontal Center"), this);
if ((hasSelection() && m_document->originSettled()) || hasMultipleSelection()) {
QMenu *subMenu = contextMenu.addMenu(tr("Align To"));
if (hasMultipleSelection()) {
connect(&alignToLocalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToLocalCenter);
subMenu->addAction(&alignToLocalCenterAction);
connect(&alignToLocalVerticalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToLocalVerticalCenter);
subMenu->addAction(&alignToLocalVerticalCenterAction);
connect(&alignToLocalHorizontalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToLocalHorizontalCenter);
subMenu->addAction(&alignToLocalHorizontalCenterAction);
}
if (hasSelection() && m_document->originSettled()) {
connect(&alignToGlobalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalCenter);
subMenu->addAction(&alignToGlobalCenterAction);
connect(&alignToGlobalVerticalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalVerticalCenter);
subMenu->addAction(&alignToGlobalVerticalCenterAction);
connect(&alignToGlobalHorizontalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalHorizontalCenter);
subMenu->addAction(&alignToGlobalHorizontalCenterAction);
}
}
QAction markAsNoneAction(tr("None"), this);
QAction *markAsActions[SKELETON_BONE_MARK_TYPE_NUM];
@ -311,7 +342,34 @@ void SkeletonGraphicsWidget::connectSelected()
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::alignSelectedToCenter()
void SkeletonGraphicsWidget::alignSelectedToLocal(bool alignToVerticalCenter, bool alignToHorizontalCenter)
{
if (!hasMultipleSelection())
return;
std::set<SkeletonGraphicsNodeItem *> nodeItems;
readMergedSkeletonNodeSetFromRangeSelection(&nodeItems);
if (nodeItems.empty())
return;
if (nodeItems.size() < 2)
return;
emit batchChangeBegin();
QVector2D center = centerOfNodeItemSet(nodeItems);
for (const auto &it: nodeItems) {
SkeletonGraphicsNodeItem *nodeItem = it;
QPointF nodeOrigin = nodeItem->origin();
float byX = alignToHorizontalCenter ? sceneRadiusToUnified(center.x() - nodeOrigin.x()) : 0;
float byY = alignToVerticalCenter ? sceneRadiusToUnified(center.y() - nodeOrigin.y()) : 0;
if (SkeletonProfile::Main == nodeItem->profile()) {
emit moveNodeBy(nodeItem->id(), byX, byY, 0);
} else {
emit moveNodeBy(nodeItem->id(), 0, byY, byX);
}
}
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::alignSelectedToGlobal(bool alignToVerticalCenter, bool alignToHorizontalCenter)
{
if (!m_document->originSettled())
return;
@ -329,15 +387,57 @@ void SkeletonGraphicsWidget::alignSelectedToCenter()
continue;
}
if (SkeletonProfile::Main == nodeItem->profile()) {
if (alignToVerticalCenter && alignToHorizontalCenter) {
emit moveNodeBy(node->id, m_document->originX - node->x, m_document->originY - node->y, 0);
} else if (alignToVerticalCenter) {
emit moveNodeBy(node->id, 0, m_document->originY - node->y, 0);
} else if (alignToHorizontalCenter) {
emit moveNodeBy(node->id, m_document->originX - node->x, 0, 0);
}
} else {
if (alignToVerticalCenter && alignToHorizontalCenter) {
emit moveNodeBy(node->id, 0, m_document->originY - node->y, m_document->originZ - node->z);
} else if (alignToVerticalCenter) {
emit moveNodeBy(node->id, 0, m_document->originY - node->y, 0);
} else if (alignToHorizontalCenter) {
emit moveNodeBy(node->id, 0, 0, m_document->originZ - node->z);
}
}
}
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::alignSelectedToGlobalVerticalCenter()
{
alignSelectedToGlobal(true, false);
}
void SkeletonGraphicsWidget::alignSelectedToGlobalHorizontalCenter()
{
alignSelectedToGlobal(false, true);
}
void SkeletonGraphicsWidget::alignSelectedToGlobalCenter()
{
alignSelectedToGlobal(true, true);
}
void SkeletonGraphicsWidget::alignSelectedToLocalVerticalCenter()
{
alignSelectedToLocal(true, false);
}
void SkeletonGraphicsWidget::alignSelectedToLocalHorizontalCenter()
{
alignSelectedToLocal(false, true);
}
void SkeletonGraphicsWidget::alignSelectedToLocalCenter()
{
alignSelectedToLocal(true, true);
}
void SkeletonGraphicsWidget::updateItems()
{
for (auto nodeItemIt = nodeItemMap.begin(); nodeItemIt != nodeItemMap.end(); nodeItemIt++) {

View File

@ -445,7 +445,12 @@ public slots:
void moveSelected(float byX, float byY);
void moveCheckedOrigin(float byX, float byY);
void originChanged();
void alignSelectedToCenter();
void alignSelectedToGlobalCenter();
void alignSelectedToGlobalVerticalCenter();
void alignSelectedToGlobalHorizontalCenter();
void alignSelectedToLocalCenter();
void alignSelectedToLocalVerticalCenter();
void alignSelectedToLocalHorizontalCenter();
void selectPartAllById(QUuid partId);
void addSelectNode(QUuid nodeId);
void addSelectEdge(QUuid edgeId);
@ -474,6 +479,8 @@ private:
void hoverPart(QUuid partId);
void switchProfileOnRangeSelection();
void setItemHoveredOnAllProfiles(QGraphicsItem *item, bool hovered);
void alignSelectedToGlobal(bool alignToVerticalCenter, bool alignToHorizontalCenter);
void alignSelectedToLocal(bool alignToVerticalCenter, bool alignToHorizontalCenter);
private: //need initalize
const SkeletonDocument *m_document;
QGraphicsPixmapItem *m_backgroundItem;