Ejemplo n.º 1
0
    def update_material_on_scene_objects(self, mat, depsgraph):
        """ Find all mesh material users and reapply material """
        material_override = depsgraph.view_layer.material_override
        frame_current = depsgraph.scene.frame_current

        use_contour = depsgraph.scene.rpr.is_contour_used(
            is_final_engine=False)

        if material_override and material_override.name == mat.name:
            objects = self.depsgraph_objects(depsgraph)
            active_mat = material_override
        else:
            objects = tuple(obj for obj in self.depsgraph_objects(depsgraph)
                            if mat.name in obj.material_slots.keys())
            active_mat = mat

        updated = False
        for obj in objects:
            rpr_material = material.sync_update(self.rpr_context,
                                                active_mat,
                                                obj=obj)
            rpr_volume = material.sync_update(self.rpr_context,
                                              active_mat,
                                              'Volume',
                                              obj=obj)
            rpr_displacement = material.sync_update(self.rpr_context,
                                                    active_mat,
                                                    'Displacement',
                                                    obj=obj)

            if not rpr_material and not rpr_volume and not rpr_displacement:
                continue

            indirect_only = obj.original.indirect_only_get(
                view_layer=depsgraph.view_layer)

            if object.key(obj) not in self.rpr_context.objects:
                object.sync(self.rpr_context,
                            obj,
                            indirect_only=indirect_only,
                            frame_current=frame_current,
                            use_contour=use_contour)
                updated = True
                continue

            updated |= object.sync_update(self.rpr_context,
                                          obj,
                                          False,
                                          False,
                                          indirect_only=indirect_only,
                                          material_override=material_override,
                                          frame_current=frame_current,
                                          use_contour=use_contour)

        return updated
    def update_material_on_scene_objects(self, mat, depsgraph):
        """ Find all mesh material users and reapply material """
        material_override = depsgraph.view_layer.material_override

        if material_override and material_override.name == mat.name:
            objects = self.depsgraph_objects(depsgraph)
            active_mat = material_override
        else:
            objects = tuple(obj for obj in self.depsgraph_objects(depsgraph)
                            if mat.name in obj.material_slots.keys())
            active_mat = mat

        has_uv_map = material.has_uv_map_node(active_mat)

        updated = False
        for obj in objects:
            rpr_material, rpr_volume, rpr_displacement = \
                self.get_object_rpr_materials(obj, active_mat, has_uv_map)

            if not rpr_material and not rpr_volume and not rpr_displacement:
                continue

            indirect_only = obj.original.indirect_only_get(
                view_layer=depsgraph.view_layer)

            if object.key(obj) not in self.rpr_context.objects:
                object.sync(self.rpr_context, obj, indirect_only=indirect_only)
                updated = True
                continue

            updated |= object.sync_update(self.rpr_context,
                                          obj,
                                          False,
                                          False,
                                          indirect_only=indirect_only,
                                          material_override=material_override)

        return updated
    def sync_update(self, context, depsgraph):
        """ sync just the updated things """

        if not self.is_synced:
            return

        if context.selected_objects != self.selected_objects:
            # only a selection change
            self.selected_objects = context.selected_objects
            return

        frame_current = depsgraph.scene.frame_current

        # get supported updates and sort by priorities
        updates = []
        for obj_type in (bpy.types.Scene, bpy.types.World, bpy.types.Material,
                         bpy.types.Object, bpy.types.Collection,
                         bpy.types.Light):
            updates.extend(update for update in depsgraph.updates
                           if isinstance(update.id, obj_type))

        sync_collection = False
        sync_world = False
        is_updated = False
        is_obj_updated = False

        material_override = depsgraph.view_layer.material_override

        shading_data = ShadingData(context)
        if self.shading_data != shading_data:
            sync_world = True

            if self.shading_data.use_scene_lights != shading_data.use_scene_lights:
                sync_collection = True

            self.shading_data = shading_data

        self.rpr_context.blender_data['depsgraph'] = depsgraph

        # if view mode changed need to sync collections
        mode_updated = False
        if self.view_mode != context.mode:
            self.view_mode = context.mode
            mode_updated = True

        if not updates and not sync_world and not sync_collection:
            return

        self._sync_update_before()
        with self.render_lock:
            for update in updates:
                obj = update.id
                log("sync_update", obj)
                if isinstance(obj, bpy.types.Scene):
                    is_updated |= self.update_render(obj, depsgraph.view_layer)

                    # Outliner object visibility change will provide us only bpy.types.Scene update
                    # That's why we need to sync objects collection in the end
                    sync_collection = True

                    if is_updated:
                        self.is_resolution_adapted = not self.user_settings.adapt_viewport_resolution

                    continue

                if isinstance(obj, bpy.types.Material):
                    is_updated |= self.update_material_on_scene_objects(
                        obj, depsgraph)
                    continue

                if isinstance(obj, bpy.types.Object):
                    if obj.type == 'CAMERA':
                        continue

                    indirect_only = obj.original.indirect_only_get(
                        view_layer=depsgraph.view_layer)
                    active_and_mode_changed = mode_updated and context.active_object == obj.original
                    is_updated |= object.sync_update(
                        self.rpr_context,
                        obj,
                        update.is_updated_geometry or active_and_mode_changed,
                        update.is_updated_transform,
                        indirect_only=indirect_only,
                        material_override=material_override,
                        frame_current=frame_current)
                    is_obj_updated |= is_updated
                    continue

                if isinstance(obj, bpy.types.Light):
                    light = obj
                    for obj in self.depsgraph_objects(depsgraph):
                        if obj.data == light:
                            is_updated |= object.sync_update(
                                self.rpr_context, obj, True, False)

                if isinstance(obj, bpy.types.World):
                    sync_world = True

                if isinstance(obj, bpy.types.Collection):
                    sync_collection = True
                    continue

            if sync_world:
                world_settings = self._get_world_settings(depsgraph)
                if self.world_settings != world_settings:
                    self.world_settings = world_settings
                    self.world_settings.export(self.rpr_context)
                    is_updated = True

            if sync_collection:
                is_updated |= self.sync_objects_collection(depsgraph)

            if is_obj_updated:
                if self.background_filter:
                    self.rpr_context.sync_catchers(False)
                    bg_filter_enabled = self.rpr_context.use_reflection_catcher or self.rpr_context.use_shadow_catcher
                    background_filter_settings = {
                        'enable': bg_filter_enabled,
                        'use_background': False,
                        'use_shadow': self.rpr_context.use_shadow_catcher,
                        'use_reflection':
                        self.rpr_context.use_reflection_catcher,
                        'resolution': (self.width, self.height)
                    }
                    self.setup_background_filter(background_filter_settings)
                else:
                    self.rpr_context.sync_catchers()

        if is_updated:
            self.restart_render_event.set()
            self._sync_update_after()
    def sync_update(self, context, depsgraph):
        """ sync just the updated things """

        if not self.is_synced:
            return

        # get supported updates and sort by priorities
        updates = []
        for obj_type in (bpy.types.Scene, bpy.types.World, bpy.types.Material,
                         bpy.types.Object, bpy.types.Collection):
            updates.extend(update for update in depsgraph.updates
                           if isinstance(update.id, obj_type))

        sync_collection = False
        sync_world = False
        is_updated = False
        is_obj_updated = False

        material_override = depsgraph.view_layer.material_override

        shading_data = ShadingData(context)
        if self.shading_data != shading_data:
            sync_world = True

            if self.shading_data.use_scene_lights != shading_data.use_scene_lights:
                sync_collection = True

            self.shading_data = shading_data

        self.rpr_context.blender_data['depsgraph'] = depsgraph

        with self.render_lock:
            for update in updates:
                obj = update.id
                log("sync_update", obj)
                if isinstance(obj, bpy.types.Scene):
                    is_updated |= self.update_render(obj, depsgraph.view_layer)

                    # Outliner object visibility change will provide us only bpy.types.Scene update
                    # That's why we need to sync objects collection in the end
                    sync_collection = True

                    continue

                if isinstance(obj, bpy.types.Material):
                    if material.has_uv_map_node(obj):
                        self.remove_material_uvs_instances(obj, depsgraph)

                    mesh_obj = context.object if context.object and \
                                                 context.object.type == 'MESH' else None
                    material.sync_update(self.rpr_context, obj, mesh_obj)
                    is_updated |= self.update_material_on_scene_objects(
                        obj, depsgraph)
                    continue

                if isinstance(obj, bpy.types.Object):
                    if obj.type == 'CAMERA':
                        continue

                    indirect_only = obj.original.indirect_only_get(
                        view_layer=depsgraph.view_layer)
                    is_updated |= object.sync_update(
                        self.rpr_context,
                        obj,
                        update.is_updated_geometry,
                        update.is_updated_transform,
                        indirect_only=indirect_only,
                        material_override=material_override)
                    is_obj_updated |= is_updated
                    continue

                if isinstance(obj, bpy.types.World):
                    sync_world = True

                if isinstance(obj, bpy.types.Collection):
                    sync_collection = True
                    continue

            if sync_world:
                world_settings = self._get_world_settings(depsgraph)
                if self.world_settings != world_settings:
                    self.world_settings = world_settings
                    self.world_settings.export(self.rpr_context)
                    is_updated = True

            if sync_collection:
                is_updated |= self.sync_objects_collection(depsgraph)

            if is_obj_updated:
                with self.resolve_lock:
                    self.rpr_context.sync_catchers()

        if is_updated:
            self.restart_render_event.set()