I have a double-sided material saved to an rmtl file. I want to load that in and then add an hdr environment texture to both front and back materials. I really have looked and looked and have found several examples by @jesterking , but none of the examples seems to be quite what I’m looking for (load a material from a file and add an hdr texture to it…much less to the front and back materials). To be fair, maybe one of his examples was what I was looking for, but maybe I’m just not quite smart enough to understand it, and it is all starting to making my head spin…document materials and render materials being created from each other for some reason and textures and childslots and parameters etc.
and a code stub of what I could come up with so far…
#! python 2
import scriptcontext as sc
import Rhino.Render as rr
mtl_path = "path\\to\\my\\custom\\material\\Gem - Stylized - Amethyst.rmtl"
hdr_path = "path\\to\\any\\hdr\\will\\be\\fine.hdr"
mtl = rr.RenderContent.LoadFromFile(mtl_path)
fmtl = mtl.FindChild('front')
bmtl = mtl.FindChild('back')
# add hdr to the environment slot of the front and back materials here
sc.doc.RenderMaterials.Add(mtl)
This seemed to be what worked for me. It seems a separate texture object had to be created for the back material (I think it was simply ignored if I tried to use the same texture as was used in the front material…like something somewhere said, “Nope, you are already using that one”). No error was thrown, but the back material just didn’t get assigned any hdr texture until I created a second texture object. Or, at least, I think that was what happened.
Anyway, I also had to turn the texture on for both materials. And then it worked.
Thank you for your help!
(NOTE: In my actual code, I build the paths with os.path.join() to keep things cross-platform)
#! python 2
import scriptcontext as sc
import Rhino.Render as rr
dsmtl_path = "path\\to\\double\\sided\\material.rmtl"
hdr_path = "path\\to\\somehdr.hdr"
# load double-sided mtl, get its front and back materials
dsmtl = rr.RenderContent.LoadFromFile(dsmtl_path)
fmtl = dsmtl.FindChild('front')
bmtl = dsmtl.FindChild('back')
# create texture for front mtl
hdr_texture_type_guid = rr.ContentUuids.HDRTextureType
hdrtex1 = rr.RenderContentType.NewContentFromTypeId(hdr_texture_type_guid)
hdrtex1.Filename = hdr_path
# create texture for back mtl
hdrtex2 = rr.RenderContentType.NewContentFromTypeId(hdr_texture_type_guid)
hdrtex2.Filename = hdr_path
# set texture on front mtl, turn it on
fmtl.SetChild(hdrtex1, 'environment-texture')
fmtl.SetParameter('environment-texture-on', True)
# set texture on the back mtl, turn it on
bmtl.SetChild(hdrtex2, 'environment-texture')
bmtl.SetParameter('environment-texture-on', True)
# add double-sided mtl to doc
sc.doc.RenderMaterials.Add(dsmtl)
In Rhino 6, the line bmtex.Filename = bm_path is throwing an error “NativeRenderTexture object has no attribute Filename.”
Is there another way to set the image path on the texture object in Rhino 6?
def AddBitmapTextureToMaterial(self, mtl, bm_path):
# create tex for front mtl
bm_texture_type_guid = rr.ContentUuids.BitmapTextureType
bmtex = rr.RenderContentType.NewContentFromTypeId(bm_texture_type_guid)
# ERROR in Rhino6 !!!
bmtex.Filename = bm_path
# set texture on mtl and turn it on
mtl.SetChild(bmtex, 'bitmap-texture')
mtl.SetParameter('bitmap-texture-on', True)
If you create a bitmap texture in Rhino 6, then save it to disk was an .rtex file you can open that in a text editor. You’ll find that the path is set as the parameter filename. You should be able to use the SetParameter method on RenderContent to set that.
This is what I’ve got so far, and it is adding the texture now (thank you), but it doesn’t turn it on in Rhino6. And it does seem that ‘bitmap-texture-on’ is the correct attribute according to the rmtl…unless I’m missing something.
Any ideas?
def AddBitmapTextureToMaterial(self, mtl, bm_path):
# create tex for front mtl
bm_texture_type_guid = rr.ContentUuids.BitmapTextureType
bmtex = rr.RenderContentType.NewContentFromTypeId(bm_texture_type_guid)
# this works in Rhino 6, 7, and 8
bmtex.SetParameter('filename', bm_path)
# set texture on mtl and turn it on
mtl.SetChild(bmtex, 'bitmap-texture')
mtl.SetParameter('bitmap-texture-on', True)
(Sorry to keep bothering you).
This is what I’ve got now, but it’s still not turning on. Did I do it right? (it doesn’t throw any errors, but it also doesn’t turn the texture on)
def AddBitmapTextureToMaterial(self, mtl, bm_path):
# create tex for front mtl
bm_texture_type_guid = rr.ContentUuids.BitmapTextureType
bmtex = rr.RenderContentType.NewContentFromTypeId(bm_texture_type_guid)
# bmtex.Filename is not available in Rhino6
# so we use this as it works in Rhino6 and up
bmtex.SetParameter('filename', bm_path)
# set texture on mtl and turn it on
mtl.BeginChange(rr.RenderContent.ChangeContexts.Program)
mtl.SetChild(bmtex, 'bitmap-texture')
mtl.SetParameter('bitmap-texture-on', True)
mtl.EndChange()