i try to create a new RenderMaterial from scratch using the Custom shader type. The material should use a Blend shader in the Texture (Color) slot to which i want to assign parameters (textures) later.
From your post on how to add a double sided material here i’ve found that i should save an rmtl file and look at the guids. This worked to create the Custom material eg. like so:
It creates the Blend Texture below the RenderMaterial in the materials tree, but i am unsure how i can set this as the Color Texture of the RenderMaterial ? Below is what i want to create (“CustomMaterialTest”) and what i have (“MyMaterial”) in the Materials tab as image:
This is almost correct. Instead of "Blend Texture" you need to pass in the name of the child slot where the texture goes.
If you look in your .rtml you’ll see that the <texture> has an attribute called child-slot-name. The value for this attribute is the name you need to use, so in this case "bitmap-texture".
Hi @nathanletwory, yes indeed. I just did not scroll so far to the right where the child-slot-name="bitmap-texture" is located
btw. one follow up question. For the Blend Texture i wanted to assign a Simple Bitmap Texture (as it does not have any other controls) but this pops up a dialog to choose a file:
RenderContent.Create() is a fairly high-level function which takes care of a number of things you wouldn’t normally think of, such as prompting the user for a file name. If you want to suppress this, you need to use a lower-level function. In this case, RenderContentType.NewContentFromTypeId() is that function.
I’m not very good at Python so I’ll give you the code in C# - I believe the syntax is quite similar.
var material = Rhino.Render.RenderContent.Create(
new Guid("BA51C000-BA51-C000-BA51-C0BA51C00000"),
RenderContent.ShowContentChooserFlags.None, doc);
var texture = RenderContentType.NewContentFromTypeId(
new Guid("57E0ED08-1907-4529-B01B-0C4A242455FD"));
material.BeginChange(RenderContent.ChangeContexts.Program);
material.SetChild(texture, "bitmap-texture");
material.EndChange();
Regarding your final question, I don’t understand that either, and I also don’t understand why it would be affected by whether or not sbt is a child. In C++, that would work the way you expect. The filename parameter belongs to sbt and has nothing to do with its parent, so querying the parent for it shouldn’t work. Unless, of course, there is something special going on in the Python framework. I’ll ask my team about this because I’d like to understand it myself.
i’ll just asume that there is something which is not working as expected from the python side. Please review the attached example python script and run it on the example document. It just contains a single material of type Custom to which i’ve assigned a diffuse texture.
If i query the the FirstChild directly using GetParameter like this:
I get a Rhino.Render.Variant which does contain NULL once i try to convert to string. (I’ve just ran into this testing backward compatibillity with RH6 SR34).
@clement Before I do anything else I just want to mention that when I wrote this:
“so querying the parent for it shouldn’t work”
I was confused. I had missed the FirstChild. Calling from the material’s first child should work and it does. The only issue is why it didn’t work when you called it on sbt. You said:
“EDIT: i see now, the first query works if it is done before adding sbt as child to the blend_material.”
That seems to be a Python issue; it would always work before or after adding as child if done in C++.
To wrap this up, I will do the final tests you provided and get back to you.
Sorry for the delay. We have figured out what’s wrong with your call to rm.GetChildSlotParameter(). The problem is in the C# which Python calls into. When the C# was written, based on the C++, the function was named incorrectly. It doesn’t actually get a child slot parameter in the way you were expecting. It gets a special kind of parameter called an “extra requirement” which is used by the automatic UI.
Somehow, the documentation for this fact got lost, leaving the function looking like it does something else. The correct way to get the parameter is your original way, by calling rm.FirstChild.GetParameter().
Sorry for the confusion. I am going to properly document this to prevent similar confusion in the future.
thank you @johnc, makes all sense now. I’ve also discovered that i can get and set things using the Fields directory which seems to be easier from Python. Not sure if there are any drawbacks using this compared to child parameter access.
I’d just want to report that making the material with all the different populated child slots seems to work on mac, though with a strange bahaviour how it is displayed in the materials tab when it is set to tree display. (I will create a new topic for that as soon as i find some time).
Under the hood, child parameters are implemented as fields, so using the field dictionary should amount to the same thing. It’s just a different way of getting at the same data. In the rare case of materials belonging to older plug-ins that don’t use fields, child parameters would work when the field dictionary fails. But for all practical purposes you can use whichever is most convenient, especially if you are using our built-in materials (Custom, Glass, Paint etc).
If there is strange behavior in the material tree on the Mac, that would be a UI issue. Please do create a new topic when you have time with a screenshot so we can take a look.