From 83c2c26e89f118715cb081a0b0aacdfbc8ffa491 Mon Sep 17 00:00:00 2001 From: DingVero Date: Thu, 14 May 2026 23:46:58 +0800 Subject: [PATCH] update --- client/gui/main_window/MainWindow.cpp | 68 +------------------ python_server/config.py | 4 +- .../model/Inpaint/flux_fill/loader.py | 11 +-- 3 files changed, 10 insertions(+), 73 deletions(-) diff --git a/client/gui/main_window/MainWindow.cpp b/client/gui/main_window/MainWindow.cpp index 4893469..a906f7a 100644 --- a/client/gui/main_window/MainWindow.cpp +++ b/client/gui/main_window/MainWindow.cpp @@ -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& entities) { - for (const auto& ex : entities) { - if (ex.blackholeVisible && ex.cutoutPolygonWorld.size() >= 3) { - entity_cutout::applyBlackFillToBackground(bgPremul, ex.cutoutPolygonWorld); - } - } -} - [[nodiscard]] QVector> visibleBlackholePolygonsFromEntities( const QVector& entities) { QVector> 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(std::floor(c.x())); - const int yi = static_cast(std::floor(c.y())); - if (xi >= 0 && yi >= 0 && xi < depth8.width() && yi < depth8.height()) { - z = static_cast(static_cast(depth8.constScanLine(yi))[xi]); - } - } - ent.depth = z; - { - const double ds01 = static_cast(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 used; - for (const auto& ex : m_workspace.entities()) { - used.insert(ex.id); - } - int n = static_cast(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); }); diff --git a/python_server/config.py b/python_server/config.py index 56bb8f2..e37ab8b 100644 --- a/python_server/config.py +++ b/python_server/config.py @@ -168,8 +168,8 @@ class DepthConfig: class InpaintConfig: # 统一补全默认后端(与 model key 对齐;实际路由以请求的 model_name 为准) backend: Literal["flux_fill", "sdxl_inpaint", "controlnet"] = "flux_fill" - # FLUX Fill(gated:须在 Hugging Face 同意条款,并建议设置环境变量 HF_TOKEN) - flux_fill_model: str = "black-forest-labs/FLUX.1-Fill-dev" + # FLUX Fill:本机 diffusers 目录(须含 model_index.json)。换机器时改此绝对路径即可。 + flux_fill_model: str = "/home/vipuser/ai-models/flux/FLUX.1-Fill-dev" # SDXL:须为专用 inpaint 权重(勿用 xl-base 当补全底模) sdxl_base_model: str = "diffusers/stable-diffusion-xl-1.0-inpainting-0.1" # ControlNet Inpaint 基础模型与 controlnet 权重 diff --git a/python_server/model/Inpaint/flux_fill/loader.py b/python_server/model/Inpaint/flux_fill/loader.py index 1c94f7e..ddf41b8 100644 --- a/python_server/model/Inpaint/flux_fill/loader.py +++ b/python_server/model/Inpaint/flux_fill/loader.py @@ -1,6 +1,6 @@ from __future__ import annotations -import os +from pathlib import Path from typing import Any, Callable import numpy as np @@ -24,12 +24,15 @@ def make_flux_fill_predictor( else: torch_dtype = torch.float32 - hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN") + root = Path(model_id.strip()).expanduser() + # 本机 diffusers 目录(含 model_index.json)时不访问 Hub,避免自动下载。 + local_files_only = root.is_dir() and (root / "model_index.json").is_file() pipe = FluxFillPipeline.from_pretrained( - model_id, + str(root), torch_dtype=torch_dtype, - token=hf_token, + token=None, + local_files_only=local_files_only, ) if device == "cuda":