New Rhino6 C# Automatic UI Material Sample available

rhino

(Max Söderström) #1

The Sample is available in github in the below link

https://github.com/mcneel/Rhino6Samples_CS/tree/master/SampleRdkMaterialAutoUI

The Sample shows how a C# Render Plug-in can create custom Materials and assign an automatically generated UI for the material. The Material is called CSharpSampleAutomaticUIMaterial and I have added two fields to the material. One boolean field “Yes/No” and one color field. The sample also demostrates how to save and import the material from files.

Below is a picture that depicts the custom materials and the automtaically created UI section called Parameters.


#2

Hi @maxsoder,

SampleRdkMaterial() contructor is called over and over, many times, before even selecting this material. e.g. called 3 times when clicking “Use New Material”. Is there a way to detect when the constructor is really called to create a material (i.e. user select the CSharpSampleAutomaticUIMaterial)?

Thanks,
Pascal


(Max Söderström) #3

Hi Pascal,

Unfortunately there is no way to detect if the constructor call was made in order to actually create a material. However there might be another solution to the problem. Can you explain a bit more why you need to know if the Material is really created when the constructor is called?

Best Regards
Max


#4

Hi Max,

not a big deal but for efficiency/memory reasons. Currently we are investigating the integration of MDL as a Rhino plugin. The ctor keeps creating some MDL material in our DB, these materials are never deleted. Is there maybe a way to detect when the material is destroyed so we can keep the MDL DB in synch and delete the temporary created material?

Thx and Regards,
Pascal


(Max Söderström) #5

Hi Pascal,

I am not sure if this is the correct way to deal with the problem, but one could listen for Material Table events.

    Rhino.RhinoDoc.MaterialTableEvent += new EventHandler<MaterialTableEventArgs>(MaterialTableChanged)


    void MaterialTableChanged(object sender, MaterialTableEventArgs e)
    {
      // Something changed in material table

    }

From the MaterialTableEventArgs one can check if the event type is added/removed.

Regards
Max


#6

Hi @maxsoder,

Apparently we need the plugin to be a render plugin in order to properly list the new material extension. I guess the key is to implement RenderContentSerializers(). Trouble is the new renderer is added to the list of renderers.

is there a way to avoid that?

thanks,
Pascal


#7

Another question: We need to store some information with the new RenderMaterial, this information does not need to be visible/editable. How to do that? I see there is no SetUserString() on RenderMaterial. Could we maybe add hidden fields? Currently I have added this information as string fields but this is only temp solution. See filename, modulename and materialdefinition below:

thanks
Pascal


(Andrew le Bihan) #8

Pascal

Just use a string field for now - we’ll figure out how to make it hide soon.

https://mcneel.myjetbrains.com/youtrack/issue/RH-37349

  • Andy

(Andrew le Bihan) #9

Pascal

Custom materials should not need to be in a rendering plug-in. It should all just work from a standard plug-in. The only trick is that you might need to make your material RenderEngineId “universal”

@maxsoder This needs to be how the CS sample works.

  • Andy

#10

Perfect, thanks


#11

OK, not sure the RenderEngineId “universal” is available in CS.
I will wait for @maxsoder to update the CS sample code.
Thx
Pascal


(Nathan 'jesterKing' Letwory) #12

Render plug-ins will automatically have any custom render content registered. For utility plug-ins you can use RenderContent.RegisterContent() explicitely to register custom render content like materials.

For instance Raytraced is a utility plug-in and does it like so:

/Nathan


#13

humm, our concern is to have MDL show up when user “Import from material library…”.
I changed to a utility plugin and I registered content the MDL material (which is a RenderMaterial), but this does not help. Not sure how the register content logic relates to the RenderContentSerializer…


(Nathan 'jesterKing' Letwory) #14

Right, the RenderContentSerializer isn’t (yet) being registered when calling RenderContent.RegisterContent(). I discussed this briefly with @maxsoder, I suggested this function also somehow takes care of RenderContentSerializers. He can let you know what the solution will be.

/Nathan


(Max Söderström) #15

The RenderContentSerializer is the one that adds the .extension to the extensions list when using “Import from material library…”

However RenderContentSerializers can only be currently registered through render plug-ins. I have this morning implemented a similar way to register Serializers like contents. This will be available in next weeks WIP. Then utility plugins can also register RenderContentSerializers.

The idea would be that the serializer could register itself like contents by calling RegisterSerializer.

    public SampleRdkMaterialAutoUIPlugIn()
    {
      Instance = this;

      // Create our custom serializer for the material (.sample files)
      m_rcs = new SampleRenderContentSerializer("sample", RenderContentKind.Material, true, true);

      // Register Serializer (plugin id as parameter)
      m_rcs.RegisterSerializer(new Guid("3285f192-ecac-40ee-a989-0930756d8f41"));
    }

(Max Söderström) #16

Hi @nvp

I have added the RegisterSerializer funcrtion to RenderContentSerializer class. By calling this method the Serializer is registered.

I have also updated the Sample C# Rhino6 AutomaticUI project to use the new function call. Also the plug-in is not anymore a render plug-in, but a utility plugin.

The changes for the RegisterSerializer will be available in the next WIP. It will take a few hours before the next WIP is build.

Best Regards
Max


(Andrew le Bihan) #17

Pascal

Fields with no “prompt” are not displayed in the automatic UI - so just exclude the prompt from your fields in that case.

// Finally add the bool field
material.Fields.Add(key, b_value, prompt);

  • Andy

#18

I just changed the code (turning into a utility plugin and registering the serializer) and this works fine, thanks.