diff --git a/packages/cultmath/tests/CultMath.Tests/GlslMirrorTests.cs b/packages/cultmath/tests/CultMath.Tests/GlslMirrorTests.cs index adcff740..8f5ee796 100644 --- a/packages/cultmath/tests/CultMath.Tests/GlslMirrorTests.cs +++ b/packages/cultmath/tests/CultMath.Tests/GlslMirrorTests.cs @@ -113,8 +113,7 @@ public sealed class GlslMirrorTests Assert.Contains(" MPL-2.0;", phacelle); Assert.DoesNotContain("MIT", phacelle); - var cycles = lowered.Single(output => output.File == "CultMath.Cycles.glsl").Text.Split(' -')[0]; + var cycles = lowered.Single(output => output.File == "CultMath.Cycles.glsl").Text.Split('\n')[0]; Assert.Contains("cultmath_cycles_ramp_index is in CultMath.Cycles.glsl", library); Assert.Contains(" Apache-2.0;", cycles); Assert.DoesNotContain("MIT", cycles); diff --git a/packages/cultmath/tools/compile-glsl.ps1 b/packages/cultmath/tools/compile-glsl.ps1 index f43a7e8c..45929cac 100644 --- a/packages/cultmath/tools/compile-glsl.ps1 +++ b/packages/cultmath/tools/compile-glsl.ps1 @@ -5,6 +5,9 @@ param( # Also concatenate shaders\CultMath.Phacelle.glsl (MPL-2.0) after CultMath.glsl, as a consumer that # calls cultmath_phacelle does. Without it the wrapper is the MIT library alone. [switch]$Phacelle, + # Also concatenate shaders\CultMath.Cycles.glsl (Apache-2.0), as a consumer that calls a cultmath_cycles_ + # function does. + [switch]$Cycles, [string]$GlslangPath = "" ) @@ -23,6 +26,9 @@ $library = Get-Content -LiteralPath (Join-Path $repoRoot "shaders\CultMath.glsl" if ($Phacelle) { $library += Get-Content -LiteralPath (Join-Path $repoRoot "shaders\CultMath.Phacelle.glsl") -Raw } +if ($Cycles) { + $library += Get-Content -LiteralPath (Join-Path $repoRoot "shaders\CultMath.Cycles.glsl") -Raw +} $calls = foreach ($match in [regex]::Matches($library, '(?m)^\w+\s+(cultmath_\w+)\s*\(([^)]*)\)')) { $arguments = foreach ($parameter in ($match.Groups[2].Value -split ',')) { $type = ($parameter.Trim() -split '\s+')[0] diff --git a/packages/cultmath/tools/cycles-oracle/oracle.py b/packages/cultmath/tools/cycles-oracle/oracle.py index 5a1f9381..66a21bf5 100644 --- a/packages/cultmath/tools/cycles-oracle/oracle.py +++ b/packages/cultmath/tools/cycles-oracle/oracle.py @@ -43,6 +43,11 @@ bpy.ops.mesh.primitive_plane_add(size=2) PLANE = bpy.context.active_object +def by_identifier(sockets, identifier): + """A node's socket by identifier: several data types share one socket name.""" + return next(socket for socket in sockets if socket.identifier == identifier) + + def f32(values): return np.asarray(values, dtype=np.float32) @@ -304,7 +309,7 @@ def family_map_range(): node.clamp = False sockets = operand_sockets(tree, imgs, 6) for k, identifier in enumerate(["Value", "From_Min", "From_Max", "To_Min", "To_Max", "Steps"]): - socket = next(i for i in node.inputs if i.identifier == identifier and i.enabled) + socket = by_identifier(node.inputs, identifier) tree.links.new(sockets[k], socket) return [node.outputs["Result"]] @@ -317,7 +322,7 @@ def family_map_range(): node.clamp = True sockets = operand_sockets(tree, imgs, 6) for k, identifier in enumerate(["Value", "From_Min", "From_Max", "To_Min", "To_Max", "Steps"]): - socket = next(i for i in node.inputs if i.identifier == identifier and i.enabled) + socket = by_identifier(node.inputs, identifier) tree.links.new(sockets[k], socket) return [node.outputs["Result"]] @@ -372,8 +377,8 @@ def family_mix(): node.clamp_result = False sockets = operand_sockets(tree, imgs, 3) for k, identifier in enumerate(["Factor_Float", "A_Float", "B_Float"]): - tree.links.new(sockets[k], next(i for i in node.inputs if i.identifier == identifier)) - return [node.outputs["Result_Float"]] + tree.links.new(sockets[k], by_identifier(node.inputs, identifier)) + return [by_identifier(node.outputs, "Result_Float")] functions.append({"function": "cycles_mix_float", "node": "ShaderNodeMix FLOAT", "cases": encode_cases(columns, bake("mix_float", images, build_float, 1))}) @@ -386,10 +391,10 @@ def family_mix(): node.factor_mode = "UNIFORM" node.clamp_factor = False sockets = operand_sockets(tree, imgs, 1) - tree.links.new(sockets[0], next(i for i in node.inputs if i.identifier == "Factor_Float")) - tree.links.new(triple_socket(tree, imgs, 1), next(i for i in node.inputs if i.identifier == "A_Vector")) - tree.links.new(triple_socket(tree, imgs, 4), next(i for i in node.inputs if i.identifier == "B_Vector")) - return node.outputs["Result_Vector"] + tree.links.new(sockets[0], by_identifier(node.inputs, "Factor_Float")) + tree.links.new(triple_socket(tree, imgs, 1), by_identifier(node.inputs, "A_Vector")) + tree.links.new(triple_socket(tree, imgs, 4), by_identifier(node.inputs, "B_Vector")) + return by_identifier(node.outputs, "Result_Vector") functions.append({"function": "cycles_mix_vector", "node": "ShaderNodeMix VECTOR UNIFORM", "cases": encode_cases(columns, vector_bake("mix_vector", images, build_vector))}) @@ -404,10 +409,10 @@ def family_mix(): node.clamp_factor = False node.clamp_result = False sockets = operand_sockets(tree, imgs, 1) - tree.links.new(sockets[0], next(i for i in node.inputs if i.identifier == "Factor_Float")) - tree.links.new(triple_socket(tree, imgs, 1), next(i for i in node.inputs if i.identifier == "A_Color")) - tree.links.new(triple_socket(tree, imgs, 4), next(i for i in node.inputs if i.identifier == "B_Color")) - return node.outputs["Result_Color"] + tree.links.new(sockets[0], by_identifier(node.inputs, "Factor_Float")) + tree.links.new(triple_socket(tree, imgs, 1), by_identifier(node.inputs, "A_Color")) + tree.links.new(triple_socket(tree, imgs, 4), by_identifier(node.inputs, "B_Color")) + return by_identifier(node.outputs, "Result_Color") functions.append({"function": function, "node": "ShaderNodeMix RGBA " + blend, "cases": encode_cases(columns, vector_bake(function, images, build))}) return functions