Add more align options.
- Add local align. - Fix crash in multiple nodes collapse case.master
parent
1391a3b8c0
commit
f2625a7ca2
|
@ -85,9 +85,9 @@ V Flip
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Flip selected nodes vertically.
|
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
|
Mark As
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -41,9 +41,16 @@ typename CGAL::Surface_mesh<typename Kernel::Point_3> *makeCgalMeshFromMeshlite(
|
||||||
assert(vertexArrayLen == vertexCount * 3);
|
assert(vertexArrayLen == vertexCount * 3);
|
||||||
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> vertices;
|
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> vertices;
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
vertices.push_back(mesh->add_vertex(typename Kernel::Point_3(vertexPositions[offset + 0],
|
float x = vertexPositions[offset + 0];
|
||||||
vertexPositions[offset + 1],
|
float y = vertexPositions[offset + 1];
|
||||||
vertexPositions[offset + 2])));
|
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;
|
offset += 3;
|
||||||
}
|
}
|
||||||
int faceCount = meshlite_get_face_count(meshlite, meshId);
|
int faceCount = meshlite_get_face_count(meshlite, meshId);
|
||||||
|
@ -53,13 +60,15 @@ typename CGAL::Surface_mesh<typename Kernel::Point_3> *makeCgalMeshFromMeshlite(
|
||||||
while (i < filledLength) {
|
while (i < filledLength) {
|
||||||
int num = faceVertexNumAndIndices[i++];
|
int num = faceVertexNumAndIndices[i++];
|
||||||
assert(num > 0 && num <= MAX_VERTICES_PER_FACE);
|
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++) {
|
for (int j = 0; j < num; j++) {
|
||||||
int index = faceVertexNumAndIndices[i++];
|
int index = faceVertexNumAndIndices[i++];
|
||||||
assert(index >= 0 && index < vertexCount);
|
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[] faceVertexNumAndIndices;
|
||||||
delete[] vertexPositions;
|
delete[] vertexPositions;
|
||||||
|
|
|
@ -303,9 +303,33 @@ 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_alignToCenterAction = new QAction(tr("Align to Center"), this);
|
m_alignToMenu = new QMenu(tr("Align To"));
|
||||||
connect(m_alignToCenterAction, &QAction::triggered, m_graphicsWidget, &SkeletonGraphicsWidget::alignSelectedToCenter);
|
|
||||||
m_editMenu->addAction(m_alignToCenterAction);
|
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"));
|
m_markAsMenu = new QMenu(tr("Mark As"));
|
||||||
|
|
||||||
|
@ -351,7 +375,13 @@ 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_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_markAsMenu->setEnabled(m_graphicsWidget->hasNodeSelection());
|
||||||
m_selectAllAction->setEnabled(m_graphicsWidget->hasItems());
|
m_selectAllAction->setEnabled(m_graphicsWidget->hasItems());
|
||||||
m_selectPartAllAction->setEnabled(m_graphicsWidget->hasItems());
|
m_selectPartAllAction->setEnabled(m_graphicsWidget->hasItems());
|
||||||
|
|
|
@ -91,7 +91,15 @@ private:
|
||||||
QAction *m_pasteAction;
|
QAction *m_pasteAction;
|
||||||
QAction *m_flipHorizontallyAction;
|
QAction *m_flipHorizontallyAction;
|
||||||
QAction *m_flipVerticallyAction;
|
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_selectAllAction;
|
||||||
QAction *m_selectPartAllAction;
|
QAction *m_selectPartAllAction;
|
||||||
QAction *m_unselectAllAction;
|
QAction *m_unselectAllAction;
|
||||||
|
|
|
@ -176,9 +176,40 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
|
||||||
|
|
||||||
QAction alignToCenterAction(tr("Align to Center"), this);
|
QAction alignToCenterAction(tr("Align to Center"), this);
|
||||||
if (hasSelection() && m_document->originSettled()) {
|
if (hasSelection() && m_document->originSettled()) {
|
||||||
connect(&alignToCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToCenter);
|
connect(&alignToCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalVerticalCenter);
|
||||||
contextMenu.addAction(&alignToCenterAction);
|
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 markAsNoneAction(tr("None"), this);
|
||||||
QAction *markAsActions[SKELETON_BONE_MARK_TYPE_NUM];
|
QAction *markAsActions[SKELETON_BONE_MARK_TYPE_NUM];
|
||||||
|
@ -311,7 +342,34 @@ void SkeletonGraphicsWidget::connectSelected()
|
||||||
emit groupOperationAdded();
|
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())
|
if (!m_document->originSettled())
|
||||||
return;
|
return;
|
||||||
|
@ -329,15 +387,57 @@ void SkeletonGraphicsWidget::alignSelectedToCenter()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (SkeletonProfile::Main == nodeItem->profile()) {
|
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);
|
emit moveNodeBy(node->id, m_document->originX - node->x, 0, 0);
|
||||||
|
}
|
||||||
} else {
|
} 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 moveNodeBy(node->id, 0, 0, m_document->originZ - node->z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
emit batchChangeEnd();
|
emit batchChangeEnd();
|
||||||
emit groupOperationAdded();
|
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()
|
void SkeletonGraphicsWidget::updateItems()
|
||||||
{
|
{
|
||||||
for (auto nodeItemIt = nodeItemMap.begin(); nodeItemIt != nodeItemMap.end(); nodeItemIt++) {
|
for (auto nodeItemIt = nodeItemMap.begin(); nodeItemIt != nodeItemMap.end(); nodeItemIt++) {
|
||||||
|
|
|
@ -445,7 +445,12 @@ public slots:
|
||||||
void moveSelected(float byX, float byY);
|
void moveSelected(float byX, float byY);
|
||||||
void moveCheckedOrigin(float byX, float byY);
|
void moveCheckedOrigin(float byX, float byY);
|
||||||
void originChanged();
|
void originChanged();
|
||||||
void alignSelectedToCenter();
|
void alignSelectedToGlobalCenter();
|
||||||
|
void alignSelectedToGlobalVerticalCenter();
|
||||||
|
void alignSelectedToGlobalHorizontalCenter();
|
||||||
|
void alignSelectedToLocalCenter();
|
||||||
|
void alignSelectedToLocalVerticalCenter();
|
||||||
|
void alignSelectedToLocalHorizontalCenter();
|
||||||
void selectPartAllById(QUuid partId);
|
void selectPartAllById(QUuid partId);
|
||||||
void addSelectNode(QUuid nodeId);
|
void addSelectNode(QUuid nodeId);
|
||||||
void addSelectEdge(QUuid edgeId);
|
void addSelectEdge(QUuid edgeId);
|
||||||
|
@ -474,6 +479,8 @@ private:
|
||||||
void hoverPart(QUuid partId);
|
void hoverPart(QUuid partId);
|
||||||
void switchProfileOnRangeSelection();
|
void switchProfileOnRangeSelection();
|
||||||
void setItemHoveredOnAllProfiles(QGraphicsItem *item, bool hovered);
|
void setItemHoveredOnAllProfiles(QGraphicsItem *item, bool hovered);
|
||||||
|
void alignSelectedToGlobal(bool alignToVerticalCenter, bool alignToHorizontalCenter);
|
||||||
|
void alignSelectedToLocal(bool alignToVerticalCenter, bool alignToHorizontalCenter);
|
||||||
private: //need initalize
|
private: //need initalize
|
||||||
const SkeletonDocument *m_document;
|
const SkeletonDocument *m_document;
|
||||||
QGraphicsPixmapItem *m_backgroundItem;
|
QGraphicsPixmapItem *m_backgroundItem;
|
||||||
|
|
Loading…
Reference in New Issue