Nodes and Nodegraphs in Lua.

Forums: Nodes and Nodegraphs in Lua.
Forum for OctaneRender Lua scripting examples, discussion and support.

Nodes and Nodegraphs in Lua.

Postby stratified » Thu Dec 12, 2013 12:53 am

stratified Thu Dec 12, 2013 12:53 am
hi all,

Today we'll give a brief overview of the node and graph module. Every Octane user is familiar with nodes and graphs but let's explain some details to get you up to speed. We won't build a full example here but we'll include some code snippets to experiment with. Note: not all the code here will work with version 1.21, some stuff was added in 1.22.

Before we take a deep dive, let's have a look at the octane module. This module contains common enumerations used in the node and graph modules:

  • octane.attributeId: A table with all the attribute identifiers available in Octane. (prefix A_ e.g. A_VALUE).
  • octane.attributeType: A table with all the attribute types (prefix AT_ e.g. AT_BYTE).
  • octane.graphType: A table with all the graph types (prefix GT_ e.g. GT_STANDARD).
  • octane.nodeType: A table with all the node types (prefix NT_ e.g. NT_CAM_THINLENS).
  • octane.pinId: A table with all the pin identifiers (prefix P_ e.g. P_KERNEL).
  • octane.pinType: A table with all the pin types (prefix PT_ e.g. PT_TEX).

When manipulating the node system, you'll be using above enums all the time. That's why we made them available directly in the octane table to save some typing (e.g. octane.nodeType.NT_BOOL is equivalent with octane.NT_BOOL).

The following code will list all nodes available. Note that all not all nodes can be created, some are internal to Octane (we probably hide them in the future):

Code: Select all
-- list all the node types
for type, value in pairs(octane.nodeType) do
    print(type, value)
end


To avoid confusion, often we'll talk of items. An item can either be a node or a graph. We usally talk of items when refering to properties that apply both to node or graphs (e.g. attributes, owners, ...).

Nodes can be created from a script and they are added to the current project. We can create nodes either in a graph or internal in a pin (graph owned or pin owned). Internal nodes must have the same output type as the type of the pin they're created in and they are implicitely connected. For example:

Code: Select all
-- create a node in the root graph (a.k.a the scene graph)
rt = octane.node.create{ type=octane.NT_RENDERTARGET, name="Impl RT" } -- implicit in the root graph
bool = octane.node.create{ type=octane.NT_BOOL, name="Expl Bool", graphOwner=octane.nodegraph.getRootGraph() }

print(rt:getProperties().graphOwned, rt:getProperties().graphOwner)

-- create a panoramic camera in the camera pin of the render target
-- we need to specify both the node that has the pin and the pin itself
pcam = octane.node.create{ type=octane.NT_CAM_PANORAMIC, pinOwnerNode=rt, pinOwnerId=octane.P_CAMERA }
print(pcam:getProperties().pinOwned, pcam:getProperties().pinOwnerNode)

-- creating a bool node in the kernel pin of the render target won't work
-- there should be an error in the log
octane.node.create{ type=octane.NT_BOOL, name="Won't work", pinOwnerNode=rt, pinOwnerId=octane.P_KERNEL }


Both nodes and graphs can have attributes. Attributes represent an internal value of the item that's not exposed to the outside world. For example a float node needs to keep around it's value. This is done via its attribute (octane.A_VALUE). When setting the value of an attribute on an item, the item needs to be evaluated. Evalution of an item means that the item checks which attributes changed and does something special with them. The specific "magic" is different per node. Evalution of nodes that aren't set up correctly can crash Octane. The dangerous ones are the image textures and the meshes. For example when changing the A_FILENAME attribute in an image texture will load the texture from disk and set up the remaining attributes. All the attributes can be accessed via their id, name of index. There are always 2 flavours of attribute manipulation functions. One function to access via index and the other to access via name or id (e.g. getAttribute vs getAttributeIx, setAttribute vs setAttributeIx). Functions taking an index always end in Ix. When manipulating attributes it's recommended to always identify attributes via it's id. This leads to more readable and less error prone code. Ideally you should only access attributes via their index when iterating over all the attributes.

