Remove grided mesh builder
This feature was been designed to make cloth mesh, however, it's not work as planned and is been replaced by the cloth simulation.master
parent
9ca0102b52
commit
6c01c0d07b
|
@ -342,10 +342,6 @@ Tips:
|
|||
<source>Auto Color</source>
|
||||
<translation>自动着色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create Wrap Parts</source>
|
||||
<translation>创建包裹部件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Marker pen</source>
|
||||
<translation>马克笔</translation>
|
||||
|
@ -1279,10 +1275,6 @@ Tips:
|
|||
<source>Colorize</source>
|
||||
<translation>着色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create Wrap Parts</source>
|
||||
<translation>创建包裹部件</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>UpdatesCheckWidget</name>
|
||||
|
|
|
@ -660,6 +660,8 @@ void Document::addEdge(QUuid fromNodeId, QUuid toNodeId)
|
|||
|
||||
void Document::checkPartGrid(QUuid partId)
|
||||
{
|
||||
return;
|
||||
/*
|
||||
SkeletonPart *part = (SkeletonPart *)findPart(partId);
|
||||
if (nullptr == part)
|
||||
return;
|
||||
|
@ -678,6 +680,7 @@ void Document::checkPartGrid(QUuid partId)
|
|||
part->gridded = isGrid;
|
||||
part->dirty = true;
|
||||
emit partGridStateChanged(partId);
|
||||
*/
|
||||
}
|
||||
|
||||
void Document::updateLinkedPart(QUuid oldPartId, QUuid newPartId)
|
||||
|
@ -1144,8 +1147,8 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeId
|
|||
part["materialId"] = partIt.second.materialId.toString();
|
||||
if (partIt.second.countershaded)
|
||||
part["countershaded"] = "true";
|
||||
if (partIt.second.gridded)
|
||||
part["gridded"] = "true";
|
||||
//if (partIt.second.gridded)
|
||||
// part["gridded"] = "true";
|
||||
snapshot->parts[part["id"]] = part;
|
||||
}
|
||||
for (const auto &nodeIt: nodeMap) {
|
||||
|
@ -1620,7 +1623,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
|
|||
if (materialIdIt != partKv.second.end())
|
||||
part.materialId = oldNewIdMap[QUuid(materialIdIt->second)];
|
||||
part.countershaded = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "countershaded"));
|
||||
part.gridded = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "gridded"));;
|
||||
//part.gridded = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "gridded"));;
|
||||
newAddedPartIds.insert(part.id);
|
||||
}
|
||||
for (const auto &it: cutFaceLinkedIdModifyMap) {
|
||||
|
|
|
@ -599,11 +599,11 @@ DocumentWindow::DocumentWindow() :
|
|||
});
|
||||
m_editMenu->addAction(m_clearCutFaceAction);
|
||||
|
||||
m_createWrapPartsAction = new QAction(tr("Create Wrap Parts"), this);
|
||||
connect(m_createWrapPartsAction, &QAction::triggered, [=] {
|
||||
m_graphicsWidget->createWrapParts();
|
||||
});
|
||||
m_editMenu->addAction(m_createWrapPartsAction);
|
||||
//m_createWrapPartsAction = new QAction(tr("Create Wrap Parts"), this);
|
||||
//connect(m_createWrapPartsAction, &QAction::triggered, [=] {
|
||||
// m_graphicsWidget->createWrapParts();
|
||||
//});
|
||||
//m_editMenu->addAction(m_createWrapPartsAction);
|
||||
|
||||
m_alignToMenu = new QMenu(tr("Align To"));
|
||||
|
||||
|
@ -698,7 +698,7 @@ DocumentWindow::DocumentWindow() :
|
|||
m_switchXzAction->setEnabled(m_graphicsWidget->hasSelection());
|
||||
m_setCutFaceAction->setEnabled(m_graphicsWidget->hasSelection());
|
||||
m_clearCutFaceAction->setEnabled(m_graphicsWidget->hasCutFaceAdjustedNodesSelection());
|
||||
m_createWrapPartsAction->setEnabled(m_graphicsWidget->hasSelection());
|
||||
//m_createWrapPartsAction->setEnabled(m_graphicsWidget->hasSelection());
|
||||
m_colorizeAsBlankAction->setEnabled(m_graphicsWidget->hasSelection());
|
||||
m_colorizeAsAutoAction->setEnabled(m_graphicsWidget->hasSelection());
|
||||
m_alignToGlobalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "theme.h"
|
||||
#include "partbase.h"
|
||||
#include "imageforever.h"
|
||||
#include "gridmeshbuilder.h"
|
||||
#include "triangulatefaces.h"
|
||||
#include "remesher.h"
|
||||
#include "polycount.h"
|
||||
|
@ -350,7 +349,7 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
|
|||
float hollowThickness = 0.0;
|
||||
auto target = PartTargetFromString(valueOfKeyInMapOrEmpty(part, "target").toUtf8().constData());
|
||||
auto base = PartBaseFromString(valueOfKeyInMapOrEmpty(part, "base").toUtf8().constData());
|
||||
bool gridded = isTrueValueString(valueOfKeyInMapOrEmpty(part, "gridded"));
|
||||
//bool gridded = isTrueValueString(valueOfKeyInMapOrEmpty(part, "gridded"));
|
||||
|
||||
QString cutFaceString = valueOfKeyInMapOrEmpty(part, "cutFace");
|
||||
std::vector<QVector2D> cutTemplate;
|
||||
|
@ -500,7 +499,6 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
|
|||
std::map<int, QString> nodeIndexToIdStringMap;
|
||||
StrokeModifier *nodeMeshModifier = nullptr;
|
||||
StrokeMeshBuilder *nodeMeshBuilder = nullptr;
|
||||
GridMeshBuilder *gridMeshBuilder = nullptr;
|
||||
|
||||
QString mirroredPartIdString;
|
||||
QUuid mirroredPartId;
|
||||
|
@ -544,166 +542,115 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
|
|||
}
|
||||
};
|
||||
|
||||
if (gridded) {
|
||||
gridMeshBuilder = new GridMeshBuilder;
|
||||
nodeMeshModifier = new StrokeModifier;
|
||||
|
||||
for (const auto &nodeIt: nodeInfos) {
|
||||
const auto &nodeIdString = nodeIt.first;
|
||||
const auto &nodeInfo = nodeIt.second;
|
||||
size_t nodeIndex = 0;
|
||||
if (addIntermediateNodes)
|
||||
nodeMeshModifier->enableIntermediateAddition();
|
||||
|
||||
nodeIndex = gridMeshBuilder->addNode(nodeInfo.position, nodeInfo.radius);
|
||||
for (const auto &nodeIt: nodeInfos) {
|
||||
const auto &nodeIdString = nodeIt.first;
|
||||
const auto &nodeInfo = nodeIt.second;
|
||||
size_t nodeIndex = 0;
|
||||
if (nodeInfo.hasCutFaceSettings) {
|
||||
std::vector<QVector2D> nodeCutTemplate;
|
||||
cutFaceStringToCutTemplate(nodeInfo.cutFace, nodeCutTemplate);
|
||||
if (chamfered)
|
||||
chamferFace2D(&nodeCutTemplate);
|
||||
nodeIndex = nodeMeshModifier->addNode(nodeInfo.position, nodeInfo.radius, nodeCutTemplate, nodeInfo.cutRotation);
|
||||
} else {
|
||||
nodeIndex = nodeMeshModifier->addNode(nodeInfo.position, nodeInfo.radius, cutTemplate, cutRotation);
|
||||
}
|
||||
nodeIdStringToIndexMap[nodeIdString] = nodeIndex;
|
||||
nodeIndexToIdStringMap[nodeIndex] = nodeIdString;
|
||||
|
||||
nodeIdStringToIndexMap[nodeIdString] = nodeIndex;
|
||||
nodeIndexToIdStringMap[nodeIndex] = nodeIdString;
|
||||
addNode(nodeIdString, nodeInfo);
|
||||
}
|
||||
|
||||
addNode(nodeIdString, nodeInfo);
|
||||
for (const auto &edgeIt: edges) {
|
||||
const QString &fromNodeIdString = edgeIt.first;
|
||||
const QString &toNodeIdString = edgeIt.second;
|
||||
|
||||
auto findFromNodeIndex = nodeIdStringToIndexMap.find(fromNodeIdString);
|
||||
if (findFromNodeIndex == nodeIdStringToIndexMap.end()) {
|
||||
qDebug() << "Find from-node failed:" << fromNodeIdString;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &edgeIt: edges) {
|
||||
const QString &fromNodeIdString = edgeIt.first;
|
||||
const QString &toNodeIdString = edgeIt.second;
|
||||
|
||||
auto findFromNodeIndex = nodeIdStringToIndexMap.find(fromNodeIdString);
|
||||
if (findFromNodeIndex == nodeIdStringToIndexMap.end()) {
|
||||
qDebug() << "Find from-node failed:" << fromNodeIdString;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto findToNodeIndex = nodeIdStringToIndexMap.find(toNodeIdString);
|
||||
if (findToNodeIndex == nodeIdStringToIndexMap.end()) {
|
||||
qDebug() << "Find to-node failed:" << toNodeIdString;
|
||||
continue;
|
||||
}
|
||||
|
||||
gridMeshBuilder->addEdge(findFromNodeIndex->second, findToNodeIndex->second);
|
||||
addEdge(fromNodeIdString, toNodeIdString);
|
||||
auto findToNodeIndex = nodeIdStringToIndexMap.find(toNodeIdString);
|
||||
if (findToNodeIndex == nodeIdStringToIndexMap.end()) {
|
||||
qDebug() << "Find to-node failed:" << toNodeIdString;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subdived)
|
||||
gridMeshBuilder->setSubdived(true);
|
||||
buildSucceed = gridMeshBuilder->build();
|
||||
nodeMeshModifier->addEdge(findFromNodeIndex->second, findToNodeIndex->second);
|
||||
addEdge(fromNodeIdString, toNodeIdString);
|
||||
}
|
||||
|
||||
partCache.vertices = gridMeshBuilder->getGeneratedPositions();
|
||||
partCache.faces = gridMeshBuilder->getGeneratedFaces();
|
||||
if (subdived)
|
||||
nodeMeshModifier->subdivide();
|
||||
|
||||
for (size_t i = 0; i < partCache.vertices.size(); ++i) {
|
||||
const auto &position = partCache.vertices[i];
|
||||
const auto &nodeIndex = gridMeshBuilder->getGeneratedSources()[i];
|
||||
const auto &nodeIdString = nodeIndexToIdStringMap[nodeIndex];
|
||||
partCache.outcomeNodeVertices.push_back({position, {partIdString, nodeIdString}});
|
||||
}
|
||||
} else {
|
||||
nodeMeshModifier = new StrokeModifier;
|
||||
if (rounded)
|
||||
nodeMeshModifier->roundEnd();
|
||||
|
||||
if (addIntermediateNodes)
|
||||
nodeMeshModifier->enableIntermediateAddition();
|
||||
nodeMeshModifier->finalize();
|
||||
|
||||
for (const auto &nodeIt: nodeInfos) {
|
||||
const auto &nodeIdString = nodeIt.first;
|
||||
const auto &nodeInfo = nodeIt.second;
|
||||
size_t nodeIndex = 0;
|
||||
if (nodeInfo.hasCutFaceSettings) {
|
||||
std::vector<QVector2D> nodeCutTemplate;
|
||||
cutFaceStringToCutTemplate(nodeInfo.cutFace, nodeCutTemplate);
|
||||
if (chamfered)
|
||||
chamferFace2D(&nodeCutTemplate);
|
||||
nodeIndex = nodeMeshModifier->addNode(nodeInfo.position, nodeInfo.radius, nodeCutTemplate, nodeInfo.cutRotation);
|
||||
} else {
|
||||
nodeIndex = nodeMeshModifier->addNode(nodeInfo.position, nodeInfo.radius, cutTemplate, cutRotation);
|
||||
}
|
||||
nodeIdStringToIndexMap[nodeIdString] = nodeIndex;
|
||||
nodeIndexToIdStringMap[nodeIndex] = nodeIdString;
|
||||
nodeMeshBuilder = new StrokeMeshBuilder;
|
||||
nodeMeshBuilder->setDeformThickness(deformThickness);
|
||||
nodeMeshBuilder->setDeformWidth(deformWidth);
|
||||
nodeMeshBuilder->setDeformMapScale(deformMapScale);
|
||||
nodeMeshBuilder->setHollowThickness(hollowThickness);
|
||||
if (nullptr != deformImage)
|
||||
nodeMeshBuilder->setDeformMapImage(deformImage);
|
||||
if (PartBase::YZ == base) {
|
||||
nodeMeshBuilder->enableBaseNormalOnX(false);
|
||||
} else if (PartBase::Average == base) {
|
||||
nodeMeshBuilder->enableBaseNormalAverage(true);
|
||||
} else if (PartBase::XY == base) {
|
||||
nodeMeshBuilder->enableBaseNormalOnZ(false);
|
||||
} else if (PartBase::ZX == base) {
|
||||
nodeMeshBuilder->enableBaseNormalOnY(false);
|
||||
}
|
||||
|
||||
addNode(nodeIdString, nodeInfo);
|
||||
}
|
||||
std::vector<size_t> builderNodeIndices;
|
||||
for (const auto &node: nodeMeshModifier->nodes()) {
|
||||
auto nodeIndex = nodeMeshBuilder->addNode(node.position, node.radius, node.cutTemplate, node.cutRotation);
|
||||
nodeMeshBuilder->setNodeOriginInfo(nodeIndex, node.nearOriginNodeIndex, node.farOriginNodeIndex);
|
||||
builderNodeIndices.push_back(nodeIndex);
|
||||
|
||||
for (const auto &edgeIt: edges) {
|
||||
const QString &fromNodeIdString = edgeIt.first;
|
||||
const QString &toNodeIdString = edgeIt.second;
|
||||
const auto &originNodeIdString = nodeIndexToIdStringMap[node.originNodeIndex];
|
||||
|
||||
auto findFromNodeIndex = nodeIdStringToIndexMap.find(fromNodeIdString);
|
||||
if (findFromNodeIndex == nodeIdStringToIndexMap.end()) {
|
||||
qDebug() << "Find from-node failed:" << fromNodeIdString;
|
||||
continue;
|
||||
}
|
||||
OutcomePaintNode paintNode;
|
||||
paintNode.originNodeIndex = node.originNodeIndex;
|
||||
paintNode.originNodeId = QUuid(originNodeIdString);
|
||||
paintNode.radius = node.radius;
|
||||
paintNode.origin = node.position;
|
||||
|
||||
auto findToNodeIndex = nodeIdStringToIndexMap.find(toNodeIdString);
|
||||
if (findToNodeIndex == nodeIdStringToIndexMap.end()) {
|
||||
qDebug() << "Find to-node failed:" << toNodeIdString;
|
||||
continue;
|
||||
}
|
||||
partCache.outcomePaintMap.paintNodes.push_back(paintNode);
|
||||
}
|
||||
for (const auto &edge: nodeMeshModifier->edges())
|
||||
nodeMeshBuilder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex);
|
||||
buildSucceed = nodeMeshBuilder->build();
|
||||
|
||||
nodeMeshModifier->addEdge(findFromNodeIndex->second, findToNodeIndex->second);
|
||||
addEdge(fromNodeIdString, toNodeIdString);
|
||||
}
|
||||
partCache.vertices = nodeMeshBuilder->generatedVertices();
|
||||
partCache.faces = nodeMeshBuilder->generatedFaces();
|
||||
for (size_t i = 0; i < partCache.vertices.size(); ++i) {
|
||||
const auto &position = partCache.vertices[i];
|
||||
const auto &source = nodeMeshBuilder->generatedVerticesSourceNodeIndices()[i];
|
||||
size_t nodeIndex = nodeMeshModifier->nodes()[source].originNodeIndex;
|
||||
const auto &nodeIdString = nodeIndexToIdStringMap[nodeIndex];
|
||||
partCache.outcomeNodeVertices.push_back({position, {partIdString, nodeIdString}});
|
||||
|
||||
if (subdived)
|
||||
nodeMeshModifier->subdivide();
|
||||
auto &paintNode = partCache.outcomePaintMap.paintNodes[source];
|
||||
paintNode.vertices.push_back(position);
|
||||
}
|
||||
|
||||
if (rounded)
|
||||
nodeMeshModifier->roundEnd();
|
||||
for (size_t i = 0; i < partCache.outcomePaintMap.paintNodes.size(); ++i) {
|
||||
auto &paintNode = partCache.outcomePaintMap.paintNodes[i];
|
||||
paintNode.baseNormal = nodeMeshBuilder->nodeBaseNormal(i);
|
||||
paintNode.direction = nodeMeshBuilder->nodeTraverseDirection(i);
|
||||
paintNode.order = nodeMeshBuilder->nodeTraverseOrder(i);
|
||||
|
||||
nodeMeshModifier->finalize();
|
||||
|
||||
nodeMeshBuilder = new StrokeMeshBuilder;
|
||||
nodeMeshBuilder->setDeformThickness(deformThickness);
|
||||
nodeMeshBuilder->setDeformWidth(deformWidth);
|
||||
nodeMeshBuilder->setDeformMapScale(deformMapScale);
|
||||
nodeMeshBuilder->setHollowThickness(hollowThickness);
|
||||
if (nullptr != deformImage)
|
||||
nodeMeshBuilder->setDeformMapImage(deformImage);
|
||||
if (PartBase::YZ == base) {
|
||||
nodeMeshBuilder->enableBaseNormalOnX(false);
|
||||
} else if (PartBase::Average == base) {
|
||||
nodeMeshBuilder->enableBaseNormalAverage(true);
|
||||
} else if (PartBase::XY == base) {
|
||||
nodeMeshBuilder->enableBaseNormalOnZ(false);
|
||||
} else if (PartBase::ZX == base) {
|
||||
nodeMeshBuilder->enableBaseNormalOnY(false);
|
||||
}
|
||||
|
||||
std::vector<size_t> builderNodeIndices;
|
||||
for (const auto &node: nodeMeshModifier->nodes()) {
|
||||
auto nodeIndex = nodeMeshBuilder->addNode(node.position, node.radius, node.cutTemplate, node.cutRotation);
|
||||
nodeMeshBuilder->setNodeOriginInfo(nodeIndex, node.nearOriginNodeIndex, node.farOriginNodeIndex);
|
||||
builderNodeIndices.push_back(nodeIndex);
|
||||
|
||||
const auto &originNodeIdString = nodeIndexToIdStringMap[node.originNodeIndex];
|
||||
|
||||
OutcomePaintNode paintNode;
|
||||
paintNode.originNodeIndex = node.originNodeIndex;
|
||||
paintNode.originNodeId = QUuid(originNodeIdString);
|
||||
paintNode.radius = node.radius;
|
||||
paintNode.origin = node.position;
|
||||
|
||||
partCache.outcomePaintMap.paintNodes.push_back(paintNode);
|
||||
}
|
||||
for (const auto &edge: nodeMeshModifier->edges())
|
||||
nodeMeshBuilder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex);
|
||||
buildSucceed = nodeMeshBuilder->build();
|
||||
|
||||
partCache.vertices = nodeMeshBuilder->generatedVertices();
|
||||
partCache.faces = nodeMeshBuilder->generatedFaces();
|
||||
for (size_t i = 0; i < partCache.vertices.size(); ++i) {
|
||||
const auto &position = partCache.vertices[i];
|
||||
const auto &source = nodeMeshBuilder->generatedVerticesSourceNodeIndices()[i];
|
||||
size_t nodeIndex = nodeMeshModifier->nodes()[source].originNodeIndex;
|
||||
const auto &nodeIdString = nodeIndexToIdStringMap[nodeIndex];
|
||||
partCache.outcomeNodeVertices.push_back({position, {partIdString, nodeIdString}});
|
||||
|
||||
auto &paintNode = partCache.outcomePaintMap.paintNodes[source];
|
||||
paintNode.vertices.push_back(position);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < partCache.outcomePaintMap.paintNodes.size(); ++i) {
|
||||
auto &paintNode = partCache.outcomePaintMap.paintNodes[i];
|
||||
paintNode.baseNormal = nodeMeshBuilder->nodeBaseNormal(i);
|
||||
paintNode.direction = nodeMeshBuilder->nodeTraverseDirection(i);
|
||||
paintNode.order = nodeMeshBuilder->nodeTraverseOrder(i);
|
||||
|
||||
partCache.outcomeNodes[paintNode.originNodeIndex].direction = paintNode.direction;
|
||||
}
|
||||
partCache.outcomeNodes[paintNode.originNodeIndex].direction = paintNode.direction;
|
||||
}
|
||||
|
||||
bool hasMeshError = false;
|
||||
|
@ -719,12 +666,8 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
|
|||
for (size_t i = 0; i < xMirroredVertices.size(); ++i) {
|
||||
const auto &position = xMirroredVertices[i];
|
||||
size_t nodeIndex = 0;
|
||||
if (gridded) {
|
||||
nodeIndex = gridMeshBuilder->getGeneratedSources()[i];
|
||||
} else {
|
||||
const auto &source = nodeMeshBuilder->generatedVerticesSourceNodeIndices()[i];
|
||||
nodeIndex = nodeMeshModifier->nodes()[source].originNodeIndex;
|
||||
}
|
||||
const auto &source = nodeMeshBuilder->generatedVerticesSourceNodeIndices()[i];
|
||||
nodeIndex = nodeMeshModifier->nodes()[source].originNodeIndex;
|
||||
const auto &nodeIdString = nodeIndexToIdStringMap[nodeIndex];
|
||||
partCache.outcomeNodeVertices.push_back({position, {mirroredPartIdString, nodeIdString}});
|
||||
}
|
||||
|
@ -811,8 +754,6 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
|
|||
delete nodeMeshBuilder;
|
||||
delete nodeMeshModifier;
|
||||
|
||||
delete gridMeshBuilder;
|
||||
|
||||
if (mesh && mesh->isNull()) {
|
||||
delete mesh;
|
||||
mesh = nullptr;
|
||||
|
|
|
@ -267,13 +267,13 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
|
|||
contextMenu.addAction(&clearCutFaceAction);
|
||||
}
|
||||
|
||||
QAction createWrapPartsAction(tr("Create Wrap Parts"), this);
|
||||
if (!m_nodePositionModifyOnly && hasSelection()) {
|
||||
connect(&createWrapPartsAction, &QAction::triggered, this, [&]() {
|
||||
createWrapParts();
|
||||
});
|
||||
contextMenu.addAction(&createWrapPartsAction);
|
||||
}
|
||||
//QAction createWrapPartsAction(tr("Create Wrap Parts"), this);
|
||||
//if (!m_nodePositionModifyOnly && hasSelection()) {
|
||||
// connect(&createWrapPartsAction, &QAction::triggered, this, [&]() {
|
||||
// createWrapParts();
|
||||
// });
|
||||
// contextMenu.addAction(&createWrapPartsAction);
|
||||
//}
|
||||
|
||||
QAction alignToLocalCenterAction(tr("Local Center"), this);
|
||||
QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this);
|
||||
|
@ -1522,6 +1522,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event)
|
|||
if (m_document->isNodeConnectable(m_hoveredNodeItem->id())) {
|
||||
emit addEdge(m_addFromNodeItem->id(), m_hoveredNodeItem->id());
|
||||
emit groupOperationAdded();
|
||||
emit setEditMode(SkeletonDocumentEditMode::Select);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue