I have a component that is designed to allow users to set a custom DisplayModeOverride on an object by object basis. It works – sort of. The thing that is making it harder for me to track down: it ALWAYS works when I am debugging a live session in Visual Studio. But in the wild, it occasionally just plain fails. Stops working entirely.
I have some code in here that is creating a registry for already set DisplayModeOverride (since I haven’t found a method that returns an objects existing override so I can do a name check) – but I had the same problems before I implemented the registry. When the component “stops working”, I get no errors, I get a “true” result from my status output, but I get no overrides. I can add them manually in Rhino but GH won’t do it for me.
Any thoughts? Code follows:
public ObjectTools_SetObjectDisplayMode()
: base("Set Object DisplayMode", "SetDisplay",
"Override the displayMode of individual objects. Useful for allowing control objects to be in Wireframe mode within shaded viewports.",
"Squirrel", "Object Tools")
{
}
/// <summary>
/// Registers all the input parameters for this component.
/// </summary>
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
pManager.AddGeometryParameter("Object", "O", "Object to fetch.", GH_ParamAccess.item);
pManager.AddTextParameter("DisplayMode", "D", "DisplayMode to assign to the object.", GH_ParamAccess.item);
pManager.AddTextParameter("Viewports", "V", "Viewport contraints for the DisplayMode (optional).", GH_ParamAccess.list);
pManager[1].Optional = true;
pManager[2].Optional = true;
}
/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
pManager.AddBooleanParameter("Status", "St", "Boolean value that indicates whether the object's DisplayMode was successfully set.", GH_ParamAccess.item);
}
bool result = false;
Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;
protected override void AfterSolveInstance()
{
if (result) doc.Views.Redraw(); // redraw viewports if we made any changes
}
// Set up a mode registry to prevent modifying objects with the same displayMode over and over (to prevent infinite loops)
public Dictionary<string, string> modeRegistry = new Dictionary<string, string>();
/// <summary>
/// This is the method that actually does the work.
/// </summary>
/// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
protected override void SolveInstance(IGH_DataAccess DA)
{
Grasshopper.Kernel.Types.IGH_GeometricGoo geo = null;
GeometryBase geoBase = null;
String dMode = "";
List<String> viewports = new List<string>();
Guid id;
if (!DA.GetData(0, ref geo)) return;
if (!DA.GetData(0, ref geoBase)) return;
DA.GetData(1, ref dMode);
DA.GetDataList<string>(2, viewports);
if (geo.IsReferencedGeometry)
{
id = geo.ReferenceID;
RhinoObject rObj = doc.Objects.Find(id);
if (rObj == null)
{
} else
{
Rhino.Display.DisplayModeDescription dmDesc = null;
if (dMode != "")
{
dmDesc = Rhino.Display.DisplayModeDescription.FindByName(dMode);
if (dmDesc == null)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, String.Format("{0} DisplayMode not found.", dMode));
return;
}
}
{
if (viewports.Count == 0)
{
ObjectAttributes attr = rObj.Attributes;
string modeKey = id.ToString() + "_" + "General";
if (dmDesc == null)
{
attr.RemoveDisplayModeOverride();
} else
{
if (!(modeRegistry.ContainsKey(modeKey) && modeRegistry[modeKey] == dmDesc.EnglishName))
{
attr.SetDisplayModeOverride(dmDesc);
result = doc.Objects.ModifyAttributes(rObj, attr, false);
rObj.CommitChanges();
if (modeRegistry.ContainsKey(modeKey))
{
modeRegistry[modeKey] = dmDesc.EnglishName;
} else
{
modeRegistry.Add(modeKey, dmDesc.EnglishName);
}
}
}
} else
{
//List<Rhino.Display.RhinoView> vps = doc.Views.GetViewList(true, true);
//Rhino.Display.RhinoView[] vps = doc.Views.GetViewList(true, true);
//vps[0].
var selected_views = doc.Views
.Where(v => viewports.Contains(v.ActiveViewport.Name))
.ToList();
foreach (Rhino.Display.RhinoView view in selected_views)
{
Guid viewportId = view.ActiveViewportID;
string viewStringId = view.ActiveViewportID.ToString();
ObjectAttributes attr = rObj.Attributes;
string modeKey = id.ToString() + "_" + viewportId.ToString();
if (attr.HasDisplayModeOverride(viewportId))
{
attr.RemoveDisplayModeOverride(viewportId); // remove any existing overrides on this viewport
}
if (dmDesc != null)
{
if (!(modeRegistry.ContainsKey(modeKey) && modeRegistry[modeKey] == dmDesc.EnglishName))
{
attr.SetDisplayModeOverride(dmDesc, viewportId);
bool success = false;
success = doc.Objects.ModifyAttributes(rObj, attr, false);
rObj.CommitChanges();
if (success) result = true;
if (modeRegistry.ContainsKey(modeKey))
{
modeRegistry[modeKey] = dmDesc.EnglishName;
}
else
{
modeRegistry.Add(modeKey, dmDesc.EnglishName);
}
}
}
}
}
}
}
} else
{
}
DA.SetData(0, result);
}