Hi,
Overview
I want to give some feedback to the user on the path of the texture referenced in the PBR material. For this, I decided to use RenderContent events.
Rhino 7 SR30 2023-6-12
Plugin
using System;
using System.IO;
using System.Text;
using System.Windows;
using Rhino;
using Rhino.PlugIns;
using Hero.Handlers;
namespace Hero
{
public class HeroPlugIn : PlugIn
{
public override PlugInLoadTime LoadTime => PlugInLoadTime.AtStartup;
public HeroPlugIn()
{
Instance = this;
}
public static HeroPlugIn Instance { get; private set; }
protected override LoadReturnCode OnLoad(ref string errorMessage)
{
MaterialHandler.Start();
TextureHandler.Start();
return LoadReturnCode.Success;
}
protected override void OnShutdown()
{
MaterialHandler.Stop();
TextureHandler.Stop();
}
}
}
Material Handler
using Rhino;
using Rhino.Render;
using Rhino.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hero.Handlers
{
public class MaterialHandler
{
public MaterialHandler() { }
private static void ValidateMaterial(object sender, RenderContentEventArgs e)
{
RenderContentChangeReason[] reasons = {
RenderContentChangeReason.Attach,
RenderContentChangeReason.ChangeAttach,
RenderContentChangeReason.AttachUndo,
RenderContentChangeReason.Open};
if (reasons.Contains(e.Reason) && e.Content is RenderMaterial material)
{
RhinoApp.WriteLine($"From Material Handler, Name: {material.Name}, Content: {e.Content}, Reason: {e.Reason}");
RenderMaterial.StandardChildSlots[] slots = (RenderMaterial.StandardChildSlots[])Enum.GetValues(typeof(RenderMaterial.StandardChildSlots));
foreach (RenderMaterial.StandardChildSlots slot in slots)
{
RenderTexture texture = material.GetTextureFromUsage(slot);
if (texture != null)
{
TextureHandler.ValidateTexturePath(texture);
}
}
}
}
public static void Start()
{
RenderContent.ContentAdded += ValidateMaterial;
}
public static void Stop()
{
RenderContent.ContentAdded -= ValidateMaterial;
}
}
}
Texture Handler
using System;
using System.IO;
using System.Net;
using System.Text;
using Rhino.Render;
using Rhino;
using Rhino.UI;
namespace Hero.Handlers
{
public class TextureHandler
{
public TextureHandler() { }
private static void ValidateTexture(object sender, RenderContentEventArgs e)
{
if (e.Reason != RenderContentChangeReason.None && e.Content is RenderTexture texture)
{
RhinoApp.WriteLine($"From Texture Handler, Name: {texture.Name}, Content: {e.Content}, Reason: {e.Reason}");
ValidateTexturePath(texture);
}
}
public static void ValidateTexturePath(RenderTexture texture)
{
string texturePath = texture.Filename;
if (!texturePath.StartsWith("P:"))
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"Texture: {texture.Name} is not sourced from a project folder on P: drive.");
sb.AppendLine();
sb.AppendLine("This is against the recommended best practice.");
Dialogs.ShowMessage(sb.ToString(), "Bad Texture");
}
}
public static void Start()
{
RenderContent.ContentAdded += ValidateTexture;
RenderContent.ContentChanged += ValidateTexture;
RenderContent.ContentReplaced += ValidateTexture;
}
public static void Stop()
{
RenderContent.ContentAdded -= ValidateTexture;
RenderContent.ContentChanged -= ValidateTexture;
RenderContent.ContentReplaced -= ValidateTexture;
}
}
}
Issue
No event is being registered if I change/replace texture from Bitmap Texture Settings.I was expecting this to trigger a change or replace event.
Any help narrowing down it would be appreciated.