diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..a33f42807 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +src/RhinoInside.Revit.GH/Scripting/Refs/Rhino.Runtime.Code.dll filter=lfs diff=lfs merge=lfs -text diff --git a/src/RhinoInside.Revit.GH/Properties/AssemblyInfo.cs b/src/RhinoInside.Revit.GH/Properties/AssemblyInfo.cs index 9e07ea8cc..300558ca3 100755 --- a/src/RhinoInside.Revit.GH/Properties/AssemblyInfo.cs +++ b/src/RhinoInside.Revit.GH/Properties/AssemblyInfo.cs @@ -54,6 +54,8 @@ public override GH_LoadingInstruction PriorityLoad() var types = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsDefined(typeof(AssemblyPriorityAttribute), false)); foreach (var type in types) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle); + + Rhino.Runtime.Code.RhinoCode.Platforms.TryRegister(Scripting.RhinoInsideRevitPlatform.Instance); } catch { return GH_LoadingInstruction.Abort; } diff --git a/src/RhinoInside.Revit.GH/RhinoInside.Revit.GH.csproj b/src/RhinoInside.Revit.GH/RhinoInside.Revit.GH.csproj index 9bb82e99c..1692e65db 100644 --- a/src/RhinoInside.Revit.GH/RhinoInside.Revit.GH.csproj +++ b/src/RhinoInside.Revit.GH/RhinoInside.Revit.GH.csproj @@ -14,6 +14,10 @@ + + + + $(RevitAddinsPath)RhinoInside.Revit\R$(RhinoVersion)\ diff --git a/src/RhinoInside.Revit.GH/Scripting/Converters/ElementIdConverter.cs b/src/RhinoInside.Revit.GH/Scripting/Converters/ElementIdConverter.cs new file mode 100644 index 000000000..4e869ae87 --- /dev/null +++ b/src/RhinoInside.Revit.GH/Scripting/Converters/ElementIdConverter.cs @@ -0,0 +1,35 @@ +using System; + +using Rhino.Runtime.Code; +using Rhino.Runtime.Code.Execution; + +namespace RhinoInside.Revit.GH.Scripting.Converters +{ + public sealed class ElementIdConverter : ParamValueConverter + { + public static ParamConverterIdentity Identity { get; } + = new ParamConverterIdentity(new Guid("5716bd31-2735-4be5-88ac-bcc0304be776"), "ElementId", "mcneel.rhino3dinrevit.rhino"); + + public ElementIdConverter() + : base(Identity, new ParamType(typeof(Autodesk.Revit.DB.ElementId))) + { + Image = default; + Category = "Revit"; + Description = "Converts DB.Element to DB.ElementId"; + } + + public override bool Cast(ConvertDirection direction, object data, out object target) + { + target = default; + + if (ConvertDirection.Incoming == direction + && data is Autodesk.Revit.DB.Element element) + { + target = element.Id; + return true; + } + + return false; + } + } +} diff --git a/src/RhinoInside.Revit.GH/Scripting/Refs/Rhino.Runtime.Code.dll b/src/RhinoInside.Revit.GH/Scripting/Refs/Rhino.Runtime.Code.dll new file mode 100644 index 000000000..63d6f32ad --- /dev/null +++ b/src/RhinoInside.Revit.GH/Scripting/Refs/Rhino.Runtime.Code.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6484c7e62593d1044be43dc0fcad6a91bbc74138f61d7696d1d056699b8e7436 +size 372736 diff --git a/src/RhinoInside.Revit.GH/Scripting/RhinoInsideRevitPlatform.cs b/src/RhinoInside.Revit.GH/Scripting/RhinoInsideRevitPlatform.cs new file mode 100644 index 000000000..17b8db793 --- /dev/null +++ b/src/RhinoInside.Revit.GH/Scripting/RhinoInsideRevitPlatform.cs @@ -0,0 +1,161 @@ +#if RHINO_8 +using System; +using System.Linq; +using System.Collections.Generic; + +using Rhino; + +using Rhino.Runtime.Code; +using Rhino.Runtime.Code.Editing; +using Rhino.Runtime.Code.Environments; +using Rhino.Runtime.Code.Execution; +using Rhino.Runtime.Code.Execution.Debugging; +using Rhino.Runtime.Code.Platform; +using Rhino.Runtime.Code.Storage; + +namespace RhinoInside.Revit.GH.Scripting +{ + public sealed class RhinoInsideRevitPlatform : Platform + { + public static IPlatform Instance { get; } = new RhinoInsideRevitPlatform(); + + #region Converters + public static IParamValueConverter ElementIdConverter { get; } = new Converters.ElementIdConverter(); + #endregion + + #region Platform + public override PlatformIdentity Id { get; } = new PlatformIdentity( + name: "Rhino.Inside.Revit", + shortName: "RIR", + description: "Rhino.Inside.Revit platform", + domain: "rhino3dinrevit", + taxonomy: "mcneel.rhino3dinrevit.rhino", + RhinoApp.Version + ); + + public override IPlatformDocument ActiveDocument { get; } = default; + + public override IEnumerable References + { + get + { + yield return CompileReference.FromAssembly(typeof(Autodesk.Revit.DB.IExternalDBApplication).Assembly); + yield return CompileReference.FromAssembly(typeof(Autodesk.Revit.UI.IExternalApplication).Assembly); + yield return CompileReference.FromAssembly(typeof(Autodesk.Windows.IRibbonPopup).Assembly); + } + } + + public override IEnumerable ReferenceFilters + { + get + { + // TODO: + // return extension filters for platfrom plugin file exts + yield break; + } + } + + public override IEnumerable EditorLibraries + { + get + { + var revitVersion = new Version(Revit.ActiveDBApplication.SubVersionNumber); + var nugetSpec = new PackageSpec($"Autodesk.Revit.SDK.refs.{revitVersion.Major}"); + var nugetPackage = NuGetEnvirons.User.AddPackage(nugetSpec); + var refsDir = revitVersion.Major >= 2025 ? "ref/net8.0" : "ref/net48"; + foreach (string revitSDK in nugetPackage.GetFiles(refsDir) + .Where(l => l.EndsWith("RevitAPI.dll") || l.EndsWith("RevitAPIUI.dll"))) + { + AssemblyEditorLibrary revitSDKLib = default; + try + { + // TODO: + // implement url builder for https://www.revitapidocs.com/ maybe? + revitSDKLib = new AssemblyEditorLibrary(revitSDK); + } + catch (Exception ex) + { + RhinoCode.Logger.Warn($"Error generating docs for Autodesk.Revit {revitVersion.Major} libraries | {ex.Message}"); + } + + if (revitSDKLib is AssemblyEditorLibrary) + yield return revitSDKLib; + } + } + } + + public override IEnumerable Converters + { + get + { + // TODO: + // add more converters + yield return ElementIdConverter; + } + } + + public override IEnumerable GetCompileGuards(BuildKind buildKind) + { + const int FIRST_RHINOCODE_SUPPORTED_REVIT = 2018; + var revitVersion = new Version(Revit.ActiveDBApplication.SubVersionNumber); + + // this creates 'flexible' guards for major versions starting from Revit FIRST_RHINOCODE_SUPPORTED_REVIT + // Example: REVIT_2018_OR_GREATER, REVIT_2019_OR_GREATER + foreach (int nextMajor in Enumerable.Range(FIRST_RHINOCODE_SUPPORTED_REVIT, + revitVersion.Major + 1 - FIRST_RHINOCODE_SUPPORTED_REVIT)) + { + yield return new CompileGuard($"REVIT_{nextMajor}_OR_GREATER", true); + } + + // this creates 'specific' guards that are only available on this Revit version + // Example: REVIT_2025_1, REVIT_2025 + yield return new CompileGuard($"REVIT_{revitVersion.Major}_{revitVersion.Minor}", true); + yield return new CompileGuard($"REVIT_{revitVersion.Major}", true); + } + + public override IDebugControls CreateDebugControls() + { + // This is not used for now. + // ScriptEditor uses debug controls provided by Rhino3d platform + throw new NotImplementedException(); + } + + public override void Pause(PauseContext context) + { + // TODO: + // implement a way to pause/disable Revit UI + // this is called when editor debugger is pausing on a breakpoint + // and wants to deactivate the platform functions to disallow + // changing document state + } + + public override void Resume() + { + // TODO: + // unpause from paused/disabled state + } + + public override bool TryGetAssemblyPath(string name, out string path) + { + // TODO: + // not necessary at this point + + path = default; + return false; + } + + public override void Write(string text) + { + // TODO: + // not necessary at this point + } + + public override void WriteError(string text) + { + // TODO: + // not necessary at this point + } + #endregion + } +} +#endif