private bool PartsAreInPrintVolume()
		{
			if (ActiveSliceSettings.Instance != null 
				&& !ActiveSliceSettings.Instance.CenterOnBed() 
				&& ActivePrinterProfile.Instance.ActivePrinter != null)
			{
				AxisAlignedBoundingBox allBounds = MeshViewerWidget.GetAxisAlignedBoundingBox(MeshGroups);
				bool onBed = allBounds.minXYZ.z > -.001 && allBounds.minXYZ.z < .001; // really close to the bed
				RectangleDouble bedRect = new RectangleDouble(0, 0, ActiveSliceSettings.Instance.BedSize.x, ActiveSliceSettings.Instance.BedSize.y);
				bedRect.Offset(ActiveSliceSettings.Instance.BedCenter - ActiveSliceSettings.Instance.BedSize / 2);

				bool inBounds = bedRect.Contains(new Vector2(allBounds.minXYZ)) && bedRect.Contains(new Vector2(allBounds.maxXYZ));

				return onBed && inBounds;
			}

			return true;
		}
		private bool PartsAreInPrintVolume()
		{
			if (ActiveSliceSettings.Instance?.GetValue<bool>(SettingsKey.center_part_on_bed) == false)
			{
				AxisAlignedBoundingBox allBounds = MeshViewerWidget.GetAxisAlignedBoundingBox(MeshGroups);
				bool onBed = allBounds.minXYZ.z > -.001 && allBounds.minXYZ.z < .001; // really close to the bed
				RectangleDouble bedRect = new RectangleDouble(0, 0, ActiveSliceSettings.Instance.GetValue<Vector2>(SettingsKey.bed_size).x, ActiveSliceSettings.Instance.GetValue<Vector2>(SettingsKey.bed_size).y);
				bedRect.Offset(ActiveSliceSettings.Instance.GetValue<Vector2>(SettingsKey.print_center) - ActiveSliceSettings.Instance.GetValue<Vector2>(SettingsKey.bed_size) / 2);

				bool inBounds = bedRect.Contains(new Vector2(allBounds.minXYZ)) && bedRect.Contains(new Vector2(allBounds.maxXYZ));

				return onBed && inBounds;
			}

			return true;
		}
        private double PrintTopOfPage(ImageBuffer plateInventoryImage, Graphics2D plateGraphics)
        {
            plateGraphics.Clear(RGBA_Bytes.White);

            double currentlyPrintingHeightPixels = plateInventoryImage.Height - PageMarginMM.Top * PixelPerMM;

            string logoPathAndFile = Path.Combine(ApplicationDataStorage.Instance.ApplicationStaticDataPath, "PartSheetLogo.png");
            if(File.Exists(logoPathAndFile))
            {
                ImageBuffer logoImage = new ImageBuffer();
                ImageIO.LoadImageData(logoPathAndFile, logoImage);
                currentlyPrintingHeightPixels -= logoImage.Height;
                plateGraphics.Render(logoImage, (plateInventoryImage.Width - logoImage.Width) / 2, currentlyPrintingHeightPixels);
            }

            currentlyPrintingHeightPixels -= PartPaddingPixels;

            double underlineHeightMM = 1;
            RectangleDouble lineBounds = new RectangleDouble(0, 0, plateInventoryImage.Width - PageMarginPixels.Left * 2, underlineHeightMM * PixelPerMM);
            lineBounds.Offset(PageMarginPixels.Left, currentlyPrintingHeightPixels - lineBounds.Height);
            plateGraphics.FillRectangle(lineBounds, RGBA_Bytes.Black);

            return currentlyPrintingHeightPixels - (lineBounds.Height + PartPaddingPixels);
        }
		private double PrintTopOfPage(ImageBuffer plateInventoryImage, Graphics2D plateGraphics)
		{
			plateGraphics.Clear(RGBA_Bytes.White);

			double currentlyPrintingHeightPixels = plateInventoryImage.Height - PageMarginMM.Top * PixelPerMM;

			// TODO: Application should not save data back to StaticDataPath - use application data dir instead
			string logoPathAndFile = "PartSheetLogo.png";
			if (StaticData.Instance.FileExists(logoPathAndFile))
			{
				ImageBuffer logoImage = StaticData.Instance.LoadImage(logoPathAndFile);
				currentlyPrintingHeightPixels -= logoImage.Height;
				plateGraphics.Render(logoImage, (plateInventoryImage.Width - logoImage.Width) / 2, currentlyPrintingHeightPixels);
			}

			currentlyPrintingHeightPixels -= PartPaddingPixels;

			double underlineHeightMM = 1;
			RectangleDouble lineBounds = new RectangleDouble(0, 0, plateInventoryImage.Width - PageMarginPixels.Left * 2, underlineHeightMM * PixelPerMM);
			lineBounds.Offset(PageMarginPixels.Left, currentlyPrintingHeightPixels - lineBounds.Height);
			plateGraphics.FillRectangle(lineBounds, RGBA_Bytes.Black);

			return currentlyPrintingHeightPixels - (lineBounds.Height + PartPaddingPixels);
		}