From 19ab99f8921f293630012cbf056b1f2a2f9e12d9 Mon Sep 17 00:00:00 2001 From: Valtteri Koskivuori Date: Sat, 16 Dec 2023 22:57:56 +0200 Subject: [PATCH] blender: Hook up background shader Blender 3.6 started crashing in the blender UI code after these changes, no idea why, I'll go test on 4.0 on my desktop. --- bindings/blender_init.py | 4 ++++ bindings/c_ray.py | 9 ++++++++- bindings/cray_wrap.c | 8 ++++++-- bindings/nodes/convert.py | 24 ++++++++++++++++++++++-- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/bindings/blender_init.py b/bindings/blender_init.py index 9d179012..aa8183dd 100644 --- a/bindings/blender_init.py +++ b/bindings/blender_init.py @@ -212,6 +212,10 @@ def sync_scene(self, renderer, depsgraph, b_scene): facebuf = (c_ray.cr_face * len(faces))(*faces) cr_mesh.bind_faces(bytearray(facebuf), len(faces)) cr_mesh.bind_vertex_buf(cr_vertex_buf(cr_scene, me)) + + # Set background shader + bl_nodetree = bpy.data.worlds[0].node_tree + cr_scene.set_background(convert_background(bl_nodetree)) return cr_scene def render(self, depsgraph): diff --git a/bindings/c_ray.py b/bindings/c_ray.py index ab0bcb5b..3d6435d7 100644 --- a/bindings/c_ray.py +++ b/bindings/c_ray.py @@ -304,7 +304,14 @@ def material_set_new(self): def instance_new(self, object, type): return instance(self.cr_ptr, object, type) def set_background(self, material): - return _lib.scene_set_background(self.cr_ptr, material) + if material is None: + return _lib.scene_set_background(self.cr_ptr, material) + self.background = material + ct.pythonapi.PyCapsule_New.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_void_p] + ct.pythonapi.PyCapsule_New.restype = ct.py_object + name = b'cray.shader_node' + capsule = ct.pythonapi.PyCapsule_New(ct.byref(material.cr_struct), name, None) + return _lib.scene_set_background(self.cr_ptr, capsule) def vertex_buf_new(self, v, vn, n, nn, t, tn): return vertex_buf(self.cr_ptr, v, vn, n, nn, t, tn) diff --git a/bindings/cray_wrap.c b/bindings/cray_wrap.c index 9ca01ef5..5623783f 100644 --- a/bindings/cray_wrap.c +++ b/bindings/cray_wrap.c @@ -518,8 +518,12 @@ static PyObject *py_cr_scene_set_background(PyObject *self, PyObject *args) { return NULL; } struct cr_scene *s = PyCapsule_GetPointer(s_ext, "cray.cr_scene"); - // TODO - bool ret = cr_scene_set_background(s, NULL); + if (!PyCapsule_IsValid(node_desc, "cray.shader_node")) { + cr_scene_set_background(s, NULL); + Py_RETURN_NONE; + } + struct cr_shader_node *desc = PyCapsule_GetPointer(node_desc, "cray.shader_node"); + bool ret = cr_scene_set_background(s, desc); return PyBool_FromLong(ret); } diff --git a/bindings/nodes/convert.py b/bindings/nodes/convert.py index de13be11..a6aaa9bc 100644 --- a/bindings/nodes/convert.py +++ b/bindings/nodes/convert.py @@ -5,6 +5,17 @@ from . value import * from . vector import * +def convert_background(nt): + if len(nt.nodes) < 1: + print("No nodes found for background, bailing out") + return None + if not 'World Output' in nt.nodes: + print("No World Output node found in tree for background, bailing out") + return None + root = nt.nodes['World Output'] + return parse_node(root.inputs['Surface'].links[0].from_node) + + def convert_node_tree(bl_depsgraph, mat, nt): if len(nt.nodes) < 1: print("No nodes found for material {}, bailing out".format(mat.name)) @@ -27,8 +38,11 @@ def parse_color(input): return NodeColorConstant(cr_color(vals[0], vals[1], vals[2], vals[3])) # case 'ShaderNodeTexImage': # return warning_color - # case 'ShaderNodeTexChecker': - # return warning_color + case 'ShaderNodeTexChecker': + color1 = parse_color(input.inputs['Color1']) + color2 = parse_color(input.inputs['Color2']) + scale = parse_value(input.inputs['Scale']) + return NodeColorCheckerboard(color1, color2, scale) # case 'ShaderNodeBlackbody': # return warning_color # case 'ShaderNodeCombineRGB': @@ -85,6 +99,12 @@ def parse_node(input): case 'ShaderNodeBsdfTranslucent': color = parse_color(input.inputs['Color']) return NodeShaderTranslucent(color) + case 'ShaderNodeBackground': + color = parse_color(input.inputs['Color']) + # Blender doesn't specify the pose here + pose = NodeVectorConstant(cr_vector(0.0, 0.0, 0.0)) + strength = parse_value(input.inputs['Strength']) + return NodeShaderBackground(color, pose, strength) case _: print("Unknown shader node of type {}, maybe fix.".format(input.bl_idname)) return warning_shader