<commit_before># utils
from .rfb_utils import object_utils
from .rfb_utils import transform_utils
from .rfb_utils import texture_utils
from .rfb_utils import scene_utils
from .rfb_utils import shadergraph_utils

from .rfb_logger import rfb_log
from .rman_sg_nodes.rman_sg_lightfilter import RmanSgLightFilter

from . import rman_constants
import bpy

class RmanSceneSync(object):
    '''
    The RmanSceneSync class handles keeping the RmanScene object in sync
    during IPR. 

    Attributes:
        rman_render (RmanRender) - pointer back to the current RmanRender object
        rman () - rman python module
        rman_scene (RmanScene) - pointer to the current RmanScene object
        sg_scene (RixSGSCene) - the RenderMan scene graph object

    '''

    def __init__(self, rman_render=None, rman_scene=None, sg_scene=None):
        self.rman_render = rman_render
        self.rman = rman_render.rman
        self.rman_scene = rman_scene
        self.sg_scene = sg_scene        

        self.new_objects = set() # set of objects that were added to the scene
        self.new_cameras = set() # set of new camera objects that were added to the scene
        self.update_instances = set() # set of objects we need to update their instances
        self.update_particles = set() # set of objects we need to update their particle systemd
        self.do_delete = False # whether or not we need to do an object deletion
        self.do_add = False # whether or not we need to add an object
        self.num_instances_changed = False # if the number of instances has changed since the last update

    @property
    def sg_scene(self):
        return self.__sg_scene

    @sg_scene.setter
    def sg_scene(self, sg_scene):
        self.__sg_scene = sg_scene          

    def update_view(self, context, depsgraph):
        camera = depsgraph.scene.camera
        self.rman_scene.context = context
        self.rman_scene.depsgraph = depsgraph
        self.rman_scene.bl_scene = depsgraph.scene_eval
        rman_sg_camera = self.rman_scene.main_camera
        translator = self.rman_scene.rman_translators['CAMERA']
        with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):
            if self.rman_scene.is_viewport_render:
                ob = translator.update_viewport_resolution(rman_sg_camera)
                if ob:
                    translator.update_viewport_cam(ob, rman_sg_camera, force_update=True)
                translator.update_transform(None, rman_sg_camera)
            else:
                translator.update_transform(camera, rman_sg_camera)  

    def _scene_updated(self):

        # Check changes to local view
        if self.rman_scene.bl_local_view and (self.rman_scene.context.space_data.local_view is None):
            self.rman_scene.bl_local_view = False
            for ob in self.rman_scene.bl_scene.objects:
                if ob.type in ('ARMATURE', 'CURVE', 'CAMERA', 'LIGHT'):
                    continue
                self.clear_instances(ob)
                self.update_instances.add(ob.original)
            with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):         
                self.rman_scene.check_solo_light()
        elif not self.rman_scene.bl_local_view and (self.rman_scene.context.space_data.local_view is not None):
            self.rman_scene.bl_local_view = True   
            for ob in self.rman_scene.bl_scene.objects:
                if ob.type in ('ARMATURE', 'CURVE', 'CAMERA', 'LIGHT'):
                    continue
                self.clear_instances(ob)               
                self.update_instances.add(ob.original)
            with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):                     
                self.rman_scene.check_solo_light()  

        # Check view_layer
        view_layer = self.rman_scene.depsgraph.view_layer
        if len(view_layer.objects) != self.rman_scene.num_objects_in_viewlayer:
            # objects can be removed from the viewlayer by hiding a collection. 
            # Figure out the difference using sets and re-emit their instances.
            self.rman_scene.num_objects_in_viewlayer = len(view_layer.objects)
            view_layer = self.rman_scene.depsgraph.view_layer
            set1 = set(self.rman_scene.objects_in_viewlayer)
            set2 =  set((view_layer.objects))
            set_diff1 = set1.difference(set2)
            set_diff2 = set2.difference(set1)

            objects = list(set_diff1.union(set_diff2))           
            for o in list(objects):
                try:
                    self.update_instances.add(o.original)
                    self.clear_instances(o)
                    self.update_particles.add(o)  
                    self.update_geometry_node_instances(o)     
                except:
                    continue

        self.rman_scene.objects_in_viewlayer = [o for o in view_layer.objects]            

        if self.rman_scene.bl_frame_current != self.rman_scene.bl_scene.frame_current:
            # frame changed, update any materials and objects that 
            # are marked as frame sensitive
            self.rman_scene.bl_frame_current = self.rman_scene.bl_scene.frame_current
            material_translator = self.rman_scene.rman_translators["MATERIAL"]

            with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):  
                for mat in bpy.data.materials:   
                    db_name = object_utils.get_db_name(mat)  
                    rman_sg_material = self.rman_scene.rman_materials.get(mat.original, None)
                    if rman_sg_material and rman_sg_material.is_frame_sensitive:
                        material_translator.update(mat, rman_sg_material)

                for o in bpy.data.objects:
                    rman_type = object_utils._detect_primitive_(o)
                    rman_sg_node = self.rman_scene.rman_objects.get(o.original, None)
                    if not rman_sg_node:
                        continue
                    translator = self.rman_scene.rman_translators.get(rman_type, None)
                    if translator and rman_sg_node.is_frame_sensitive:
                        translator.update(o, rman_sg_node)                   

    def _mesh_light_update(self, mat):
        with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):
            for ob_inst in self.rman_scene.depsgraph.object_instances:
                psys = None
                if ob_inst.is_instance:
                    ob = ob_inst.instance_object
                    group_db_name =  object_utils.get_group_db_name(ob_inst)<commit_msg>During IPR, if the frame changes, make sure we also update Ri_Frame.<commit_after># utils
