diff --git a/Rhinoceros_Engine/Compute/CaptureNamedViews.cs b/Rhinoceros_Engine/Compute/CaptureNamedViews.cs new file mode 100644 index 0000000..1debf2b --- /dev/null +++ b/Rhinoceros_Engine/Compute/CaptureNamedViews.cs @@ -0,0 +1,102 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base; +using BH.oM.Base.Attributes; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.IO; +using Rhino; +using Rhino.Display; +using System.Drawing; +using BH.oM.Rhinoceros.ViewCapture; +using System.Drawing.Imaging; + +namespace BH.Engine.Rhinoceros +{ + public static partial class Compute + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Captures all named views to files.")] + [Input("active", "Toggle to activate. Toggle to true to capture the view port.")] + [Input("folderPath", "Folder path to store the image in. To folder that the currently open rhino model is stored in will be used if nothing is provided.")] + [Input("imageName", "Name of the image, without file ending. THe name of the image will be this name + _viewName. To update the file ending, please see the viewcapture settings. If nothing is provided, the named view name will be the full filename.")] + [Input("namedViewFilter", "Optional filter of which named views that should be captured to file. All named views are captured if nothing is provided.")] + [Input("settings", "Settings to control the view capture.")] + [Output("success", "Returns true if the view capture was successful.")] + public static bool CaptureNamedViews(bool active = false, string folderPath = "", string imageName = "", List namedViewFilter = null, IViewCaptureSettings settings = null) + { + RhinoDoc doc; + try + { + doc = RhinoDoc.ActiveDoc; + } + catch (Exception e) + { + string msg = "Failed to get the active rhino document. Exception thrown: " + e.Message; + Base.Compute.RecordError(msg); + return false; + } + + if (doc == null) + return false; + + folderPath = ValidateFolderPath(folderPath, doc); + if (folderPath == null) + return false; + + if (!active) + return false; + + bool success = true; + + settings = settings ?? new ScaleViewCaptureSettings(); //Default view capture settings + + for (int i = 0; i < doc.NamedViews.Count; i++) + { + string namedView = doc.NamedViews[i].Name; + + if (namedViewFilter != null && namedViewFilter.Count != 0) //If named view filter provided + if (!namedViewFilter.Contains(namedView)) //Filter out items in the list. If no filter provided, assume all to be captured + continue; + + doc.NamedViews.Restore(i, doc.Views.ActiveView.ActiveViewport); + string name; + if (string.IsNullOrEmpty(imageName)) + name = namedView; + else + name = imageName + "_" + namedView; + success &= CaptureActiveView(doc, settings, folderPath, name); + + } + + return success; + } + + /***************************************************/ + } +} diff --git a/Rhinoceros_Engine/Compute/CaptureView.cs b/Rhinoceros_Engine/Compute/CaptureView.cs new file mode 100644 index 0000000..038ba97 --- /dev/null +++ b/Rhinoceros_Engine/Compute/CaptureView.cs @@ -0,0 +1,218 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Base; +using BH.oM.Base.Attributes; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.IO; +using Rhino; +using Rhino.Display; +using System.Drawing; +using BH.oM.Rhinoceros.ViewCapture; +using System.Drawing.Imaging; + +namespace BH.Engine.Rhinoceros +{ + public static partial class Compute + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Captures the currently active view to file.")] + [Input("active", "Toggle to activate. Toggle to true to capture the view port.")] + [Input("folderPath", "Folder path to store the image in. To folder that the currently open rhino model is stored in will be used if nothing is provided.")] + [Input("imageName", "Name of the image, without file ending. To update the file ending, please see the viewcapture settings. The viewport name will be used if nothing is provided.")] + [Input("settings", "Settings to control the view capture.")] + [Output("success", "Returns true if the view capture was successful.")] + public static bool CaptureView(bool active = false, string folderPath = "", string imageName = "", IViewCaptureSettings settings = null) + { + RhinoDoc doc; + try + { + doc = RhinoDoc.ActiveDoc; + } + catch (Exception e) + { + string msg = "Failed to get the active rhino document. Exception thrown: " + e.Message; + Base.Compute.RecordError(msg); + return false; + } + + if (doc == null) + return false; + + folderPath = ValidateFolderPath(folderPath, doc); + if (folderPath == null) + return false; + + if (!active) + return false; + + settings = settings ?? new ScaleViewCaptureSettings(); //Default view capture settings + + return CaptureActiveView(doc, settings, folderPath, imageName); + } + + + /***************************************************/ + /**** Private Methods ****/ + /***************************************************/ + + [Description("")] + [Input("", "")] + [Output("", "")] + private static bool CaptureActiveView(RhinoDoc doc, IViewCaptureSettings settings, string folderName, string imageName) + { + var view = doc.Views.ActiveView; + + if (string.IsNullOrWhiteSpace(imageName)) + { + Engine.Base.Compute.RecordNote("No image name provided. Name of active viewport will be used."); + imageName = view.ActiveViewport.Name; + } + + ViewCapture viewCapture = settings.IViewCapture(view.ActiveViewport); + + if (viewCapture == null) + return false; + + var bitmap = viewCapture.CaptureToBitmap(view); + + if (null != bitmap) + { + string fileEnding; + ImageFormat imageFormat = settings.GetImageFormat(out fileEnding); + if (imageFormat == null) + return false; + + var filename = Path.Combine(folderName, imageName + fileEnding); + bitmap.Save(filename, imageFormat); + return true; + } + + return false; + } + + /***************************************************/ + + private static string ValidateFolderPath(string folderPath, RhinoDoc doc) + { + if (string.IsNullOrEmpty(folderPath)) + { + folderPath = Path.GetDirectoryName(doc.Path); + Engine.Base.Compute.RecordNote($"No path provided. Images will be saved in the same folder as the Open rhino model."); + } + + if (!Directory.Exists(folderPath)) + { + Engine.Base.Compute.RecordError($"Directory {folderPath} does not exist."); + return null; + } + return folderPath; + } + + /***************************************************/ + + private static ImageFormat GetImageFormat(this IViewCaptureSettings settings, out string fileEnding) + { + string imageFormat = settings.FileFormat.ToUpper(); + + switch (imageFormat) + { + case "BMP": + fileEnding = ".bmp"; + return ImageFormat.Bmp; + case "EMF": + fileEnding = ".emf"; + return ImageFormat.Emf; + case "WMF": + fileEnding = ".wmf"; + return ImageFormat.Wmf; + case "GIF": + fileEnding = ".gif"; + return ImageFormat.Gif; + case "JPG": + case "JPEG": + fileEnding = ".jpg"; + return ImageFormat.Jpeg; + case "PNG": + fileEnding = ".png"; + return ImageFormat.Png; + case "TIFF": + fileEnding = ".tiff"; + return ImageFormat.Tiff; + case "EXIF": + fileEnding = ".exif"; + return ImageFormat.Exif; + case "ICON": + fileEnding = ".icon"; + return ImageFormat.Icon; + default: + Engine.Base.Compute.RecordError("Unknown image format."); + fileEnding = ""; + return null; + } + } + + /***************************************************/ + + private static ViewCapture IViewCapture(this IViewCaptureSettings settings, RhinoViewport viewport) + { + ViewCapture viewCapture = ViewCapture(settings as dynamic, viewport); + viewCapture.ScaleScreenItems = settings.ScaleScreenItems; + viewCapture.DrawAxes = settings.DrawAxes; + viewCapture.DrawGrid = settings.DrawGrid; + viewCapture.DrawGridAxes = settings.DrawGridAxes; + viewCapture.TransparentBackground = settings.TransparentBackground; + viewCapture.Preview = settings.Preview; + return viewCapture; + } + + /***************************************************/ + + private static ViewCapture ViewCapture(this ScaleViewCaptureSettings settings, RhinoViewport viewport) + { + return new ViewCapture + { + Height = (int)Math.Round(viewport.Size.Height * settings.Scale), + Width = (int)Math.Round(viewport.Size.Width * settings.Scale) + }; + } + + /***************************************************/ + + private static ViewCapture ViewCapture(this DimensionViewCaptureSettings settings, RhinoViewport viewport) + { + return new ViewCapture + { + Height = settings.Height, + Width = settings.Width + }; + } + + /***************************************************/ + } +} diff --git a/Rhinoceros_Engine/Rhinoceros_Engine.csproj b/Rhinoceros_Engine/Rhinoceros_Engine.csproj index c1ef0cd..61d0687 100644 --- a/Rhinoceros_Engine/Rhinoceros_Engine.csproj +++ b/Rhinoceros_Engine/Rhinoceros_Engine.csproj @@ -47,6 +47,9 @@ C:\ProgramData\BHoM\Assemblies\Dimensional_oM.dll False + + ..\packages\RhinoCommon.6.33.20343.16431\lib\net45\Eto.dll + C:\ProgramData\BHoM\Assemblies\Geometry_Engine.dll False @@ -62,9 +65,11 @@ C:\ProgramData\BHoM\Assemblies\Graphics_oM.dll False - - ..\packages\RhinoCommon.5.12.50810.13095\lib\net35\RhinoCommon.dll - True + + ..\packages\RhinoCommon.6.33.20343.16431\lib\net45\Rhino.UI.dll + + + ..\packages\RhinoCommon.6.33.20343.16431\lib\net45\RhinoCommon.dll @@ -77,6 +82,8 @@ + + @@ -108,17 +115,23 @@ + + + {5c0492bc-0ff4-45c9-963c-2514add35263} + Rhinoceros_oM + + - + + xcopy "$(TargetDir)$(TargetFileName)" "C:\\ProgramData\\BHoM\\Assemblies" /Y + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - - xcopy "$(TargetDir)$(TargetFileName)" "C:\\ProgramData\\BHoM\\Assemblies" /Y - + \ No newline at end of file diff --git a/Rhinoceros_oM/ViewCapture/DimensionViewCaptureSettings.cs b/Rhinoceros_oM/ViewCapture/DimensionViewCaptureSettings.cs new file mode 100644 index 0000000..5282e2a --- /dev/null +++ b/Rhinoceros_oM/ViewCapture/DimensionViewCaptureSettings.cs @@ -0,0 +1,69 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BH.oM.Base; +using System.ComponentModel; + +namespace BH.oM.Rhinoceros.ViewCapture +{ + [Description("View capture settings class with control over the final size of the image in pixels.")] + public class DimensionViewCaptureSettings : IViewCaptureSettings + { + /***************************************************/ + /**** Properties ****/ + /***************************************************/ + + [Description("Width (in pixels) of the final image.")] + public virtual int Width { get; set; } + + [Description("Height (in pixels) of the final image.")] + public virtual int Height { get; set; } + + [Description("File format to be used. Defaults to png.")] + public virtual string FileFormat { get; set; } = "png"; + + [Description("")] + public virtual bool ScaleScreenItems { get; set; } + + [Description("Controls if the world axes should be captured or not.")] + public virtual bool DrawAxes { get; set; } + + [Description("Controls if the grid should be captured or not.")] + public virtual bool DrawGrid { get; set; } + + [Description("Controls if the grid axes should be captured or not.")] + public virtual bool DrawGridAxes { get; set; } + + [Description("Controls if the background should be transparent.")] + public virtual bool TransparentBackground { get; set; } + + [Description("")] + public virtual bool Preview { get; set; } + + /***************************************************/ + } +} diff --git a/Rhinoceros_oM/ViewCapture/IViewCaptureSettings.cs b/Rhinoceros_oM/ViewCapture/IViewCaptureSettings.cs new file mode 100644 index 0000000..4b5e28d --- /dev/null +++ b/Rhinoceros_oM/ViewCapture/IViewCaptureSettings.cs @@ -0,0 +1,64 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BH.oM.Base; +using System.ComponentModel; + +namespace BH.oM.Rhinoceros.ViewCapture +{ + [Description("Base itnerface for interface controling settings for view capture.")] + public interface IViewCaptureSettings : IObject + { + /***************************************************/ + /**** Properties ****/ + /***************************************************/ + + [Description("File format to be used.")] + string FileFormat { get; set; } + + [Description("")] + bool ScaleScreenItems { get; set; } + + [Description("Controls if the world axes should be captured or not.")] + bool DrawAxes { get; set; } + + [Description("Controls if the grid should be captured or not.")] + bool DrawGrid { get; set; } + + [Description("Controls if the grid axes should be captured or not.")] + bool DrawGridAxes { get; set; } + + [Description("Controls if the background should be transparent.")] + bool TransparentBackground { get; set; } + + [Description("")] + bool Preview { get; set; } + + /***************************************************/ + + } +} diff --git a/Rhinoceros_oM/ViewCapture/ScaleViewCaptureSettings.cs b/Rhinoceros_oM/ViewCapture/ScaleViewCaptureSettings.cs new file mode 100644 index 0000000..d007c6a --- /dev/null +++ b/Rhinoceros_oM/ViewCapture/ScaleViewCaptureSettings.cs @@ -0,0 +1,67 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BH.oM.Base; +using System.ComponentModel; + +namespace BH.oM.Rhinoceros.ViewCapture +{ + [Description("View capture settings allowing the size of the image to be controled as a scale of the current viewport size.")] + public class ScaleViewCaptureSettings : IViewCaptureSettings + { + + /***************************************************/ + /**** Properties ****/ + /***************************************************/ + + [Description("Scale factor of the current preview. A factor of 2 gives a resolution twice to the current viewport resolution.")] + public virtual double Scale { get; set; } = 2.0; + + [Description("File format to be used. Defaults to png.")] + public virtual string FileFormat { get; set; } = "png"; + + [Description("")] + public virtual bool ScaleScreenItems { get; set; } + + [Description("Controls if the world axes should be captured or not.")] + public virtual bool DrawAxes { get; set; } + + [Description("Controls if the grid should be captured or not.")] + public virtual bool DrawGrid { get; set; } + + [Description("Controls if the grid axes should be captured or not.")] + public virtual bool DrawGridAxes { get; set; } + + [Description("Controls if the background should be transparent.")] + public virtual bool TransparentBackground { get; set; } + + [Description("")] + public virtual bool Preview { get; set; } + + /***************************************************/ + } +}