How can I load a material from file in Rhino 6+ in Rhinoscript? This is what was working in Rhino4:
Function LoadMaterialToLayer(MatFilename, LayerName)
Set RDK = Rhino.GetPlugInObject("Renderer Development Kit")
MatID = RDK.ContentLoadFromFile(MatFilename)
MatIndex = Rhino.LayerMaterialIndex(LayerName)
If MatIndex < 0 Then MatIndex = Rhino.AddMaterialToLayer(LayerName)
LoadMaterialToLayer = RDK.SetMaterialInstanceId(MatID, MatIndex)
End Function
It works so far as loading the material in Rhino 6, but it wonât get assigned to the layer. Instead. an âunnamedâ generic material gets created and assigned to the layer. I can manually assign the newly imported material to the layer, so what am I missing? Thanks.
Thank you Dale. I ended up switching to calling the command â-_RenderAssignMaterialToLayerâ which luckily accepts Material instance ID.
I would love to switch to Python, but with 50 thousand lines of interconnected vbs automation code spanning 16-17 years, sadly, itâs not happening. I am hoping vbs support is not dropped or gets the ugly duckling treatment in the near future for the sake of long time customers.
RhinoScript wonât be going away anytime soon. Because it is limited to Windows-only, along with other reasons, it isnât being actively worked on. And while weâre happy to fix issues as they arise, you probably wonât see much, if any, new functionality added.
I am in the same boat, with complex RS tools developed over a decade; there is no way they will get recreated in Python. So I was happy to hear that at least weâll have issues fixed. RS already got some ugly duckling treatment with the Script Editor getting worse and having a few new bugs and features gone in V6. For me the sad part is dropping the development of it while it was actually getting quite powerful with new methods added in V6, but without even small additions or modifications to RS it will be hard to keep up with Rhino changing over time.
@C.S - with the above in mind, if you ever run into a need to add some functionality to your old RS code that is not possible with RS but doable in Python, it is actually possible to mix them, or rather run Python code inside RS or even exchange data between. I had to come up with this method to be able to keep the tools up to speed.
You can take a look at this sample : changing an advanced setting from RS that is normally not possible unless using Python/RhinoCommon:
Call Main()
Sub Main()
Call Rhino.Print("Current ZoomScaleFactor: " & PythonZoomWheelScaleGet)
Dim dbScale : dbScale = Rhino.GetReal("New ZoomScaleFactor?", 0.9, 0, 1)
If Not isnull(dbScale) Then
Call PythonZoomWheelScaleSet(dbScale)
Call Rhino.Print("Current ZoomScaleFactor: " & PythonZoomWheelScaleGet)
End If
End Sub
Function PythonZoomWheelScaleGet()
Dim s : s = ""
'python code goes here in this format:
s = s & "import scriptcontext as sc" & vbCrLf
s = s & "import Rhino.ApplicationSettings as appsettings" & vbCrLf
s = s & "sc.doc.Strings.SetString(""SAMPLE"", ""ZoomScale"", appsettings.ViewSettings.ZoomScale.ToString())" & vbCrLf
'end of Python code
'run Python code
Call Rhino.Command("_-RunPythonScript (" & s & ")", False)
'retrieve the data from Python to RhinoScript via DocumentUserText
PythonZoomWheelScaleGet = Cdbl(Rhino.GetDocumentUserText("SAMPLE\ZoomScale"))
'clear DocUserText
Call Rhino.SetDocumentUserText("SAMPLE\ZoomScale")
End Function
Sub PythonZoomWheelScaleSet(dbScale)
Dim s : s = ""
'python code goes here in ths format:
s = s & "import scriptcontext as sc" & vbCrLf
s = s & "import Rhino.ApplicationSettings as appsettings" & vbCrLf
'adding RS variable value to Python code as String
s = s & "appsettings.ViewSettings.ZoomScale = " & Cstr(dbScale) & vbCrLf
'end of Python code
'run Python code
Call Rhino.Command("_-RunPythonScript (" & s & ")", False)
End Sub
The above method works even with complex Python code, including conduits etc. Obviously itâs using DocumentUserText to exchange data between languages, so depending on data type the conversion would be needed to/from string. So for tasks where speed is critical this may not be the best, but we managed to expand the old RS tools using this method quite well.
Here is a code to convert any Python script into a set of RS multi-line string to be executed by RunPythonScript command inside RS:
Option Explicit
Call ConvertPythonCodeToStrings()
Sub ConvertPythonCodeToStrings()
'get text file
Dim i,arrText : arrText = Rhino.ReadTextFile(Rhino.OpenFileName(), False, False)
'replace quotes with double-quotes and add NextLine character
For i=0 To Ubound(arrText)
arrText(i) = "s = s & " & chr(34) & Replace(arrText(i), chr(34), chr(34) & chr(34)) & chr(34) & " & vbCrLf"
Next
'save text file
Call Rhino.WriteTextFile(Rhino.SaveFileName(), arrText, False, 0)
End Sub
I have fixed the issue that stopped your function LoadMaterialToLayer from working. This fix will be available in version 7.5.
Note that the script is relying on old Rhino 4 behavior which has now changed. You will see a âspareâ material appear in the Material Editor. This is because of the call to Rhino.AddMaterialToLayer() which now adds a new material for the layer to the Material Editor. Then the scriptâs call to RDK.SetMaterialInstanceId() redirects the layer material to the loaded one, leaving the other one unused.
If this is a problem, you can use RenderRemoveUnusedMaterials to get rid of the unused ones.