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; } /// /// компенсация для кристалла /// 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 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()) .Create(10, 20, 0), }; } }