From e316e514be78a20879a98f2fe0c51de99041f58e Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Mon, 22 Oct 2018 14:15:53 -0600 Subject: [PATCH] various fixes to make the rivet shader work. --- Nodes.py | 42 +++++++++++++++++++++++++++++++++++++++++- OSOInstruction.py | 5 ++++- OSOReader.py | 11 ++++++++--- OSOVariable.py | 3 ++- OpcodeBaseTypes.py | 2 +- Opcodes.py | 7 +++++-- __init__.py | 14 +++++++++++++- osl_py_addin.py | 1 + 8 files changed, 75 insertions(+), 10 deletions(-) diff --git a/Nodes.py b/Nodes.py index 5e42dac..ba73dd4 100644 --- a/Nodes.py +++ b/Nodes.py @@ -68,6 +68,33 @@ def AddNodeLink(self, targetNode, targetIndex, sourceNode, SourceIndex): link = NodeLink(targetNode, targetIndex, sourceNode, SourceIndex) self.LinkList.append(link) + def prune(self): + return + print("---------prune---------") + while True: + SourceNodes = [] + for el in self.LinkList: + if el.SourceNode not in SourceNodes: + SourceNodes.append(el.SourceNode) + + DeadNodes = [] + for el in self.NodeList: + if el not in SourceNodes: + if (el.Name != "OutputNode"): + DeadNodes.append(el) + print("Dead Nodes : %s" % len(DeadNodes)) + for nod in DeadNodes: + print("Dead node : %s " % nod.Name) + TargetLinks = [] + for el in self.LinkList: + if el.TargetNode == nod: + TargetLinks.append(el) + for el in TargetLinks: + self.LinkList.remove(el) + self.NodeList.remove(nod) + if (len(DeadNodes)==0): + break + def Nodes(self): return self.Nodes @@ -110,15 +137,28 @@ def MakeConst(self, var): print("Unsupported const type %s(%s)" % (var.Name, var.dataType)) def MakeGlobal(self,var): - node = self.CreateNode('ShaderNodeNewGeometry') if var.Name=="N": + node = self.CreateNode('ShaderNodeNewGeometry') self.SetVar(var, node, 1) elif var.Name=="I": + node = self.CreateNode('ShaderNodeNewGeometry') self.SetVar(var, node, 4) elif var.Name=="P": + node = self.CreateNode('ShaderNodeNewGeometry') self.SetVar(var, node, 0) elif var.Name=="Ng": + node = self.CreateNode('ShaderNodeNewGeometry') self.SetVar(var, node, 3) + elif var.Name=="u": + node = self.CreateNode('ShaderNodeTexCoord') + Split = self.CreateNode('ShaderNodeSeparateXYZ') + self.AddNodeLink(Split, 0, node, 0) + self.SetVar(var, Split, 0) + elif var.Name=="v": + node = self.CreateNode('ShaderNodeTexCoord') + Split = self.CreateNode('ShaderNodeSeparateXYZ') + self.AddNodeLink(Split, 0, node, 0) + self.SetVar(var, Split, 1) else: print("Unhandled global %s" % var.Name) diff --git a/OSOInstruction.py b/OSOInstruction.py index a4180d1..522023f 100644 --- a/OSOInstruction.py +++ b/OSOInstruction.py @@ -1,6 +1,9 @@ +import shlex + class OSOInstruction(): def __init__(self, line, tag): - tokens = line.split() + tokens = shlex.split(line) + tokens = [word for word in tokens if not word.startswith('%meta')] self.Opcode = tokens[0] self.Tag = tag self.Hints = [] diff --git a/OSOReader.py b/OSOReader.py index ffdce0a..2719885 100644 --- a/OSOReader.py +++ b/OSOReader.py @@ -1,3 +1,4 @@ +import shlex from .OSOVariable import OSOVariable from .OSOInstruction import OSOInstruction from enum import Enum @@ -23,7 +24,7 @@ def __init__(self, filename): self.Instructions.append(inst) def HandleVersion(self, line): - tokens = line.split() + tokens = shlex.split(line) if tokens[0] == 'OpenShadingLanguage': self.Version = tokens[1] self.ParserState = ParserState.WaitVariablesAndCode @@ -31,7 +32,9 @@ def HandleVersion(self, line): return False def HandleCode(self, line): - tokens = line.split() + tokens = shlex.split(line) + tokens = [word for word in tokens if not word.startswith('%meta')] + if tokens[0] == 'code': self.CurrentTag = tokens[1] else: @@ -40,7 +43,9 @@ def HandleCode(self, line): return True def HandleVariablesAndCode(self, line): - tokens = line.split() + tokens = shlex.split(line) + tokens = [word for word in tokens if not word.startswith('%meta')] + if tokens[0] == 'code': self.ParserState = ParserState.WaitCode return self.HandleCode(line) diff --git a/OSOVariable.py b/OSOVariable.py index 447e945..ac61185 100644 --- a/OSOVariable.py +++ b/OSOVariable.py @@ -1,6 +1,7 @@ +import shlex class OSOVariable(): def __init__(self, line): - tokens = line.split() + tokens = shlex.split(line) idx = 2 if len(tokens) > 2: self.InitVar = "" diff --git a/OpcodeBaseTypes.py b/OpcodeBaseTypes.py index e8d65db..e2fde24 100644 --- a/OpcodeBaseTypes.py +++ b/OpcodeBaseTypes.py @@ -156,7 +156,7 @@ def GeneratePointPoint(self, nodeGraph): nodeGraph.AddLink(node, 0, self.Source1) nodeGraph.AddLink(node, 1, self.Source2) nodeGraph.SetVar(self.Destination, node, 0) - elif self.Operation in ["MULTIPLY" ,"DIVIDE"]: + elif self.Operation in ["MULTIPLY" ,"DIVIDE","MODULO"]: node1 = nodeGraph.CreateNode('ShaderNodeSeparateXYZ') nodeGraph.AddLink(node1, 0, self.Source1) node2 = nodeGraph.CreateNode('ShaderNodeSeparateXYZ') diff --git a/Opcodes.py b/Opcodes.py index f854d76..46d26e8 100644 --- a/Opcodes.py +++ b/Opcodes.py @@ -691,6 +691,9 @@ def __init__(self, OSO, index): elif (len(self.Instuction.Parameters) == 2): self.Source1 = OSOVariable('const string uperlin "uperlin"') self.Source2 = OSO.GetVariable(self.Instuction.Parameters[1]) + if (len(self.Instuction.Parameters) == 4): #TODO: period is ignored. + self.Source1 = OSO.GetVariable(self.Instuction.Parameters[1]) + self.Source2 = OSO.GetVariable(self.Instuction.Parameters[2]) def Destination(self): return self.Destination @@ -715,7 +718,7 @@ def Generate(self, nodeGraph): elif (self.Destination.IsPointLike()): nodeGraph.SetVar(self.Destination, node, 0) - if self.Source1.defaults[0] in ['"perlin"','"snoise"'] : + if self.Source1.defaults[0] in ['"perlin"','"snoise"',"perlin","snoise"] : node = nodeGraph.CreateNode("ShaderNodeTexNoise") node.SetProperty("inputs[1].default_value", "1.0") node.SetProperty("inputs[2].default_value", "0.0") @@ -780,7 +783,7 @@ def Generate(self, nodeGraph): else: print("unknown noise target") - if self.Source1.defaults[0] == '"cell"': + if self.Source1.defaults[0] in ['"cell"','cell'] : # split the source vector node = nodeGraph.CreateNode('ShaderNodeSeparateXYZ') nodeGraph.AddLink(node, 0, self.Source2) diff --git a/__init__.py b/__init__.py index 09d9b96..26b1def 100644 --- a/__init__.py +++ b/__init__.py @@ -2,6 +2,9 @@ import bpy import nodeitems_utils from nodeitems_utils import NodeCategory, NodeItem +import sys +import importlib + bl_info = { "name": "OSLPY", @@ -16,7 +19,16 @@ "wiki_url": "", "category": "Node"} - +modulesNames = ['NodeGroupBuilder', 'Nodes','OpcodeBaseTypes','Opcodes','osl_py_addin','OSOInstruction','OSOReader','OSOVariable','StringBuilder'] + +modulesFullNames = {} +for currentModuleName in modulesNames: + modulesFullNames[currentModuleName] = ('{}'.format(currentModuleName)) + +for currentModuleFullName in modulesFullNames.values(): + if currentModuleFullName in sys.modules: + importlib.reload(sys.modules[currentModuleFullName]) + class ExtraNodesCategory(NodeCategory): @classmethod def poll(cls, context): diff --git a/osl_py_addin.py b/osl_py_addin.py index 21650e8..4bd78be 100644 --- a/osl_py_addin.py +++ b/osl_py_addin.py @@ -123,6 +123,7 @@ def UpdateScript(self): OutputIdx = OutputIdx + 1 # print("Compiled %s", graph.ShaderName) # print("Generating nodegroup...") + graph.prune() self.node_tree = CreateNodeGroup(graph, oso.Variables) for var in oso.Variables: if var.varType == 'param' and 'oslpy_has_' in var.Name: