GetPlugInObject not working for VBScript?

8200 would be VarType ( VT_ARRAY | VT_BSTR ). While GetSceneMaterialNamesScript outputs VarType (VT_ARRAY | VT_VARIANT). This was the reason I wrote up this different function to get around that error.

Which version of V-Ray For Rhino / V-Ray For Matrix are you running and getting the said error with GetSceneMaterialNamesScript?

Hi Matt, V-Ray For Rhino 1.5 Edu. I remeber to have searched how to access ByteString in rvb in the past without success.

c.

@clement

GetSceneMaterialNamesScript was added in the builds from Mid July 2014.You will have to get a newer build to use that function.

Possible typo, strObjects should be strObject. If i understand it correctly, it should be an array of objects but i cannot test it as i do not get past the GetSceneMaterialNamesScript method at this point.

Btw. you might use Option Explicit to avoid writing variable names which have not been declared before.

c.

@clement can you try running this code instead (which uses Rhino.MaterialName instead)

    f = "C:\WhiteReflective.vismat"
    Call Rhino.Command("-visLoadVismat " + f)
    Dim arrMaterials: arrMaterials = Rhino.MaterialIndices
    Dim strObject: strObject = Rhino.GetObject("select")
    Dim vRay, mat_name, i, name, f, mat_index, materials, str_name, thisStr, obj_index, newIndex
    Set vRay = Rhino.GetPluginObject("{E8CFE179-B60C-411A-8416-62A893334519}")
    mat_name = vRay.GetMaterialNameFromVismat(f, False)
    str_name = "WhiteReflective"
    For i = 0 to UBound(arrMaterials)
        thisStr = Rhino.MaterialName(arrMaterials(i))
        If InStr(thisStr, str_name) <> 0 Then
            Exit For
        End If
    Next
    obj_index = Rhino.ObjectMaterialIndex(strObject)
    vRay.ApplyVRayMaterialToObjects mat_name, 1, strObject

Can you describe what are you trying to accomplish with your script ?

I´ve tried to run it and get the same “unsupported property or method” error using VRay.ApplyMaterialToObjects. But i guess this is because i´m using the older VRay version.

c.

Ah, that’s a shame. Well, what I’m trying to achieve is the supremely elusive and seemingly vindictive task of assigning a material to an object. In this case, I have added a ground plane right before this code snippet and here I’m trying to assign add the WhiteReflective material to it.

1 Like

Well, it is clear that you finally want to assign the material :smile: what i do not understand in your last script is:

  1. Why are you getting the index and do not use it in your script ?
  2. Do you get the same type error like i have, when using ApplyVRayMaterialToObjects ?
  3. Why the for loop when you do not use the variable thisStr ?

c.

Here is my workaround when ApplyVRayMaterialToObjects is not working:

Option Explicit

Call Main()
Sub Main()
    
    Dim f, strObject, rid, vRay, mat_name, cmd, result
    
    f = "C:\White Plastic.vismat"
    Call Rhino.Command("-visLoadVismat " + CHR(34) + f + CHR(34))
    
    strObject = Rhino.GetObject("select object", 8+16+32, True, True)
    If IsNull(strObject) Then Exit Sub
    
    rid = "{E8CFE179-B60C-411A-8416-62A893334519}"
    
    Set vRay = Rhino.GetPluginObject(rid)
    If Not IsObject(vRay) Then Exit Sub
    
    mat_name = vRay.GetMaterialNameFromVismat(f, True)
    If len(mat_name) = 0 Then Exit Sub
    
    cmd = "-visApplyMaterial " + CHR(34) + mat_name + CHR(34)
    result = Rhino.Command(cmd, False)
    If result = False Then Rhino.Print "error assigning material"
    
End Sub

Note that i have a different material and that i put the material name (mat_name) in extra quotes. If you would not do this it would fail using a material name with spaces in the name.

c.

@clement I don’t know if I’m doing something wrong but visApplyMaterial does not seem to do the job for me. The script executes fine, but the material does not seem to apply in the render. So far, I’ve only been able to assign material successfully with rs.CopyMaterial (that was in Rhino Python). Weirdly, when I try Rhino.CopyMaterial (or Rhino.MatchMaterial), I get this error message ‘Type mismatch in parameter. Float required’. Float required?! Aren’t the indices of integer type?

Alright, got this to work. The issue was that Rhino.MaterialIndex needs a material identifier (Rhino.MaterialId) as parameter and not a material name.

   Dim vRay, mat_name, i, name, f, mat_index, materials, str_name, thisStr
   f = "C:\WhiteReflective.vismat"
   Call Rhino.Command("-visLoadVismat " + f)
   Dim idMaterials: idMaterials = Rhino.MaterialIds
   Dim indexMaterials: indexMaterials = Rhino.MaterialIndices
   Dim strObject: strObject = Rhino.GetObject("select")
   Set vRay = Rhino.GetPluginObject("{E8CFE179-B60C-411A-8416-62A893334519}")
   mat_name = vRay.GetMaterialNameFromVismat(f, False)
   str_name = "WhiteReflective"
   For i = 0 to UBound(indexMaterials)
        thisStr = Rhino.MaterialName(indexMaterials(i))
        If InStr(thisStr, str_name) <> 0 Then
            mat_index = Rhino.MaterialIndex(idMaterials(i))
            Exit For
        End If
    Next
    If IsNull(mat_index) Then
        Rhino.Print("Wow, Null")
        Rhino.Print("But looks like we have" + thisStr)
    Else
        Rhino.Print("I'm Neo" + CStr(mat_index))
    End If
    Rhino.ObjectMaterialIndex strObject, mat_Index

