feat(server): add layer-separation generator task
Introduce the `layer-separation` generator (edit-elements node action) that splits a source image into a clean background layer, foreground image artifacts with bounding boxes, and editable text render data. - New layer_separation.go builds the separated result and artifacts - SubmitGeneratorTask routes layer-separation and move-object via a switch; standalone task completion + polling support - Extend artifact metadata with BBox and GeneratorName across the domain, API types, mapper, .api schema, and API.md - edit-elements gets a transparent manual-frame placeholder holding the separated foreground images and text layers beside the original Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -892,12 +892,14 @@ func (s *DesignService) RunNodeActionAsync(ctx context.Context, projectID string
|
||||
now := s.now()
|
||||
threadID := newID()
|
||||
target := project.Nodes[nodeIndex]
|
||||
if req.Action == "remove-background" || req.Action == "vectorize" || req.Action == "move-object" {
|
||||
if req.Action == "remove-background" || req.Action == "vectorize" || req.Action == "move-object" || req.Action == "edit-elements" {
|
||||
resultNode := newBackgroundRemovalPlaceholder(target)
|
||||
if req.Action == "vectorize" {
|
||||
resultNode = newVectorizePlaceholder(target)
|
||||
} else if req.Action == "move-object" {
|
||||
resultNode = newMoveObjectPlaceholder(target)
|
||||
} else if req.Action == "edit-elements" {
|
||||
resultNode = newLayerSeparationPlaceholder(target)
|
||||
}
|
||||
if req.Options == nil {
|
||||
req.Options = make(map[string]string)
|
||||
@@ -1845,7 +1847,10 @@ func (s *DesignService) completeNodeActionGeneration(ctx context.Context, projec
|
||||
if req.Action == "vectorize" {
|
||||
return s.completeVectorizeGeneration(ctx, projectID, threadID, target, req)
|
||||
}
|
||||
if req.Action == "edit-elements" || req.Action == "edit-text" {
|
||||
if req.Action == "edit-elements" {
|
||||
return s.completeLayerSeparationGeneration(ctx, projectID, threadID, target, req)
|
||||
}
|
||||
if req.Action == "edit-text" {
|
||||
return s.completeEditableLayerGeneration(ctx, projectID, threadID, target, req)
|
||||
}
|
||||
editToolContent := "正在根据选中图片执行模型编辑,完成后会替换画布中的图片节点。"
|
||||
@@ -4709,8 +4714,30 @@ func newMoveObjectPlaceholder(target design.Node) design.Node {
|
||||
return result
|
||||
}
|
||||
|
||||
func newLayerSeparationPlaceholder(target design.Node) design.Node {
|
||||
result := target
|
||||
result.ID = newID()
|
||||
result.Type = design.NodeTypeFrame
|
||||
result.Title = nodeActionWorkingTitle("edit-elements")
|
||||
result.X = target.X + target.Width + 32
|
||||
result.Y = target.Y
|
||||
result.Content = target.Content
|
||||
result.Tone = "frame"
|
||||
result.Status = "generating"
|
||||
result.ParentID = ""
|
||||
result.LayerRole = "manual-frame"
|
||||
result.FillColor = "transparent"
|
||||
result.StrokeColor = "#C7C7C7"
|
||||
result.StrokeWidth = 1
|
||||
result.StrokeStyle = "solid"
|
||||
result.MockupSurface = design.MockupSurface{}
|
||||
result.MockupModel = design.MockupModel{}
|
||||
result.MockupSourceContent = ""
|
||||
return result
|
||||
}
|
||||
|
||||
func nodeActionResultNodeID(target design.Node, req design.NodeActionRequest) string {
|
||||
if (req.Action == "remove-background" || req.Action == "vectorize" || req.Action == "move-object") && len(req.Options) > 0 {
|
||||
if (req.Action == "remove-background" || req.Action == "vectorize" || req.Action == "move-object" || req.Action == "edit-elements") && len(req.Options) > 0 {
|
||||
if id := strings.TrimSpace(req.Options[nodeActionResultNodeIDOption]); id != "" {
|
||||
return id
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user