Hi,
I have added a texture path handler to my rhino plugin as shown below. It works as expected on the ContentAdded
event. When I change the texture on a material, the ContentChanged
event if triggered four times. I am not able to understand the reason.
TexturePathHandler
using System;
using System.IO;
using System.Text;
using Rhino.Render;
using Rhino;
using Rhino.UI;
namespace Hero.Handlers
{
public class TexturePathHandler
{
public TexturePathHandler()
{
}
private static void ValidateMaterial(object sender, RenderContentEventArgs e)
{
// When a material is added to the document, check if any of the texture files are not sourced from the P: drive.
// Give a warning if this is the case.
if (e.Content is RenderMaterial material && !ValidateTexturePaths(material))
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"Material: {material.Name}");
sb.AppendLine();
sb.AppendLine("Has one or more texture files that are 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");
}
}
private static bool ValidateTexturePaths(RenderMaterial material)
{
// Get the possible child slots for the material. These child slots are essentially filled by the Texture objects.
RenderMaterial.StandardChildSlots[] slots = (RenderMaterial.StandardChildSlots[])Enum.GetValues(typeof(RenderMaterial.StandardChildSlots));
// Get the texture for each of the child slots and check if the texture path starts with "P:".
foreach (RenderMaterial.StandardChildSlots slot in slots)
{
RenderTexture texture = material.GetTextureFromUsage(slot);
if (texture == null)
{
continue;
}
string texturePath = texture.Filename;
if (!texturePath.StartsWith("P:"))
{
return false;
}
}
return true;
}
public void Start()
{
RenderContent.ContentAdded += ValidateMaterial;
RenderContent.ContentChanged += ValidateMaterial;
}
public void Stop()
{
RenderContent.ContentAdded -= ValidateMaterial;
RenderContent.ContentChanged -= ValidateMaterial;
}
}
}
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;
private readonly TexturePathHandler _texturePathHandler;
public HeroPlugIn()
{
Instance = this;
_texturePathHandler = new TexturePathHandler();
}
public static HeroPlugIn Instance { get; private set; }
protected override LoadReturnCode OnLoad(ref string errorMessage)
{
_texturePathHandler.Start();
return LoadReturnCode.Success;
}
protected override void OnShutdown()
{
_texturePathHandler.Stop();
}
}
}