private decimal GetCurrentZ(GCodeMountain mountain, int x, int y, SpinOptions freeze) { var numberOfPointsPerX = mountain.Heights.GetLength(0); var numberOfPointsPerY = mountain.Heights.GetLength(1); var maxHeight = mountain.Heights[x, y]; var xPointsOfInterestCount = (int)(freeze.SpinSize * numberOfPointsPerX / mountain.MountainWidthInGCode); var yPointsOfInterestCount = (int)(freeze.SpinSize * numberOfPointsPerY / mountain.MountainLengthInGCode); for (int i = 0; i <= xPointsOfInterestCount; i++) { for (int j = 0; j <= yPointsOfInterestCount; j++) { var xCoord = x + i - xPointsOfInterestCount / 2; var yCoord = y + j - yPointsOfInterestCount / 2; if (xCoord >= 0 && xCoord < numberOfPointsPerX && yCoord >= 0 && yCoord < numberOfPointsPerY) { maxHeight = Math.Max(maxHeight, mountain.Heights[xCoord, yCoord]); } } } return(mountain.MountainHeightInGCode * (1 - (maxHeight - mountain.MinHeight) / (mountain.MaxHeight - mountain.MinHeight))); }
private List <IGCodeMove> ProcessCubes(List <Cube> cubes, Layer layer, SpinOptions freeze, decimal targetZ, GCodeConfiguration config) { var commands = new List <IGCodeMove>(); foreach (var cube in cubes) { commands.AddRange(GetCommandsForCube(cube, layer, freeze, targetZ, config)); SetLayerPointsAsProcessed(layer, cube, config); } return(commands); }
public List <IGCodeMove> ProcessClean(GCodeMountain mountain, GCodeConfiguration configuration) { var spin = new SpinOptions { SpinSize = configuration.CleanSpinSizeMM }; var moves = Process( mountain, configuration, 0, configuration.XIncrementClean, configuration.YIncrementClean, spin); return(moves); }
public List <IGCodeMove> ProcessDirty(GCodeMountain mountain, GCodeConfiguration configuration) { var moves = new List <IGCodeMove>(); var spin = new SpinOptions { SpinSize = configuration.DirtySpinSizeMM }; var r1Moves = Process(mountain, configuration, configuration.DirtyR1OffsetHeightMM, configuration.XIncrementDirty, configuration.YIncrementDirty, spin); var r2Moves = Process(mountain, configuration, configuration.DirtyR2OffsetHeightMM, configuration.XIncrementDirty, configuration.YIncrementDirty, spin); var r3Moves = Process(mountain, configuration, configuration.DirtyR3OffsetHeightMM, configuration.XIncrementDirty, configuration.YIncrementDirty, spin); moves.AddRange(r1Moves); moves.AddRange(r2Moves); moves.AddRange(r3Moves); return(moves); }
public List <IGCodeMove> ProcessLayer(Layer layer, GCodeConfiguration config, decimal targetZ) { var freeze = new SpinOptions { SpinSize = config.PreparationSpinSizeMM }; var commandList = new List <IGCodeMove>(); var width = layer.Points.GetLength(0); var length = layer.Points.GetLength(1); do { width = width / 2; length = length / 2; var cubes = GetCubesToProcess(layer, width, length, config); commandList.AddRange(ProcessCubes(cubes, layer, freeze, targetZ, config)); }while (width >= config.MinWidth && length >= config.MinLength); return(commandList); }
private List <IGCodeMove> Process(GCodeMountain mountain, GCodeConfiguration config, decimal zOffset, int xIncrement, int yIncrement, SpinOptions spin) { var moves = new List <IGCodeMove>(); // go to zero point var currentZ = 0.0m; var x = 0; var y = 0; var previousZ = 0.0m; var fromTopToBottom = true; var numberOfPointsPerX = mountain.Heights.GetLength(0); var numberOfPointsPerY = mountain.Heights.GetLength(1); moves.Add(new GCodeChangeZ { Z = 0 }); while (x < numberOfPointsPerX) { if (WithinRadius(mountain, x, y)) { previousZ = currentZ; currentZ = Math.Round(GetCurrentZ(mountain, x, y, spin), 2); currentZ = currentZ + zOffset; currentZ = Math.Max(config.ZMin, currentZ); currentZ = Math.Min(config.ZMax, currentZ); var xGCode = mountain.MountainWidthInGCode * x / numberOfPointsPerX; var yGCode = mountain.MountainLengthInGCode * y / numberOfPointsPerY; if (currentZ > previousZ) { moves.Add(new GCodeLine { X = xGCode, Y = yGCode }); moves.Add(new GCodeChangeZ { Z = currentZ }); } else { moves.Add(new GCodeChangeZ { Z = currentZ }); moves.Add(new GCodeLine { X = xGCode, Y = yGCode }); } } y += fromTopToBottom ? yIncrement : -yIncrement; if (y < 0) { fromTopToBottom = true; y = 0; x += xIncrement; } else if (y >= numberOfPointsPerY) { fromTopToBottom = false; y = numberOfPointsPerY - 1; x += xIncrement; } } return(moves); }
public List <IGCodeMove> ProcessLayer(Layer layer, SpinOptions freezeOptions, decimal currentZ) { var commandList = new List <IGCodeMove>(); var numberOfRowsToProcess = layer.Points.GetLength(0) - freezeOptions.SpinSize + 1; var numberOfColsToProcess = layer.Points.GetLength(1) - freezeOptions.SpinSize + 1; var freezePoints = new MPoint[numberOfRowsToProcess, numberOfColsToProcess]; for (int r = 0; r < numberOfRowsToProcess; r++) { for (int c = 0; c < numberOfColsToProcess; c++) { var freezeRegion = new MPoint[freezeOptions.SpinSize, freezeOptions.SpinSize]; for (int freezeRegionRow = 0; freezeRegionRow < freezeOptions.SpinSize; freezeRegionRow++) { for (int freezeRegionCol = 0; freezeRegionCol < freezeOptions.SpinSize; freezeRegionCol++) { freezeRegion[freezeRegionRow, freezeRegionCol] = layer.Points[r + freezeRegionRow, c + freezeRegionCol]; } } freezePoints[r, c] = new MPoint { ShouldBeProcessed = !freezeRegion.Cast <MPoint>().Any(i => !i.ShouldBeProcessed) // maybe some other algorithm will be used soon }; } } for (int fr = 0; fr < numberOfRowsToProcess; fr++) { var currentRow = fr + freezeOptions.SpinSize / 2.0m; // move to freeze zero point commandList.Add(new GCodeChangeZ { Z = 0 }); var inverse = (fr % 2) == 1; var currentFirstColumn = !inverse ? 0 : numberOfColsToProcess - 1; var currentLastColumn = !inverse ? numberOfColsToProcess - 1 : 0; if (freezePoints[fr, currentFirstColumn].ShouldBeProcessed) { commandList.Add(new GCodeMove { X = currentRow, Y = currentFirstColumn + freezeOptions.SpinSize / 2.0m }); commandList.Add(new GCodeChangeZ { Z = currentZ }); } for (int fc = 1; fc < numberOfColsToProcess; fc++) { var currentColumn = !inverse ? fc : numberOfColsToProcess - 1 - fc; var previousColumn = !inverse ? currentColumn - 1 : currentColumn + 1; var shouldPreviousPointBeProcessed = freezePoints[fr, previousColumn].ShouldBeProcessed; var shouldCurrentPointBeProcessed = freezePoints[fr, currentColumn].ShouldBeProcessed; if (shouldCurrentPointBeProcessed != shouldPreviousPointBeProcessed) { if (shouldPreviousPointBeProcessed) { commandList.Add(new GCodeLine { X = currentRow, Y = previousColumn + freezeOptions.SpinSize / 2.0m }); commandList.Add(new GCodeChangeZ { Z = 0 }); } else { commandList.Add(new GCodeMove { X = currentRow, Y = currentColumn + freezeOptions.SpinSize / 2.0m }); commandList.Add(new GCodeChangeZ { Z = currentZ }); } } } if (freezePoints[fr, currentLastColumn].ShouldBeProcessed) { commandList.Add(new GCodeLine { X = currentRow, Y = currentLastColumn + freezeOptions.SpinSize / 2.0m }); } } return(commandList); }
private List <IGCodeMove> GetCommandsForCube(Cube cube, Layer layer, SpinOptions freeze, decimal targetZ, GCodeConfiguration config) { var commands = new List <IGCodeMove>(); var mmBetweenPointsForX = config.FormSizeMMWidth / layer.Points.GetLength(0); var mmBetweenPointsForY = config.FormSizeMMLength / layer.Points.GetLength(1); var minX = cube.X * mmBetweenPointsForX + freeze.SpinSize / 2; var minY = cube.Y * mmBetweenPointsForY + freeze.SpinSize / 2; var maxX = (cube.X + cube.Width) * mmBetweenPointsForX - freeze.SpinSize / 2; var maxY = (cube.Y + cube.Length) * mmBetweenPointsForY - freeze.SpinSize / 2; var currentX = minX; var currentY = minY; var currentZ = targetZ - layer.SplittedMountain.MountainSplitOptions.HeightPerLayerInGCode; var xDirection = 1; var fromTopToBottom = true; var stepZ = config.PreparationHeightMMPerLayer; commands.Add(new GCodeChangeZ { Z = 0 }); commands.Add(new GCodeMove { X = minX, Y = minY }); do { currentZ = Math.Min(currentZ + stepZ, targetZ); commands.Add(new GCodeChangeZ { Z = currentZ }); while (true) { currentY = fromTopToBottom ? maxY : minY; commands.Add(new GCodeLine { X = currentX, Y = currentY }); fromTopToBottom = !fromTopToBottom; if ((currentX == maxX && xDirection > 0) || (currentX == minX && xDirection < 0)) { break; } currentX += xDirection * freeze.SpinSize / 2; if (currentX > maxX) { currentX = maxX; } if (currentX < minX) { currentX = minX; } commands.Add(new GCodeLine { X = currentX, Y = currentY }); } xDirection *= -1; }while (currentZ != targetZ); return(commands); }