You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
4.7 KiB
158 lines
4.7 KiB
using System; |
|
using System.ComponentModel.DataAnnotations; |
|
using System.Threading.Tasks; |
|
using Avalonia.Threading; |
|
using CommunityToolkit.Mvvm.ComponentModel; |
|
using CommunityToolkit.Mvvm.Input; |
|
using DynamicData.Binding; |
|
using FluentAvalonia.UI.Controls; |
|
using StabilityMatrix.Avalonia.Controls; |
|
using StabilityMatrix.Avalonia.Services; |
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
|
using StabilityMatrix.Avalonia.ViewModels.Dialogs; |
|
using StabilityMatrix.Core.Attributes; |
|
using StabilityMatrix.Core.Helper; |
|
using StabilityMatrix.Core.Models; |
|
using StabilityMatrix.Core.Models.Api.Comfy; |
|
using StabilityMatrix.Core.Models.Api.Comfy.Nodes; |
|
|
|
namespace StabilityMatrix.Avalonia.ViewModels.Inference; |
|
|
|
[View(typeof(ControlNetCard))] |
|
[ManagedService] |
|
[Transient] |
|
public partial class ControlNetCardViewModel : LoadableViewModelBase |
|
{ |
|
public const string ModuleKey = "ControlNet"; |
|
|
|
private readonly ServiceManager<ViewModelBase> vmFactory; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
private HybridModelFile? selectedModel; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
private ComfyAuxPreprocessor? selectedPreprocessor; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
[Range(0, 2048)] |
|
private int width; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
[Range(0, 2048)] |
|
private int height; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
[Range(0d, 10d)] |
|
private double strength = 1.0; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
[Range(0d, 1d)] |
|
private double startPercent; |
|
|
|
[ObservableProperty] |
|
[Required] |
|
[Range(0d, 1d)] |
|
private double endPercent = 1.0; |
|
|
|
public SelectImageCardViewModel SelectImageCardViewModel { get; } |
|
|
|
public IInferenceClientManager ClientManager { get; } |
|
|
|
public ControlNetCardViewModel( |
|
IInferenceClientManager clientManager, |
|
ServiceManager<ViewModelBase> vmFactory |
|
) |
|
{ |
|
this.vmFactory = vmFactory; |
|
|
|
ClientManager = clientManager; |
|
SelectImageCardViewModel = vmFactory.Get<SelectImageCardViewModel>(); |
|
|
|
// Update our width and height when the image changes |
|
SelectImageCardViewModel |
|
.WhenPropertyChanged(card => card.CurrentBitmapSize) |
|
.Subscribe(propertyValue => |
|
{ |
|
if (!propertyValue.Value.IsEmpty) |
|
{ |
|
Width = propertyValue.Value.Width; |
|
Height = propertyValue.Value.Height; |
|
} |
|
}); |
|
} |
|
|
|
[RelayCommand] |
|
private async Task RemoteDownload(HybridModelFile? modelFile) |
|
{ |
|
if (modelFile?.DownloadableResource is not { } resource) |
|
return; |
|
|
|
var confirmDialog = vmFactory.Get<DownloadResourceViewModel>(); |
|
confirmDialog.Resource = resource; |
|
confirmDialog.FileName = modelFile.FileName; |
|
|
|
if (await confirmDialog.GetDialog().ShowAsync() == ContentDialogResult.Primary) |
|
{ |
|
confirmDialog.StartDownload(); |
|
} |
|
} |
|
|
|
[RelayCommand] |
|
private async Task PreviewPreprocessor(ComfyAuxPreprocessor? preprocessor) |
|
{ |
|
if ( |
|
preprocessor is null |
|
|| SelectImageCardViewModel.ImageSource is not { } imageSource |
|
|| SelectImageCardViewModel.IsImageFileNotFound |
|
) |
|
return; |
|
|
|
var args = new InferenceQueueCustomPromptEventArgs(); |
|
|
|
var images = SelectImageCardViewModel.GetInputImages(); |
|
|
|
await ClientManager.UploadInputImageAsync(imageSource); |
|
|
|
var image = args.Nodes.AddTypedNode( |
|
new ComfyNodeBuilder.LoadImage |
|
{ |
|
Name = args.Nodes.GetUniqueName("Preprocessor_LoadImage"), |
|
Image = |
|
SelectImageCardViewModel.ImageSource?.GetHashGuidFileNameCached("Inference") |
|
?? throw new ValidationException("No ImageSource") |
|
} |
|
).Output1; |
|
|
|
var aioPreprocessor = args.Nodes.AddTypedNode( |
|
new ComfyNodeBuilder.AIOPreprocessor |
|
{ |
|
Name = args.Nodes.GetUniqueName("Preprocessor"), |
|
Image = image, |
|
Preprocessor = preprocessor.ToString(), |
|
Resolution = Width is <= 2048 and > 0 ? Width : 512 |
|
} |
|
); |
|
|
|
args.Builder.Connections.OutputNodes.Add( |
|
args.Nodes.AddTypedNode( |
|
new ComfyNodeBuilder.PreviewImage |
|
{ |
|
Name = args.Nodes.GetUniqueName("Preprocessor_OutputImage"), |
|
Images = aioPreprocessor.Output |
|
} |
|
) |
|
); |
|
|
|
// Queue |
|
Dispatcher.UIThread.Post(() => EventManager.Instance.OnInferenceQueueCustomPrompt(args)); |
|
|
|
// We don't know when it's done so wait a bit? |
|
await Task.Delay(1000); |
|
} |
|
}
|
|
|