Code: Select all
-- create a bool node and get it's attribute value
boolNode = octane.node.create{ type=octane.NT_BOOL, name="My Bool" }
print(boolNode:getAttribute(octane.A_VALUE))
-- set the value of the attribute to true
boolNode:setAttribute(octane.A_VALUE, true)
print(boolNode:getAttribute(octane.A_VALUE))

-- create an image texture
texNode = octane.node.create{ type=octane.NT_TEX_IMAGE, name="Tex" }
-- none of the attributes on the node are set
print("before eval")
print(texNode:getAttribute(octane.A_TYPE))
print(texNode:getAttribute(octane.A_SOURCE_INFO))

-- set up the filename in the texture (MODIFY THIS TO SOME of your own textures)
-- on evaluation, Octane will try to load the texture and fill in the empty attributes
texNode:setAttribute(octane.A_FILENAME, "/home/thomas/Documents/textures/uv_test.jpg")
print("after eval")
print(texNode:getAttribute(octane.A_TYPE))
print(texNode:getAttribute(octane.A_SOURCE_INFO))
print(texNode:getAttribute(octane.A_SIZE)[1], texNode:getAttribute(octane.A_SIZE)[2])


Most nodes have input pins (graphs don't have input pins). A connection can be made with another node if the output type of the other node matches the pin type. When creating an internal node the connection is made implicitely. When a connection can't be made, the script will halt with an error. Like with attributes, pins can be accessed via id, name or index. Using the id is the preferred method. Pins can have a specific value range. For example fov on the camera goes from 1 to 179 degrees. When you connect a float node with x value 1000 to the camera's fov pin, the fov will still be only 179 and not 1000. This is because pins validate the value they get from a connected node. If you want modify or fetch the value of a connected node, you can either do it directly via the node (setAttribute, getAttribute) or "through" the pin (setPinValue, getPinValue). When going through the pin, the value is clamped to the range of the pin. (pins that have this behavior are PT_FLOAT, PT_INT, PT_ENUN and PT_TRANSFORM).

Code: Select all
-- create a diffuse material
mat = octane.node.create{ type=octane.NT_MAT_DIFFUSE, name="Diffuse", position={ 500, 500 } }
-- let's create a grayscale colour
tex = octane.node.create{ type=octane.NT_TEX_FLOAT, name="GrayScale", position={ 400, 400 } }
-- connect the grayscale colour to the bump pin of the material
mat:connectTo(octane.P_BUMP, tex)
-- see if the connection was really made
print(mat:getConnectedNode(octane.P_BUMP) == tex)

-- get the value of the grayscale texture through the pin.
print(mat:getPinValue(octane.P_BUMP)[1])

-- set the value again through the pin, if the value is out of the range of this pin
-- [0, 1] in this case, it will be clamped if set via the pin
mat:setPinValue(octane.P_BUMP, { -1, 0, 0 })
-- get the value directly from the texture, it should be clamped to 0
print(tex:getAttribute(octane.A_VALUE))

-- now disconnect the node again by passing in nil
mat:disconnect(octane.P_BUMP)
print(mat:getConnectedNode(octane.P_BUMP))


Graphs are simply put a container of items. A project always has a single root graph, the scene graph, which can be accessed via octane.node.getRootGraph(). Items are added to a graph on creation. Altough it appears in the standalone that graphs have pins, they don't. Graphs get their input via input linker nodes (prefix NT_IN) and output via output linker nodes (PREFIX NT_OUT). There's nothing special about them, all they do is pass a connection through from a node outside the graph to a node inside (or vica versa). We can get the items in a graph, search for stuff or copy from one graph to another:

Code: Select all
-- helper to generate a random position so we don't create
-- all the items on top of each other.
function rndPos()
    return { math.random(400, 600), math.random(400, 600) }
end

-- create a graph in the scene's root graph
g = octane.nodegraph.create{ type=octane.GT_STANDARD, name="Black Box", position=rndPos() }
-- an output linker
outLink = octane.node.create{ type=octane.NT_OUT_FLOAT, name="Output", graphOwner=g, position=rndPos() }
-- create an input linker
inLink = octane.node.create{ type=octane.NT_IN_FLOAT, name="Input", graphOwner=g, position=rndPos() }
-- let's just connect through the graph (not that usefull ;)
outLink:connectTo(octane.P_INPUT, inLink)

-- now let's add some random nodes in the graph
for i=1,3 do
    octane.node.create{ type=octane.NT_BOOL, name="Random Noise", graphOwner=g, position=rndPos() }
end

-- let's find out what is in our graph
print("-- items in the graph")
for i, v in ipairs(g:getOwnedItems()) do
    print(i, v)
end

-- lets find all the bool nodes
print("-- bool nodes")
for i,v in ipairs(g:findNodes(octane.NT_BOOL)) do
    print(i, v)
end

-- lets copy all the bool nodes directly in the scene graph
octane.nodegraph.getRootGraph():copyFrom(g:findNodes(octane.NT_BOOL))

-- let's create a graph and copy all the cruft in there
copy = octane.nodegraph.create{ type=octane.GT_STANDARD, name="Copy", position=rndPos() }
copy:copyFromGraph(g)


There's a special flavor of graphs called root graphs. We already encoutered one, the scene graph. Root graphs can do everything a plain graph can but they don't have an owner (and you can set an animation time on them, but more on that later). When created, they don't appear in your project and they're automatically destroyed when the script ends. They come in handy as a temporary storage for the scene graph. For example if you don't want your script to modify the original project. Because they don't have an owner, they're not coupled to a project so you could use them to copy between projects:

Code: Select all
-- load a project
octane.project.load("/home/thomas/Documents/octane-projects/cube-test.ocs")

-- create a root graph (without an owner)
rootGraph = octane.nodegraph.createRootGraph("Copier")

-- copy the whole scene in the root graph
rootGraph:copyFromGraph(octane.nodegraph.getRootGraph())

-- create a new project
octane.project.reset()

-- dump the content from our graph in the new project
octane.nodegraph.getRootGraph():copyFromGraph(rootGraph)


That wraps up the basic node and graphs stuff. I hope the modules octane.node and octane.nodegraph make a bit more sense now. If something is not clear, please ask.

cheers,
Thomas
User avatar
stratified
OctaneRender Team
OctaneRender Team
 
Posts: 945
Joined: Wed Aug 15, 2012 6:32 am
Location: Auckland, New Zealand

Re: Nodes and Nodegraphs in Lua.

Postby matej » Thu Dec 12, 2013 11:08 am

matej Thu Dec 12, 2013 11:08 am
Here I'm trying to create a "proto" shader graph with inputs & outputs. I'm able to create the pins, but not the nodes that go inside the pin. The node has two RGB textures and a float scale for inputs.

The script executes, but the pin is not populated with a node:

Code: Select all
-- root node graph parameters
params = {}
params.type = octane.GT_STANDARD
params.name = "Proto Shader"
params.position = {200, 200}

root = octane.nodegraph.create(params)

-- create input pins
inColor1 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Color1", graphOwner=root}
inColor2 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Color2", graphOwner=root}
inScale = octane.node.create{type=octane.NT_IN_FLOAT, name="Scale", graphOwner=root}

-- create a RGB texture node for the "inColor1" pin
octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor1, pinOwnerId=octane.P_TEXTURE}

