parent
64e0511356
commit
14b65e193b
|
@ -187,16 +187,43 @@ void ContourToPartConverter::optimizeNodes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContourToPartConverter::alignSkeleton(const std::vector<std::pair<QVector2D, float>> &referenceSkeleton,
|
||||||
|
std::vector<std::pair<QVector2D, float>> &adjustSkeleton)
|
||||||
|
{
|
||||||
|
if (referenceSkeleton.empty() || adjustSkeleton.empty())
|
||||||
|
return;
|
||||||
|
float sumOfDistance2 = 0.0;
|
||||||
|
float reversedSumOfDistance2 = 0.0;
|
||||||
|
for (size_t i = 0; i < adjustSkeleton.size(); ++i) {
|
||||||
|
size_t j = ((float)i / adjustSkeleton.size()) * referenceSkeleton.size();
|
||||||
|
if (j >= referenceSkeleton.size())
|
||||||
|
continue;
|
||||||
|
size_t k = referenceSkeleton.size() - 1 - j;
|
||||||
|
sumOfDistance2 += std::pow(adjustSkeleton[i].first.y() - referenceSkeleton[j].first.y(), 2.0f);
|
||||||
|
reversedSumOfDistance2 += std::pow(adjustSkeleton[i].first.y() - referenceSkeleton[k].first.y(), 2.0f);
|
||||||
|
}
|
||||||
|
if (sumOfDistance2 <= reversedSumOfDistance2)
|
||||||
|
return;
|
||||||
|
std::reverse(adjustSkeleton.begin(), adjustSkeleton.end());
|
||||||
|
}
|
||||||
|
|
||||||
void ContourToPartConverter::convert()
|
void ContourToPartConverter::convert()
|
||||||
{
|
{
|
||||||
std::vector<std::pair<QVector2D, float>> sideSkeleton;
|
std::vector<std::pair<QVector2D, float>> sideSkeleton;
|
||||||
|
std::vector<std::pair<QVector2D, float>> mainSkeleton;
|
||||||
auto mainBoundingBox = m_mainProfile.boundingRect();
|
auto mainBoundingBox = m_mainProfile.boundingRect();
|
||||||
extractSkeleton(m_sideProfile, &sideSkeleton);
|
extractSkeleton(m_sideProfile, &sideSkeleton);
|
||||||
|
extractSkeleton(m_mainProfile, &mainSkeleton);
|
||||||
|
smoothRadius(&sideSkeleton);
|
||||||
|
smoothRadius(&mainSkeleton);
|
||||||
if (!sideSkeleton.empty()) {
|
if (!sideSkeleton.empty()) {
|
||||||
float x = mainBoundingBox.center().x() / m_canvasSize.height();
|
alignSkeleton(sideSkeleton, mainSkeleton);
|
||||||
|
float defaultX = mainBoundingBox.center().x() / m_canvasSize.height();
|
||||||
m_nodes.reserve(sideSkeleton.size());
|
m_nodes.reserve(sideSkeleton.size());
|
||||||
for (size_t i = 0; i < sideSkeleton.size(); ++i) {
|
for (size_t i = 0; i < sideSkeleton.size(); ++i) {
|
||||||
const auto &it = sideSkeleton[i];
|
const auto &it = sideSkeleton[i];
|
||||||
|
size_t j = ((float)i / sideSkeleton.size()) * mainSkeleton.size();
|
||||||
|
float x = j < mainSkeleton.size() ? mainSkeleton[j].first.x() : defaultX;
|
||||||
m_nodes.push_back(std::make_pair(QVector3D(x, it.first.y(), it.first.x()),
|
m_nodes.push_back(std::make_pair(QVector3D(x, it.first.y(), it.first.x()),
|
||||||
it.second));
|
it.second));
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ private:
|
||||||
const std::set<std::pair<int, int>> &black);
|
const std::set<std::pair<int, int>> &black);
|
||||||
void nodesToSnapshot();
|
void nodesToSnapshot();
|
||||||
void smoothRadius(std::vector<std::pair<QVector2D, float>> *skeleton);
|
void smoothRadius(std::vector<std::pair<QVector2D, float>> *skeleton);
|
||||||
|
void alignSkeleton(const std::vector<std::pair<QVector2D, float>> &referenceSkeleton,
|
||||||
|
std::vector<std::pair<QVector2D, float>> &adjustSkeleton);
|
||||||
void optimizeNodes();
|
void optimizeNodes();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,8 @@ void SkeletonGraphicsWidget::setBackgroundBlur(float turnaroundOpacity)
|
||||||
|
|
||||||
void SkeletonGraphicsWidget::shortcutEscape()
|
void SkeletonGraphicsWidget::shortcutEscape()
|
||||||
{
|
{
|
||||||
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
|
if (SkeletonDocumentEditMode::Add == m_document->editMode ||
|
||||||
|
SkeletonDocumentEditMode::Mark == m_document->editMode) {
|
||||||
emit setEditMode(SkeletonDocumentEditMode::Select);
|
emit setEditMode(SkeletonDocumentEditMode::Select);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -725,6 +726,10 @@ void SkeletonGraphicsWidget::updateCursor()
|
||||||
m_cursorNodeItem->hide();
|
m_cursorNodeItem->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SkeletonDocumentEditMode::Mark != m_document->editMode) {
|
||||||
|
m_markerItem->reset();
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_document->editMode) {
|
switch (m_document->editMode) {
|
||||||
case SkeletonDocumentEditMode::Add:
|
case SkeletonDocumentEditMode::Add:
|
||||||
setCursor(QCursor(Theme::awesome()->icon(fa::plus).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize)));
|
setCursor(QCursor(Theme::awesome()->icon(fa::plus).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize)));
|
||||||
|
@ -1455,6 +1460,7 @@ bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event)
|
||||||
const QPolygonF &previousPolygon = m_markerItem->previousPolygon();
|
const QPolygonF &previousPolygon = m_markerItem->previousPolygon();
|
||||||
if (previousPolygon.empty()) {
|
if (previousPolygon.empty()) {
|
||||||
m_markerItem->save();
|
m_markerItem->save();
|
||||||
|
m_markerItem->toggleProfile();
|
||||||
} else {
|
} else {
|
||||||
if (m_markerItem->isMainProfile()) {
|
if (m_markerItem->isMainProfile()) {
|
||||||
emit addPartByPolygons(m_markerItem->polygon(), previousPolygon, sceneRect().size());
|
emit addPartByPolygons(m_markerItem->polygon(), previousPolygon, sceneRect().size());
|
||||||
|
@ -1464,7 +1470,6 @@ bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event)
|
||||||
m_markerItem->reset();
|
m_markerItem->reset();
|
||||||
}
|
}
|
||||||
m_markerItem->hide();
|
m_markerItem->hide();
|
||||||
m_markerItem->toggleProfile();
|
|
||||||
updateCursor();
|
updateCursor();
|
||||||
} else {
|
} else {
|
||||||
m_markerItem->clear();
|
m_markerItem->clear();
|
||||||
|
|
|
@ -171,6 +171,10 @@ public:
|
||||||
{
|
{
|
||||||
m_previousPolygon.clear();
|
m_previousPolygon.clear();
|
||||||
clear();
|
clear();
|
||||||
|
if (!m_mainProfile) {
|
||||||
|
m_mainProfile = true;
|
||||||
|
updateAppearance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
QPolygonF m_polygon;
|
QPolygonF m_polygon;
|
||||||
|
|
Loading…
Reference in New Issue