Make3.Renderer/Make3.RenderServer/Layers/TestLayer.cs
2025-06-28 03:00:25 +03:00

184 lines
7.3 KiB
C#

using Domain;
using Domain.Entities;
using Domain.Interfaces;
using Domain.Project;
using Google.Protobuf;
using Grpc.Core;
using ImageMagick;
using LayerClients;
using Make3.CommonTypes.Interfaces;
using Make3.CommonTypes.Interfaces.Matrices;
using Make3.RenderServer.Grpc;
using IlluminationLevels = LayerClients.IlluminationLevels;
using Resolution = LayerClients.Resolution;
using Size = LayerClients.Size;
using SizeUnit = LayerClients.SizeUnit;
namespace Make3.RenderServer.Layers;
public class TestLayer(LayerClients.TestLayer.TestLayerClient grpcClient, IMatrixAbstractFactory matrixAbstractFactory) : ILayer
{
public uint Order { get; init; }
public OpticalSchema OpticalSchema { get; init; }
public IBinaryMask? Mask { get; init; }
public required MagickImage Image { get; init; }
public bool InvertMask { get; init; }
public HardwareSettings HardwareSettings { get; init; }
public double HologramWidth { get; init; }
public double HologramHeight { get; init; }
public double DifractionAngle { get; set; }
public bool PosterizeResult { get; set; }
public bool InvertProfile { get; set; }
public bool InvertHorizontalAngle { get; set; }
//Освещение голограммы
public double DirectAngle { get; set; }
public double AngleOfView { get; set; }
/// <summary>
/// компенсация для кристалла
/// </summary>
public double ObjectAngle { get; set; }
public double HorizontalRoughness { get; set; }
public double VerticalRoughness { get; set; }
private readonly LayerClients.TestLayer.TestLayerClient _grpcClient = grpcClient;
private readonly IMatrixAbstractFactory _matrixAbstractFactory = matrixAbstractFactory;
public async Task Prerender()
{
var imageData = Image.ToByteArray(MagickFormat.Png);
using var call = _grpcClient.StreamPrerenderData();
await GrpcConverters.SendStream(new MemoryStream(imageData), async (imageChunk) =>
{
var request = MakePrerenderRequest();
request.Image = imageChunk;
await call.RequestStream.WriteAsync(request);
});
if (Mask != null)
{
await GrpcConverters.SendStream(Mask.GetStream(), async (maskChunk) =>
{
var request = MakePrerenderRequest();
request.Mask = maskChunk;
request.InvertMask = InvertMask;
await call.RequestStream.WriteAsync(request);
});
// request.Mask = ByteString.CopyFrom(maskData);
// request.InvertMask = InvertMask;
}
await call.RequestStream.CompleteAsync();
Stream gratingStream = new MemoryStream();
Stream anglesStream = new MemoryStream();
Stream phasesStream = new MemoryStream();
Stream saturationStream = new MemoryStream();
Stream table1Stream = new MemoryStream(); // Тестовая таблица
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
GrpcConverters.AppendToStream(gratingStream, response.GratingPeriod);
GrpcConverters.AppendToStream(anglesStream, response.AnglesHorizontal);
GrpcConverters.AppendToStream(phasesStream, response.Phases);
GrpcConverters.AppendToStream(saturationStream, response.Saturation);
// GrpcConverters.DecodeMatrix(table1Stream, response.Table1); // Чтение тестовой таблицы
}
// var response = await _grpcClient.PrerenderAsync(request);
var m1 = GrpcConverters.ConvertStreamToMatrix(gratingStream, Image.Width, Image.Height);
}
private PrerenderRequest MakePrerenderRequest()
{
return new PrerenderRequest
{
ProjectData = new ProjectData
{
HologramWidth = HologramWidth,
HologramHeight = HologramHeight,
},
HardwareData = new HardwareData()
{
Ppu = HardwareSettings.Ppu,
UnitSize = HardwareSettings.UnitSize,
IlluminationLevels = new IlluminationLevels
{
Zero = HardwareSettings.IlluminationLevels.Zero,
LinearLow = HardwareSettings.IlluminationLevels.LinearLow,
LinearHigh = HardwareSettings.IlluminationLevels.LinearHigh,
},
MatrixResolution = new Resolution
{
X = HardwareSettings.MatrixResolution.X,
Y = HardwareSettings.MatrixResolution.Y,
},
FrameResolution = new Resolution
{
X = HardwareSettings.FrameResolution.X,
Y = HardwareSettings.FrameResolution.Y,
},
FrameSize = new Size
{
Width = GrpcConverters.ConvertDecimalValue(HardwareSettings.FrameSize.Width),
Height = GrpcConverters.ConvertDecimalValue(HardwareSettings.FrameSize.Height),
Unit = HardwareSettings.FrameSize.Unit switch
{
Domain.Project.SizeUnit.um => SizeUnit.Um,
Domain.Project.SizeUnit.mm => SizeUnit.Mm,
_ => throw new NotImplementedException()
},
}
},
OpticalSchemaData = OpticalSchema.ToString(),
// Image = ByteString.CopyFrom(imageData),
DifractionAngle = DifractionAngle,
PosterizeResult = PosterizeResult,
InvertProfile = InvertProfile,
InvertHorizontalAngle = InvertHorizontalAngle,
VerticalRoughness = VerticalRoughness,
HorizontalRoughness = HorizontalRoughness,
DirectAngle = DirectAngle,
AngleOfView = AngleOfView,
ObjectAngle = ObjectAngle,
};
}
public async Task<IntermediateRenderResult> Render(uint x, uint y, uint frameWidth, uint frameHeight, IBinaryMask? automask)
{
//здесь надо кусок изображения взять
var imageData = Image.ToByteArray(MagickFormat.Png);
// var maskData = Mask?.ToByteArray(MagickFormat.Png);
IBinaryMask? maskData = null;
// using var automaskData = automask?.Encode(SKEncodedImageFormat.Png, 100);
byte[]? automaskData = null;
var request = new RenderRequest
{
X = x,
Y = y,
FrameWidth = frameWidth,
FrameHeight = frameHeight,
Image = ByteString.CopyFrom(imageData),
// Automask = ByteString.CopyFrom(imageData.Span),
};
if (maskData != null)
{
// request.Mask = ByteString.CopyFrom(maskData);
// request.InvertMask = InvertMask;
}
request.Automask = automaskData == null ? null : ByteString.CopyFrom(automaskData);
var response = await _grpcClient.RenderAsync(request);
var byteArray = response.RenderedImage.ToByteArray();
return new IntermediateRenderResult
{
Automask = ((IBinaryMaskFactory)matrixAbstractFactory.GetFactory<bool>())
.Create(10, 20, 0),
};
}
}