-- create output pin
octane.node.create{type=octane.NT_OUT_MATERIAL, name="Material", graphOwner=root}



What is confusing is what constant to use for the "pinOwnerId"? I guess it should be a P_TEXTURE, since I'm trying to create RGB texture node for the texture input pin? I've tried also P_TEXTURE1 and P_TEXTURE2, but also doesn't work.

Or since it's a custom pin node it has a custom pin Id, and I need to get it somehow, but I dont know how :)
SW: Octane 3.05 | Linux Mint 18.1 64bit | Blender 2.78 HW: EVGA GTX 1070 | i5 2500K | 16GB RAM Drivers: 375.26
cgmo.net
User avatar
matej
Licensed Customer
Licensed Customer
 
Posts: 2083
Joined: Fri Jun 25, 2010 7:54 pm
Location: Slovenia

Re: Nodes and Nodegraphs in Lua.

Postby stratified » Thu Dec 12, 2013 7:18 pm

stratified Thu Dec 12, 2013 7:18 pm
Hi Matej,

All linker nodes (both input and output) have a single input pin with id octane.P_INPUT (you can look it up in the API browser). It's a bit confusing for input linkers because the input pin isn't actually drawn in the standalone (it's drawn as a pin on the encapsulating graph).

This should work:

Code: Select all
-- create a RGB texture node for the "inColor1" pin <- NOTE: graphs don't have pins. inColor1 is a linker node ;)
-- input of the linker node is octane.P_INPUT
octane.node.create{type=octane.NT_TEX_RGB, name="RGB", pinOwnerNode=inColor1, pinOwnerId=octane.P_INPUT}


cheers,
Thomas
User avatar
stratified
OctaneRender Team
OctaneRender Team
 
Posts: 945
Joined: Wed Aug 15, 2012 6:32 am
Location: Auckland, New Zealand

Re: Nodes and Nodegraphs in Lua.

Postby matej » Fri Dec 13, 2013 9:57 am

matej Fri Dec 13, 2013 9:57 am
Thanks Thomas, yeah now it works.

Here's the small example that will create this simple shader setup inside a custom node graph (ie. "macro"):
shader1.png


Code: Select all
-- table with params for the "macro" node graph
params = {}
params.type = octane.GT_STANDARD
params.name = "Proto Shader"
params.position = {200, 200}

-- creates the "macro" node graph, ie. root for all other nodes
root = octane.nodegraph.create(params)

-- creates two texture input pins and populates them with RGB texture nodes
inColor1 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Color1", graphOwner=root, position={300, 30}}
inColor2 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Color2", graphOwner=root, position={400, 30}}
inColor1Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor1, pinOwnerId=octane.P_INPUT}
inColor2Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor2, pinOwnerId=octane.P_INPUT}