I forgot to mention that -visApplyMaterial only works if your object(s) are selected beforehand. If nothing is selected it will just run through doing nothing. If it assigns the material properly, -visApplyMaterial reports the success to the commandline as well.

Yesterday i´ve tried something which was identical using your last code snippet above but i´ve found something strange: If i get the material index using RhinoScript methods and assign that index to the object, the material name gets assigned as usual, the plugin box gets checked in properties BUT: the edit Button stays greyed out. Somehow this cannot be right. So i´ve done the version above using -visApplyMaterial which seems to fix that.

So as a last comment to your last code, i do not think that it is required to get the index, then compare the material name with all scene material names and finaly assign it. The VRay material name is enough to assign it, at least with the version using -visApplyMaterial. Downside is, it requires the object selection.

c.

I’ll have to check that; I haven’t observed the edit button. Somehow, visApplyMaterial doesn’t work for me and I’m not going to investigate it further. Much thanks for your inputs, @clement. Before we seal this thread for good, do you know of any way of assigning a material from the material library without having to call visLoadVismat?

Please try this first:

  1. Create a few objects in a new scene
  2. Assign a few different vray materials to them
  3. Create a surface and select it
  4. type visApplyMaterial (without the - sign in front)
  5. A dialog pops up, showing all scene materials
  6. Choose one to assign it to the surface, click ok
  7. Look into properties / material and check for:

A: Is the material name assigned ?
B: Is the plugin box checked ?
C: Is the edit button clickable or grayed out ?

In my case, A B C all work using visApplyMaterial. I can do the same using a script, if i put the - sign in front of -visApplyMaterial, the dialog is suppressed, then i can simply type the material name eg. “\White Plastic”. If the material has spaces in it, i need to type this in quotes. Note the \ in front of the material name. In your last script, you´re just missing this, you might print out the results of your variables to find such errors faster and handle them.

If i run your last posted script, i do not get any of A, B, C, no material gets assigned at all. Using visApplyMaterial is the easiest method to get all things in one go. If you do not use it, you have to control (script) the material source (ByObject, ByLayer) as well. Your script does not do that.

In general, it is required to understand what material indices are. A material index can be any positive integer, including zero.

To assign one material from the scene materials, you might use the vRay.GetSceneMaterialNamesScript method and pop up a listbox filled with the materials array. Then assign the choosen material using visApplyMaterial. Note that the object(s) to assign to need to be selected beforehand. If not, it will not work. Just enter “visApplyMaterial” to the commandline and read what it prints to the command line.

c.

1 Like

Thanks for your reply, @clement. I am just getting around to trying this out.

@clement have you had any success working with V-Ray scripting methods for Rhinoscript/Python? I seem to be having the same issues still, so I have stopped wrangling with them and I’m using Rhinoscript methods for material calling.

Yes, below one example how to apply a loaded VRay materials using material indices. If no materials have been loaded, nothing will happen. Short description:

  • Get all non deleted material names and their material indices
  • put them in dictionary to remove duplicates
  • open listbox to select one material by name
  • ask for objects to apply picked material (ByObject) using its index
import rhinoscriptsyntax as rs
import scriptcontext

def ApplyLoadedVRayMaterial():
    vRay = rs.GetPlugInObject("E8CFE179-B60C-411A-8416-62A893334519")
    if not vRay:
        print "VRAY not found or not loaded !"
        return
    
    d = {}
    materials = scriptcontext.doc.Materials
    for m in materials:
        if not m.IsDeleted: 
            d[m.Name] = m.MaterialIndex
    if len(d) == 0: return
    
    mat_name = rs.ListBox(d.keys(), "Select", "Title")
    if not mat_name: return
    
    ids = rs.GetObjects("Objects", 8+16+32, False, False, False)
    if not ids: return
    
    rs.ObjectMaterialSource(ids, 1)
    for id in ids: rs.ObjectMaterialIndex(id, d[mat_name])
    
    print "Applied {0} to {1} objects".format(mat_name, len(ids))

if __name__=="__main__":
    ApplyLoadedVRayMaterial()

tested with Rhino5 SR12 and VRay 2.00.25962 (x64).

c.

c.

1 Like

This looks great! But you haven’t used any of the actual vRay scripting methods, have you? I mean like GetSceneMaterialNames and others listed in the VRayforRhinoExports file?

That is correct. I was not able to get the GetSceneMaterialNames and GetSceneMaterialNamesScript methods do work. They where reported to be available using

hasattr(vRay, 'GetSceneMaterialNames')

but accessing them or putting their return values into a variable was not possible. However all the options related stuff discussed here was working fine.

c.

The below attached code appears to work:

 names = clr.Reference[System.Object]()
 vRay.GetSceneMaterialNames(names)
 RhinoApp.WriteLine(str(names))

and

list = clr.Reference[System.Object]()
vRay.GetSceneMaterialNamesScipt(list)
RhinoApp.WriteLine(list.ToString())

and this one below will work in the latest service release


import clr
from Rhino import *
import Rhino

def LoadPlugin(path):
	if path == None:
		return False
	# MRhinoPlugIn will be null if it is a C++ plugin
	plugin = Rhino.RhinoApp.GetPlugInObject(path)
	
	return plugin

def RunCommand():
    hPlugIn = LoadPlugin("V-Ray for Rhino")
    clr.AddReferenceToFileAndPath("C:\ProgramData\ASGVIS\VfR564\VRayForRhinoNETInterface.dll")
    import VRayForRhinoNETInterface
    
    names = VRayForRhinoNETInterface.VRayInterface.GetSceneMaterialNames()
    
    RhinoApp.WriteLine(str(names))
    
RunCommand()

There are a few more samples scripts installed in on the latest service release:
C:\ProgramData\ASGVIS\VfR564\SampleScripts

1 Like