Skip to content

Commit

Permalink
Merge pull request #1255 from mcneel/kike/1.x
Browse files Browse the repository at this point in the history
Enabled UI plugins on the Player.
  • Loading branch information
kike-garbo authored Dec 18, 2024
2 parents b2a1d5f + 9dbb7cd commit 1b8f3b2
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms.Interop;
using System.Windows.Input;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using GH_IO.Serialization;
using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Grasshopper.Kernel.Types;
using Grasshopper.Plugin;
using Microsoft.Win32.SafeHandles;
using Rhino;

namespace RhinoInside.Revit.AddIn.Commands
{
Expand Down Expand Up @@ -95,6 +97,7 @@ public static Result ReadFromFile(string filePath, out GH_Document definition)
}
}

#region Prompt
internal static IList<IGH_Param> GetInputParams(GH_Document definition)
{
var inputs = new List<IGH_Param>();
Expand Down Expand Up @@ -342,6 +345,7 @@ internal static IEnumerable<IGH_Goo> PromptBrep(UIDocument doc, string prompt)

return null;
}
#endregion

public override Result Execute(ExternalCommandData data, ref string message, ElementSet elements)
{
Expand All @@ -354,6 +358,82 @@ public override Result Execute(ExternalCommandData data, ref string message, Ele
return result;
}

private struct RunInCommandContextGuard : IDisposable
{
public readonly GH_Document Document;
private readonly bool DocumentWasModified;
private readonly bool DocumentWasEnabled;
private readonly bool SolverWasEnabled;

private readonly RhinoDoc RhinoDocument;
private readonly uint UndoRecord;

public RunInCommandContextGuard(GH_Document document)
{
Document = document;
RhinoDocument = document.RhinoDocument();
DocumentWasModified = document.IsModified;
DocumentWasEnabled = document.Enabled;
SolverWasEnabled = GH_Document.EnableSolutions;

GH_Document.EnableSolutions = true;
document.Enabled = true;

var urName = File.Exists(document.FilePath) ? Path.GetFileNameWithoutExtension(document.FilePath).Replace("-", " ") : "unnamed";
UndoRecord = RhinoDocument?.BeginUndoRecord(urName) ?? 0;
}

void IDisposable.Dispose()
{
RhinoDocument?.EndUndoRecord(UndoRecord);

Document.IsModified = DocumentWasModified;
Document.Enabled = DocumentWasEnabled;
GH_Document.EnableSolutions = SolverWasEnabled;
}
}

internal static Result Execute
(
UIApplication app,
View view,
IDictionary<string, string> journalData,
GH_Document definition,
ref string message
)
{
if (definition is null) return Result.Failed;
if (definition.RhinoDocument() is RhinoDoc rhinoDocument && rhinoDocument != RhinoDoc.ActiveDoc) return Result.Failed;

try
{
using (new RunInCommandContextGuard(definition))
{
using (var transGroup = new TransactionGroup(app.ActiveUIDocument.Document))
{
transGroup.Start(Path.GetFileNameWithoutExtension(definition.Properties.ProjectFileName));

definition.NewSolution(expireAllObjects: true);

if (definition.SolutionState == GH_ProcessStep.Aborted)
{
message = $"Solution aborted by user after ~{definition.SolutionSpan.TotalSeconds} seconds";
return Result.Cancelled;
}

transGroup.Assimilate();
}
}
}
catch (Exception e)
{
message = e.Message;
return Result.Failed;
}

return Result.Succeeded;
}

public static Result Execute
(
UIApplication app,
Expand All @@ -367,74 +447,164 @@ ref string message
{
// Load Grasshopper window in case the user has not did it before.
// This enables definitions that relay on Grasshopper window like those that show UI.
GH.Guest.LoadEditor();
var script = new GH_RhinoScriptInterface();
script.DisableBanner();
script.LoadEditor();

var result = ReadFromFile(filePath, out var definition);
if (result == Result.Succeeded)
{
using (definition)
{
bool enableSolutions = GH_Document.EnableSolutions;
var currentCulture = Thread.CurrentThread.CurrentCulture;
try
{
using (var transGroup = new TransactionGroup(app.ActiveUIDocument.Document))
{
transGroup.Start(Path.GetFileNameWithoutExtension(definition.Properties.ProjectFileName));
var remotePanelVisible = Instances.IsRemotePanelVisible;
var editorWasEnabled = Instances.ActiveCanvas.ModifiersEnabled;
var editorWasVisible = Instances.DocumentEditor.Visible;

GH_Document.EnableSolutions = true;
definition.Enabled = true;
definition.ExpireSolution();
if (editorWasVisible)
{
Instances.DocumentEditor.FadeOut();
}
if (editorWasEnabled) Instances.DocumentEditor.DisableUI();

var inputs = GetInputParams(definition);
result = PromptForInputs(app.ActiveUIDocument, inputs, out var values);
if (result != Result.Succeeded)
return (result, default);
var index = Instances.DocumentServer.IndexOf(filePath);
var wasOpen = index >= 0;
var document = default(GH_Document);
{
if (wasOpen)
{
document = Instances.DocumentServer[index];
document.ExpireSolution();
}
else
{
var io = new GH_DocumentIO();
if (!io.Open(filePath)) return (Result.Failed, default);
document = io.Document;

// Update input volatile data values
foreach (var value in values)
value.Key.AddVolatileDataList(new Grasshopper.Kernel.Data.GH_Path(0), value.Value);
Instances.DocumentServer.AddDocument(document);
}
}

Grasshopper.Instances.EnforceInvariantCulture();
using (var modal = new ModalScope())
{
definition.NewSolution(false, GH_SolutionMode.Silent);
// Synchronize units.
GH.Guest.AuditUnits(view.Document);

do
{
if (modal.Run(false, false) == Result.Failed)
return (Result.Failed, default);
// Activate the document without computing it
if (Instances.ActiveCanvas.Document != document)
{
var enableSolutions = GH_Document.EnableSolutions;
try
{
GH_Document.EnableSolutions = false;
Instances.ActiveCanvas.Document = document;
document.Enabled = false;
if (!wasOpen) document.IsModified = false;
}
finally
{
GH_Document.EnableSolutions = enableSolutions;
document.Enabled = true;
}
}

} while (definition.ScheduleDelay >= GH_Document.ScheduleRecursive);
}
Thread.CurrentThread.CurrentCulture = currentCulture;
if (document.RemotePanelLayout.Count > 0) Instances.ShowRemotePanel();

if (definition.SolutionState == GH_ProcessStep.Aborted)
{
return (Result.Cancelled, $"Solution aborted by user after ~{ definition.SolutionSpan.TotalSeconds} seconds");
}
var m = default(string);
var result = Execute(app, view, journalData, document, ref m);
if (!document.KeepOpen() || result != Result.Succeeded)
{
if (!remotePanelVisible) Instances.HideRemotePanel();
if (!wasOpen) Instances.DocumentServer.RemoveDocument(document);
}

transGroup.Assimilate();
}
}
catch (Exception e)
{
return (Result.Failed, e.Message);
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
GH_Document.EnableSolutions = enableSolutions;
}
}
if (editorWasEnabled) Instances.DocumentEditor.EnableUI();
if (editorWasVisible)
{
Instances.DocumentEditor.FadeIn();
}

return (result, default);
}, default);
return (result, m);
});