-- change the color attribute for the RGB texture nodes to not 100% bright red & yellow
inColor1Node:setAttribute(octane.A_VALUE, {0.75, 0, 0})
inColor2Node:setAttribute(octane.A_VALUE, {0.75, 0.75, 0})

-- creates the output pin, material type
outMat = octane.node.create{type=octane.NT_OUT_MATERIAL, name="Material", graphOwner=root, position={450, 350}}

-- creates two materials and a material mix node
diffuse = octane.node.create{type=octane.NT_MAT_DIFFUSE, name="Diffuse", graphOwner=root, position={300, 250}}
glossy = octane.node.create{type=octane.NT_MAT_GLOSSY, name="Glossy", graphOwner=root, position={600, 250}}
matMix = octane.node.create{type=octane.NT_MAT_MIX, name="MatMix", graphOwner=root, position={450, 300}}

-- connects everything
diffuse:connectTo(octane.P_DIFFUSE, inColor1)
glossy:connectTo(octane.P_DIFFUSE, inColor2)
matMix:connectTo(octane.P_MATERIAL1, diffuse)
matMix:connectTo(octane.P_MATERIAL2, glossy)
outMat:connectTo(octane.P_INPUT, matMix)
SW: Octane 3.05 | Linux Mint 18.1 64bit | Blender 2.78 HW: EVGA GTX 1070 | i5 2500K | 16GB RAM Drivers: 375.26
cgmo.net
User avatar
matej
Licensed Customer
Licensed Customer
 
Posts: 2083
Joined: Fri Jun 25, 2010 7:54 pm
Location: Slovenia

Re: Nodes and Nodegraphs in Lua.

Postby stratified » Fri Dec 13, 2013 10:02 am

stratified Fri Dec 13, 2013 10:02 am
Yep, that's a great example of how to create a setup in Lua, nice work!

cheers,
Thomas
User avatar
stratified
OctaneRender Team
OctaneRender Team
 
Posts: 945
Joined: Wed Aug 15, 2012 6:32 am
Location: Auckland, New Zealand

Re: Nodes and Nodegraphs in Lua.

Postby bepeg4d » Fri Dec 13, 2013 11:48 am

bepeg4d Fri Dec 13, 2013 11:48 am
wow, a big thanks to thomas and matej :)
this is very useful :)
i have absolutely any knowledge in programming, but with your example i was able to modify it quite easily :)
here is my version with a pin color for the transmission channel of the diffuse material:
Code: Select all
-- table with params for the "macro" node graph
params = {}
params.type = octane.GT_STANDARD
params.name = "Mix-Diff-Glossy"
params.position = {300, 200}

