This commit is contained in:
2026-05-14 23:46:58 +08:00
parent 2653a5eb1e
commit 83c2c26e89
3 changed files with 10 additions and 73 deletions
+1 -67
View File
@@ -114,14 +114,6 @@ constexpr int kProjectTreeDockStartupHeight = 170;
constexpr int kPropertiesDockStartupHeight = 380;
constexpr char kMimeHotspotAnimationJson[] = "application/x-hfut-hotspot-animation+json";
void applyVisibleBlackholesToBackground(QImage& bgPremul, const QVector<core::Project::Entity>& entities) {
for (const auto& ex : entities) {
if (ex.blackholeVisible && ex.cutoutPolygonWorld.size() >= 3) {
entity_cutout::applyBlackFillToBackground(bgPremul, ex.cutoutPolygonWorld);
}
}
}
[[nodiscard]] QVector<QVector<QPointF>> visibleBlackholePolygonsFromEntities(
const QVector<core::Project::Entity>& entities) {
QVector<QVector<QPointF>> holes;
@@ -3883,65 +3875,7 @@ void MainWindow::rebuildCentralPages() {
return;
}
core::Project::Entity ent;
ent.id.clear();
ent.cutoutPolygonWorld = polyWorld;
ent.originWorld = entity_cutout::polygonCentroid(ent.cutoutPolygonWorld);
ent.polygonLocal.clear();
ent.polygonLocal.reserve(ent.cutoutPolygonWorld.size());
for (const auto& pt : ent.cutoutPolygonWorld) {
ent.polygonLocal.push_back(pt - ent.originWorld);
}
const QString bgAbs = m_workspace.backgroundAbsolutePath();
QImage depth8;
if (m_workspace.hasDepth()) {
const QString dpath = m_workspace.depthAbsolutePath();
if (!dpath.isEmpty() && QFileInfo::exists(dpath) && !bgAbs.isEmpty()) {
depth8 = core::image_file::loadDepthMapAlignedToBackground(dpath, bgAbs);
}
}
const QPointF c = entity_cutout::polygonCentroid(ent.cutoutPolygonWorld);
int z = 0;
if (!depth8.isNull()) {
const int xi = static_cast<int>(std::floor(c.x()));
const int yi = static_cast<int>(std::floor(c.y()));
if (xi >= 0 && yi >= 0 && xi < depth8.width() && yi < depth8.height()) {
z = static_cast<int>(static_cast<const uchar*>(depth8.constScanLine(yi))[xi]);
}
}
ent.depth = z;
{
const double ds01 = static_cast<double>(std::clamp(z, 0, 255)) / 255.0;
ent.distanceScaleCalibMult = 0.5 + ds01 * 1.0;
}
QImage bg =
core::image_file::loadImageLimited(bgAbs, core::image_decode::kWorkspaceMaxPixels);
if (!bg.isNull() && bg.format() != QImage::Format_ARGB32_Premultiplied) {
bg = bg.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
applyVisibleBlackholesToBackground(bg, m_workspace.entities());
QImage cutout;
if (!bg.isNull()) {
QPointF topLeft;
cutout = entity_cutout::extractEntityImage(bg, ent.cutoutPolygonWorld, topLeft);
ent.imageTopLeftWorld = topLeft;
}
QSet<QString> used;
for (const auto& ex : m_workspace.entities()) {
used.insert(ex.id);
}
int n = static_cast<int>(m_workspace.entities().size()) + 1;
for (int guard = 0; guard < 100000; ++guard, ++n) {
const QString cand = QStringLiteral("entity-%1").arg(n);
if (!used.contains(cand)) {
ent.id = cand;
break;
}
}
// 不直接落盘:进入待确认(可微调)
// 待确认态只需多边形;深度/抠图在「确认创建实体」时再算,避免此处整图解码阻塞 UI 数秒。
m_editorCanvas->setPendingEntityPolygonWorld(polyWorld);
});