Load ZBrush Polygroups as Material Inputs

Forum for OctaneRender Lua scripting examples, discussion and support.
Post Reply
tonysculptor
Licensed Customer
Posts: 62
Joined: Fri Aug 16, 2013 12:27 am
Location: Austin, TX
Contact:

Hey all. I finally made the lua script to load polygroups from ZBrush as material inputs. Mike Pavlovich was asking for this, so I made it for him. Now its for everyone.
This is my first Lua script -- the tough part was figuring out how to get the attribute values of the Octane nodes. When you pass a string value as the name of an attribute it errors out. So I had to type in integers, one at a time, until I found the ones that were associated with "A_FILENAME" and "A_RELOAD". Crappy process, but hopefully the documentation on the API will improve.
Anyhow, it works without updating the mtl file. So have fun ZBrushers!

Here's the script :

Code: Select all

function updateFileData(objFile)
    local f = io.open(objFile, "r")
    local fileData = f:read("*all")
    f:close()
    fileData = fileData:gsub("g (%w+)", "usemtl %1")
	
	f = io.open(objFile, "w")
	f:write(fileData)
	f:close()
	--print (fileData)
	
end

-- main function body

-- get the selected mesh
local selectedRt = octane.project.getSelection()[1]
if not selectedRt or selectedRt.type ~= octane.NT_GEO_MESH then
	showError("no mesh selected")
	return nil
end
--print (selectedRt)

-- get the file path for the mesh
local objFileName = octane.node.getAttribute( selectedRt , 29 ) 

--print (objFileName )
updateFileData(objFileName)

--reload mesh
octane.node.setAttribute(selectedRt, 94, true, true)
Attachments
LoadPolyGroupAsMaterial.lua
(743 Bytes) Downloaded 528 times
Tony Reynolds

i7 6 Core Processor | 680 GTX x 3, 4 GB VRAM | 128 GB Ram
User avatar
stratified
OctaneRender Team
Posts: 945
Joined: Wed Aug 15, 2012 6:32 am
Location: Auckland, New Zealand

Hi Tony,

Thanks for the script.

Indeed the documentation still lacks. But the API browser is just meant as a reference. The best information is found here on the forum in the tutorials and examples. For example have a look at this one http://render.otoy.com/forum/viewtopic.php?f=73&t=37333.

getAttribute and setAttribute take the attribute id. You could rewrite your script like this:

Code: Select all

-- get the file path for the mesh
local objFileName = selectedRt:getAttribute(octane.A_FILENAME)

--print (objFileName )
updateFileData(objFileName)

--reload mesh
selectedRt:setAttribute(octane.A_FILENAME, true, true)
cheers,
Thomas
tonysculptor
Licensed Customer
Posts: 62
Joined: Fri Aug 16, 2013 12:27 am
Location: Austin, TX
Contact:

Thanks. I did a bit of searching on the forums, but missed that notation. Thanks.
As for using the script, import thr geometry into octane, then select the mesh node and run the script. I will try to see if I can highjack the initial mesh import process later, so it can be one step.
Tony Reynolds

i7 6 Core Processor | 680 GTX x 3, 4 GB VRAM | 128 GB Ram
Tugpsx
Licensed Customer
Posts: 1150
Joined: Thu Feb 04, 2010 8:04 pm
Location: Chicago, IL
Contact:

Getting the dreaded nil value error on run. If I recall this happens when the variable is undefined.

Code: Select all

[string "function updateFileData(objFile)..."]:3: attempt to index local 'f' (a nil value)
Win 11 64GB | NVIDIA RTX3060 12GB
tonysculptor
Licensed Customer
Posts: 62
Joined: Fri Aug 16, 2013 12:27 am
Location: Austin, TX
Contact:

Fixed the error.

Code: Select all

-- helper to pop-up an error dialog
local function showError(text)
    octane.gui.showDialog
    {
        type  = octane.gui.dialogType.BUTTON_DIALOG,
        icon  = octane.gui.dialogIcon.WARNING,
        title = "Daylight Animation Error",
        text  = text,
    }
end



function updateFileData(objFile)
    local f = io.open(objFile, "r")
    local fileData = f:read("*all")
    f:close()
    fileData = fileData:gsub("g (%w+)", "usemtl %1")
	
	f = io.open(objFile, "w")
	f:write(fileData)
	f:close()
	--print (fileData)
	
end

local function reloadMeshGroupsAsMaterials()
	-- get the selected mesh
	local selected = octane.project.getSelection()[1]
	if not selected or selected.type ~= octane.NT_GEO_MESH then
		showError("no mesh selected")
		return nil
	end

	-- get the file path for the mesh
	local objFileName = octane.node.getAttribute( selected , 29 ) 

	--print (objFileName )
	updateFileData(objFileName)

	--reload mesh
	octane.node.setAttribute(selected, 94, true, true)
end

reloadMeshGroupsAsMaterials()
Attachments
LoadPolyGroupAsMaterial.lua
(1.04 KiB) Downloaded 527 times
Tony Reynolds

i7 6 Core Processor | 680 GTX x 3, 4 GB VRAM | 128 GB Ram
Metalkid1974
Licensed Customer
Posts: 9
Joined: Sun Jul 28, 2013 7:13 pm

What a nice script - That will make my life easier from this point on ;)

It works in standalone 1.55, but i 2.05 i get: "[string "-- helper to pop-up an error dialog..."]:15: bad argument #1 to 'open' (string expected, got boolean"

It's not a huge problem, since running the script on a mesh in 1.55 means it can then be loaded into 2.05 with its new material inputs, but just thought I'd mention it in case someone can make it work directly in 2.xx :)
User avatar
bepeg4d
Octane Guru
Posts: 10321
Joined: Wed Jun 02, 2010 6:02 am
Location: Italy
Contact:

Hi,
here is a revisited version of the script to make it works also with recent versions of OctaneRender.
You need to select the imported obj node and run the attached script, to have all the polygroups listed as material pins:
Screen Shot 2017-09-26 at 11.00.58.jpg
LoadPolyGroupAsMaterial_b.lua
(1.08 KiB) Downloaded 697 times
Basically, the script was not working with v2 or v3 because the octane attribute were called via ID number instead of name, and the id numbers have changed during versions.
ciao beppe
Post Reply

Return to “Lua Scripting”