-- creates the "macro" node graph, ie. root for all other nodes
root = octane.nodegraph.create(params)

-- creates three texture input pins and populates them with RGB texture nodes
inColor1 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Diffuse-Color", graphOwner=root, position={250, 100}}
inColor2 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Glossy-Color", graphOwner=root, position={550, 100}}
inColor3 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Trans-Color", graphOwner=root, position={350, 100}}
inColor1Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor1, pinOwnerId=octane.P_INPUT}
inColor2Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor2, pinOwnerId=octane.P_INPUT}
inColor3Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor3, pinOwnerId=octane.P_INPUT}

-- change the color attribute for the RGB texture nodes to not 100% bright red & yellow
inColor1Node:setAttribute(octane.A_VALUE, {0, 0.75, 0})
inColor2Node:setAttribute(octane.A_VALUE, {0.75, 0.75, 0})
inColor3Node:setAttribute(octane.A_VALUE, {1, 1, 0.75})

-- creates the output pin, material type
outMat = octane.node.create{type=octane.NT_OUT_MATERIAL, name="Material", graphOwner=root, position={450, 350}}

-- creates two materials and a material mix node
diffuse = octane.node.create{type=octane.NT_MAT_DIFFUSE, name="Diffuse", graphOwner=root, position={300, 250}}
glossy = octane.node.create{type=octane.NT_MAT_GLOSSY, name="Glossy", graphOwner=root, position={600, 250}}
matMix = octane.node.create{type=octane.NT_MAT_MIX, name="MatMix", graphOwner=root, position={450, 300}}

-- connects everything
diffuse:connectTo(octane.P_DIFFUSE, inColor1)
diffuse:connectTo(octane.P_TRANSMISSION, inColor3)
glossy:connectTo(octane.P_DIFFUSE, inColor2)
matMix:connectTo(octane.P_MATERIAL1, diffuse)
matMix:connectTo(octane.P_MATERIAL2, glossy)
outMat:connectTo(octane.P_INPUT, matMix)

ciao beppe

p.s. thanks for the lua on mac, thomas ;)
User avatar
bepeg4d
Octane Guru
Octane Guru
 
Posts: 6578
Joined: Wed Jun 02, 2010 6:02 am
Location: Italy

Re: Nodes and Nodegraphs in Lua.

Postby bepeg4d » Fri Dec 13, 2013 3:23 pm

bepeg4d Fri Dec 13, 2013 3:23 pm
i have tried to go a bit further but i get an error at line 29 :roll:
Code: Select all
-- table with params for the "macro" node graph
params = {}
params.type = octane.GT_STANDARD
params.name = "Mix-Organic"
params.position = {500, 200}

-- creates the "macro" node graph, ie. root for all other nodes
root = octane.nodegraph.create(params)

-- creates three texture input pins and populates them with RGB texture nodes
inColor1 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Diffuse-Color", graphOwner=root, position={200, 100}}
inColor2 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Bump", graphOwner=root, position={450, 150}}
inColor3 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Trans-Color", graphOwner=root, position={300, 100}}
inColor4 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Specular-Rough", graphOwner=root, position={500, 100}}
invert = octane.node.create{type=octane.NT_TEX_INVERT, name="invert", graphOwner=root, position={550, 150}}
inColor5 = octane.node.create{type=octane.NT_IN_TEXTURE, name="Opacity", graphOwner=root, position={450, 200}}
inColor1Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor1, pinOwnerId=octane.P_INPUT}
inColor2Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor2, pinOwnerId=octane.P_INPUT}
inColor3Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor3, pinOwnerId=octane.P_INPUT}
inColor4Node = octane.node.create{type=octane.NT_TEX_RGB, pinOwnerNode=inColor4, pinOwnerId=octane.P_INPUT}
invertNode = octane.node.create{type=octane.NT_TEX_INVERT, pinOwnerNode=invert, pinOwnerId=octane.P_INPUT}
inColor5Node = octane.node.create{type=octane.NT_TEX_FLOAT, pinOwnerNode=inColor5, pinOwnerId=octane.P_INPUT}