message = msg;
return res;
}

//public static Result Execute
//(
// UIApplication app,
// View view,
// IDictionary<string, string> journalData,
// string filePath,
// ref string message
//)
//{
// var (res, msg) = External.ActivationGate.Open(() =>
// {
// // Load Grasshopper window in case the user has not did it before.
// // This enables definitions that relay on Grasshopper window like those that show UI.
// GH.Guest.LoadEditor();

// var result = ReadFromFile(filePath, out var definition);
// if (result == Result.Succeeded)
// {
// using (definition)
// {
// bool enableSolutions = GH_Document.EnableSolutions;
// var currentCulture = Thread.CurrentThread.CurrentCulture;
// try
// {
// using (var transGroup = new TransactionGroup(app.ActiveUIDocument.Document))
// {
// transGroup.Start(Path.GetFileNameWithoutExtension(definition.Properties.ProjectFileName));

// GH_Document.EnableSolutions = true;
// definition.Enabled = true;
// definition.ExpireSolution();

// var inputs = GetInputParams(definition);
// result = PromptForInputs(app.ActiveUIDocument, inputs, out var values);
// if (result != Result.Succeeded)
// return (result, default);

// // Update input volatile data values
// foreach (var value in values)
// value.Key.AddVolatileDataList(new Grasshopper.Kernel.Data.GH_Path(0), value.Value);

// Grasshopper.Instances.EnforceInvariantCulture();
// using (var modal = new ModalScope())
// {
// definition.NewSolution(false, GH_SolutionMode.Silent);

// do
// {
// if (modal.Run(false, false) == Result.Failed)
// return (Result.Failed, default);

// } while (definition.ScheduleDelay >= GH_Document.ScheduleRecursive);
// }
// Thread.CurrentThread.CurrentCulture = currentCulture;

// if (definition.SolutionState == GH_ProcessStep.Aborted)
// {
// return (Result.Cancelled, $"Solution aborted by user after ~{ definition.SolutionSpan.TotalSeconds} seconds");
// }

// transGroup.Assimilate();
// }
// }
// catch (Exception e)
// {
// return (Result.Failed, e.Message);
// }
// finally
// {
// Thread.CurrentThread.CurrentCulture = currentCulture;
// GH_Document.EnableSolutions = enableSolutions;
// }
// }
// }

// return (result, default);
// }, default);

// message = msg;
// return res;
//}
}

/// <summary>
Expand Down
25 changes: 25 additions & 0 deletions src/RhinoInside.Revit.External/Extensions/Grasshopper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Grasshopper.Kernel;

namespace Grasshopper
{
internal static class GH_DocumentExtension
{
public static bool KeepOpen(this GH_Document document)
{
#if RHINO_8
return document.Properties.KeepOpen;
#else
return false;
#endif
}

public static Rhino.RhinoDoc RhinoDocument(this GH_Document document)
{
#if RHINO_8
return document.RhinoDocument;
#else
return Rhino.RhinoDoc.ActiveDoc;
#endif
}
}
}
4 changes: 2 additions & 2 deletions src/RhinoInside.Revit.External/Extensions/System.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace System
{
static class EnumExtensions
static class EnumExtension
{
public static T WithFlag<T>(this T @enum, T flag, bool value) where T : struct, Enum
{
Expand Down Expand Up @@ -190,7 +190,7 @@ internal static string Unescape(this string value, params char[] allowed)
#endregion
}

static class EventHandlerExtenion
static class EventHandlerExtension
{
#region Events
/// <summary>
Expand Down
Loading

0 comments on commit 1b8f3b2

Please sign in to comment.