public List <IGCodeMove> Process(GCodeMountain mountain, GCodeConfiguration configuration)
        {
            var mountainSplitter = new MountainSplitter();


            var mountainSplitOptions = new MountainSplitOptions {
                HeightPerLayerInGCode = configuration.PreparationHeightMMPerLayer
            };
            var roughSplittedMountain = mountainSplitter.SplitMountainOnLevels(mountain, mountainSplitOptions);

            var moves          = new List <IGCodeMove>();
            var layerProcessor = new CubeLayerProcessor();
            var targetZ        = 0.0m;

            foreach (var layer in roughSplittedMountain.Layers)
            {
                targetZ += roughSplittedMountain.MountainSplitOptions.HeightPerLayerInGCode;
                moves.AddRange(layerProcessor.ProcessLayer(layer, configuration, targetZ));
            }
            return(moves);
        }
        public MountainSplittedOnLevels SplitMountainOnLevels(GCodeMountain mountain, MountainSplitOptions options)
        {
            var splittedMountain = new MountainSplittedOnLevels
            {
                OriginalMountain     = mountain,
                MountainSplitOptions = options
            };

            var maxHeight     = mountain.MaxHeight;
            var minHeight     = mountain.MinHeight;
            var currentHeight = maxHeight - options.HeightPerLayerInGCode * mountain.HeightPerGCode;

            while (currentHeight >= minHeight)
            {
                var xDimensionLength = mountain.Heights.GetLength(0);
                var yDimensionLength = mountain.Heights.GetLength(1);

                var layer = new Layer
                {
                    SplittedMountain = splittedMountain,
                    Points           = new MPoint[xDimensionLength, yDimensionLength]
                };

                for (int i = 0; i < xDimensionLength; i++)
                {
                    for (int j = 0; j < yDimensionLength; j++)
                    {
                        layer.Points[i, j] = new MPoint
                        {
                            Layer             = layer,
                            ShouldBeProcessed = mountain.Heights[i, j] < currentHeight,
                            ProcessedStatus   = ProcessedStatus.NotProcessed
                        };
                    }
                }
                splittedMountain.Layers.Add(layer);
                currentHeight -= options.HeightPerLayerInGCode * mountain.HeightPerGCode;
            }

            return(splittedMountain);
        }