diff --git a/__init__.py b/__init__.py index 6397f461..cf457304 100644 --- a/__init__.py +++ b/__init__.py @@ -30,7 +30,7 @@ bl_info = { "name": "RenderMan For Blender", "author": "Pixar", - "version": (25, 1, 0), + "version": (25, 2, 0), "blender": (2, 93, 0), "location": "Render Properties > Render Engine > RenderMan", "description": "RenderMan 25 integration", diff --git a/changelog.txt b/changelog.txt index fd58dff1..e299afb8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,19 @@ +v25.2, June 29, 2023 + +Changes: +* Changing the diffuseColor parameter when using PxrDiffuse should now update +the viewport color of the object, similar to PxrSurface. + +Bug fixes: +* Fixed a bug where perspective view was incorrectly taking into account the render +camera's shift_x and shift_y properties. +* Fixed issue where
was not getting correctly substititued in the tooltips +* Fixed a bug where blender_batch would fail when using Blender 3.5 +* Fixed an issue with using numpy.int when using Blender 3.5. +* Fixed a bug where node names with a ':' character in them would cause shading errors +* Fixed a bug where updating the parameters of any stylized filters would not update correctly +during IPR. + v25.1, June 1, 2023 Changes: diff --git a/rfb_utils/mesh_utils.py b/rfb_utils/mesh_utils.py index b1ba1d03..d04e7fee 100644 --- a/rfb_utils/mesh_utils.py +++ b/rfb_utils/mesh_utils.py @@ -34,17 +34,17 @@ def get_mesh(mesh, get_normals=False): N = [] npolygons = len(mesh.polygons) - fastnvertices = np.zeros(npolygons, dtype=np.int) + fastnvertices = np.zeros(npolygons, dtype=np.int32) mesh.polygons.foreach_get('loop_total', fastnvertices) nverts = fastnvertices.tolist() loops = len(mesh.loops) - fastvertices = np.zeros(loops, dtype=np.int) + fastvertices = np.zeros(loops, dtype=np.int32) mesh.loops.foreach_get('vertex_index', fastvertices) verts = fastvertices.tolist() if get_normals: - fastsmooth = np.zeros(npolygons, dtype=np.int) + fastsmooth = np.zeros(npolygons, dtype=np.int32) mesh.polygons.foreach_get('use_smooth', fastsmooth) if mesh.use_auto_smooth or True in fastsmooth: mesh.calc_normals_split() diff --git a/rfb_utils/property_callbacks.py b/rfb_utils/property_callbacks.py index 62918510..2aae59d0 100644 --- a/rfb_utils/property_callbacks.py +++ b/rfb_utils/property_callbacks.py @@ -209,6 +209,16 @@ def update_integrator_func(self, context): update_conditional_visops(node) scenegraph_utils.update_sg_integrator(context) +def update_samplefilters_func(self, context): + node = self.node if hasattr(self, 'node') else self + update_conditional_visops(node) + scenegraph_utils.update_sg_samplefilters(context) + +def update_displayfilters_func(self, context): + node = self.node if hasattr(self, 'node') else self + update_conditional_visops(node) + scenegraph_utils.update_sg_displayfilters(context) + def update_options_func(self, s, context): scenegraph_utils.update_sg_options(s, context) diff --git a/rfb_utils/rfb_node_desc_utils/rfb_node_desc.py b/rfb_utils/rfb_node_desc_utils/rfb_node_desc.py index 615c16bc..4728483d 100644 --- a/rfb_utils/rfb_node_desc_utils/rfb_node_desc.py +++ b/rfb_utils/rfb_node_desc_utils/rfb_node_desc.py @@ -16,7 +16,8 @@ from .rfb_node_desc_param import ( RfbNodeDescParamXML, RfbNodeDescParamOSL, - RfbNodeDescParamJSON) + RfbNodeDescParamJSON, + blender_finalize) # globals LIGHTFILTER_CLASSIF = "classification:rendernode/RenderMan/lightfilter" @@ -49,6 +50,7 @@ def __init__(self, *args): self._backward_compatibility() # free memory self.clear_parsed_data() + blender_finalize(self) def _set_ctlname(self): """remove any illegal character for a maya ui object.""" diff --git a/rfb_utils/rfb_node_desc_utils/rfb_node_desc_param.py b/rfb_utils/rfb_node_desc_utils/rfb_node_desc_param.py index 4732f95c..2f5de1cf 100644 --- a/rfb_utils/rfb_node_desc_utils/rfb_node_desc_param.py +++ b/rfb_utils/rfb_node_desc_utils/rfb_node_desc_param.py @@ -19,13 +19,12 @@ def blender_finalize(obj): """Post-process some parameters for Blender. """ - if obj.type in ['int', 'matrix']: + if hasattr(obj, 'type') and obj.type in ['int', 'matrix']: # these are NEVER connectable obj.connectable = False - if hasattr(obj, 'help'): + if hasattr(obj, 'help') and obj.help is not None: obj.help = obj.help.replace('\\"', '"') - #obj.help = obj.help.replace("'", "\\'") obj.help = obj.help.replace('
', '\n') class RfbNodeDescParamXML(NodeDescParamXML): diff --git a/rfb_utils/scenegraph_utils.py b/rfb_utils/scenegraph_utils.py index 2c482872..6003e03e 100644 --- a/rfb_utils/scenegraph_utils.py +++ b/rfb_utils/scenegraph_utils.py @@ -18,7 +18,17 @@ def set_material(sg_node, sg_material_node): def update_sg_integrator(context): from .. import rman_render rr = rman_render.RmanRender.get_rman_render() - rr.rman_scene_sync.update_integrator(context) + rr.rman_scene_sync.update_integrator(context) + +def update_sg_samplefilters(context): + from .. import rman_render + rr = rman_render.RmanRender.get_rman_render() + rr.rman_scene_sync.update_samplefilters(context) + +def update_sg_displayfilters(context): + from .. import rman_render + rr = rman_render.RmanRender.get_rman_render() + rr.rman_scene_sync.update_displayfilters(context) def update_sg_options(prop_name, context): from .. import rman_render diff --git a/rfb_utils/string_utils.py b/rfb_utils/string_utils.py index 06f1266c..1a021054 100644 --- a/rfb_utils/string_utils.py +++ b/rfb_utils/string_utils.py @@ -16,7 +16,7 @@ 'ies': 'ies', 'ptex': 'ptex' } -__NODE_NAME_REGEXP__ = r'\s+|\.+' +__NODE_NAME_REGEXP__ = r'\s+|\.+|:' class SceneStringConverter(object): """Class maintaining an up-to-date StringExpression object. diff --git a/rman_bl_nodes/__init__.py b/rman_bl_nodes/__init__.py index dc12c717..da0b5c55 100644 --- a/rman_bl_nodes/__init__.py +++ b/rman_bl_nodes/__init__.py @@ -175,6 +175,10 @@ def class_generate_properties(node, parent_name, node_desc): update_function = None if node_desc.node_type == 'integrator': update_function = update_integrator_func + elif node_desc.node_type == 'samplefilter': + update_function = update_samplefilters_func + elif node_desc.node_type == 'displayfilter': + update_function = update_displayfilters_func else: update_function = update_func_with_inputs if 'enable' in node_desc_param.name else update_func diff --git a/rman_config/config/rfb.json b/rman_config/config/rfb.json index 05994223..84ce6546 100644 --- a/rman_config/config/rfb.json +++ b/rman_config/config/rfb.json @@ -70,6 +70,9 @@ 1.0 ] }, + "PxrDiffuse": { + "diffuse_color": ["diffuseColor"] + }, "PxrMarschnerHair": { "diffuse_color": ["diffuseColor"], "specular_color": ["specularColorR"] diff --git a/rman_render.py b/rman_render.py index e970fd5c..f4336fa4 100644 --- a/rman_render.py +++ b/rman_render.py @@ -1091,6 +1091,7 @@ def start_interactive_render(self, context, depsgraph): self.rman_is_live_rendering = True render_cmd = "prman -live" render_cmd = self._append_render_cmd(render_cmd) + self.rman_scene_sync.reset() # reset the rman_scene_sync instance self.sg_scene.Render(render_cmd) self.start_stats_thread() diff --git a/rman_scene_sync.py b/rman_scene_sync.py index dcd4cadf..99e0c615 100644 --- a/rman_scene_sync.py +++ b/rman_scene_sync.py @@ -59,6 +59,7 @@ def __init__(self, rman_render=None, rman_scene=None, sg_scene=None): self.check_all_instances = False # force checking all instances self.rman_updates = dict() # A dicitonary to hold RmanUpdate instances + self.selected_channel = None @property def sg_scene(self): @@ -68,6 +69,13 @@ def sg_scene(self): def sg_scene(self, sg_scene): self.__sg_scene = sg_scene + def reset(self): + self.num_instances_changed = False + self.frame_number_changed = False + self.check_all_instances = False + self.rman_updates = dict() + self.selected_channel = None + def update_view(self, context, depsgraph): camera = depsgraph.scene.camera self.rman_scene.context = context @@ -978,6 +986,22 @@ def update_integrator(self, context): self.rman_scene.export_integrator() self.rman_scene.export_viewport_stats() + def update_samplefilters(self, context): + if not self.rman_render.rman_interactive_running: + return + if context: + self.rman_scene.bl_scene = context.scene + with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene): + self.rman_scene.export_samplefilters(sel_chan_name=self.selected_channel) + + def update_displayfilters(self, context): + if not self.rman_render.rman_interactive_running: + return + if context: + self.rman_scene.bl_scene = context.scene + with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene): + self.rman_scene.export_displayfilters() + def update_viewport_integrator(self, context, integrator): if not self.rman_render.rman_interactive_running: return @@ -1115,6 +1139,7 @@ def update_un_solo_light(self, context): def update_viewport_chan(self, context, chan_name): if not self.rman_render.rman_interactive_running: return + self.selected_channel = chan_name with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene): self.rman_scene.export_samplefilters(sel_chan_name=chan_name) diff --git a/rman_translators/rman_camera_translator.py b/rman_translators/rman_camera_translator.py index 45f4bf3c..8b98c3ee 100644 --- a/rman_translators/rman_camera_translator.py +++ b/rman_translators/rman_camera_translator.py @@ -263,9 +263,11 @@ def update_viewport_resolution(self, rman_sg_camera): # shift and offset shift_x = 0.0 shift_y = 0.0 - if cam: - shift_x = cam.shift_x - shift_y = cam.shift_y + + # FIXME: for now, don't take camera shift into account + #if cam: + # shift_x = cam.shift_x + # shift_y = cam.shift_y # FIXME? It seems like we don't need the view_camera_offset for some reason # Need to do some more testing, but taking it into account seems to shift the image diff --git a/rman_translators/rman_hair_curves_translator.py b/rman_translators/rman_hair_curves_translator.py index e3ec8bdc..9114d77b 100644 --- a/rman_translators/rman_hair_curves_translator.py +++ b/rman_translators/rman_hair_curves_translator.py @@ -154,7 +154,7 @@ def get_attributes(self, ob, bl_curve): hair_attr.array_len = -1 npoints = len(attr.data) - values = np.zeros(npoints, dtype=np.int) + values = np.zeros(npoints, dtype=np.int32) attr.data.foreach_get('value', values) hair_attr.values = values.tolist() diff --git a/rman_translators/rman_mesh_translator.py b/rman_translators/rman_mesh_translator.py index 0a06275c..cacc63cb 100644 --- a/rman_translators/rman_mesh_translator.py +++ b/rman_translators/rman_mesh_translator.py @@ -132,7 +132,7 @@ def _get_mesh_vgroup_(ob, mesh, name=""): return weights def _get_material_ids(ob, geo): - fast_material_ids = np.zeros(len(geo.polygons), dtype=np.int) + fast_material_ids = np.zeros(len(geo.polygons), dtype=np.int32) geo.polygons.foreach_get("material_index", fast_material_ids) material_ids = fast_material_ids.tolist() return material_ids @@ -284,7 +284,7 @@ def _get_subd_tags_(self, ob, mesh, primvar): if (creases > 0.0).any(): # we have edges where their crease is > 0.0 # grab only those edges - crease_edges = np.zeros(edges_len*2, dtype=np.int) + crease_edges = np.zeros(edges_len*2, dtype=np.int32) mesh.edges.foreach_get('vertices', crease_edges) crease_edges = np.reshape(crease_edges, (edges_len, 2)) crease_edges = crease_edges[creases > 0.0] diff --git a/rman_ui/rman_ui_light_handlers/__init__.py b/rman_ui/rman_ui_light_handlers/__init__.py index f817dc61..05d1d191 100644 --- a/rman_ui/rman_ui_light_handlers/__init__.py +++ b/rman_ui/rman_ui_light_handlers/__init__.py @@ -15,11 +15,12 @@ import bpy import gpu -if USE_GPU_MODULE: - bgl = None - from gpu_extras.batch import batch_for_shader -else: - import bgl +if not bpy.app.background: + if USE_GPU_MODULE: + bgl = None + from gpu_extras.batch import batch_for_shader + else: + import bgl _DRAW_HANDLER_ = None _FRUSTUM_DRAW_HELPER_ = None @@ -457,7 +458,7 @@ __MTX_Y_90__ = Matrix.Rotation(math.radians(90.0), 4, 'Y') -if USE_GPU_MODULE: +if USE_GPU_MODULE and not bpy.app.background: # Code reference: https://projects.blender.org/blender/blender/src/branch/main/doc/python_api/examples/gpu.7.py vert_out = gpu.types.GPUStageInterfaceInfo("image_interface")