Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabled UI plugins on the Player. #1255

Merged
merged 3 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading