diff options
Diffstat (limited to 'UVtools.Core/Layer/Layer.cs')
-rw-r--r-- | UVtools.Core/Layer/Layer.cs | 651 |
1 files changed, 5 insertions, 646 deletions
diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs index 3aa1fc1..875ca1b 100644 --- a/UVtools.Core/Layer/Layer.cs +++ b/UVtools.Core/Layer/Layer.cs @@ -210,14 +210,10 @@ namespace UVtools.Core } set { - using (var vector = new VectorOfByte()) - { - CvInvoke.Imencode(".png", value, vector); - CompressedBytes = vector.ToArray(); - - GetBoundingRectangle(value, true); - } - + using var vector = new VectorOfByte(); + CvInvoke.Imencode(".png", value, vector); + CompressedBytes = vector.ToArray(); + GetBoundingRectangle(value, true); RaisePropertyChanged(); } } @@ -633,646 +629,9 @@ namespace UVtools.Core return result; } - public void Move(OperationMove operation) - { - using (var mat = LayerMat) - { - if (operation.ImageWidth == 0) operation.ImageWidth = (uint)mat.Width; - if (operation.ImageHeight == 0) operation.ImageHeight = (uint)mat.Height; - - /*layer.Transform(1.0, 1.0, move.MarginLeft - move.MarginRight, move.MarginTop-move.MarginBottom); - LayerMat = layer;*/ - /*using (var layerRoi = new Mat(layer, operation.SrcRoi)) - using (var dstLayer = layer.CloneBlank()) - using (var dstRoi = new Mat(dstLayer, operation.DstRoi)) - { - layerRoi.CopyTo(dstRoi); - LayerMat = dstLayer; - }*/ - - using (var srcRoi = new Mat(mat, operation.ROI)) - using (var dstRoi = new Mat(mat, operation.DstRoi)) - { - if (operation.IsCutMove) - { - using (var targetRoi = srcRoi.Clone()) - { - srcRoi.SetTo(new MCvScalar(0)); - targetRoi.CopyTo(dstRoi); - } - } - else - { - srcRoi.CopyTo(dstRoi); - } - - LayerMat = mat; - } - } - } - - - public void Resize(double xScale, double yScale, OperationResize operation) - { - using (var mat = LayerMat) - { - Mat target = operation.GetRoiOrDefault(mat); - target.TransformFromCenter(xScale, yScale); - LayerMat = mat; - } - } - - public void Flip(OperationFlip operation) - { - using (var mat = LayerMat) - { - Mat target = operation.GetRoiOrDefault(mat); - - if (operation.MakeCopy) - { - using (Mat dst = new Mat()) - { - - CvInvoke.Flip(target, dst, operation.FlipTypeOpenCV); - CvInvoke.Add(target, dst, target); - } - } - else - { - CvInvoke.Flip(target, target, operation.FlipTypeOpenCV); - } - - LayerMat = mat; - } - } - - public void Rotate(OperationRotate operation) - { - using (var mat = LayerMat) - { - Mat target = operation.GetRoiOrDefault(mat); - target.Rotate((double) operation.AngleDegrees); - LayerMat = mat; - } - } - - public void Solidify(OperationSolidify operation) - { - using (Mat mat = LayerMat) - { - using (Mat filteredMat = new Mat()) - { - Mat target = operation.GetRoiOrDefault(mat); - - - CvInvoke.Threshold(target, filteredMat, 127, 255, ThresholdType.Binary); // Clean AA - - using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) - { - using (Mat hierarchy = new Mat()) - { - CvInvoke.FindContours(filteredMat, contours, hierarchy, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple); - var arr = hierarchy.GetData(); - for (int i = 0; i < contours.Size; i++) - { - if ((int)arr.GetValue(0, i, 2) != -1 || (int)arr.GetValue(0, i, 3) == -1) continue; - if (operation.MinimumArea >= 1) - { - var rectangle = CvInvoke.BoundingRectangle(contours[i]); - if (operation.AreaCheckType == OperationSolidify.AreaCheckTypes.More) - { - if (rectangle.GetArea() < operation.MinimumArea) continue; - } - else - { - if (rectangle.GetArea() > operation.MinimumArea) continue; - } - - } - - CvInvoke.DrawContours(target, contours, i, new MCvScalar(255), -1); - } - } - } - } - - LayerMat = mat; - } - } - - public void Mask(OperationMask operation) - { - using (var mat = LayerMat) - { - Mat target = operation.GetRoiOrDefault(mat); - if(operation.Mask.Size != target.Size) return; - CvInvoke.BitwiseAnd(target, operation.Mask, target); - LayerMat = mat; - } - } - - /*public void MutatePixelDimming(Matrix<byte> evenPattern = null, Matrix<byte> oddPattern = null, ushort borderSize = 5) - { - var anchor = new Point(-1, -1); - var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - if (ReferenceEquals(evenPattern, null)) - { - evenPattern = new Matrix<byte>(2, 2) - { - [0, 0] = 127, - [0, 1] = 255, - [1, 0] = 255, - [1, 1] = 127, - }; - - if (ReferenceEquals(oddPattern, null)) - { - oddPattern = new Matrix<byte>(2, 2) - { - [0, 0] = 255, - [0, 1] = 127, - [1, 0] = 127, - [1, 1] = 255, - }; - } - } - - using (Mat dst = LayerMat) - { - using (Mat erode = new Mat()) - { - using (Mat diff = new Mat()) - { - using (Mat mask = dst.CloneBlank()) - { - CvInvoke.Erode(dst, erode, kernel, anchor, borderSize, BorderType.Reflect101, default); - CvInvoke.Subtract(dst, erode, diff); - - if (Index % 2 == 0) - { - CvInvoke.Repeat(evenPattern, dst.Rows / evenPattern.Rows + 1, dst.Cols / evenPattern.Cols + 1, mask); - } - else - { - CvInvoke.Repeat(oddPattern, dst.Rows / oddPattern.Rows + 1, dst.Cols / oddPattern.Cols + 1, mask); - } - - using (var maskReshape = new Mat(mask, new Rectangle(0, 0, dst.Width, dst.Height))) - { - CvInvoke.BitwiseAnd(erode, maskReshape, dst); - } - - CvInvoke.Add(dst, diff, dst); - LayerMat = dst; - } - } - } - } - }*/ - - public void PixelDimming(OperationPixelDimming operation, Mat patternMask, Mat alternatePatternMask = null) - { - var anchor = new Point(-1, -1); - var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - - if (ReferenceEquals(alternatePatternMask, null)) - { - alternatePatternMask = patternMask; - } - - int wallThickness = LayerManager.MutateGetIterationChamfer( - Index, - operation.LayerIndexStart, - operation.LayerIndexEnd, - (int)operation.WallThicknessStart, - (int)operation.WallThicknessEnd, - operation.Chamfer - ); - - - using (Mat dst = LayerMat) - using (Mat erode = new Mat()) - using (Mat diff = new Mat()) - { - Mat target = operation.GetRoiOrDefault(dst); - - - CvInvoke.Erode(target, erode, kernel, anchor, wallThickness, BorderType.Reflect101, default); - CvInvoke.Subtract(target, erode, diff); - - - if (operation.WallsOnly) - { - CvInvoke.BitwiseAnd(diff, operation.IsNormalPattern(Index) ? patternMask : alternatePatternMask, target); - CvInvoke.Add(erode, target, target); - } - else - { - CvInvoke.BitwiseAnd(erode, operation.IsNormalPattern(Index) ? patternMask : alternatePatternMask, target); - CvInvoke.Add(target, diff, target); - } - - LayerMat = dst; - } - } - - public void Infill(OperationInfill operation) - { - var anchor = new Point(-1, -1); - var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - - uint layerIndex = Index - operation.LayerIndexStart; - var infillColor = new MCvScalar(operation.InfillBrightness); - - Mat patternMask = null; - using (Mat dst = LayerMat) - using (Mat erode = new Mat()) - using (Mat diff = new Mat()) - { - Mat target = operation.GetRoiOrDefault(dst); - - /*if (operation.InfillType == OperationInfill.InfillAlgorithm.Rhombus) - { - const double rotationAngle = 55; - patternMask = target.CloneBlank(); - int offsetLayerPos = (int)(layerIndex % operation.InfillSpacing); - var pivot = new Point( operation.InfillThickness / 2, operation.InfillThickness / 2); - - Point[] points1 = { - new Point(operation.InfillThickness / 4, operation.InfillThickness / 2), // Left - new Point(operation.InfillThickness / 2, 0), // Top - new Point((int) (operation.InfillThickness / 1.25), operation.InfillThickness / 2), // Right - new Point(operation.InfillThickness / 2, operation.InfillThickness) // Bottom - }; - var vec1 = new VectorOfPoint(points1); - - - Point[] points2 = { - points1[0].Rotate(rotationAngle, pivot), - points1[1].Rotate(rotationAngle, pivot), - points1[2].Rotate(rotationAngle, pivot), - points1[3].Rotate(rotationAngle, pivot), - }; - var vec2 = new VectorOfPoint(points2); - - Point[] points3 = { - points1[0].Rotate(-rotationAngle, pivot), - points1[1].Rotate(-rotationAngle, pivot), - points1[2].Rotate(-rotationAngle, pivot), - points1[3].Rotate(-rotationAngle, pivot), - }; - var vec3 = new VectorOfPoint(points3); - - - /*int halfPos = (operation.InfillThickness + offsetPos) / 2; - - Point[] points = { - new Point(0+offsetPos, halfPos), // Left - new Point(halfPos, 0+offsetPos), // Top - new Point(operation.InfillThickness+offsetPos, halfPos), // Right - new Point(halfPos, operation.InfillThickness+offsetPos) // Bottom - }; */ - /* for (int y = 0; y < patternMask.Height; y += operation.InfillSpacing) - { - for (int x = 0; x < patternMask.Width; x+=operation.InfillSpacing) - { - CvInvoke.FillPoly(patternMask, vec1, infillColor, LineType.EightConnected, default, new Point(x, y+offsetLayerPos)); - CvInvoke.FillPoly(patternMask, vec2, infillColor, LineType.EightConnected, default, new Point(x- offsetLayerPos, y+ offsetLayerPos)); - CvInvoke.FillPoly(patternMask, vec3, infillColor, LineType.EightConnected, default, new Point(x+ offsetLayerPos, y+ offsetLayerPos)); - } - } - - patternMask.Save("D:\\mask.png"); - - - } - else*/ if (operation.InfillType == OperationInfill.InfillAlgorithm.Cubic || - operation.InfillType == OperationInfill.InfillAlgorithm.CubicCenterLink || - operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink || - operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked) - { - using (var infillPattern = EmguExtensions.InitMat(new Size(operation.InfillSpacing, operation.InfillSpacing))) - using (Mat matPattern = dst.CloneBlank()) - { - bool firstPattern = true; - uint accumulator = 0; - uint step = 0; - bool dynamicCenter = false; - while (accumulator < layerIndex) - { - dynamicCenter = !dynamicCenter; - firstPattern = true; - accumulator += operation.InfillSpacing; - - if (accumulator >= layerIndex) break; - firstPattern = false; - accumulator += operation.InfillThickness; - } - - if (firstPattern) - { - int thickness = operation.InfillThickness / 2; - // Top Left - CvInvoke.Rectangle(infillPattern, - new Rectangle(0, 0, thickness, thickness), - infillColor, -1); - - // Top Right - CvInvoke.Rectangle(infillPattern, - new Rectangle(infillPattern.Width - thickness, 0, thickness, thickness), - infillColor, -1); - - // Bottom Left - CvInvoke.Rectangle(infillPattern, - new Rectangle(0, infillPattern.Height - thickness, thickness, thickness), - infillColor, -1); - - // Bottom Right - CvInvoke.Rectangle(infillPattern, - new Rectangle(infillPattern.Width - thickness, infillPattern.Height - thickness, - thickness, thickness), - infillColor, -1); - - // Center cross - int margin = (int)(operation.InfillSpacing - accumulator + layerIndex) - thickness; - int marginInv = (int)(accumulator - layerIndex) - thickness; - - if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicCenterLink || - (operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink && - dynamicCenter) || - operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked) - { - - CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, margin, operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, marginInv, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, marginInv, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, margin, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - } - - - if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked || - (operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink && !dynamicCenter)) - { - CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, -thickness, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, -thickness, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(-thickness, margin, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(-thickness, marginInv, operation.InfillThickness, - operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(operation.InfillSpacing - thickness, margin, - operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(operation.InfillSpacing - thickness, marginInv, - operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(margin, operation.InfillSpacing - thickness, - operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - - CvInvoke.Rectangle(infillPattern, - new Rectangle(marginInv, operation.InfillSpacing - thickness, - operation.InfillThickness, operation.InfillThickness), - infillColor, -1); - } - - - } - else - { - CvInvoke.Rectangle(infillPattern, - new Rectangle(0, 0, operation.InfillSpacing, operation.InfillSpacing), - infillColor, operation.InfillThickness); - } - - - { - CvInvoke.Repeat(infillPattern, target.Rows / infillPattern.Rows + 1, - target.Cols / infillPattern.Cols + 1, matPattern); - patternMask = new Mat(matPattern, new Rectangle(0, 0, target.Width, target.Height)); - } - } - } - - - CvInvoke.Erode(target, erode, kernel, anchor, operation.WallThickness, BorderType.Reflect101, - default); - CvInvoke.Subtract(target, erode, diff); - - - CvInvoke.BitwiseAnd(erode, patternMask, target); - CvInvoke.Add(target, diff, target); - patternMask?.Dispose(); - - LayerMat = dst; - } - } - - public void Morph(OperationMorph operation, int iterations = 1, BorderType borderType = BorderType.Default, MCvScalar borderValue = default) - { - if (iterations == 0) - iterations = (int) operation.IterationsStart; - - using (Mat dst = LayerMat) - { - Mat target = operation.GetRoiOrDefault(dst); - CvInvoke.MorphologyEx(target, target, operation.MorphOperation, operation.Kernel.Matrix, operation.Kernel.Anchor, iterations, borderType, borderValue); - LayerMat = dst; - } - } - - public void MutateErode(int iterations = 1, IInputArray kernel = null, Point anchor = default, BorderType borderType = BorderType.Default, MCvScalar borderValue = default) - { - if (anchor.IsEmpty) anchor = new Point(-1, -1); - if (ReferenceEquals(kernel, null)) - { - kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - } - using (Mat dst = LayerMat) - { - CvInvoke.Erode(dst, dst, kernel, anchor, iterations, borderType, borderValue); - LayerMat = dst; - } - } - - public void MutateDilate(int iterations = 1, IInputArray kernel = null, Point anchor = default, BorderType borderType = BorderType.Default, MCvScalar borderValue = default) - { - if (anchor.IsEmpty) anchor = new Point(-1, -1); - if (ReferenceEquals(kernel, null)) - { - kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - } - using (Mat dst = LayerMat) - { - CvInvoke.Dilate(dst, dst, kernel, anchor, iterations, borderType, borderValue); - LayerMat = dst; - } - } - - public void MutateOpen(int iterations = 1, IInputArray kernel = null, Point anchor = default, BorderType borderType = BorderType.Default, MCvScalar borderValue = default) - { - if (anchor.IsEmpty) anchor = new Point(-1, -1); - if (ReferenceEquals(kernel, null)) - { - kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - } - using (Mat dst = LayerMat) - { - CvInvoke.MorphologyEx(dst, dst, MorphOp.Open, kernel, anchor, iterations, borderType, borderValue); - LayerMat = dst; - } - } - - public void MutateClose(int iterations = 1, IInputArray kernel = null, Point anchor = default, BorderType borderType = BorderType.Default, MCvScalar borderValue = default) - { - if (anchor.IsEmpty) anchor = new Point(-1, -1); - if (ReferenceEquals(kernel, null)) - { - kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); - } - using (Mat dst = LayerMat) - { - CvInvoke.MorphologyEx(dst, dst, MorphOp.Close, kernel, anchor, iterations, borderType, borderValue); - LayerMat = dst; - } - } - - public void MutateGradient(int iterations = 1, IInputArray kernel = null, Point anchor = default, BorderType borderType = BorderType.Default, MCvScalar borderValue = default) - { - if (anchor.IsEmpty) anchor = new Point(-1, -1); - if (ReferenceEquals(kernel, null)) - { - kernel = CvInvoke.GetStructuringElement(ElementShape.Cross, new Size(3, 3), anchor); - } - using (Mat dst = LayerMat) - { - CvInvoke.MorphologyEx(dst, dst, MorphOp.Gradient, kernel, anchor, iterations, borderType, borderValue); - LayerMat = dst; - } - } - - public void ThresholdPixels(OperationThreshold operation) - { - using (Mat dst = LayerMat) - { - Mat target = operation.GetRoiOrDefault(dst); - CvInvoke.Threshold(target, target, operation.Threshold, operation.Maximum, operation.Type); - LayerMat = dst; - } - } - - public void Blur(OperationBlur operation) - { - Size size = new Size((int) operation.Size, (int) operation.Size); - Point anchor = operation.Kernel.Anchor; - if (anchor.IsEmpty) anchor = new Point(-1, -1); - //if (size.IsEmpty) size = new Size(3, 3); - //if (anchor.IsEmpty) anchor = new Point(-1, -1); - using (Mat dst = LayerMat) - { - Mat target = operation.GetRoiOrDefault(dst); - switch (operation.BlurOperation) - { - case OperationBlur.BlurAlgorithm.Blur: - CvInvoke.Blur(target, target, size, operation.Kernel.Anchor); - break; - case OperationBlur.BlurAlgorithm.Pyramid: - CvInvoke.PyrDown(target, target); - CvInvoke.PyrUp(target, target); - break; - case OperationBlur.BlurAlgorithm.MedianBlur: - CvInvoke.MedianBlur(target, target, (int) operation.Size); - break; - case OperationBlur.BlurAlgorithm.GaussianBlur: - CvInvoke.GaussianBlur(target, target, size, 0); - break; - case OperationBlur.BlurAlgorithm.Filter2D: - CvInvoke.Filter2D(target, target, operation.Kernel.Matrix, anchor); - break; - default: - throw new ArgumentOutOfRangeException(); - } - - LayerMat = dst; - } - } - - public void ChangeResolution(OperationChangeResolution operation) - { - using (var mat = LayerMat) - { - //mat.Transform(1, 1, newResolutionX-mat.Width+roi.Width, newResolutionY-mat.Height - roi.Height/2, new Size((int) newResolutionX, (int) newResolutionY)); - using (var matRoi = new Mat(mat, operation.VolumeBonds)) - { - using (var matDst = new Mat(new Size((int)operation.NewResolutionX, (int)operation.NewResolutionY), mat.Depth, - mat.NumberOfChannels)) - { - using (var matDstRoi = new Mat(matDst, - new Rectangle((int) (operation.NewResolutionX / 2 - operation.VolumeBonds.Width / 2), - (int)operation.NewResolutionY / 2 - operation.VolumeBonds.Height / 2, - operation.VolumeBonds.Width, operation.VolumeBonds.Height))) - { - matRoi.CopyTo(matDstRoi); - LayerMat = matDst; - } - } - } - } - } - - public void Pattern(OperationPattern operation) - { - using (var layer = LayerMat) - using (var layerRoi = new Mat(layer, operation.ROI)) - using (var dstLayer = layer.CloneBlank()) - { - for (ushort col = 0; col < operation.Cols; col++) - for (ushort row = 0; row < operation.Rows; row++) - { - using (var dstRoi = new Mat(dstLayer, operation.GetRoi(col, row))) - { - layerRoi.CopyTo(dstRoi); - } - } - - LayerMat = dstLayer; - } - } public Layer Clone() { - return new Layer(_index, CompressedBytes.ToArray(), ParentLayerManager) + return new(_index, CompressedBytes.ToArray(), ParentLayerManager) { PositionZ = _positionZ, ExposureTime = _exposureTime, |