-- change the color attribute for the RGB texture nodes to not 100% bright red & yellow
inColor1Node:setAttribute(octane.A_VALUE, {0.75, 0.75, 0})
inColor2Node:setAttribute(octane.A_VALUE, {0, 0, 0})
inColor3Node:setAttribute(octane.A_VALUE, {1, 1, 0.75})
inColor4Node:setAttribute(octane.A_VALUE, {1, 1, 1})
inColor5Node:setAttribute(octane.A_VALUE, {1})

-- creates the output pin, material type
outMat = octane.node.create{type=octane.NT_OUT_MATERIAL, name="Material", graphOwner=root, position={450, 350}}

-- creates two materials and a material mix node
diffuse = octane.node.create{type=octane.NT_MAT_DIFFUSE, name="Diffuse", graphOwner=root, position={300, 250}}
glossy = octane.node.create{type=octane.NT_MAT_GLOSSY, name="Glossy", graphOwner=root, position={600, 250}}
matMix = octane.node.create{type=octane.NT_MAT_MIX, name="MatMix", graphOwner=root, position={450, 300}}

-- connects everything
diffuse:connectTo(octane.P_DIFFUSE, inColor1)
diffuse:connectTo(octane.P_TRANSMISSION, inColor3)
diffuse:connectTo(octane.P_BUMP, inColor2)
diffuse:connectTo(octane.P_OPACITY, inColor5)
glossy:connectTo(octane.P_DIFFUSE, inColor1)
glossy:connectTo(octane.P_BUMP, inColor2)
glossy:connectTo(octane.P_SPECULAR, inColor4)
invert:connectTo(octane.P_TEXTURE, inColor4)
glossy:connectTo(octane.P_ROUGHNESS, invert)
glossy:connectTo(octane.P_OPACITY, inColor5)
matMix:connectTo(octane.P_MATERIAL1, diffuse)
matMix:connectTo(octane.P_MATERIAL2, glossy)
outMat:connectTo(octane.P_INPUT, matMix)

ciao beppe
User avatar
bepeg4d
Octane Guru
Octane Guru
 
Posts: 6578
Joined: Wed Jun 02, 2010 6:02 am
Location: Italy

Re: Nodes and Nodegraphs in Lua.

Postby pixelrush » Fri Dec 13, 2013 5:29 pm

pixelrush Fri Dec 13, 2013 5:29 pm
Possibly you need 3 values...
i7-3820 @4.3Ghz | 24gb | Win7pro-64
GTS 250 display + 2 x GTX 780 cuda| driver 331.65
Octane v1.55
User avatar
pixelrush
Licensed Customer
Licensed Customer
 
Posts: 1618
Joined: Mon Jan 11, 2010 7:11 pm
Location: Nelson, New Zealand

Re: Nodes and Nodegraphs in Lua.

Postby bepeg4d » Fri Dec 13, 2013 6:03 pm

bepeg4d Fri Dec 13, 2013 6:03 pm
pixelrush wrote:Possibly you need 3 values...

i have tried also with 3 values but it doesn't work :mrgreen:
since i had the brilliant idea to switch from RGB to FLOAT, i always got the error :)
in theory, one value should be enough :roll:
ciao beppe
User avatar
bepeg4d
Octane Guru
Octane Guru
 
Posts: 6578
Joined: Wed Jun 02, 2010 6:02 am
Location: Italy

Re: Nodes and Nodegraphs in Lua.

Postby r-username » Fri Dec 13, 2013 7:48 pm

r-username Fri Dec 13, 2013 7:48 pm
Very nice script.

Would it be possible to enter hex values or 0-255 values? I looked thru the API without success.

I understand the whole linear workflow but all my clients use hex or 0-255 to define colors. if not please add for a future release, I would really like to use the script method.

Thanks in advance
i7 960 - W7x64 - 12 GB - 2x GTX 780ti
http://www.startsimple.com/ - http://www.gigavr.com/
r-username
Licensed Customer
Licensed Customer
 
Posts: 217
Joined: Thu Nov 24, 2011 3:39 pm
Next

Return to Lua Scripting


Who is online

Users browsing this forum: No registered users and 3 guests

Tue Sep 17, 2019 2:54 am [ UTC ]