from .rfb_utils import object_utils
from .rfb_utils import transform_utils
from .rfb_utils import texture_utils
from .rfb_utils import scene_utils
from .rfb_utils import shadergraph_utils

from .rfb_logger import rfb_log
from .rman_sg_nodes.rman_sg_lightfilter import RmanSgLightFilter

from . import rman_constants
import bpy

class RmanSceneSync(object):
    '''
    The RmanSceneSync class handles keeping the RmanScene object in sync
    during IPR. 

    Attributes:
        rman_render (RmanRender) - pointer back to the current RmanRender object
        rman () - rman python module
        rman_scene (RmanScene) - pointer to the current RmanScene object
        sg_scene (RixSGSCene) - the RenderMan scene graph object

    '''

    def __init__(self, rman_render=None, rman_scene=None, sg_scene=None):
        self.rman_render = rman_render
        self.rman = rman_render.rman
        self.rman_scene = rman_scene
        self.sg_scene = sg_scene        

        self.new_objects = set() # set of objects that were added to the scene
        self.new_cameras = set() # set of new camera objects that were added to the scene
        self.update_instances = set() # set of objects we need to update their instances
        self.update_particles = set() # set of objects we need to update their particle systemd
        self.do_delete = False # whether or not we need to do an object deletion
        self.do_add = False # whether or not we need to add an object
        self.num_instances_changed = False # if the number of instances has changed since the last update

    @property
    def sg_scene(self):
        return self.__sg_scene

    @sg_scene.setter
    def sg_scene(self, sg_scene):
        self.__sg_scene = sg_scene          

    def update_view(self, context, depsgraph):
        camera = depsgraph.scene.camera
        self.rman_scene.context = context
        self.rman_scene.depsgraph = depsgraph
        self.rman_scene.bl_scene = depsgraph.scene_eval
        rman_sg_camera = self.rman_scene.main_camera
        translator = self.rman_scene.rman_translators['CAMERA']
        with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):
            if self.rman_scene.is_viewport_render:
                ob = translator.update_viewport_resolution(rman_sg_camera)
                if ob:
                    translator.update_viewport_cam(ob, rman_sg_camera, force_update=True)
                translator.update_transform(None, rman_sg_camera)
            else:
                translator.update_transform(camera, rman_sg_camera)  

    def _scene_updated(self):

        # Check changes to local view
        if self.rman_scene.bl_local_view and (self.rman_scene.context.space_data.local_view is None):
            self.rman_scene.bl_local_view = False
            for ob in self.rman_scene.bl_scene.objects:
                if ob.type in ('ARMATURE', 'CURVE', 'CAMERA', 'LIGHT'):
                    continue
                self.clear_instances(ob)
                self.update_instances.add(ob.original)
            with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):         
                self.rman_scene.check_solo_light()
        elif not self.rman_scene.bl_local_view and (self.rman_scene.context.space_data.local_view is not None):
            self.rman_scene.bl_local_view = True   
            for ob in self.rman_scene.bl_scene.objects:
                if ob.type in ('ARMATURE', 'CURVE', 'CAMERA', 'LIGHT'):
                    continue
                self.clear_instances(ob)               
                self.update_instances.add(ob.original)
            with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):                     
                self.rman_scene.check_solo_light()  

        # Check view_layer
        view_layer = self.rman_scene.depsgraph.view_layer
        if len(view_layer.objects) != self.rman_scene.num_objects_in_viewlayer:
            # objects can be removed from the viewlayer by hiding a collection. 
            # Figure out the difference using sets and re-emit their instances.
            self.rman_scene.num_objects_in_viewlayer = len(view_layer.objects)
            view_layer = self.rman_scene.depsgraph.view_layer
            set1 = set(self.rman_scene.objects_in_viewlayer)
            set2 =  set((view_layer.objects))
            set_diff1 = set1.difference(set2)
            set_diff2 = set2.difference(set1)

            objects = list(set_diff1.union(set_diff2))           
            for o in list(objects):
                try:
                    self.update_instances.add(o.original)
                    self.clear_instances(o)
                    self.update_particles.add(o)  
                    self.update_geometry_node_instances(o)     
                except:
                    continue

        self.rman_scene.objects_in_viewlayer = [o for o in view_layer.objects]            

        if self.rman_scene.bl_frame_current != self.rman_scene.bl_scene.frame_current:
            # frame changed, update any materials and objects that 
            # are marked as frame sensitive
            rfb_log().debug("Frame changed: %d -> %d" % (self.rman_scene.bl_frame_current, self.rman_scene.bl_scene.frame_current))
            self.rman_scene.bl_frame_current = self.rman_scene.bl_scene.frame_current
            material_translator = self.rman_scene.rman_translators["MATERIAL"]

            with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):  
                # update frame number
                options = self.rman_scene.sg_scene.GetOptions()
                options.SetInteger(self.rman.Tokens.Rix.k_Ri_Frame, self.rman_scene.bl_frame_current)
                self.rman_scene.sg_scene.SetOptions(options)        

                for mat in bpy.data.materials:   
                    db_name = object_utils.get_db_name(mat)  
                    rman_sg_material = self.rman_scene.rman_materials.get(mat.original, None)
                    if rman_sg_material and rman_sg_material.is_frame_sensitive:
                        material_translator.update(mat, rman_sg_material)

                for o in bpy.data.objects:
                    rman_type = object_utils._detect_primitive_(o)
                    rman_sg_node = self.rman_scene.rman_objects.get(o.original, None)
                    if not rman_sg_node:
                        continue
                    translator = self.rman_scene.rman_translators.get(rman_type, None)
                    if translator and rman_sg_node.is_frame_sensitive:
                        translator.update(o, rman_sg_node)                   

    def _mesh_light_update(self, mat):
        with self.rman_scene.rman.SGManager.ScopedEdit(self.rman_scene.sg_scene):
            for ob_inst in self.rman_scene.depsgraph.object_instances:
                psys = None
                if ob_inst.is_instance:
                    ob = ob_inst.instance_object
                    group_db_name =  object_utils.get_group_db_name(ob_inst)
{'fraction_non_alphanumeric': 0.06871609403254973, 'fraction_numerical': 0.0014466546112115732, 'mean_word_length': 2.1437016825829924, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4289123', 'n_tokens_mistral': 4214, 'n_tokens_neox': 4056, 'n_words': 846}